Skip to main content
The Appointments API is the system-to-system scheduling surface for HueChat. An ERP, CRM, website, mobile app or partner platform can configure the booking catalog, find available times, create customer appointments and maintain their full lifecycle. Every request is restricted to the account that issued the API key.

Before you start

Create a scoped API key in HueChat → Account → Developer API with the smallest set of permissions the integration needs:
Use the account id that issued the key. A key from another account receives 403; resource, service, appointment, contact and deal identifiers are never resolved across accounts. Appointment configuration writes also verify that the key’s current owner is still an administrator.
The account must have native Appointments enabled. A plan or feature gate that is not enabled returns 403 without weakening the other authorization checks.

Authenticate and test an appointment request

The interactive endpoint panel on this site uses the same bearer authentication as the rest of the HueChat API. Open an appointment operation, choose Authorize (or click the Authorization field), and paste the complete token. The panel adds the Bearer prefix for you; do not paste Bearer twice. Use a personal token only for a quick account-owner check, or use a scoped hc_… API key for an integration. The key must belong to the accountId in the request. Start with a read-only request before trying a write:
For the historical import operation, the key additionally needs appointments:history:write. Supplying contact_id also needs contacts:read, and supplying deal_id needs deals:write. The Send button executes a real request against the selected account: use a deliberate external_id, and do not use the historical-import example as a harmless connectivity probe. A successful replay is idempotent, but it still writes the appointment when that external_id is new.

Complete API coverage

The public contract contains 46 operations. Appointment types are called services in request fields; resources can represent a doctor, employee, room, branch, device or any other capacity that can receive a booking.

Booking and discovery

Booking mutations

Scheduling system connections

These operations need a REST key with appointments:sync on an account HueChat approved. Bookings are stored exactly as the system of record has them; see Scheduling system connections for matching, ordering and the FHIR mapping. POST /appointments from an approved scheduling-system key behaves like PUT /appointments/external/{externalId}.

Administrator configuration

Every operation in this table requires appointments:settings and an administrator key owner.

WhatsApp reminder automation

Reading rules and receipts requires appointments:read. Creating, updating, enabling or disabling a rule requires appointments:settings and an administrator key owner. All routes above are relative to /api/v2/accounts/{accountId}.

Endpoint behavior, one by one

Read and discovery operations

  • GET /appointments returns appointments plus resources, services, settings, availability rules, overlapping exceptions and service-resource links. Its default window is 14 days; optional RFC3339 start and end may span at most 366 days. Use a focused endpoint when the integration does not need the combined scheduling context.
  • GET /appointments/{id} accepts a HueChat public_id or UUID and returns the enriched appointment with chronological status history. Linked-deal data is omitted unless the key also has deals:read.
  • GET /appointments/external/{externalId} finds the account-local record by the calling system’s stable identifier. Use it to reconcile after a timeout or when the external system does not store a HueChat ID.
  • GET /appointments/catalog returns active appointment types, durations, buffers and each service’s eligible active resources. It is the smallest complete catalog response for an external booking interface.
  • GET /appointments/settings returns the account timezone, slot interval, minimum notice, booking horizon, cancellation notice, calendar defaults and confirmation policy without changing them.
  • GET /appointments/resources lists bookable people, rooms, branches, devices or other capacity, including archived rows. Each row includes its type, timezone, color, position and active state.
  • GET /appointments/resources/{resourceId} returns one account-local resource UUID or 404 when it is unavailable to that account.
  • GET /appointments/services lists active and archived appointment types, with duration, before/after buffers, optional price, currency, order and active state.
  • GET /appointments/services/{serviceId} returns one account-local service UUID or 404 when it is unavailable to that account.
  • GET /appointments/availability returns all weekly rules and exceptions overlapping optional RFC3339 start and end. The default range begins now and ends one year later; the requested range cannot exceed 366 days. Weekly rows include inactive and date-bounded rules so an integration can reproduce the complete scheduling policy rather than infer it from currently open days.
  • GET /appointments/slots requires date plus a service ID or exact name. It accepts an optional resource ID/name, preferred_time, and limit from 1 to 50. date is a civil date in the account’s IANA timezone. Each result identifies the service and resource and gives absolute start/end plus local date, local time and timezone. An empty slots array is a successful closed or fully booked result, not an API failure.
  • GET /appointments/reports returns lifecycle totals, AI-booked count and a per-service breakdown. The default range is the previous month; optional RFC3339 start and end cannot span more than 366 days.

