SchedulinqDocs
Go to Schedulinq

Appointments

Read appointments back — one by id, or every one with a metadata value — and follow an appointment that moved to a new id.

Appointments are made in Schedulinq: by a caller from a planning link, by the customer from an invitation or the booking page, or by your team. The API reads them back, so your CRM can show what was booked. To hear about changes as they happen, use webhooks: every webhook about an appointment carries the same shape as these reads.

Reading one

GET /api/v1/appointments/{id} (scope appointments:read):

Example request · GET /api/v1/appointments/{id}

curl https://api.schedulinq.com/api/v1/appointments/3f0c8a52-6b1e-4d7a-9c3e-1a2b3c4d5e09 \
  -H "Authorization: Bearer $SCHEDULINQ_API_KEY"

Response · 200

{
  "address": {
    "city": "Amsterdam",
    "country": "NL",
    "line1": "Keizersgracht 100",
    "postalCode": "1015 AA"
  },
  "cancellationReason": "Ziek",
  "cancelledAt": "2026-10-12T15:30:00+02:00",
  "cancelledBy": "CUSTOMER",
  "colleagues": [
    {
      "id": "3f0c8a52-6b1e-4d7a-9c3e-1a2b3c4d5e01",
      "name": "Offertebezoek"
    }
  ],
  "createdAt": "2026-10-01T09:00:00+02:00",
  "customerId": "3f0c8a52-6b1e-4d7a-9c3e-1a2b3c4d5e06",
  "end": "2026-10-14T11:00:00+02:00",
  "id": "3f0c8a52-6b1e-4d7a-9c3e-1a2b3c4d5e09",
  "invitationId": "3f0c8a52-6b1e-4d7a-9c3e-1a2b3c4d5e08",
  "lineageRootId": "3f0c8a52-6b1e-4d7a-9c3e-1a2b3c4d5e09",
  "location": {
    "id": "3f0c8a52-6b1e-4d7a-9c3e-1a2b3c4d5e01",
    "name": "Offertebezoek"
  },
  "locationMode": "AT_CUSTOMER",
  "meetingProvider": "GOOGLE_MEET",
  "meetingUrl": "https://meet.google.com/abc-defg-hij",
  "metadata": {
    "campaignId": "C-42",
    "dealId": "D-123"
  },
  "planningLinkId": "3f0c8a52-6b1e-4d7a-9c3e-1a2b3c4d5e07",
  "rescheduledFromId": "3f0c8a52-6b1e-4d7a-9c3e-1a2b3c4d5e09",
  "service": {
    "id": "3f0c8a52-6b1e-4d7a-9c3e-1a2b3c4d5e01",
    "name": "Offertebezoek"
  },
  "start": "2026-10-14T10:00:00+02:00",
  "status": "CONFIRMED",
  "timeZone": "Europe/Amsterdam",
  "updatedAt": "2026-10-01T09:00:00+02:00"
}

An archived appointment, or another organisation's, answers 404 errors.api.appointmentNotFound.

Finding by metadata

GET /api/v1/appointments finds the appointments that carry your metadata — the deal id you put on the planning link or invitation, for example.

Example request · GET /api/v1/appointments

curl --globoff "https://api.schedulinq.com/api/v1/appointments?from=2026-10-01T00:00:00Z&to=2026-11-01T00:00:00Z&metadata[dealId]=D-123&limit=25" \
  -H "Authorization: Bearer $SCHEDULINQ_API_KEY"
  • metadata[<key>]=<value> matches exactly. At least one is required, and every one you send must match. The brackets may be sent as they are or as %5B and %5D. See Metadata.
  • status only returns appointments in that status.
  • from (inclusive) and to (exclusive) apply to the start. Send them as date-times with an offset; write the + of an offset as %2B, or use Z.
  • limit (1 to 100) and cursor page through the results: pass the previous page's nextCursor.

An unknown query parameter is refused: a typo such as metdata[dealId] is a 400 errors.validation.unknownField, not the list of every appointment.

Results are ordered by creation, oldest first, and a cursor makes one pass through them. An appointment that is still being saved while you page past its creation time is not returned to that cursor. To reconcile, run the lookup again from the start; to keep up, follow changes through webhooks.

Statuses

Today Schedulinq produces three statuses:

  • CONFIRMED — booked;
  • COMPLETED — finished, also when its invoice was issued;
  • CANCELLED — cancelled.

PENDING and NO_SHOW exist in the list of values, but nothing sets them yet.

A cancelled appointment also carries cancelledAt, cancellationReason (when one was given) and cancelledBy: CUSTOMER, STAFF, SYSTEM, or STAFF_RESCHEDULE when a team member cancelled it with Reschedule so the customer can book a new time.

When an appointment moves to a new id

A customer who reschedules through their own link does not move the appointment: the old one is cancelled and a new one is created. The new appointment carries:

  • rescheduledFromId — the appointment it replaced;
  • lineageRootId — the first appointment of the booking, however often it moved.

Key your records by lineageRootId when it is there, and by id when it is not, to keep one record per booking. Or follow appointment.rescheduled, which arrives on the new appointment and names the old one. See Webhook events.

When a team member uses Reschedule instead, the appointment is cancelled with cancelledBy: STAFF_RESCHEDULE, and the customer gets an invitation to book a new time. The appointment they then book carries rescheduledFromId and lineageRootId in the same way, and it carries your metadata too.

What it carries

  • Times as date-times with the offset of your organisation's time zone, plus timeZone (an IANA name such as Europe/Amsterdam).
  • The service and the team members, by id and name.
  • The customer as a customerId, with no name or contact details.
  • Where it happens: locationMode (AT_CUSTOMER, ON_LOCATION, VIDEO or PHONE), the visit address when it is at the customer's, the location when it is at one of yours, and for a video call the meetingUrl once there is one.
  • invitationId or planningLinkId when it was booked from one of those.
  • Your metadata, as metadata.

Polling

Prefer webhooks: they arrive within seconds of a change and cost you no requests. Use the list now and then to reconcile, for example after your webhook receiver was down. See Rate limits.

Frequently asked questions

Can I create or change an appointment through the API?

No. Appointments are made in Schedulinq — by your team from a planning link, or by the customer from an invitation — so that the planner and the booking page check every time. Changes are made in the dashboard.

Why is there no customer name in the answer?

Metadata and the customerId link the appointment to the lead in your CRM, which already has the customer's details. Sending them again would spread personal data further than it needs to go.

Last updated October 2, 2026