> ## Documentation Index
> Fetch the complete documentation index at: https://developer.eka.care/llms.txt
> Use this file to discover all available pages before exploring further.

# Get Slots

> Bookable slots for a doctor or a clinic, one entry per schedule per clinic.

Replaces [Get Appointment Slots (Legacy)](https://developer.eka.care/api-sdk/emr/appointment-api/get-appointment-slots.md).

Every schedule mapped against that doctor and clinic: patient, front desk or IPD.

## Query keys

| Key | Required | What it means | If you leave it out |
| - | - | - | - |
| `doc_id` | yes | Doctor id. For clinic slots, use the clinic id in its place | `400 MISSING_DOC_ID` |
| `startTime` | yes | Window start, ISO with `Z`: `2026-11-13T18:30:00.000Z` | `400` |
| `endTime` | yes | Window end, same format | `400` |
| `cid` | no | Clinic id | Every clinic of the doctor |
| `bookable_by` | no | `patient`, `front_desk` or `ipd`. See below | Every schedule |
| `schedule_id` | no | Only this schedule's slots | Slots of all schedules |
| `service_id` | no | Only that service is returned | Every service mapped |
| `mode` | no | `in-clinic` or `tele` | Both |
| `duration` | no | Slot length in minutes. Only duration schedules use it; service schedules ignore it. A length the schedule doesn't have (e.g. `45` when `slot_durations` is `[15, 30, 60]`) falls back to the shortest one, see [Slot length in a duration schedule](#slot-length-in-a-duration-schedule) | The schedule's shortest length |
| header `time-zone` | no | Time zone of `s` and `e` in the reply | `Asia/Kolkata` |

> [!NOTE]
>
> **`mode` is set on each service, not on the schedule.**
>
> * Service schedule: every service is `in-clinic`, `tele`. `mode=tele` gives only the tele services' slots. in service based schedules are mapped on the service
> * Duration schedule: it has no services, so its slots are for both `in-clinic` and `tele`. `mode` is ignored.

## `bookable_by`

| Value | Who books | What changes in the reply |
| - | - | - |
| `patient` | The slots/schedules you want to expose to the patient for booking: your website, booking page, patient app, the slots you might send to the patient over whats-app, etc | Services with `allow_patient_booking: false` are hidden, even when you also send `schedule_id`. Duration schedules are skipped; if only those exist, `400`. With `schedule_id`, that schedule is served even if it is a duration schedule |
| `front_desk` | Anyone booking from the clinic side: your reception, front desk, doctor, clinic staff, or your own EMR | Nothing hidden |
| `ipd` | Bookings for admitted (in-patient) patients | Nothing hidden |

Whatever you send, only regular services get slots. Follow-up services (`appointment_type` other than `REGULAR`) and archived services never do.

## Which schedules come back

| You send | You get |
| - | - |
| `schedule_id` | Only that schedule, whoever can book on it. Not this doctor's or clinic's: `404` |
| `bookable_by` | Every active schedule that group can book on |
| Neither | Every active schedule. A schedule that both patients and the front desk can book on comes once |

With `mode`, `service_id` or `bookable_by=patient`, a service schedule that never offers a matching service is left out. Example: `mode=tele` leaves out a schedule that only has in-clinic services. A schedule that offers it but has no slots between `startTime` and `endTime` stays, with empty slots and `next`. Duration schedules always stay. If nothing is left: `404`.

## Clinic slots (no doctor)

> [!NOTE]
>
> Put the clinic id in **both** `doc_id` and `cid`:
>
> `?doc_id=c-cc6a93720d7445af890c4cc0&cid=c-cc6a93720d7445af890c4cc0`
>
> You get the clinic's own schedules and services. `doctor_oid` comes back `null`. Clinic schedules are read in IST.
>
> To make one, call [Create Schedule](https://developer.eka.care/api-sdk/emr/appointment-api/create-schedule.md) with the clinic id in both `entity_id` and `location_id`.

## Service schedules vs duration schedules

A duration schedule has no services. Its slots are plain time cut at one length, so `conf_id` is `null`, it has no `services` list, and it adds nothing to the top-level `services`. A reply with only duration schedules has `services: []`.

| | Service schedule (`slot_mode: service`) | Duration schedule (`slot_mode: duration`) |
| - | - | - |
| Slot length | Each service's own `duration` | The `duration` you send if it is in the schedule's `slot_durations`, else the shortest one there |
| Slots come in | `services[].slots`, one list per service type | `slots` |
| `conf_id` on a slot | The service it books | `null` |
| `service_id`, `mode` | Applied | Ignored |

Service slots also follow each service's booking window: none sooner than `book_before_mins` from now, none later than `book_ahead_days` ahead. Past slots never come back.

### Slot length in a duration schedule

A schedule with `slot_durations: [15, 30, 60]`:

| `duration` you send | Slots are cut at | `slot_duration` in the reply |
| - | - | - |
| `30` | 30 minutes | `30` |
| `40`, not in `slot_durations` | 15 minutes, the shortest | `15` |
| Left out | 15 minutes, the shortest | `15` |

> [!WARNING]
>
> A `duration` the schedule doesn't have is not an error. You get `200` with slots at the shortest length. Read `slot_duration` before you show or book a slot, so a 15-minute slot is not shown as a 40-minute one.

## Dates

> [!WARNING]
>
> Send `startTime` and `endTime` as full ISO with `Z`. One day in India is `startTime=2026-11-13T18:30:00.000Z&endTime=2026-11-14T18:29:59.999Z`.
>
> A date alone (`2026-11-14`) means 00:00 UTC, which is 05:30 IST, so early-morning slots get cut.

## Errors

| Status | `error` | Why |
| - | - | - |
| `400` | `Invalid date input: ...` | `startTime` or `endTime` is bad, or the end is before the start |
| `400` | `MISSING_DOC_ID` | No `doc_id` |
| `400` | `Invalid <key>` | Bad value, or the same key sent twice |
| `400` | `Unpaid doctor account` | The doctor's Eka plan is not active |
| `400` | `duration-based schedules are not available on this endpoint` | when you send `bookable_by=patient`, but the doctor/clinic has ONLY duration based schedules |
| `400` | `INTERNAL_ERROR` | Something failed on our side. Retry |
| `404` | `Schedule not setup for the doctor` | No active schedule for this doctor and clinic |
| `404` | `Schedule not found` | `schedule_id` is unknown or not this doctor's |
| `404` | `No schedule offers the requested mode / service_id` | You sent `mode`, `service_id` or `bookable_by=patient`, and no schedule offers a matching service |

Every error body carries empty `data`: `{ "schedules": [], "services": [] }`.

## Coming from Get Appointment Slots (Legacy)

| | Legacy | Get Slots |
| - | - | - |
| Path | `/dr/v1/doctor/{doctor_id}/clinic/{clinic_id}/appointment/slot` | `/dr/v1/slots?doc_id=...&cid=...` |
| Dates | `start_date`, `end_date` | `startTime`, `endTime` |
| Schedules | Only the one patients book on | Any. Pick with `bookable_by` or `schedule_id` |
| Reply shape | Objects keyed by clinic and service | Lists: `schedules[]`, `services[]` |
| Errors | Empty body, no reason | The reason is in `error` |
| Unpaid doctor | Slots still come back | `400 Unpaid doctor account` |


## OpenAPI

````yaml get /dr/v1/slots
openapi: 3.0.0
info:
  title: Ekacare API & Webhook Documentation
  contact: {}
  version: '1.0'
servers:
  - description: Production
    url: https://api.eka.care
  - description: Stage/Sandbox
    url: https://api.dev.eka.care
security: []
paths:
  /dr/v1/slots:
    get:
      tags:
        - Appointment API
      summary: Get Slots
      description: >-
        Bookable slots for a doctor or a clinic, one entry per schedule per
        clinic.
      operationId: GetSlots
      parameters:
        - name: auth
          in: header
          description: ''
          required: true
          style: simple
          schema:
            type: string
            example: auth
        - name: time-zone
          in: header
          description: >-
            Time zone for `s` and `e` in the reply, e.g. `Asia/Dubai`. Defaults
            to `Asia/Kolkata`.
          required: false
          style: simple
          schema:
            type: string
            example: Asia/Kolkata
        - name: doc_id
          in: query
          description: >-
            Doctor id. For clinic slots, use the clinic id in its place (send
            the same id in `cid`).
          required: true
          style: form
          explode: true
          schema:
            type: string
            example: '174368482468425'
        - name: startTime
          in: query
          description: >-
            Window start, ISO-8601 with `Z`. A date alone (`2026-11-14`) means
            00:00 UTC, which is 05:30 in India.
          required: true
          style: form
          explode: true
          schema:
            type: string
            example: '2026-11-13T18:30:00.000Z'
        - name: endTime
          in: query
          description: Window end, same format. Must not be before `startTime`.
          required: true
          style: form
          explode: true
          schema:
            type: string
            example: '2026-11-14T18:29:59.999Z'
        - name: cid
          in: query
          description: Clinic id. Leave it out to get every clinic of the doctor.
          required: false
          style: form
          explode: true
          schema:
            type: string
            example: 67ee84d9087b41001de0cfb1
        - name: bookable_by
          in: query
          description: >-
            Only schedules this group can book on: `patient` (patients book by
            themselves), `front_desk` (anyone booking from the clinic side: your
            reception, front desk, doctor, clinic staff, or your own EMR) or
            `ipd` (admitted patients). Leave it out to get every schedule.
          required: false
          style: form
          explode: true
          schema:
            type: string
            enum:
              - patient
              - front_desk
              - ipd
        - name: schedule_id
          in: query
          description: >-
            Only this schedule, whoever can book on it. `bookable_by=patient`
            still hides services patients can't book.
          required: false
          style: form
          explode: true
          schema:
            type: string
            example: 6a7b046c1cf45d28c2c308b3
        - name: service_id
          in: query
          description: >-
            Only services of this service type, e.g. Consultation. A service
            schedule that never offers it is left out. Duration schedules ignore
            it.
          required: false
          style: form
          explode: true
          schema:
            type: integer
            example: 444895
        - name: mode
          in: query
          description: >-
            Only services offered in this mode. A service schedule that never
            offers this mode is left out. Duration schedules ignore it.
          required: false
          style: form
          explode: true
          schema:
            type: string
            enum:
              - in-clinic
              - tele
        - name: duration
          in: query
          description: >-
            Slot length in minutes, for duration schedules only. If it is in the
            schedule's `slot_durations`, slots are cut at it. If it is not, or
            you leave it out, slots are cut at the shortest length in
            `slot_durations` (not an error). `slot_duration` in the reply is the
            length used.
          required: false
          style: form
          explode: true
          schema:
            type: integer
            example: 15
      responses:
        '200':
          description: OK
          content:
            application/json:
              schema:
                type: object
                properties:
                  success:
                    type: boolean
                    example: true
                  data:
                    type: object
                    properties:
                      schedules:
                        type: array
                        description: One entry per schedule per clinic.
                        items:
                          type: object
                          properties:
                            schedule_id:
                              type: string
                            name:
                              type: string
                            doctor_oid:
                              type: string
                              nullable: true
                              description: The doctor. `null` for clinic slots.
                            clinic_id:
                              type: string
                            slot_mode:
                              type: string
                              enum:
                                - service
                                - duration
                              description: >-
                                `service`: slots are grouped under `services`,
                                one list per service type. `duration`: one plain
                                `slots` list.
                            services:
                              type: array
                              description: Only when `slot_mode` is `service`.
                              items:
                                type: object
                                properties:
                                  service_id:
                                    type: integer
                                    description: Service type, e.g. Consultation.
                                  slots:
                                    type: array
                                    items:
                                      $ref: '#/components/schemas/GetSlotsSlot'
                            slot_durations:
                              type: array
                              items:
                                type: integer
                              description: >-
                                Only when `slot_mode` is `duration`. Lengths
                                this schedule allows, in minutes.
                            slot_duration:
                              type: integer
                              nullable: true
                              description: >-
                                Only when `slot_mode` is `duration`. Length the
                                slots are cut at: the `duration` you sent if it
                                is in `slot_durations`, else the shortest one in
                                `slot_durations`. `null`, with empty `slots`,
                                only if the schedule has no `slot_durations`
                                saved.
                            slots:
                              type: array
                              description: Only when `slot_mode` is `duration`.
                              items:
                                $ref: '#/components/schemas/GetSlotsSlot'
                      services:
                        type: array
                        description: >-
                          Every service used in `schedules`, with all its keys:
                          price, length, mode and more. Same object as List
                          Services. Empty when only duration schedules come
                          back.
                        items:
                          type: object
                          properties:
                            conf_id:
                              type: string
                            service_id:
                              type: integer
                            service_name:
                              type: string
                            duration:
                              type: integer
                            price:
                              type: number
                            currency:
                              type: string
                            mode:
                              type: array
                              items:
                                type: string
                            allow_patient_booking:
                              type: boolean
                            book_ahead_days:
                              type: integer
                            book_before_mins:
                              type: integer
                      next:
                        type: object
                        description: >-
                          First day after your window with open weekly hours and
                          no block. Service schedules only.
                        properties:
                          av:
                            type: boolean
                            description: '`true` when such a day exists.'
                          av_date:
                            type: string
                            description: That day as ISO. Missing when `av` is `false`.
              example:
                success: true
                data:
                  schedules:
                    - schedule_id: 6a5073b865b26270f8a5d4a3
                      name: Morning OPD
                      doctor_oid: '174368482468425'
                      clinic_id: 67ee84d9087b41001de0cfb1
                      slot_mode: service
                      services:
                        - service_id: 444895
                          slots:
                            - s: '2026-11-14T09:00:00+05:30'
                              e: '2026-11-14T09:15:00+05:30'
                              available: true
                              slots_booked: 0
                              is_calendar_blocked: false
                              in_schedule: true
                              conf_id: 3bee28a5c1d94f0e
                              slot_duration: 15
                            - s: '2026-11-14T09:15:00+05:30'
                              e: '2026-11-14T09:30:00+05:30'
                              available: false
                              slots_booked: 1
                              is_calendar_blocked: false
                              in_schedule: true
                              conf_id: 3bee28a5c1d94f0e
                              slot_duration: 15
                    - schedule_id: 6a68f727583a473d68758ab3
                      name: Front desk walk-ins
                      doctor_oid: '174368482468425'
                      clinic_id: 67ee84d9087b41001de0cfb1
                      slot_mode: duration
                      slot_durations:
                        - 15
                        - 30
                      slot_duration: 15
                      slots:
                        - s: '2026-11-14T17:00:00+05:30'
                          e: '2026-11-14T17:15:00+05:30'
                          available: true
                          slots_booked: 0
                          is_calendar_blocked: false
                          in_schedule: true
                          conf_id: null
                          slot_duration: 15
                  services:
                    - conf_id: 3bee28a5c1d94f0e
                      service_id: 444895
                      service_name: Consultation
                      duration: 15
                      price: 500
                      currency: INR
                      mode:
                        - in-clinic
                      allow_patient_booking: true
                      book_ahead_days: 30
                      book_before_mins: 0
                  next:
                    av: true
                    av_date: '2026-11-15T18:30:00.000Z'
        '400':
          description: >-
            Bad request, or the doctor can't be served right now. `error` says
            why; see the Errors table on this page.
          content:
            application/json:
              schema:
                type: object
                properties:
                  success:
                    type: boolean
                    example: false
                  error:
                    type: string
                  data:
                    type: object
                    properties:
                      schedules:
                        type: array
                        items:
                          type: object
                      services:
                        type: array
                        items:
                          type: object
              example:
                success: false
                error: Unpaid doctor account
                data:
                  schedules: []
                  services: []
        '404':
          description: >-
            No schedule found for this doctor and clinic, or `schedule_id` is
            unknown, or you sent `mode`, `service_id` or `bookable_by=patient`
            and no schedule offers a matching service.
          content:
            application/json:
              schema:
                type: object
                properties:
                  success:
                    type: boolean
                    example: false
                  error:
                    type: string
                  data:
                    type: object
              example:
                success: false
                error: Schedule not setup for the doctor
                data:
                  schedules: []
                  services: []
      deprecated: false
components:
  schemas:
    GetSlotsSlot:
      title: GetSlotsSlot
      type: object
      properties:
        s:
          type: string
          description: Slot start, ISO, in the `time-zone` header zone.
        e:
          type: string
          description: Slot end.
        available:
          type: boolean
          description: >-
            `true` = can be booked: not blocked, and fewer bookings than the
            schedule's `overbooking_limit`.
        slots_booked:
          type: integer
          description: Appointments already in this slot.
        is_calendar_blocked:
          type: boolean
          description: '`true` = a block covers this time (leave, holiday).'
        in_schedule:
          type: boolean
          description: Always `true`. Ignore it.
        conf_id:
          type: string
          nullable: true
          description: The service this slot books. `null` in a duration schedule.
        slot_duration:
          type: integer
          description: Slot length in minutes.

````

This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.