Booking write operations

  • POST /appointments/history is a restricted migration endpoint for approved accounts. The REST key must carry appointments:history:write. The endpoint accepts an archived or active service/resource by UUID or exact name, records one initial lifecycle history event, and never runs live slot discovery or sends booking/reminder notifications. See Import historical appointments.
  • POST /appointments creates a booking from external_id, customer data, appointment type and time. It accepts UUIDs or exact active names, optional automatic resource selection, and either RFC3339 starts_at or local date plus time. An identical retry returns the original record.
  • PATCH /appointments/{id} updates the editable customer record and can move an active appointment in the same transaction. Send resource, service, start time, customer fields and the current version; stale versions fail with 409.
  • PATCH /appointments/{id}/status changes lifecycle state with an optional reason and required version. The appointment and its status-history row commit together.
  • PATCH /appointments/{id}/schedule moves a tentative, booked or confirmed appointment to the supplied resource UUID, service UUID and RFC3339 start. Availability conflicts, invalid catalog combinations and stale versions are rejected instead of overwriting newer work.

Configuration operations

  • PUT /appointments/settings saves a complete, coherent native/external mode, timezone, slot interval, notice limits, calendar defaults and confirmation policy. Enabling native mode retires superseded external booking configuration atomically.
  • POST /appointments/resources creates a capacity resource with required name and type plus optional description, IANA timezone, hex color and position.
  • PUT /appointments/resources/{resourceId} changes only supplied resource fields and can activate or deactivate it.
  • DELETE /appointments/resources/{resourceId} archives the resource so it is unavailable for new scheduling while all historical appointments remain.
  • POST /appointments/resources/{resourceId}/restore makes an archived resource available for configuration and booking again.
  • POST /appointments/services creates an appointment type with a 5–1440 minute duration, optional buffers, non-negative price, three-letter currency, color and position.
  • PUT /appointments/services/{serviceId} changes only supplied service fields, including duration, buffers, price, currency, position and active state.
  • DELETE /appointments/services/{serviceId} archives the appointment type while preserving bookings that used it.
  • POST /appointments/services/{serviceId}/restore makes an archived service selectable again.
  • PUT /appointments/services/{serviceId}/resources replaces the complete eligible-resource set with an array of account-local UUIDs. An empty array means every active resource may provide the service.
  • POST /appointments/availability/rules replaces one resource/weekday rule. day_of_week is 0–6 and start/end are minutes after local midnight. effective_from and effective_to are optional inclusive civil dates in the account timezone; is_active:false retains an explicitly closed rule.
  • POST /appointments/availability/rules/bulk validates and atomically replaces up to seven resource/weekday rules, so a bad item leaves the existing schedule unchanged. Only supplied resource/weekday pairs are replaced; omitted weekdays are not deleted.
  • POST /appointments/availability/exceptions creates a one-off open or closed RFC3339 interval with an explicit UTC offset. Omit resource_id to apply it account-wide. An open interval may add availability outside weekly rule dates; an overlapping closed interval wins and removes availability.
  • DELETE /appointments/availability/exceptions/{exceptionId} deletes that account-local exception and does not alter appointment history.

Reminder operations

  • GET /appointments/reminders returns timing, doctor/resource scope, inbox, approved template metadata, variable bindings and activation state. Reading this endpoint never creates or enables a rule.
  • POST /appointments/reminders validates the resource, the exact WhatsApp inbox, and an approved UTILITY template belonging to the same account. New rules may be saved with is_active:false; nothing is sent until an administrator explicitly activates a rule.
  • PUT /appointments/reminders/{reminderId} replaces the complete rule. When an inactive rule becomes active—or an active rule’s timing, resource, inbox, template or bindings change—the activation boundary is reset. HueChat does not catch up reminders whose intended send time predates that boundary.
  • DELETE /appointments/reminders/{reminderId} is a history-preserving disable operation. Existing delivery receipts remain available for the appointment and Customer CDP timeline.
  • GET /appointments/reminder-deliveries accepts an optional appointment UUID or contact ID and limit from 1 to 100. sent means WhatsApp accepted the request; skipped records a safety or eligibility decision; failed is a definite rejection; uncertain means HueChat cannot prove whether the provider accepted a request and will not replay it automatically.

Configure the scheduling model

1. Save account settings

The IANA timezone is used when an integration sends local date and time. Enabling native booking disables superseded external booking configurations in the same transaction.

2. Create resources and appointment types

