Get free appointment slots for a Doctolib practitioner.
Free Doctolib appointment slots for one practitioner, visit type (motive), agendas and practice, from a start date for up to 7 days, grouped by day, plus the next free slot when the window is empty. Takes visit_motive_id, agenda_ids and practice_id from doctolib.de/search-practitioners. Exact slot times can be passed to doctolib.de/book-slot.
- Site
- Doctolib, Germany
- Version
- v1
- Runs, last 7 days
- No reports yet
- sha256
- 1495ecf8e9b7…
Requests
sent from your browser, in order- 1GET/availabilities.json?agenda_ids&insurance_sector&limit&practice_ids&start_date&telehealth&visit_motive_ids
Parameters
from your agentagenda_idsinteger[]required
daysinteger = 7
insurance_sectorenumMust match the patient's insurance; a wrong sector returns empty days, not an error "public" | "private" = "public"
practice_idintegerrequired
start_datestringrequiredYYYY-MM-DD
telehealthbooleanVideo consultation slots = false
visit_motive_idintegerrequired
Returns
to your agentdaysobject[]date, slots, times
next_slotstringNext free slot after the window
reasonstringDoctolib's explanation when nothing is bookable
totalintegerFree slots in the window
Where it can send
- www.doctolib.de
Anything else is blocked by the extension.
Reads from your session
Nothing. Your browser attaches the site's cookies by itself.
Used only in requests to the addresses on the left. Never sent to wield.run or your agent.
Checks
a run passes when- output.total > `0` || output.next_slot != `null` || output.reason != `null`
- length(output.days) <= `7`
Raw recipe
Served as canonical JSON from /api/v1/recipes/doctolib.de/get-slots, so its sha256 matches the ETag and the index.
Check it yourself
curl -s https://wield.run/api/v1/recipes/doctolib.de/get-slots | shasum -a 256 # 1495ecf8e9b75cc6e0bcebda524b17876eab4f38c4f24c4b288c6bfc6568050d
doctolib.de/get-slots.json, v1
{ "description": "Free Doctolib appointment slots for one practitioner, visit type (motive), agendas and practice, from a start date for up to 7 days, grouped by day, plus the next free slot when the window is empty. Takes visit_motive_id, agenda_ids and practice_id from doctolib.de/search-practitioners. Exact slot times can be passed to doctolib.de/book-slot.", "effect": "read", "id": "doctolib.de/get-slots", "keywords": [ "doctolib", "arzt", "arzttermin", "termin buchen", "hautarzt", "hausarzt", "zahnarzt", "facharzt", "praxis", "doctor", "doctor appointment", "book appointment", "medical", "freie termine", "slots", "verfügbarkeit" ], "output": { "schema": { "properties": { "days": { "items": { "properties": { "date": { "format": "date", "type": "string" }, "slots": { "description": "Exact slot timestamps, as book-slot expects them", "items": { "type": "string" }, "type": "array" }, "times": { "description": "HH:mm, Europe/Berlin", "items": { "type": "string" }, "type": "array" } }, "type": "object" }, "type": "array" }, "next_slot": { "description": "Next free slot after the window", "type": [ "string", "null" ] }, "reason": { "description": "Doctolib's explanation when nothing is bookable", "type": [ "string", "null" ] }, "total": { "description": "Free slots in the window", "type": "integer" } }, "required": [ "total", "days" ], "type": "object" }, "value": "{total: steps.slots.total, days: steps.slots.days[?length(slots) > `0`].{date: date, times: slots[*].join(':', split(split(@, 'T')[1], ':')[:2]), slots: slots}, next_slot: steps.slots.next_slot, reason: steps.slots.reason}" }, "params": { "additionalProperties": false, "properties": { "agenda_ids": { "items": { "type": "integer" }, "minItems": 1, "type": "array" }, "days": { "default": 7, "maximum": 7, "minimum": 1, "type": "integer" }, "insurance_sector": { "default": "public", "description": "Must match the patient's insurance; a wrong sector returns empty days, not an error", "enum": [ "public", "private" ], "type": "string" }, "practice_id": { "type": "integer" }, "start_date": { "description": "YYYY-MM-DD", "pattern": "^\\d{4}-\\d{2}-\\d{2}$", "type": "string" }, "telehealth": { "default": false, "description": "Video consultation slots", "type": "boolean" }, "visit_motive_id": { "type": "integer" } }, "required": [ "visit_motive_id", "agenda_ids", "practice_id", "start_date" ], "type": "object" }, "provenance": { "method": "browser-inspect", "notes": "spikes/doctolib.md. Plain same-origin JSON; agenda_ids are dash-joined and limit is the number of days. Slots were ISO strings in every sample; multi-step motives may return objects, so start_date is read when present. A wrong insurance_sector returns empty days, not an error.", "recorded_at": "2026-11-07T12:12:00+01:00", "recorded_by": "C4" }, "requires_login": false, "schema": "https://wield.run/schema/recipe/v1.json", "site": { "country": "DE", "id": "doctolib.de", "language": "de", "login_url": "https://www.doctolib.de/auth/patient_de", "name": "Doctolib", "origin": "https://www.doctolib.de", "origins": [ "https://www.doctolib.de" ] }, "steps": [ { "expect": { "assert": "body.availabilities != null", "content_type": "json", "status": [ 200 ] }, "extract": { "json": { "days": "availabilities[].{date: date, slots: map(¬_null(start_date, @), slots || `[]`)}", "next_slot": "next_slot || `null`", "reason": "reason || message || `null`", "total": "total" } }, "id": "slots", "request": { "headers": { "Accept": "application/json" }, "method": "GET", "query": { "agenda_ids": "{{params.agenda_ids | join:-}}", "insurance_sector": "{{params.insurance_sector}}", "limit": "{{params.days}}", "practice_ids": "{{params.practice_id}}", "start_date": "{{params.start_date}}", "telehealth": "{{params.telehealth | string}}", "visit_motive_ids": "{{params.visit_motive_id}}" }, "url": "/availabilities.json" } } ], "task": "Get free appointment slots for a Doctolib practitioner", "tos": { "notes": "Doctolib's terms prohibit automated access and scraping. One user-initiated lookup at a time from the user's own browser (1 request); do not poll for slots.", "reviewed": false }, "verify": { "checks": [ "output.total > `0` || output.next_slot != `null` || output.reason != `null`", "length(output.days) <= `7`" ], "example_params": { "agenda_ids": [ 2359956 ], "insurance_sector": "public", "practice_id": 723928, "start_date": "2026-11-09", "visit_motive_id": 14928354 }, "max_ms": 3000 }, "version": 1 }