Zum Hauptinhalt springen

Scheduling

Die Scheduling API ermöglicht patientenseitige Selbstbuchung für Videosprechstunden. Öffentliche Discovery-Endpunkte können mit einer shop_uid aufgerufen werden. Buchungs- und Umbuchungsvorgänge nutzen entweder einen Organisations-API-Key oder einen kurzlebigen Patient Booking Token.
Übermitteln Sie signierte Patient Booking Tokens niemals in URLs. Tauschen Sie das Token gegen einen booking_launch_code ein und verwenden Sie diesen Code für gehostete Buchungslinks oder eingebettete Widgets.

Authentifizierung

Die Scheduling API akzeptiert zwei Credentials. Die meisten Endpunkte akzeptieren beides; einige sind auf eines beschränkt.

Patient Booking Tokens (empfohlen für Patientenflüsse)

Ein kurzlebiges JWT, das Ihr Partner-Backend für einen bestimmten Patienten ausstellt. Übergeben Sie es im Header X-RxScale-Booking-Token. Das Token wird gegen ein in RxScale hinterlegtes Organisations-Booking-Token-Secret verifiziert. Algorithmus: HS256 JOSE-Header: muss kid enthalten — die key_id, die beim Provisionieren des Secrets zurückgegeben wurde. Erforderliche Claims:
ClaimTypBeschreibung
audstringMuss rxscale-scheduling sein.
expintAblauf (Unix-Sekunden). Kurz halten — unter 5 Minuten ist üblich.
nbfintNot-before (Unix-Sekunden).
iatintIssued-at (Unix-Sekunden).
shop_identifierstringDer in RxScale konfigurierte Shop-Identifier.
shop_customer_idstringIhre stabile Kunden-ID. RxScale dedupliziert Patienten anhand dieser ID.
patient_profile_fieldsarrayProfilfelder, die übernommen werden sollen. Jeder Eintrag: { "field": "<field_key>", "value": <wert>, "source": "shop" }.
import jwt, time
now = int(time.time())
payload = {
    "aud": "rxscale-scheduling",
    "exp": now + 300,
    "nbf": now - 10,
    "iat": now,
    "shop_identifier": "shop_abc",
    "shop_customer_id": "cust_123",
    "patient_profile_fields": [
        {"field": "first_name", "value": "Ada", "source": "shop"},
        {"field": "last_name",  "value": "Lovelace", "source": "shop"},
        {"field": "email",      "value": "ada@example.com", "source": "shop"},
    ],
}
token = jwt.encode(payload, SECRET, algorithm="HS256", headers={"kid": KEY_ID})
Booking-Token-Secrets werden in der RxScale-Datenbank verschlüsselt gespeichert. Nur Ihre key_id liegt im Klartext für das Routing vor; der Secret-Wert wird sowohl bei der Token-Verifikation als auch beim Abruf durch einen Admin (Admin-Portal oder Secrets-API) im Speicher entschlüsselt. Rotieren Sie, indem Sie ein neues Secret provisionieren und das alte widerrufen, sobald Ihr Minter umgestellt ist.

Organisations-API-Key

Senden Sie X-API-Key: <key> statt des Booking Tokens für Server-zu-Server-Flüsse. Der Key benötigt die Berechtigung scheduling:write. Nutzen Sie das für Back-Office-Tools, skriptgesteuertes Umbuchen oder Operations-Skripte.

Terminarten auflisten

GET /v1/scheduling/appointment-types?shop_uid={shop_uid}
shop_uid
string
erforderlich
Shop-UID, mit der die Terminarten auf die richtige Organisation eingeschränkt werden.
Kein API-Key erforderlich.
curl "https://api.rxscale.com/v1/scheduling/appointment-types?shop_uid=shop_123"
{
  "data": [
    {
      "uid": "apt_video_15",
      "name": "Videosprechstunde",
      "duration_minutes": 15,
      "hold_ttl_seconds": 900,
      "booking_min_notice_minutes": 10,
      "doctor_assignment_mode": "all_available_doctors",
      "allow_patient_rebooking": true,
      "rebooking_mode": "same_doctor_only"
    }
  ]
}

Slots suchen

