Skip to main content

Scheduling

The Scheduling API lets telemedicine partners offer patient self-booking for video appointments. Public discovery endpoints can be called with a shop_uid. Booking and rebooking operations use either an organisation API key or a short-lived patient booking token.
Never put signed patient booking tokens in URLs. Exchange the token for a booking_launch_code and use that code for hosted booking links or embedded widgets.

Authentication

The Scheduling API accepts two credentials. Most endpoints accept either; some require a specific one. A short-lived JWT minted by the partner backend for a specific patient. Sent in the X-RxScale-Booking-Token header. The token is verified against an organisation booking-token secret provisioned by RxScale. Algorithm: HS256 JOSE header: must include kid — the key_id returned when you provisioned the booking-token secret. Required claims:
Booking-token secrets are stored encrypted at rest in the RxScale database. Only your key_id is stored in plaintext for routing; the secret value is decrypted in-memory both at verification time and whenever an admin reads the value back through the admin portal or the secrets API. Rotate by provisioning a new secret and revoking the old one once your minter has switched over.

Organisation API key

Send X-API-Key: <key> instead of the booking token for server-to-server flows. The key needs the scheduling:write permission. Use this for back-office tooling, scripted rebooking, or operational scripts.

List Appointment Types

string
required
Shop UID used to scope appointment types to the correct organisation.
No API key is required.

Search Slots

No API key is required. Slot search only returns slots that satisfy the appointment type’s effective booking notice. If a doctor has a doctor-specific override for that appointment type, the doctor’s value takes precedence, including 0 minutes. Appointment types configured as selected_doctors_only only return doctors with an active doctor-specific setting.
string
required
string
required
int
required
Window start (Unix seconds).
int
required
Window end (Unix seconds). Max 31 days from from.
string
Restrict to a single doctor.
string
IANA timezone (e.g. Europe/Berlin) used to localize the output. Defaults to Europe/Berlin. Each slot includes start_local/end_local rendered in this zone; start_date/end_date remain Unix seconds.

Create Booking Session

Use this endpoint when launching the hosted UI or script widget. The request can include the signed patient booking token either in X-RxScale-Booking-Token or in the JSON body as booking_token.
string
required
booking for a new appointment, rebooking for an existing one.
string
Required for booking mode.
int
Window start (Unix seconds). Required for booking mode.
int
Window end (Unix seconds). Required for booking mode.
string
URL to redirect the patient to after a successful booking.
string
Patient booking JWT, if not sent via header.

Get Booking Session

The hosted UI calls this with just the launch code to load the booking context. No authentication header is needed — the launch code itself is the credential.
The response intentionally omits patient_profile_uid and other patient identifiers, so the launch code can be safely passed through URLs in the patient’s browser.

Create and Confirm Holds

Authenticated integrations can create holds with an API key that has scheduling:write. Hosted UI integrations use the booking_launch_code routes.
string
required
string
required
int
required
Unix seconds.
string
Optional reason for the appointment, up to 2000 characters. Blank values are stored as null.
string
Optional. Repeating the same key with the same body returns the existing hold instead of creating a duplicate.
string
Optional reason for the appointment, up to 2000 characters. Omit this field to keep the value set when the hold was created; sending a blank value clears it.
If a hold has expired but no other appointment has taken the slot, confirmation is still allowed and the appointment moves to confirmed.
When present, visit_reason is visible to doctors/admins and can appear in appointment reminder email/SMS content and synced calendar invite descriptions. It can be set at hold time, and edited or cleared when confirming — a request body without visit_reason leaves the existing value untouched.

Cancel Appointment

Cancel a confirmed or held appointment. Accepts either a booking token (patient-driven cancel) or an organisation API key (operations).
string
Optional free-text reason. Stored on the appointment for audit.
Patient cancellations honour the appointment type’s cancellation_min_notice_minutes. If you cancel inside the notice window the API returns a 400 with the offending field; rebook the patient or call with an API key for an operational override.

Rebook Appointment

Move an existing appointment to a new slot. The rebook flow allocates a new appointment row (with previous_meeting_uid set to the original) and cancels the old one atomically.
int
required
Unix seconds for the new slot.
string
Required when the appointment type’s rebooking_mode is any_doctor. For same_doctor_only, the original doctor is reused.
string
Optional. Defaults to the original appointment type.
string
Strongly recommended — protects against double-rebooks during retries.
Rebooks are blocked if the appointment type sets allow_patient_rebooking: false, if rebooking_min_notice_minutes has not been met, or if the new slot is taken.

Get Join Token