Create a resource:
Create a service, which is the appointment type selected by customers:
Assign the service to selected resources. The body is an array of resource UUIDs. An empty array means every active resource is eligible.

3. Set weekly hours and exceptions

day_of_week uses 0 for Sunday through 6 for Saturday. Start and end minutes are measured from local midnight, so 600 is 10:00 and 1320 is 22:00. Date bounds are inclusive and use the account timezone; they are not UTC instants.
Use an exception for a holiday, special opening or temporary closure. Omit resource_id to apply it to every resource.
The bulk weekly-rules request is validated before any rule changes. Settings and status/history mutations are also transactional.

Availability precedence and fallback

HueChat evaluates availability in this order for each resource and account-local date:
  1. A resource with no weekly rules at all receives the bootstrap 08:00–18:00 window. This exists only so a newly created resource is immediately usable.
  2. Once any weekly rule exists for that resource, the bootstrap window no longer applies. Only active rules matching the weekday and inclusive date bounds open time. An inactive rule, an omitted weekday, or a date outside all active bounds is closed.
  3. A matching open exception adds its exact interval, including when the weekly rule is inactive or out of range. A matching closed exception removes every overlapping candidate and takes precedence over an opening.
  4. Service duration and buffers must fit entirely inside an open window. Notice, maximum-advance and existing-booking checks are then applied.
The slot-list, create and reschedule endpoints all call this same resolver. A client cannot create a time that the slot API would reject merely by bypassing slot discovery. For cross-country integrations, configure the account with an IANA timezone such as Asia/Dubai, Europe/London, or America/New_York. Send weekly bounds as YYYY-MM-DD, and send appointment/exception instants as RFC3339 with an explicit offset. Persist the returned absolute timestamps in the HIS and use the response’s local_date, local_time, and timezone for clinic display. HueChat rejects local wall times that do not exist during a daylight-saving clock jump. During a repeated clock hour, book with the exact starts_at returned by the slot endpoint so the intended UTC offset is unambiguous.

Find a slot by name, type and date

An integration may use UUIDs for long-lived catalog references or exact names for a human-friendly flow. Do not send both forms for the same selector.
service_name and resource_name use exact, account-local active names. Replace them with service_id and resource_id when catalog names may change. The resource is optional: omitting both resource selectors returns slots for all eligible resources.

Create by customer, date, time and appointment type

API-key creation requires external_id, the stable appointment identifier in the calling system. It must be 1–128 ASCII characters, start with a letter or digit, and otherwise use only letters, digits, ., _, : or -. This example uses exact human-readable catalog names and local time. date and time are interpreted in the account appointment timezone.
You may instead send service_id, optional resource_id, and an RFC3339 starts_at. If the resource is omitted, HueChat selects an eligible resource that is free at that time. The configured service duration and buffers are authoritative; ends_at is optional and, when supplied, is validation input rather than a duration override. contact_id is optional. It must identify a contact in the same account and requires contacts:read. You may also send customer name, phone and email directly without creating a Contact first. Use the Contacts and Customer CDP API when the external system needs to maintain the unified customer record. deal_id is optional. It must be an account-local deal UUID whose branch allows the selected resource and service. It requires deals:write; linked deal metadata is returned only with deals:read.

Import historical appointments

Historical import is intentionally separate from live booking and restricted to approved accounts. The request must use a REST API key with appointments:history:write. This is a vendor-neutral HueChat contract. Its lifecycle aliases align with the HL7 FHIR R4 Appointment resource, but the route is not a FHIR or SMART-on-FHIR server. Vendor-certified EHR/HIS adapters can be added separately without changing this generic contract.
external_id and status are required. Select exactly one service and one resource with service_id/resource_id or exact service_name/resource_name; historical import may resolve archived catalog rows. Supply either RFC3339 starts_at or local date plus time. An omitted ends_at uses the service’s current duration. The start must be on or after 1900-01-01 and cannot be more than five minutes in the future. A completed record must already have ended. Native statuses are tentative, booked, confirmed, completed, cancelled, and no_show. These FHIR R4 aliases are also accepted: entered-in-error is rejected instead of creating a misleading appointment. The original status, optional source_system, status time and FHIR-alias flag are retained as import provenance. cancellation_reason is valid only for a cancelled record. An identical retry of the same external_id returns 200 with X-Idempotent-Replayed: true; the first import returns 201. Reusing the identifier for different content returns 409. A resource overlap involving an active lifecycle state also returns 409 to preserve the account’s appointment integrity. Use GET /appointments/external/{externalId} to reconcile after an uncertain network result. Sending contact_id additionally requires contacts:read. Sending deal_id additionally requires deals:write. Both identifiers are resolved only inside the API key’s account. The import writes appointment data and its initial history atomically; it does not backfill reminders, send WhatsApp messages, or alter the live /appointments behavior.

Retry without duplicate bookings

If a network timeout leaves the result uncertain, send the exact request again with the same external_id. HueChat returns the existing appointment and:
This also reconciles a missing optional deal link after partial downstream failure. Reusing the identifier with different request data returns 409 Conflict; it never silently changes the first appointment. A temporary 503 is safe to retry with the identical request. When the appointment was stored but its deal link still needs reconciliation, the response also includes Retry-After: 0. Unknown JSON fields, multiple JSON values and bodies larger than 1 MiB are rejected. A 429 response is JSON and includes Retry-After: 60 and X-RateLimit-* headers.

Update, reschedule and complete

Appointment responses include public_id, the internal UUID and version. Use either ID in the detail and mutation routes, and send the latest version with every change. A stale write returns 409; reload and decide whether to retry. Change lifecycle state:
Creation accepts tentative, booked and confirmed. Later status changes also accept completed, cancelled and no_show. Each successful status change and its history entry commit together. Reschedule an active appointment with resource and service UUIDs:
The general PATCH /appointments/{id} endpoint updates the full editable customer details and can move an active appointment at the same time. Supply the selected resource_id, service_id, starts_at, customer fields and current version. Completed, cancelled and no-show appointments retain their original schedule.

Configure WhatsApp appointment reminders

Reminder rules are account-scoped automation. Each rule chooses one approved WhatsApp UTILITY template from one WhatsApp inbox/phone number and applies to either every active resource or one doctor/resource. A rule can run a fixed number of minutes before the appointment or at a local wall-clock time on the previous day.
Create and review a rule with is_active:false first. Changing it to true is the explicit action that authorizes future customer messages. API deployment, template selection and receipt reads do not activate a rule.

24 hours before an appointment

The order of bindings is the order of the numbered body variables {{1}}, {{2}}, and so on. Supported sources are: If a required value is missing, HueChat records skipped and sends nothing. The current reminder contract supports numbered body variables, a static text header and static buttons. Media or dynamic headers, dynamic URL buttons and call-permission templates are rejected.

Previous day at a local time

Use timing_type:"previous_day", omit minutes_before, and provide send_minute, the number of minutes after local midnight. For example, 09:00 is 540:
An empty resource_id applies the rule to every active resource. HueChat uses the selected resource’s IANA timezone, falling back to the account timezone, so the same rule works across countries and daylight-saving changes. Store appointments as RFC3339 instants with explicit offsets; do not convert local times to a fixed +03:00 offset for countries that observe daylight saving.

Delivery guarantees and receipts

HueChat creates one durable receipt per rule, appointment and scheduled instant. Editing notes or another non-schedule field cannot duplicate a send; rescheduling to a new instant creates a new eligible schedule. Before dispatch, HueChat rechecks appointment status and version, rule activation, current Meta approval, inbox availability, customer service-message permission and phone suppression/block status. Provider timeouts after a send attempt become uncertain, never an automatic retry. Pre-provider transient checks retry a bounded number of times. A reminder more than 30 minutes late is recorded as skipped, preventing stale messages after a prolonged outage.
Receipts preserve the rule and template names used for that attempt even if the live rule is later edited. They are also shown on the appointment and in the linked customer’s CDP history.

Read history and reports

GET /appointments/{id} returns the appointment plus chronological status history. GET /appointments/reports?start=…&end=… returns totals by lifecycle state and by service. Overview, availability and reporting ranges use RFC3339, require end after start, and cannot exceed 366 days.

Security and intentional boundaries

  • The bearer token is retained by HueChat only as a one-way hash.
  • Account ownership, scope, expiry, optional IP allowlist, revocation and per-key rate limit are checked on every request.
  • Catalog names and IDs are resolved only inside the account. A duplicate or missing exact name fails closed instead of selecting another account’s row.
  • Appointment scopes never imply contact, deal or AI-agent access.
  • Archive and restore are public administration operations because they retain history. Permanent resource/service deletion is not part of the documented integration contract.
  • Resource-to-AI-agent assignment remains an AI administration workflow, not an appointment integration operation.
See the interactive API reference for every request field, response schema and error status.