POST /v1/scheduling/slots/search
Kein API-Key erforderlich. Die Slot-Suche liefert nur Slots zurück, die den wirksamen Buchungsvorlauf der Terminart erfüllen. Wenn ein Arzt für diese Terminart eine eigene Einstellung hat, geht dieser Wert vor, auch 0 Minuten. Terminarten mit selected_doctors_only liefern nur Ärzte mit aktiver arztspezifischer Einstellung zurück.
shop_uid
string
erforderlich
appointment_type_uid
string
erforderlich
from
int
erforderlich
Fensterstart (Unix-Sekunden).
to
int
erforderlich
Fensterende (Unix-Sekunden). Max. 31 Tage ab from.
doctor_uid
string
Auf einen Arzt einschränken.
curl -X POST "https://api.rxscale.com/v1/scheduling/slots/search" \
  -H "Content-Type: application/json" \
  -d '{
    "shop_uid": "shop_123",
    "appointment_type_uid": "apt_video_15",
    "from": 1778457600,
    "to": 1778544000
  }'
{
  "slots": [
    {
      "doctor_uid": "doc_123",
      "doctor_name": "Dr. Max Meyer",
      "start_date": 1778490000,
      "end_date": 1778490900
    }
  ]
}

Booking Session erstellen

Verwenden Sie diesen Endpunkt beim Start der gehosteten UI oder des Widget-Skripts. Die Anfrage kann das signierte Patient Booking Token entweder in X-RxScale-Booking-Token oder im JSON-Body als booking_token enthalten.
POST /v1/scheduling/booking-sessions
mode
string
erforderlich
booking für einen neuen Termin, rebooking für eine bestehende Buchung.
appointment_type_uid
string
Pflicht im booking-Modus.
from
int
Fensterstart (Unix-Sekunden). Pflicht im booking-Modus.
to
int
Fensterende (Unix-Sekunden). Pflicht im booking-Modus.
return_url
string
URL, zu der der Patient nach erfolgreicher Buchung weitergeleitet wird.
booking_token
string
Patient Booking JWT, falls nicht im Header übergeben.
curl -X POST "https://api.rxscale.com/v1/scheduling/booking-sessions" \
  -H "Content-Type: application/json" \
  -H "X-RxScale-Booking-Token: eyJ..." \
  -d '{
    "mode": "booking",
    "appointment_type_uid": "apt_video_15",
    "from": 1778457600,
    "to": 1778544000,
    "return_url": "https://partner.example/booking-complete"
  }'
{
  "booking_launch_code": "blc_Nc8...",
  "expires_at": 1778458500,
  "launch_url": "https://meetings.rxscale.com/booking?launch=blc_Nc8..."
}

Booking Session abrufen

Die gehostete UI ruft diesen Endpunkt nur mit dem Launch-Code auf, um den Buchungskontext zu laden. Kein Auth-Header nötig — der Launch-Code selbst ist das Credential.
GET /v1/scheduling/booking-sessions/{booking_launch_code}
curl "https://api.rxscale.com/v1/scheduling/booking-sessions/blc_Nc8..."
{
  "uid": "bsn_abc...",
  "shop_uid": "shop_123",
  "appointment_type_uid": "apt_video_15",
  "appointment_type": {
    "uid": "apt_video_15",
    "name": "Videosprechstunde",
    "duration_minutes": 15
  },
  "start_from": 1778457600,
  "start_to": 1778544000,
  "mode": "booking",
  "return_url": "https://partner.example/booking-complete",
  "expires_at": 1778458500
}
Die Antwort enthält bewusst kein patient_profile_uid und keine weiteren Patienten-Identifier, damit der Launch-Code gefahrlos durch die URL im Browser des Patienten geführt werden kann.

Holds erstellen und bestätigen

Authentifizierte Integrationen können Holds mit einem API-Key mit scheduling:write anlegen. Gehostete-UI-Integrationen nutzen die booking_launch_code-Routen.
POST /v1/scheduling/booking-sessions/{booking_launch_code}/holds
doctor_uid
string
erforderlich
appointment_type_uid
string
erforderlich
start_date
int
erforderlich
Unix-Sekunden.
Idempotency-Key
string
Optional. Derselbe Key mit identischem Body liefert den bestehenden Hold zurück, statt einen neuen anzulegen.
curl -X POST "https://api.rxscale.com/v1/scheduling/booking-sessions/blc_Nc8.../holds" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: hold-attempt-1" \
  -d '{
    "doctor_uid": "doc_123",
    "appointment_type_uid": "apt_video_15",
    "start_date": 1778490000
  }'
{
  "hold_uid": "pdm_123",
  "expires_at": 1778490900,
  "ttl_seconds": 900,
  "status": "held"
}
POST /v1/scheduling/booking-sessions/{booking_launch_code}/holds/{hold_uid}/confirm
curl -X POST "https://api.rxscale.com/v1/scheduling/booking-sessions/blc_Nc8.../holds/pdm_123/confirm"
{
  "uid": "pdm_123",
  "status": "confirmed",
  "start_date": 1778490000,
  "end_date": 1778490900
}
Wenn ein Hold abgelaufen ist, der Slot aber noch nicht durch einen anderen Termin belegt wurde, ist die Bestätigung weiterhin möglich und der Termin wechselt in den Status confirmed.

Termin stornieren

Storniert einen bestätigten oder gehaltenen Termin. Akzeptiert entweder ein Booking Token (patientenseitige Stornierung) oder einen Organisations-API-Key (Operations).
POST /v1/scheduling/appointments/{appointment_uid}/cancel
reason
string
Optionaler Freitext-Grund. Wird am Termin für Audit-Zwecke gespeichert.
curl -X POST "https://api.rxscale.com/v1/scheduling/appointments/pdm_123/cancel" \
  -H "X-RxScale-Booking-Token: eyJ..." \
  -H "Content-Type: application/json" \
  -d '{"reason": "patient_request"}'
{
  "appointment_uid": "pdm_123",
  "status": "cancelled"
}
Patientenseitige Stornierungen respektieren cancellation_min_notice_minutes der Terminart. Eine Stornierung innerhalb der Frist gibt 400 mit dem betroffenen Feld zurück; buchen Sie den Patienten um oder rufen Sie den Endpunkt mit einem API-Key auf, wenn ein operativer Override nötig ist.

Termin umbuchen

Verschiebt einen bestehenden Termin auf einen neuen Slot. Der Rebook-Flow legt atomar einen neuen Termin an (mit previous_meeting_uid auf den Originaltermin) und storniert den alten.
POST /v1/scheduling/appointments/{appointment_uid}/rebook
new_start_date
int
erforderlich
Unix-Sekunden für den neuen Slot.
new_doctor_uid
string
Pflicht, wenn die Terminart rebooking_mode: any_doctor setzt. Bei same_doctor_only wird der ursprüngliche Arzt übernommen.
appointment_type_uid
string
Optional. Standard ist die ursprüngliche Terminart.
Idempotency-Key
string
Dringend empfohlen — schützt vor doppelten Umbuchungen bei Retries.
curl -X POST "https://api.rxscale.com/v1/scheduling/appointments/pdm_123/rebook" \
  -H "X-RxScale-Booking-Token: eyJ..." \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: rebook-attempt-1" \
  -d '{"new_start_date": 1778510000}'
{
  "appointment_uid": "pdm_456",
  "status": "confirmed"
}
Umbuchungen werden blockiert, wenn die Terminart allow_patient_rebooking: false setzt, rebooking_min_notice_minutes nicht eingehalten ist oder der neue Slot bereits belegt ist.

Join-Token abrufen

Liefert ein kurzlebiges Jitsi-Waiting-Room-JWT und den Raumnamen. Wird von der Patient-UI verwendet, um den Videocall zu starten.
POST /v1/scheduling/appointments/{appointment_uid}/join
curl -X POST "https://api.rxscale.com/v1/scheduling/appointments/pdm_123/join" \
  -H "X-RxScale-Booking-Token: eyJ..."
{
  "room_name": "doctor-123-room",
  "token": "eyJhbGciOi...",
  "expires_at": 1778497200
}

Join-Fenster

Der Endpunkt akzeptiert Join-Anfragen ab 10 Minuten vor start_date des Termins bis 60 Minuten nach end_date. Anfragen außerhalb dieses Fensters liefern:
{ "error": ["Appointment is outside the join window"] }
Stellen Sie das in Ihrer UI klar dar — der Patient sollte einen Countdown oder einen “Join öffnet in N Minuten”-Hinweis sehen statt eines blockierten Buttons.

Gehostete UI

Leiten Sie den Patienten auf die launch_url aus der Booking-Session-Antwort weiter oder binden Sie das Widget-Skript ein:
<script
  src="https://meetings.rxscale.com/booking-widget.js"
  data-launch-code="blc_Nc8..."
  data-target="#rxscale-booking"
  data-base-url="https://meetings.rxscale.com">
</script>
Das Widget rendert die gehostete Buchungsseite in einem iframe innerhalb eines Shadow-DOM-Wrappers, damit Styles nicht in die Host-Seite überschwappen.

Arztportal-Endpunkte

Diese Endpunkte sind auf den authentifizierten Arzt (Auth0-Token) eingeschränkt und werden vom RxScale-Arztportal genutzt. Partner müssen sie in der Regel nicht direkt aufrufen.

Geplante Termine auflisten

GET /v1/doctor/appointments
Query-Parameter wie beim Admin-Listing: status, from, to, patient_uid, page, limit. Die Antwort enthält ausschließlich Termine des authentifizierten Arztes.