Returns a short-lived Jitsi waiting-room JWT and the room name. Used by the patient hosted UI to launch the video call.
The response does not return a ready-made link. Your integration must build it:
You can optionally append a return_url query parameter to redirect the patient back to your platform after the call ends:
string
required
The token value returned by this endpoint. Signed by RxScale; do not modify it.
string
URL to redirect the patient to after the call ends. The redirect is honoured only if the URL’s origin (scheme + host + port) is on the organisation’s admin-configured allow-list. If the origin is not on the list, or if no return_url is supplied, the patient is simply returned to the previous page. Configure the allow-list in the Admin Portal under Settings → Return URLs.
This return_url is only for post-call navigation on the meeting page. It is distinct from the return_url in the booking session body (used to redirect the patient after a successful booking). Do not confuse them.

Join window

The endpoint accepts join requests from 10 minutes before the appointment start_date until 60 minutes after the appointment end_date. Requests outside that window return:
Surface this clearly in your hosted UI — the patient should see a countdown or “join opens in N minutes” hint rather than a blocked button.

Hosted UI

Redirect patients to the launch_url returned by the booking session endpoint, or embed the widget script:
The widget renders the hosted booking page in an iframe inside a Shadow DOM wrapper so styles do not leak into the host page.
These endpoints are called by the RxScale-hosted meetings UI when a patient opens a Join, Reschedule, or Cancel link from an appointment reminder email or SMS. Partners do not call them directly — they are documented here for completeness.
Each reminder link embeds an opaque, single-use launch code minted by RxScale when the reminder is sent. The code itself is the credential — no API key or patient booking token is required or accepted on these routes. Loads the display context the hosted UI needs to render the reminder landing page.
No authentication header is needed — the code itself is the credential. A missing, expired, or out-of-scope code returns 404.

Join

Returns the same waiting-room token shape as Get Join Token. Reusable while the join window stays open.
Returns 400 if called outside the join window (10 minutes before appointment_start to 60 minutes after appointment_end).

Cancel

string
Optional free-text reason.
Single-use: once the code has cancelled the appointment, calling it again returns 409, as does any call once the appointment is no longer cancellable (already completed, or outside the cancellation notice window). This is the only one of these four endpoints that emits a patient_doctor_meeting_updated event with change: "cancelled".

Start a Rebooking Session

Mints a rebook-mode hosted booking session so the patient can pick a new slot through the same hosted booking flow described under Create Booking Session.
Idempotent — calling it again before the session expires returns the same booking_launch_code rather than minting a new one, and it does not consume the reminder action-link code. The original appointment stays active until the patient actually confirms a new slot: only then is it cancelled and replaced, firing a rebooked event.

Doctor Portal Endpoints

These endpoints are scoped to the authenticated doctor (Auth0 token), used by the RxScale Doctor Portal. Partners typically don’t need to call them directly.

List Scheduled Appointments

Query parameters mirror the admin list endpoint: status, from, to, patient_uid, page, limit. The response is the doctor’s own appointments only.

Availability Rules CRUD

Each rule has weekday (0 = Monday … 6 = Sunday), start_time and end_time in minutes since midnight, an optional buffer_minutes between consecutive slots, and optional valid_from / valid_until Unix-second bounds. PATCH bodies are partial; pass clear_valid_from: true or clear_valid_until: true to drop a previously-set bound. DELETE is a soft delete.

Admin Endpoints

These endpoints are scoped to the authenticated organisation admin (Auth0 token).

List Appointments

Query parameters: doctor_uid, patient_uid, status, from, to, page, limit. By default returns active (held + confirmed) appointments scheduled from now onwards; pass status=all and from=0 to see history.

Cancel Appointment

Requires {"reason": "..."} in the body.

Appointment Type Reminders

Each reminder has recipient_role (patient / doctor / admin), minutes_before (positive integer up to 60 days), send_email, send_sms, and active. Multiple reminders per (appointment_type, recipient_role) are allowed as long as the minutes_before offset differs. A maintenance job runs every minute, finds confirmed appointments whose firing window includes “now”, and publishes one scheduling.appointment_reminder_due event per resolved recipient. The published event always fires (partner webhook subscribers receive it); RxScale’s own notification handler only dispatches email/SMS when the corresponding send_email / send_sms flag is set on the reminder row. If the appointment has a visit_reason, the reminder event and RxScale email/SMS content include it. Partners subscribe to the event via the existing organisation notification subscription endpoint with notification_type=APPOINTMENT_REMINDER_DUE.

View Doctor Availability

Read-only listing of a doctor’s weekly bookable windows. Returns 404 if the doctor is not in the admin’s organisation.

Booking-Token Secrets

POST provisions a new secret and returns {key_id, secret}. GET returns the secret value decrypted — RxScale stores secrets encrypted at rest, but admins can re-read them any time from this endpoint (and from the admin portal Settings → Booking secrets page) so a new minter can be configured without re-provisioning. DELETE revokes the secret. The legacy organisation-scoped paths (/v1/admin/scheduling/organisations/{organisation_uid}/booking-token-secrets[/<key_id>]) are still accepted and validate against the authenticated organisation.

Errors

The Scheduling API uses standard HTTP status codes: