SchedulinqDocs
Go to Schedulinq

Invitations

The Invite button — one call sends the customer an invitation to book with one of the team members you chose.

An invitation is the Invite button in your CRM. One call sends the customer a personal link to book a service with one of the team members you chose; the customer picks a time that suits them on your booking page. It is the same invitation you can send from the dashboard, described in Send invitations.

The request

POST /api/v1/invitations (scope invitations:write), with an Idempotency-Key:

Example request · POST /api/v1/invitations

IDEMPOTENCY_KEY=$(uuidgen)   # once per action; to retry, run only the curl line again (same key)
curl -X POST https://api.schedulinq.com/api/v1/invitations \
  -H "Authorization: Bearer $SCHEDULINQ_API_KEY" \
  -H "Idempotency-Key: $IDEMPOTENCY_KEY" \
  -H "Content-Type: application/json" \
  -d '{
  "address": {
    "city": "Amsterdam",
    "country": "NL",
    "line1": "Keizersgracht 100",
    "postalCode": "1015 AA"
  },
  "appointmentTypeId": "3f0c8a52-6b1e-4d7a-9c3e-1a2b3c4d5e01",
  "customer": {
    "id": "3f0c8a52-6b1e-4d7a-9c3e-1a2b3c4d5e06"
  },
  "metadata": {
    "campaignId": "C-42",
    "dealId": "D-123"
  },
  "users": [
    {
      "id": "3f0c8a52-6b1e-4d7a-9c3e-1a2b3c4d5e03"
    }
  ]
}'

Request body · POST /api/v1/invitations

{
  "address": {
    "city": "Amsterdam",
    "country": "NL",
    "line1": "Keizersgracht 100",
    "postalCode": "1015 AA"
  },
  "appointmentTypeId": "3f0c8a52-6b1e-4d7a-9c3e-1a2b3c4d5e01",
  "customer": {
    "id": "3f0c8a52-6b1e-4d7a-9c3e-1a2b3c4d5e06"
  },
  "metadata": {
    "campaignId": "C-42",
    "dealId": "D-123"
  },
  "users": [
    {
      "id": "3f0c8a52-6b1e-4d7a-9c3e-1a2b3c4d5e03"
    }
  ]
}
  • users are the team members the customer can book with: one or more, at most 100, each as {"id": …} or {"email": …} and each once. The booking page offers the times any of them is free, and the appointment is booked with one of them — just like the team members you tick on an invitation in the dashboard. Every one must be active, schedulable, and do the service and every add-on. A refusal names the entry, for example users[1].
  • appointmentTypeId is the service (GET /api/v1/services).
  • addOns are optional: each add-on once, offered with the service, and with a quantity above one only where the add-on allows it.
  • customer is an existing customer by id — {"id": …} and nothing else — or the customer's details, found by e-mail address or created. The rules are the same as on a planning link.
  • address and metadata follow the same rules as on a planning link: the address is this appointment's own, never the customer's billing address. See Metadata.
  • validUntil: see Until when.

With a customer you already know, by id:

Request body · POST /api/v1/invitations

{
  "address": {
    "city": "Amsterdam",
    "country": "NL",
    "line1": "Keizersgracht 100",
    "postalCode": "1015 AA"
  },
  "appointmentTypeId": "3f0c8a52-6b1e-4d7a-9c3e-1a2b3c4d5e01",
  "customer": {
    "id": "3f0c8a52-6b1e-4d7a-9c3e-1a2b3c4d5e06"
  },
  "metadata": {
    "campaignId": "C-42",
    "dealId": "D-123"
  },
  "users": [
    {
      "id": "3f0c8a52-6b1e-4d7a-9c3e-1a2b3c4d5e03"
    }
  ]
}

You do not send a name or a duration. Schedulinq takes the name from the service, in your organisation's language, and the duration from the service plus its add-ons. A service with no duration of its own and no add-on time gives a 422 errors.validation.serviceHasNoDuration.

A deactivated customer is refused with a 409 errors.api.customerDeactivated: they could never book the link. An id that is not one of your customers — unknown, archived, or another organisation's — gives a 404 errors.api.customerNotFound; a customer that was merged into another is followed to that one.

What happens

The invitation is sent at once, in your organisation's name and branding, through your communication steps — by e-mail, SMS or WhatsApp, just as when you send one from the dashboard.

Response · 201