Verfügbarkeits-CRUD

GET    /v1/doctor/availability-rules
POST   /v1/doctor/availability-rules
PATCH  /v1/doctor/availability-rules/{rule_uid}
DELETE /v1/doctor/availability-rules/{rule_uid}
Jede Regel hat weekday (0 = Montag … 6 = Sonntag), start_time und end_time in Minuten seit Mitternacht, optional buffer_minutes zwischen Slots sowie optionale Gültigkeitsgrenzen valid_from / valid_until (Unix-Sekunden). PATCH-Bodies sind partiell; mit clear_valid_from: true oder clear_valid_until: true lassen sich gesetzte Grenzen entfernen. DELETE ist ein Soft-Delete.

Admin-Endpunkte

Auf die authentifizierte Admin-Organisation (Auth0-Token) eingeschränkt.

Termine auflisten

GET /v1/admin/scheduling/appointments
Query: doctor_uid, patient_uid, status, from, to, page, limit. Standard: aktive (gehalten + bestätigt) Termine ab jetzt; mit status=all und from=0 lässt sich die Historie einsehen.

Termin stornieren

POST /v1/admin/scheduling/appointments/{appointment_uid}/cancel
Body {"reason": "..."} erforderlich.

Termin­art-Erinnerungen

GET    /v1/admin/scheduling/appointment-types/{appointment_type_uid}/reminders
POST   /v1/admin/scheduling/appointment-types/{appointment_type_uid}/reminders
PATCH  /v1/admin/scheduling/appointment-types/{appointment_type_uid}/reminders/{reminder_uid}
DELETE /v1/admin/scheduling/appointment-types/{appointment_type_uid}/reminders/{reminder_uid}
Jede Erinnerung hat recipient_role (patient / doctor / admin), minutes_before (positive ganze Zahl bis 60 Tage), send_email, send_sms und active. Mehrere Erinnerungen pro (appointment_type, recipient_role) sind erlaubt, solange sich der minutes_before-Offset unterscheidet. Ein Maintenance-Job läuft jede Minute, findet bestätigte Termine, deren Auslösefenster “jetzt” umfasst, und publiziert pro auflösbarem Empfänger ein scheduling.appointment_reminder_due-Event. Das Event feuert immer (Partner-Webhook-Subscriber erhalten es); der RxScale-eigene Notification-Handler verschickt E-Mail/SMS nur, wenn die jeweiligen Flags send_email / send_sms auf der Erinnerungszeile gesetzt sind. Partner abonnieren das Event über den bestehenden Endpunkt für Organisations- Benachrichtigungs-Abonnements mit notification_type=APPOINTMENT_REMINDER_DUE.

Verfügbarkeiten eines Arztes ansehen

GET /v1/admin/scheduling/doctors/{doctor_uid}/availability-rules
Lesende Auflistung der wöchentlichen Buchungsfenster eines Arztes. Gibt 404 zurück, wenn der Arzt nicht in der Organisation des Admins ist.

Booking-Token-Secrets

GET    /v1/admin/scheduling/booking-token-secrets
GET    /v1/admin/scheduling/booking-token-secrets/{key_id}
POST   /v1/admin/scheduling/booking-token-secrets
DELETE /v1/admin/scheduling/booking-token-secrets/{key_id}
POST legt ein neues Secret an und gibt {key_id, secret} zurück. GET liefert den Wert entschlüsselt zurück — Secrets liegen verschlüsselt in der Datenbank, sind aber von Admins jederzeit über die API und das Admin-Portal (Einstellungen → Buchungs-Secrets) wieder lesbar, damit ein neuer Minter ohne Neu-Provisionierung konfiguriert werden kann. DELETE widerruft das Secret. Die legacy organisations-gebundenen Pfade (/v1/admin/scheduling/organisations/{organisation_uid}/booking-token-secrets[/<key_id>]) werden weiterhin akzeptiert und gegen die authentifizierte Organisation validiert.

Fehler

Die Scheduling API nutzt Standard-HTTP-Statuscodes:
StatusBedeutung
400Schema-Validierung fehlgeschlagen oder eine Geschäftsregel hat die Aktion blockiert (Details im error-Body).
401Booking Token oder API-Key fehlt oder ist ungültig.
404Ressource nicht gefunden oder der Aufrufer ist nicht berechtigt, sie zu sehen. Bei unberechtigtem Zugriff liefert die API 404, um Resource-Enumeration zu verhindern.
409Slot wurde zwischen Hold und Confirm anderweitig belegt. Neu suchen und erneut versuchen.
429Rate Limit (10 Anfragen pro Sekunde pro Service). Backoff und retry.