Two Approaches

Traditional scheduling relies on polling. ESUS also supports push updates through the FHIR Subscription resource, so your client can react immediately when a slot is freed or booked.

Subscription (Push)

Subscribe to Slot changes that match a search criteria. When a matching event happens, ESUS POSTs a notification to your endpoint.

curl -X POST https://api.esus.health/fhir/Subscription \
  -H "Authorization: Bearer YOUR_TOKEN" \
  -H "Content-Type: application/fhir+json" \
  -d '{
    "status": "active",
    "reason": "Slot availability for practitioner",
    "criteria": "Slot?schedule.actor=Practitioner/a7b1c2d3-e4f5-6789-abcd-ef0123456789",
    "channel": {
      "type": "rest-hook",
      "endpoint": "https://your-app.example.com/webhooks/slots",
      "payload": "application/fhir+json"
    }
  }'

When a slot matching the criteria is created or updated, your endpoint receives a FHIR Bundle of type: notification:

{
  "resourceType": "Bundle",
  "type": "notification",
  "entry": [{
    "resource": {
      "resourceType": "Slot",
      "id": "c1a2e3d4-5b6f-7890-abcd-ef1234567890",
      "status": "busy",
      "start": "2026-04-21T09:00:00Z",
      "end": "2026-04-21T09:30:00Z"
    }
  }]
}

Polling

For simpler integrations, poll the Slot search endpoint:

# Next 10 free slots for a practitioner
curl "https://api.esus.health/fhir/Slot?status=free&schedule.actor=Practitioner/a7b1c2d3-e4f5-6789-abcd-ef0123456789&_count=10&_sort=start" \
  -H "Authorization: Bearer YOUR_TOKEN"

Nearest Available Slot

curl "https://api.esus.health/fhir/Slot?status=free&schedule.actor=Practitioner/a7b1c2d3-e4f5-6789-abcd-ef0123456789&date=ge2026-04-21T00:00:00Z&_count=1&_sort=start" \
  -H "Authorization: Bearer YOUR_TOKEN"

Overbooking and Conflict Handling

Overbooking is controlled by the Slot.overbooked boolean. A slot with overbooked: false accepts a single booking; booking it again returns 409 Conflict. A slot with overbooked: true can accept multiple bookings, at your application’s discretion.

There is no _conflictDetection parameter — conflict handling is enforced by the server based on Slot.status and Slot.overbooked. A booking attempt against a busy slot without overbooked returns 409 Conflict with an OperationOutcome:

{
  "resourceType": "OperationOutcome",
  "issue": [{
    "severity": "error",
    "code": "conflict",
    "diagnostics": "Slot is not available"
  }]
}