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"
}
]
}usersare 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 exampleusers[1].appointmentTypeIdis the service (GET /api/v1/services).addOnsare optional: each add-on once, offered with the service, and with aquantityabove one only where the add-on allows it.customeris 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.addressandmetadatafollow 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: truemeans 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: truemeans the first message was not sent because the customer has no e-mail address.bookingUrlis 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-123finds invitations by a metadata value. At least onemetadata[…]filter is required;statusnarrows toPENDING(can be booked),USED(booked),CANCELLEDorEXPIRED;limitandcursorpage 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 webhookinvitation.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.
Can I see the booking link later?
No. It is in the create's answer only. Store it then if you need it, as carefully as you would a password.