An availability is one block of time on one day in which a practitioner offers appointments of one availability type. Free slots are what is left of the availabilities after appointments are booked; see Free slots and booking.
Requirements
- Appointment booking must be enabled for the organization. Without it, every endpoint on this page returns
403with the codefeature_disabled. - Instance tokens name the organization with
organization_idororganization_external_idwhen they create an availability, and may use them as a filter on lists. - The practitioner must exist in the organization and be a practitioner (
doctor), or a medical assistant where medical assistants may plan. Any other reference returns404.
The availability object
| Field | Type | Description |
|---|---|---|
id |
string (uuid) | MeetOne's ID of the availability. |
external_id |
string, nullable | Your key for the availability. Unique within the organization. See Identifiers. |
doctor |
object | The practitioner: id, external_id, first_name, last_name. |
availability_type |
object | The type: id, external_id, display_name. |
starts_at, ends_at |
string (date-time) | The block as ISO 8601 timestamps in Europe/Berlin. |
date |
string (date) | The day, e.g. 2026-10-12. |
start_time, end_time |
string | The times of day as HH:MM, e.g. 09:00. |
created_at, updated_at |
string (date-time) | Timestamps. |
date, start_time and end_time say the same as starts_at and ends_at; use whichever is easier for your system.
Rules
- An availability lies within one day in
Europe/Berlin:starts_atandends_athave to fall on the same calendar day (422, codesame_day, attributeends_at), andends_athas to be afterstarts_at(422, codenot_after_start_time, attributeends_at). - It lies within the working day of the organization (settings
planner_day_start_hourandplanner_day_end_hour, see Organizations endpoints). Otherwise422with the codeoutside_working_hours. - It must not overlap another availability of the same type of the same practitioner (
422, codeoverlaps, attributestarts_at). Availabilities of different types may overlap each other; a booking in one type still takes the practitioner's time away from the others.
List availabilities
GET /api/v1/availabilities
from and to are required and bound the days to list. The range covers at most 92 days (to at most 92 days after from); otherwise 422 with the code invalid and the attribute to.
| Query parameter | Type | Description |
|---|---|---|
from |
string (date) | First day, e.g. 2026-10-12. Required. |
to |
string (date) | Last day, inclusive. Required. |
doctor_id, doctor_external_id |
string | Only this practitioner's availabilities. |
availability_type_id, availability_type_external_id |
string | Only availabilities of this type. |
external_id |
string | Only the availability with this external ID. |
organization_id, organization_external_id |
string | Instance tokens: only this organization's availabilities. |
updated_since |
string (date-time) | Only availabilities changed at or after this time. |
page, per_page |
integer | Pagination. |
Availabilities are listed by day and start time, unless you use updated_since.
curl "https://acme.meetone.io/api/v1/availabilities?from=2026-10-12&to=2026-10-18&doctor_external_id=staff-12" \
-H "Authorization: Bearer $TOKEN"
Create an availability
POST /api/v1/availabilities
| Field | Type | Required | Description |
|---|---|---|---|
doctor_id or doctor_external_id |
string | Yes | The practitioner. |
availability_type_id or availability_type_external_id |
string | Yes | The type. |
starts_at, ends_at |
string (date-time) | Yes | The block. A time without an offset is read in Europe/Berlin. |
external_id |
string | No | Your key for the availability. |
repeat |
object | No | Creates copies on the following days or weeks. See Repeat. |
curl -X POST "https://acme.meetone.io/api/v1/availabilities" \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{
"doctor_external_id": "staff-12",
"availability_type_external_id": "first-visit",
"starts_at": "2026-10-12T09:00:00+02:00",
"ends_at": "2026-10-12T12:00:00+02:00",
"external_id": "shift-2026-10-12"
}'
A successful request returns 201 Created:
{
"data": {
"id": "2a8f6d14-95b3-4e0c-87d1-c4b9e3a7f520",
"external_id": "shift-2026-10-12",
"doctor": {
"id": "b7d2e9c4-1a3f-4c58-8e66-2f9a0d7c5b13",
"external_id": "staff-12",
"first_name": "Maria",
"last_name": "Muster"
},
"availability_type": {
"id": "5d9a2f77-c3e1-4b08-8a64-7e1f0c92d3b6",
"external_id": "first-visit",
"display_name": "First visit"
},
"starts_at": "2026-10-12T09:00:00+02:00",
"ends_at": "2026-10-12T12:00:00+02:00",
"date": "2026-10-12",
"start_time": "09:00",
"end_time": "12:00",
"created_at": "2026-10-08T10:00:00+02:00",
"updated_at": "2026-10-08T10:00:00+02:00"
}
}
Free slots follow a grid that starts at the beginning of the working day and advances by the type's slot_duration, and a slot is only offered when it fits completely inside an availability. Align availabilities with that grid: for a type with 30-minute slots, start and end them on the hour or the half hour.
Repeat
With repeat, MeetOne copies the availability to the following days or weeks in one request:
| Field | Type | Description |
|---|---|---|
repeat.interval |
string (enum) | daily or weekly. |
repeat.count |
integer | 1 to 52. The number of availabilities including the one you send. |
curl -X POST "https://acme.meetone.io/api/v1/availabilities" \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{
"doctor_external_id": "staff-12",
"availability_type_external_id": "first-visit",
"starts_at": "2026-10-12T09:00:00+02:00",
"ends_at": "2026-10-12T12:00:00+02:00",
"external_id": "series-2026-10-12",
"repeat": { "interval": "weekly", "count": 4 }
}'
This creates four availabilities, on 12, 19 and 26 October and 2 November. The response is 201 Created and data is a list of the whole series, with the availability you sent first:
{
"data": [
{ "id": "2a8f6d14-95b3-4e0c-87d1-c4b9e3a7f520", "external_id": "series-2026-10-12", "date": "2026-10-12", "...": "..." },
{ "id": "7e3b9c51-0d2a-4f68-a1c4-5b8d2e6f9a03", "external_id": null, "date": "2026-10-19", "...": "..." },
{ "id": "d05a1f8e-3b7c-4296-8e4d-1c9a6b2f7e30", "external_id": null, "date": "2026-10-26", "...": "..." },
{ "id": "48c2e7a1-9f5d-4b03-b6e8-0a3d7c1f5b92", "external_id": null, "date": "2026-11-02", "...": "..." }
]
}
A repeat is atomic: either the whole series is created, or nothing is. If any copy would overlap an availability of the same type of the same practitioner, the response is 422 with the code overlaps and the attribute repeat, and no availability is created, not even the first one. The message names the first date that is taken in ISO 8601 format, for example 2026-10-15. Unlike the planner in the app, the API never deletes overlapping availabilities for you.
The external_id applies to the first availability only, because external IDs must be unique. Copies have external_id null; set theirs afterwards with PATCH if you need them. An unknown interval returns 422 (code inclusion, attribute repeat.interval), and so does a count outside 1 to 52 (code invalid, attribute repeat.count).
Show an availability
GET /api/v1/availabilities/{id} returns the availability in the object shown above, or 404 if it does not exist or belongs to another organization.
Update an availability
PATCH /api/v1/availabilities/{id}
Send only the fields you want to change: doctor_id/doctor_external_id, availability_type_id/availability_type_external_id and external_id. To move the block, send starts_at and ends_at together; one without the other returns 422 (blank). The same rules apply as on creation.
curl -X PATCH "https://acme.meetone.io/api/v1/availabilities/2a8f6d14-95b3-4e0c-87d1-c4b9e3a7f520" \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{ "starts_at": "2026-10-12T10:00:00+02:00", "ends_at": "2026-10-12T13:00:00+02:00" }'
Delete an availability
DELETE /api/v1/availabilities/{id} returns 204 No Content. Appointments that are already booked inside the availability stay as they are; only the times that were still free disappear from the free slots.
Related
Questions? Contact us at support@meetone.io.