Doctor shifts
The queue shifts a doctor is running on a given date, with fees and capacity.
GET /v1/qms-appointments/doctor/shiftsThe queue equivalent of available slots. A QMS doctor does not sell fixed times — they run shifts, and a patient takes a numbered token in one. This returns the shifts for a single day, with how full each one already is.
You need the qmsWorkShiftId from here before you can book a token.
No OTP is needed to read shifts.
Query parameters
| Name | Type | Required | Description |
|---|---|---|---|
addressId | number | Yes | The clinic location. |
doctorId | number | Yes | The practitioner. |
date | string | Yes | YYYY-MM-DD in the clinic's timezone. The calendar is always day-scoped. |
workspaceId | number | No | Defaults to the workspace your key belongs to, which is what you want. |
Try it
/v1/qms-appointments/doctor/shiftsQuery
GET /v1/qms-appointments/doctor/shifts?addressId=1&doctorId=4&date=2026-10-12https://api.medos.oneUse a dedicated test key, and put your browser's address on its allowlist
A Developer API key authenticates on its own, so it only works from the addresses registered against it — and this page calls from your browser, not your servers. Unless your own public address is on the list you get a 403 naming it, which is the allowlist doing its job. Your browser may also reach us over IPv6 even when your server does not, so the address in the error is often not the one you expected. The key here is kept in memory only and never written to storage, but create a test key for it and deactivate that key when you are done.
Request
curl -sG "https://api.medos.one/v1/qms-appointments/doctor/shifts" \
-H "x-api-key: $MEDOS_API_KEY" \
--data-urlencode "addressId=1" \
--data-urlencode "doctorId=4" \
--data-urlencode "date=2026-09-20"Response
{
"doctor": { "id": 4, "name": "Dr. Meera Rao" },
"clinicTimezone": "Asia/Kolkata",
"international": false,
"billingCurrency": "INR",
"domesticCurrency": "INR",
"dates": [
{
"date": "2026-09-20",
"shifts": [
{
"qmsWorkShiftId": 331,
"startTime": "09:00",
"endTime": "13:00",
"mode": "OFFLINE",
"consultationFee": 400,
"internationalFee": 25,
"avgDuration": 480,
"bookedCount": 12,
"maxAppointments": 40,
"isStarted": true,
"isEnded": false,
"actualStartedAt": "2026-09-20T09:04:11+05:30",
"actualEndedAt": null
}
]
}
]
}| Field | Meaning |
|---|---|
qmsWorkShiftId | What you send when booking a token. |
mode | OFFLINE or ONLINE. Queue shifts do not offer the home-visit modes. |
consultationFee / internationalFee | The domestic and international price for this shift. Which one applies is decided by isInternational at booking time. |
avgDuration | Average seconds per patient, from this doctor's history — what a wait-time estimate is built from. |
bookedCount / maxAppointments | How full the shift is. Equal values mean it is full. |
isStarted / isEnded | Whether the queue is running. This is what separates the two booking routes below. |
billingCurrency | The currency the patient will actually be charged in. |
Which booking route
| Shift state | Route |
|---|---|
isStarted: false | Pre-book a token |
isStarted: true, isEnded: false | Immediate token |
isEnded: true | Neither — the queue is closed for the day. |
Common failures
| Status | Cause |
|---|---|
400 | date is not YYYY-MM-DD. |
An empty calendar is a 200, not a 404
A doctor who is not set up for the queue system comes back as
{ "dates": [] } rather than an error, so you can render a "not available"
state instead of handling a failure. An empty dates array therefore means
either no shifts that day or not a queue doctor — check whether the
doctor offers scheduled slots
instead.