{
  "address": {
    "city": "Amsterdam",
    "country": "NL",
    "line1": "Keizersgracht 100",
    "postalCode": "1015 AA"
  },
  "bookingPageClosed": false,
  "bookingUrl": "https://schedulinq.com/i/EXAMPLE-INVITATION",
  "colleagues": [
    {
      "id": "3f0c8a52-6b1e-4d7a-9c3e-1a2b3c4d5e01",
      "name": "Offertebezoek"
    }
  ],
  "createdAt": "2026-10-01T09:00:00+02:00",
  "customerId": "3f0c8a52-6b1e-4d7a-9c3e-1a2b3c4d5e06",
  "id": "3f0c8a52-6b1e-4d7a-9c3e-1a2b3c4d5e08",
  "initialEmailDeferred": false,
  "lineageRootId": "3f0c8a52-6b1e-4d7a-9c3e-1a2b3c4d5e09",
  "location": {
    "id": "3f0c8a52-6b1e-4d7a-9c3e-1a2b3c4d5e01",
    "name": "Offertebezoek"
  },
  "locationMode": "VIDEO",
  "metadata": {
    "campaignId": "C-42",
    "dealId": "D-123"
  },
  "rescheduledFromAppointmentId": "3f0c8a52-6b1e-4d7a-9c3e-1a2b3c4d5e09",
  "service": {
    "id": "3f0c8a52-6b1e-4d7a-9c3e-1a2b3c4d5e01",
    "name": "Offertebezoek"
  },
  "status": "PENDING",
  "updatedAt": "2026-10-01T09:00:00+02:00",
  "validUntil": "2026-10-31"
}
  • The answer says the first message is queued, never that it was sent.
  • bookingPageClosed: true means your booking page is not taking bookings right now. The invitation exists, but its first message is not sent, and its link lands on a closed page until you reopen your booking page.
  • initialEmailDeferred: true means the first message was not sent because the customer has no e-mail address.
  • bookingUrl is the customer's personal link: it opens the booking page with their details filled in and books in their name. Give it only to that customer. Never log it, and never show it to anyone else.

In the dashboard the invitation says Created: Via API and the name of the key. It then behaves like any other invitation: your team can open it, change it and send it again.

Several buyers per lead

A second invitation for the same customer and service is simply another invitation: neither the API nor the dashboard refuses it, and booking one never closes the other. So a lead platform can invite one customer on behalf of several buyers in two ways: one invitation per buyer, each booked on its own, or one invitation with several buyers in users, of whom the customer books one. A retry of the same request is caught by the Idempotency-Key: the same key and body answer the first invitation again and send nothing. See Idempotency.

Three budgets apply per organisation, whatever the number of keys: 60 invitations a minute, 5,000 per 24 hours, and 10 to the same customer per 24 hours, counted by e-mail address (a customer named by id counts under its address). The last one answers 429 errors.api.customerInvitationLimit. See Rate limits.

Until when

validUntil is the last day the invitation can be booked, as a date in your organisation's time zone. Without it the invitation gets your organisation's default, the same one the dashboard proposes. A date in the past or too far ahead is refused. How the end date works is described under Until when the customer can book.

Reading it back

With scope invitations:read:

  • GET /api/v1/invitations/{id} reads one invitation.
  • GET /api/v1/invitations?metadata[dealId]=D-123 finds invitations by a metadata value. At least one metadata[…] filter is required; status narrows to PENDING (can be booked), USED (booked), CANCELLED or EXPIRED; limit and cursor page through the results.

Example request · GET /api/v1/invitations

curl --globoff "https://api.schedulinq.com/api/v1/invitations?metadata[dealId]=D-123&limit=25" \
  -H "Authorization: Bearer $SCHEDULINQ_API_KEY"

bookingUrl is only in the answer to the create (and to a replay of it with the same Idempotency-Key), never in a read or a webhook. If your system needs it, keep it from that answer.

Once the customer books, the invitation is USED and appointmentIds lists the appointments, earliest first. The webhook invitation.booked carries the same ids. See Webhook events.

Ended in the dashboard

The API cannot cancel an invitation; your team does that in the dashboard.

  • A cancelled invitation gets status CANCELLED, and the webhook invitation.cancelled.
  • An archived invitation answers 404 from then on, and the webhook is invitation.deleted.

Frequently asked questions

Can I send one invitation with several services?

Not through the API. An API invitation holds one service, with its add-ons, and the team members you name. Several services in one invitation can be sent from the dashboard.

The customer says they received nothing. What now?

Read the invitation and check status. Then look at the invitation's page in the dashboard: its message timeline shows whether the message went out, and your team can send it again from there.

No. It is in the create's answer only. Store it then if you need it, as carefully as you would a password.

Last updated October 4, 2026