Klantly Developers

API-referentie

Afspraken

Afspraken in de agenda: inplannen, verzetten, bevestigen, annuleren en afronden, en de klant een bericht sturen.

Endpoints

Afspraken opvragen

GET /api/v1/appointments

Een lijst van afspraken, nieuwste eerst. Filter op status, klant, gebruiker, begintijd of wijzigingsdatum. Sorteer op starts_at voor de volgorde van de agenda; afspraken zonder datum (een uitnodiging) vallen dan weg.

Scope
appointments.read — Afspraken (met naam, e-mail en telefoon van de klant), afspraaktypes en beschikbaarheid lezen
Vereiste functie
appointments

Queryparameters

NaamTypeOmschrijving
limit integer Aantal resultaten per pagina. van 1 tot 100 · standaard: 50
cursor string De next_cursor of prev_cursor uit meta van het vorige antwoord.
sort string Sortering op created_at, updated_at of starts_at; een min-teken ervoor is aflopend. Bij starts_at vallen afspraken zonder datum weg. een van: -created_at, created_at, -updated_at, updated_at, -starts_at, starts_at · standaard: -created_at
filter[status] string Alleen afspraken met deze status: pending (nog niet bevestigd), confirmed, cancelled of completed. een van: pending, confirmed, cancelled, completed
filter[customer_id] string (uuid) Alleen wat bij deze klant hoort.
filter[user_id] string Alleen afspraken van deze gebruiker (de id uit Gebruikers opvragen).
filter[starts_from] string (date-time) Alleen afspraken die op of na dit tijdstip beginnen: ISO 8601 mét tijdzone.
filter[starts_until] string (date-time) Alleen afspraken die vóór dit tijdstip beginnen: ISO 8601 mét tijdzone.
filter[updated_since] string (date-time) Alleen wat sinds dit tijdstip is gewijzigd: ISO 8601 mét tijdzone, bijvoorbeeld 2026-09-14T10:15:00Z. Handig om te synchroniseren.

Voorbeeldverzoek

cURL
curl "https://app.klantly.com/api/v1/appointments?filter[starts_from]=2026-10-01T00%3A00%3A00Z&sort=starts_at" \
  -H "Authorization: Bearer $KLANTLY_API_KEY"
PHP
$client = new \GuzzleHttp\Client([
    'base_uri' => 'https://app.klantly.com/api/v1/',
    'headers' => ['Authorization' => 'Bearer ' . getenv('KLANTLY_API_KEY')],
]);

$response = $client->request('GET', 'appointments', [
    'query' => [
        'filter[starts_from]' => '2026-10-01T00:00:00Z',
        'sort' => 'starts_at',
    ],
]);

$data = json_decode((string) $response->getBody(), true)['data'];
JavaScript
const response = await fetch('https://app.klantly.com/api/v1/appointments?filter[starts_from]=2026-10-01T00%3A00%3A00Z&sort=starts_at', {
  headers: {
    Authorization: `Bearer ${process.env.KLANTLY_API_KEY}`,
  },
});

const { data } = await response.json();
Python
import os

import requests

response = requests.get(
    "https://app.klantly.com/api/v1/appointments",
    headers={
        "Authorization": f"Bearer {os.environ['KLANTLY_API_KEY']}",
    },
    params={
        "filter[starts_from]": "2026-10-01T00:00:00Z",
        "sort": "starts_at"
    },
)
data = response.json()["data"]

Antwoord 200

Het antwoord is een lijst met cursorpaginering: data bevat de objecten, meta de paginering.

Voorbeeldantwoord
{
  "data": [
    {
      "object": "appointment",
      "id": "9d3f7d83-4f8b-4a0e-9d5c-6b7f8a9bacb4",
      "title": "Inmeten veranda",
      "description": null,
      "status": "confirmed",
      "starts_at": "2026-10-01T08:00:00Z",
      "ends_at": "2026-10-01T09:00:00Z",
      "all_day": false,
      "location": "Dorpsstraat 1, Utrecht",
      "customer_id": "9d3f6c1e-4b2a-4c8e-9f1a-2b3c4d5e6f70",
      "contact": {
        "name": "Jan de Vries",
        "email": "jan@example.com",
        "phone": "+31 6 12345678"
      },
      "user_id": "usr_0k3j9x21m4zq8p",
      "appointment_type_id": "9d3f7ea4-5a9c-4b1f-8e6d-7c8a9bacbdc5",
      "deal_id": "9d3f7a20-1c5e-4d7b-8a2f-3e4c5d6f7a81",
      "quote_id": null,
      "invoice_id": null,
      "notes": null,
      "cancellation_reason": null,
      "confirmed_at": "2026-09-14T10:15:00Z",
      "cancelled_at": null,
      "rescheduled_at": null,
      "created_at": "2026-09-14T10:15:00Z",
      "updated_at": "2026-09-14T10:15:00Z"
    }
  ],
  "meta": {
    "limit": 50,
    "next_cursor": "eyJpZCI6IjlkM2Y2YzFlIn0",
    "prev_cursor": null
  }
}

Mogelijke fouten

Daarnaast kan elk endpoint de algemene fouten geven, zoals een ongeldige sleutel of een bereikte limiet. Bekijk alle foutcodes.

Afspraak ophalen

GET /api/v1/appointments/{appointment}

Eén afspraak op id. Het antwoord bevat een ETag die je bij bijwerken in If-Match kunt meesturen.

Scope
appointments.read — Afspraken (met naam, e-mail en telefoon van de klant), afspraaktypes en beschikbaarheid lezen
Vereiste functie
appointments

Padparameters

NaamTypeOmschrijving
appointment verplicht string (uuid) De id (UUID) van de afspraak.

Voorbeeldverzoek

cURL
curl "https://app.klantly.com/api/v1/appointments/9d3f6c1e-4b2a-4c8e-9f1a-2b3c4d5e6f70" \
  -H "Authorization: Bearer $KLANTLY_API_KEY"
PHP
$client = new \GuzzleHttp\Client([
    'base_uri' => 'https://app.klantly.com/api/v1/',
    'headers' => ['Authorization' => 'Bearer ' . getenv('KLANTLY_API_KEY')],
]);

$response = $client->request('GET', 'appointments/9d3f6c1e-4b2a-4c8e-9f1a-2b3c4d5e6f70');

$data = json_decode((string) $response->getBody(), true)['data'];
JavaScript
const response = await fetch('https://app.klantly.com/api/v1/appointments/9d3f6c1e-4b2a-4c8e-9f1a-2b3c4d5e6f70', {
  headers: {
    Authorization: `Bearer ${process.env.KLANTLY_API_KEY}`,
  },
});

const { data } = await response.json();
Python
import os

import requests

response = requests.get(
    "https://app.klantly.com/api/v1/appointments/9d3f6c1e-4b2a-4c8e-9f1a-2b3c4d5e6f70",
    headers={
        "Authorization": f"Bearer {os.environ['KLANTLY_API_KEY']}",
    },
)
data = response.json()["data"]

Antwoord 200

Voorbeeldantwoord
{
  "data": {
    "object": "appointment",
    "id": "9d3f7d83-4f8b-4a0e-9d5c-6b7f8a9bacb4",
    "title": "Inmeten veranda",
    "description": null,
    "status": "confirmed",
    "starts_at": "2026-10-01T08:00:00Z",
    "ends_at": "2026-10-01T09:00:00Z",
    "all_day": false,
    "location": "Dorpsstraat 1, Utrecht",
    "customer_id": "9d3f6c1e-4b2a-4c8e-9f1a-2b3c4d5e6f70",
    "contact": {
      "name": "Jan de Vries",
      "email": "jan@example.com",
      "phone": "+31 6 12345678"
    },
    "user_id": "usr_0k3j9x21m4zq8p",
    "appointment_type_id": "9d3f7ea4-5a9c-4b1f-8e6d-7c8a9bacbdc5",
    "deal_id": "9d3f7a20-1c5e-4d7b-8a2f-3e4c5d6f7a81",
    "quote_id": null,
    "invoice_id": null,
    "notes": null,
    "cancellation_reason": null,
    "confirmed_at": "2026-09-14T10:15:00Z",
    "cancelled_at": null,
    "rescheduled_at": null,
    "created_at": "2026-09-14T10:15:00Z",
    "updated_at": "2026-09-14T10:15:00Z"
  }
}

Mogelijke fouten

Daarnaast kan elk endpoint de algemene fouten geven, zoals een ongeldige sleutel of een bereikte limiet. Bekijk alle foutcodes.

Afspraak inplannen

POST /api/v1/appointments

Plant een afspraak in bij een klant; naam, e-mail en telefoon komen van de klant. Zonder ends_at duurt de afspraak zo lang als het afspraaktype, anders de standaardduur uit de afspraakinstellingen. Klantly controleert hier geen beschikbaarheid: jouw planning is leidend. De API stuurt de klant zelf geen mail; daarvoor is Bericht aan de klant sturen. Heeft het bedrijf automations op "afspraak ingepland", dan lopen die wél, net als bij een afspraak in de agenda.

Scope
appointments.write — Afspraken aanmaken, wijzigen, bevestigen, annuleren en afronden (automations van het bedrijf lopen mee)
Vereiste functie
appointments

Stuur een Idempotency-Key mee, dan maakt een nieuwe poging na een time-out geen dubbel record.

Body (JSON)

VeldTypeOmschrijving
customer_id verplicht string (uuid) De klant van de afspraak. Verplicht bij aanmaken.
title optioneel string Titel van de afspraak. kan leeg zijn (null) · maximaal 255 tekens · verplicht zonder appointment_type_id
description optioneel string Omschrijving. kan leeg zijn (null) · maximaal 2000 tekens
location optioneel string Locatie, bijvoorbeeld het adres van de klant. kan leeg zijn (null) · maximaal 255 tekens
starts_at verplicht string (date-time) Begin (UTC). Leeg bij een uitnodiging waarvoor de klant nog een tijd kiest. Bij invoer: ISO 8601 mét tijdzone.
ends_at optioneel string (date-time) Einde (UTC). Zonder ends_at bij aanmaken: de duur van het afspraaktype of de standaardduur. kan leeg zijn (null)
all_day optioneel boolean Een afspraak voor de hele dag. Tijden staan in het antwoord in UTC: reken voor de datum terug naar de tijdzone van het bedrijf (Europe/Amsterdam), anders valt een afspraak die om 00:00 begint op de dag ervoor.
appointment_type_id optioneel string (uuid) Het afspraaktype, of null. kan leeg zijn (null)
user_id optioneel string De gebruiker die de afspraak heeft, of null. kan leeg zijn (null)
status optioneel string pending (nog niet bevestigd), confirmed, cancelled (geannuleerd) of completed (afgerond). Bij aanmaken pending of confirmed (standaard). een van: pending, confirmed
notes optioneel string Interne notitie bij de afspraak. kan leeg zijn (null) · maximaal 2000 tekens

Voorbeeldverzoek

cURL
curl -X POST "https://app.klantly.com/api/v1/appointments" \
  -H "Authorization: Bearer $KLANTLY_API_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: 6f1c2d3e-4a5b-4c6d-8e7f-9a0b1c2d3e4f" \
  -d '{
  "customer_id": "9d3f6c1e-4b2a-4c8e-9f1a-2b3c4d5e6f70",
  "title": "Inmeten veranda",
  "starts_at": "2026-10-01T10:00:00+02:00",
  "appointment_type_id": "9d3f7ea4-5a9c-4b1f-8e6d-7c8a9bacbdc5"
}'
PHP
$client = new \GuzzleHttp\Client([
    'base_uri' => 'https://app.klantly.com/api/v1/',
    'headers' => ['Authorization' => 'Bearer ' . getenv('KLANTLY_API_KEY')],
]);

$response = $client->request('POST', 'appointments', [
    'headers' => [
        'Idempotency-Key' => '6f1c2d3e-4a5b-4c6d-8e7f-9a0b1c2d3e4f',
    ],
    'json' => [
        'customer_id' => '9d3f6c1e-4b2a-4c8e-9f1a-2b3c4d5e6f70',
        'title' => 'Inmeten veranda',
        'starts_at' => '2026-10-01T10:00:00+02:00',
        'appointment_type_id' => '9d3f7ea4-5a9c-4b1f-8e6d-7c8a9bacbdc5',
    ],
]);

$data = json_decode((string) $response->getBody(), true)['data'];
JavaScript
const response = await fetch('https://app.klantly.com/api/v1/appointments', {
  method: 'POST',
  headers: {
    Authorization: `Bearer ${process.env.KLANTLY_API_KEY}`,
    'Content-Type': 'application/json',
    'Idempotency-Key': '6f1c2d3e-4a5b-4c6d-8e7f-9a0b1c2d3e4f',
  },
  body: JSON.stringify({
  "customer_id": "9d3f6c1e-4b2a-4c8e-9f1a-2b3c4d5e6f70",
  "title": "Inmeten veranda",
  "starts_at": "2026-10-01T10:00:00+02:00",
  "appointment_type_id": "9d3f7ea4-5a9c-4b1f-8e6d-7c8a9bacbdc5"
}),
});

const { data } = await response.json();
Python
import os

import requests

response = requests.post(
    "https://app.klantly.com/api/v1/appointments",
    headers={
        "Authorization": f"Bearer {os.environ['KLANTLY_API_KEY']}",
        "Idempotency-Key": "6f1c2d3e-4a5b-4c6d-8e7f-9a0b1c2d3e4f",
    },
    json={
        "customer_id": "9d3f6c1e-4b2a-4c8e-9f1a-2b3c4d5e6f70",
        "title": "Inmeten veranda",
        "starts_at": "2026-10-01T10:00:00+02:00",
        "appointment_type_id": "9d3f7ea4-5a9c-4b1f-8e6d-7c8a9bacbdc5"
    },
)
data = response.json()["data"]

Antwoord 201

Voorbeeldantwoord
{
  "data": {
    "object": "appointment",
    "id": "9d3f7d83-4f8b-4a0e-9d5c-6b7f8a9bacb4",
    "title": "Inmeten veranda",
    "description": null,
    "status": "confirmed",
    "starts_at": "2026-10-01T08:00:00Z",
    "ends_at": "2026-10-01T09:00:00Z",
    "all_day": false,
    "location": "Dorpsstraat 1, Utrecht",
    "customer_id": "9d3f6c1e-4b2a-4c8e-9f1a-2b3c4d5e6f70",
    "contact": {
      "name": "Jan de Vries",
      "email": "jan@example.com",
      "phone": "+31 6 12345678"
    },
    "user_id": "usr_0k3j9x21m4zq8p",
    "appointment_type_id": "9d3f7ea4-5a9c-4b1f-8e6d-7c8a9bacbdc5",
    "deal_id": "9d3f7a20-1c5e-4d7b-8a2f-3e4c5d6f7a81",
    "quote_id": null,
    "invoice_id": null,
    "notes": null,
    "cancellation_reason": null,
    "confirmed_at": "2026-09-14T10:15:00Z",
    "cancelled_at": null,
    "rescheduled_at": null,
    "created_at": "2026-09-14T10:15:00Z",
    "updated_at": "2026-09-14T10:15:00Z"
  }
}

Mogelijke fouten

Daarnaast kan elk endpoint de algemene fouten geven, zoals een ongeldige sleutel of een bereikte limiet. Bekijk alle foutcodes.

Afspraak bijwerken

PATCH /api/v1/appointments/{appointment}

Wijzigt alleen de velden die je meestuurt. Een nieuwe starts_at is een verzetting: rescheduled_at wordt gezet, en zonder ends_at blijft de duur gelijk. Krijgt een afspraak zonder datum een starts_at, dan komt ends_at erbij zoals bij aanmaken; een ends_at zonder begintijd kan niet (422). De status verander je met bevestigen, annuleren of afronden.

Scope
appointments.write — Afspraken aanmaken, wijzigen, bevestigen, annuleren en afronden (automations van het bedrijf lopen mee)
Vereiste functie
appointments

Stuur de ETag mee in If-Match, dan overschrijf je nooit per ongeluk een nieuwere versie.

Padparameters

NaamTypeOmschrijving
appointment verplicht string (uuid) De id (UUID) van de afspraak.

Body (JSON)

VeldTypeOmschrijving
title optioneel string Titel van de afspraak. maximaal 255 tekens
description optioneel string Omschrijving. kan leeg zijn (null) · maximaal 2000 tekens
location optioneel string Locatie, bijvoorbeeld het adres van de klant. kan leeg zijn (null) · maximaal 255 tekens
starts_at optioneel string (date-time) Begin (UTC). Leeg bij een uitnodiging waarvoor de klant nog een tijd kiest. Bij invoer: ISO 8601 mét tijdzone.
ends_at optioneel string (date-time) Einde (UTC). Zonder ends_at bij aanmaken: de duur van het afspraaktype of de standaardduur.
all_day optioneel boolean Een afspraak voor de hele dag. Tijden staan in het antwoord in UTC: reken voor de datum terug naar de tijdzone van het bedrijf (Europe/Amsterdam), anders valt een afspraak die om 00:00 begint op de dag ervoor.
appointment_type_id optioneel string (uuid) Het afspraaktype, of null. kan leeg zijn (null)
user_id optioneel string De gebruiker die de afspraak heeft, of null. kan leeg zijn (null)
notes optioneel string Interne notitie bij de afspraak. kan leeg zijn (null) · maximaal 2000 tekens

Voorbeeldverzoek

cURL
curl -X PATCH "https://app.klantly.com/api/v1/appointments/9d3f6c1e-4b2a-4c8e-9f1a-2b3c4d5e6f70" \
  -H "Authorization: Bearer $KLANTLY_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
  "starts_at": "2026-10-02T09:00:00Z"
}'
PHP
$client = new \GuzzleHttp\Client([
    'base_uri' => 'https://app.klantly.com/api/v1/',
    'headers' => ['Authorization' => 'Bearer ' . getenv('KLANTLY_API_KEY')],
]);

$response = $client->request('PATCH', 'appointments/9d3f6c1e-4b2a-4c8e-9f1a-2b3c4d5e6f70', [
    'json' => [
        'starts_at' => '2026-10-02T09:00:00Z',
    ],
]);

$data = json_decode((string) $response->getBody(), true)['data'];
JavaScript
const response = await fetch('https://app.klantly.com/api/v1/appointments/9d3f6c1e-4b2a-4c8e-9f1a-2b3c4d5e6f70', {
  method: 'PATCH',
  headers: {
    Authorization: `Bearer ${process.env.KLANTLY_API_KEY}`,
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({
  "starts_at": "2026-10-02T09:00:00Z"
}),
});

const { data } = await response.json();
Python
import os

import requests

response = requests.patch(
    "https://app.klantly.com/api/v1/appointments/9d3f6c1e-4b2a-4c8e-9f1a-2b3c4d5e6f70",
    headers={
        "Authorization": f"Bearer {os.environ['KLANTLY_API_KEY']}",
    },
    json={
        "starts_at": "2026-10-02T09:00:00Z"
    },
)
data = response.json()["data"]

Antwoord 200

Voorbeeldantwoord
{
  "data": {
    "object": "appointment",
    "id": "9d3f7d83-4f8b-4a0e-9d5c-6b7f8a9bacb4",
    "title": "Inmeten veranda",
    "description": null,
    "status": "confirmed",
    "starts_at": "2026-10-01T08:00:00Z",
    "ends_at": "2026-10-01T09:00:00Z",
    "all_day": false,
    "location": "Dorpsstraat 1, Utrecht",
    "customer_id": "9d3f6c1e-4b2a-4c8e-9f1a-2b3c4d5e6f70",
    "contact": {
      "name": "Jan de Vries",
      "email": "jan@example.com",
      "phone": "+31 6 12345678"
    },
    "user_id": "usr_0k3j9x21m4zq8p",
    "appointment_type_id": "9d3f7ea4-5a9c-4b1f-8e6d-7c8a9bacbdc5",
    "deal_id": "9d3f7a20-1c5e-4d7b-8a2f-3e4c5d6f7a81",
    "quote_id": null,
    "invoice_id": null,
    "notes": null,
    "cancellation_reason": null,
    "confirmed_at": "2026-09-14T10:15:00Z",
    "cancelled_at": null,
    "rescheduled_at": null,
    "created_at": "2026-09-14T10:15:00Z",
    "updated_at": "2026-09-14T10:15:00Z"
  }
}

Mogelijke fouten

Daarnaast kan elk endpoint de algemene fouten geven, zoals een ongeldige sleutel of een bereikte limiet. Bekijk alle foutcodes.

Afspraak bevestigen

POST /api/v1/appointments/{appointment}/confirm

Zet een afspraak op bevestigd. Is hij al bevestigd, dan verandert er niets.

Scope
appointments.write — Afspraken aanmaken, wijzigen, bevestigen, annuleren en afronden (automations van het bedrijf lopen mee)
Vereiste functie
appointments

Stuur een Idempotency-Key mee, dan maakt een nieuwe poging na een time-out geen dubbel record.

Padparameters

NaamTypeOmschrijving
appointment verplicht string (uuid) De id (UUID) van de afspraak.

Voorbeeldverzoek

cURL
curl -X POST "https://app.klantly.com/api/v1/appointments/9d3f6c1e-4b2a-4c8e-9f1a-2b3c4d5e6f70/confirm" \
  -H "Authorization: Bearer $KLANTLY_API_KEY" \
  -H "Idempotency-Key: 6f1c2d3e-4a5b-4c6d-8e7f-9a0b1c2d3e4f"
PHP
$client = new \GuzzleHttp\Client([
    'base_uri' => 'https://app.klantly.com/api/v1/',
    'headers' => ['Authorization' => 'Bearer ' . getenv('KLANTLY_API_KEY')],
]);

$response = $client->request('POST', 'appointments/9d3f6c1e-4b2a-4c8e-9f1a-2b3c4d5e6f70/confirm', [
    'headers' => [
        'Idempotency-Key' => '6f1c2d3e-4a5b-4c6d-8e7f-9a0b1c2d3e4f',
    ],
]);

$data = json_decode((string) $response->getBody(), true)['data'];
JavaScript
const response = await fetch('https://app.klantly.com/api/v1/appointments/9d3f6c1e-4b2a-4c8e-9f1a-2b3c4d5e6f70/confirm', {
  method: 'POST',
  headers: {
    Authorization: `Bearer ${process.env.KLANTLY_API_KEY}`,
    'Idempotency-Key': '6f1c2d3e-4a5b-4c6d-8e7f-9a0b1c2d3e4f',
  },
});

const { data } = await response.json();
Python
import os

import requests

response = requests.post(
    "https://app.klantly.com/api/v1/appointments/9d3f6c1e-4b2a-4c8e-9f1a-2b3c4d5e6f70/confirm",
    headers={
        "Authorization": f"Bearer {os.environ['KLANTLY_API_KEY']}",
        "Idempotency-Key": "6f1c2d3e-4a5b-4c6d-8e7f-9a0b1c2d3e4f",
    },
)
data = response.json()["data"]

Antwoord 200

Voorbeeldantwoord
{
  "data": {
    "object": "appointment",
    "id": "9d3f7d83-4f8b-4a0e-9d5c-6b7f8a9bacb4",
    "title": "Inmeten veranda",
    "description": null,
    "status": "confirmed",
    "starts_at": "2026-10-01T08:00:00Z",
    "ends_at": "2026-10-01T09:00:00Z",
    "all_day": false,
    "location": "Dorpsstraat 1, Utrecht",
    "customer_id": "9d3f6c1e-4b2a-4c8e-9f1a-2b3c4d5e6f70",
    "contact": {
      "name": "Jan de Vries",
      "email": "jan@example.com",
      "phone": "+31 6 12345678"
    },
    "user_id": "usr_0k3j9x21m4zq8p",
    "appointment_type_id": "9d3f7ea4-5a9c-4b1f-8e6d-7c8a9bacbdc5",
    "deal_id": "9d3f7a20-1c5e-4d7b-8a2f-3e4c5d6f7a81",
    "quote_id": null,
    "invoice_id": null,
    "notes": null,
    "cancellation_reason": null,
    "confirmed_at": "2026-09-14T10:15:00Z",
    "cancelled_at": null,
    "rescheduled_at": null,
    "created_at": "2026-09-14T10:15:00Z",
    "updated_at": "2026-09-14T10:15:00Z"
  }
}

Mogelijke fouten

Daarnaast kan elk endpoint de algemene fouten geven, zoals een ongeldige sleutel of een bereikte limiet. Bekijk alle foutcodes.

Afspraak annuleren

POST /api/v1/appointments/{appointment}/cancel

Annuleert de afspraak, met optioneel een reden. Een afgeronde afspraak kan niet meer worden geannuleerd. Automations op "afspraak geannuleerd" lopen, net als in de agenda.

Scope
appointments.write — Afspraken aanmaken, wijzigen, bevestigen, annuleren en afronden (automations van het bedrijf lopen mee)
Vereiste functie
appointments

Stuur een Idempotency-Key mee, dan maakt een nieuwe poging na een time-out geen dubbel record.

Padparameters

NaamTypeOmschrijving
appointment verplicht string (uuid) De id (UUID) van de afspraak.

Body (JSON)

VeldTypeOmschrijving
reason optioneel string De reden van annuleren (optioneel). kan leeg zijn (null) · maximaal 500 tekens

Voorbeeldverzoek

cURL
curl -X POST "https://app.klantly.com/api/v1/appointments/9d3f6c1e-4b2a-4c8e-9f1a-2b3c4d5e6f70/cancel" \
  -H "Authorization: Bearer $KLANTLY_API_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: 6f1c2d3e-4a5b-4c6d-8e7f-9a0b1c2d3e4f" \
  -d '{
  "reason": "Klant is verhinderd"
}'
PHP
$client = new \GuzzleHttp\Client([
    'base_uri' => 'https://app.klantly.com/api/v1/',
    'headers' => ['Authorization' => 'Bearer ' . getenv('KLANTLY_API_KEY')],
]);

$response = $client->request('POST', 'appointments/9d3f6c1e-4b2a-4c8e-9f1a-2b3c4d5e6f70/cancel', [
    'headers' => [
        'Idempotency-Key' => '6f1c2d3e-4a5b-4c6d-8e7f-9a0b1c2d3e4f',
    ],
    'json' => [
        'reason' => 'Klant is verhinderd',
    ],
]);

$data = json_decode((string) $response->getBody(), true)['data'];
JavaScript
const response = await fetch('https://app.klantly.com/api/v1/appointments/9d3f6c1e-4b2a-4c8e-9f1a-2b3c4d5e6f70/cancel', {
  method: 'POST',
  headers: {
    Authorization: `Bearer ${process.env.KLANTLY_API_KEY}`,
    'Content-Type': 'application/json',
    'Idempotency-Key': '6f1c2d3e-4a5b-4c6d-8e7f-9a0b1c2d3e4f',
  },
  body: JSON.stringify({
  "reason": "Klant is verhinderd"
}),
});

const { data } = await response.json();
Python
import os

import requests

response = requests.post(
    "https://app.klantly.com/api/v1/appointments/9d3f6c1e-4b2a-4c8e-9f1a-2b3c4d5e6f70/cancel",
    headers={
        "Authorization": f"Bearer {os.environ['KLANTLY_API_KEY']}",
        "Idempotency-Key": "6f1c2d3e-4a5b-4c6d-8e7f-9a0b1c2d3e4f",
    },
    json={
        "reason": "Klant is verhinderd"
    },
)
data = response.json()["data"]

Antwoord 200

Voorbeeldantwoord
{
  "data": {
    "object": "appointment",
    "id": "9d3f7d83-4f8b-4a0e-9d5c-6b7f8a9bacb4",
    "title": "Inmeten veranda",
    "description": null,
    "status": "confirmed",
    "starts_at": "2026-10-01T08:00:00Z",
    "ends_at": "2026-10-01T09:00:00Z",
    "all_day": false,
    "location": "Dorpsstraat 1, Utrecht",
    "customer_id": "9d3f6c1e-4b2a-4c8e-9f1a-2b3c4d5e6f70",
    "contact": {
      "name": "Jan de Vries",
      "email": "jan@example.com",
      "phone": "+31 6 12345678"
    },
    "user_id": "usr_0k3j9x21m4zq8p",
    "appointment_type_id": "9d3f7ea4-5a9c-4b1f-8e6d-7c8a9bacbdc5",
    "deal_id": "9d3f7a20-1c5e-4d7b-8a2f-3e4c5d6f7a81",
    "quote_id": null,
    "invoice_id": null,
    "notes": null,
    "cancellation_reason": null,
    "confirmed_at": "2026-09-14T10:15:00Z",
    "cancelled_at": null,
    "rescheduled_at": null,
    "created_at": "2026-09-14T10:15:00Z",
    "updated_at": "2026-09-14T10:15:00Z"
  }
}

Mogelijke fouten

Daarnaast kan elk endpoint de algemene fouten geven, zoals een ongeldige sleutel of een bereikte limiet. Bekijk alle foutcodes.

Afspraak afronden

POST /api/v1/appointments/{appointment}/complete

Rondt de afspraak af. Staat de omzetting van leads bij het bedrijf op "afspraak afgerond", dan wordt een lead daarbij klant, net als in de agenda; bij de andere instellingen blijft hij lead.

Scope
appointments.write — Afspraken aanmaken, wijzigen, bevestigen, annuleren en afronden (automations van het bedrijf lopen mee)
Vereiste functie
appointments

Stuur een Idempotency-Key mee, dan maakt een nieuwe poging na een time-out geen dubbel record.

Padparameters

NaamTypeOmschrijving
appointment verplicht string (uuid) De id (UUID) van de afspraak.

Voorbeeldverzoek

cURL
curl -X POST "https://app.klantly.com/api/v1/appointments/9d3f6c1e-4b2a-4c8e-9f1a-2b3c4d5e6f70/complete" \
  -H "Authorization: Bearer $KLANTLY_API_KEY" \
  -H "Idempotency-Key: 6f1c2d3e-4a5b-4c6d-8e7f-9a0b1c2d3e4f"
PHP
$client = new \GuzzleHttp\Client([
    'base_uri' => 'https://app.klantly.com/api/v1/',
    'headers' => ['Authorization' => 'Bearer ' . getenv('KLANTLY_API_KEY')],
]);

$response = $client->request('POST', 'appointments/9d3f6c1e-4b2a-4c8e-9f1a-2b3c4d5e6f70/complete', [
    'headers' => [
        'Idempotency-Key' => '6f1c2d3e-4a5b-4c6d-8e7f-9a0b1c2d3e4f',
    ],
]);

$data = json_decode((string) $response->getBody(), true)['data'];
JavaScript
const response = await fetch('https://app.klantly.com/api/v1/appointments/9d3f6c1e-4b2a-4c8e-9f1a-2b3c4d5e6f70/complete', {
  method: 'POST',
  headers: {
    Authorization: `Bearer ${process.env.KLANTLY_API_KEY}`,
    'Idempotency-Key': '6f1c2d3e-4a5b-4c6d-8e7f-9a0b1c2d3e4f',
  },
});

const { data } = await response.json();
Python
import os

import requests

response = requests.post(
    "https://app.klantly.com/api/v1/appointments/9d3f6c1e-4b2a-4c8e-9f1a-2b3c4d5e6f70/complete",
    headers={
        "Authorization": f"Bearer {os.environ['KLANTLY_API_KEY']}",
        "Idempotency-Key": "6f1c2d3e-4a5b-4c6d-8e7f-9a0b1c2d3e4f",
    },
)
data = response.json()["data"]

Antwoord 200

Voorbeeldantwoord
{
  "data": {
    "object": "appointment",
    "id": "9d3f7d83-4f8b-4a0e-9d5c-6b7f8a9bacb4",
    "title": "Inmeten veranda",
    "description": null,
    "status": "confirmed",
    "starts_at": "2026-10-01T08:00:00Z",
    "ends_at": "2026-10-01T09:00:00Z",
    "all_day": false,
    "location": "Dorpsstraat 1, Utrecht",
    "customer_id": "9d3f6c1e-4b2a-4c8e-9f1a-2b3c4d5e6f70",
    "contact": {
      "name": "Jan de Vries",
      "email": "jan@example.com",
      "phone": "+31 6 12345678"
    },
    "user_id": "usr_0k3j9x21m4zq8p",
    "appointment_type_id": "9d3f7ea4-5a9c-4b1f-8e6d-7c8a9bacbdc5",
    "deal_id": "9d3f7a20-1c5e-4d7b-8a2f-3e4c5d6f7a81",
    "quote_id": null,
    "invoice_id": null,
    "notes": null,
    "cancellation_reason": null,
    "confirmed_at": "2026-09-14T10:15:00Z",
    "cancelled_at": null,
    "rescheduled_at": null,
    "created_at": "2026-09-14T10:15:00Z",
    "updated_at": "2026-09-14T10:15:00Z"
  }
}

Mogelijke fouten

Daarnaast kan elk endpoint de algemene fouten geven, zoals een ongeldige sleutel of een bereikte limiet. Bekijk alle foutcodes.

Bericht aan de klant sturen

POST /api/v1/appointments/{appointment}/notify

Mailt de klant een bevestiging, verzetting, annulering of herinnering, met het sjabloon dat het bedrijf in Klantly heeft ingesteld. Het bericht moet passen bij de status van de afspraak. Heeft het bedrijf dat sjabloon uitgezet, dan volgt 409 en gaat er niets weg. Vraagt de scope appointments.send.

Scope
appointments.send — Afspraakberichten naar klanten mailen
Vereiste functie
appointments

Stuur een Idempotency-Key mee, dan maakt een nieuwe poging na een time-out geen dubbel record.

Padparameters

NaamTypeOmschrijving
appointment verplicht string (uuid) De id (UUID) van de afspraak.

Body (JSON)

VeldTypeOmschrijving
message verplicht string Welk bericht: confirmation (bevestiging), reschedule (verzetting), cancellation (annulering) of reminder (herinnering). een van: confirmation, reschedule, cancellation, reminder

Voorbeeldverzoek

cURL
curl -X POST "https://app.klantly.com/api/v1/appointments/9d3f6c1e-4b2a-4c8e-9f1a-2b3c4d5e6f70/notify" \
  -H "Authorization: Bearer $KLANTLY_API_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: 6f1c2d3e-4a5b-4c6d-8e7f-9a0b1c2d3e4f" \
  -d '{
  "message": "confirmation"
}'
PHP
$client = new \GuzzleHttp\Client([
    'base_uri' => 'https://app.klantly.com/api/v1/',
    'headers' => ['Authorization' => 'Bearer ' . getenv('KLANTLY_API_KEY')],
]);

$response = $client->request('POST', 'appointments/9d3f6c1e-4b2a-4c8e-9f1a-2b3c4d5e6f70/notify', [
    'headers' => [
        'Idempotency-Key' => '6f1c2d3e-4a5b-4c6d-8e7f-9a0b1c2d3e4f',
    ],
    'json' => [
        'message' => 'confirmation',
    ],
]);

$data = json_decode((string) $response->getBody(), true)['data'];
JavaScript
const response = await fetch('https://app.klantly.com/api/v1/appointments/9d3f6c1e-4b2a-4c8e-9f1a-2b3c4d5e6f70/notify', {
  method: 'POST',
  headers: {
    Authorization: `Bearer ${process.env.KLANTLY_API_KEY}`,
    'Content-Type': 'application/json',
    'Idempotency-Key': '6f1c2d3e-4a5b-4c6d-8e7f-9a0b1c2d3e4f',
  },
  body: JSON.stringify({
  "message": "confirmation"
}),
});

const { data } = await response.json();
Python
import os

import requests

response = requests.post(
    "https://app.klantly.com/api/v1/appointments/9d3f6c1e-4b2a-4c8e-9f1a-2b3c4d5e6f70/notify",
    headers={
        "Authorization": f"Bearer {os.environ['KLANTLY_API_KEY']}",
        "Idempotency-Key": "6f1c2d3e-4a5b-4c6d-8e7f-9a0b1c2d3e4f",
    },
    json={
        "message": "confirmation"
    },
)
data = response.json()["data"]

Antwoord 200

Voorbeeldantwoord
{
  "data": {
    "object": "appointment",
    "id": "9d3f7d83-4f8b-4a0e-9d5c-6b7f8a9bacb4",
    "title": "Inmeten veranda",
    "description": null,
    "status": "confirmed",
    "starts_at": "2026-10-01T08:00:00Z",
    "ends_at": "2026-10-01T09:00:00Z",
    "all_day": false,
    "location": "Dorpsstraat 1, Utrecht",
    "customer_id": "9d3f6c1e-4b2a-4c8e-9f1a-2b3c4d5e6f70",
    "contact": {
      "name": "Jan de Vries",
      "email": "jan@example.com",
      "phone": "+31 6 12345678"
    },
    "user_id": "usr_0k3j9x21m4zq8p",
    "appointment_type_id": "9d3f7ea4-5a9c-4b1f-8e6d-7c8a9bacbdc5",
    "deal_id": "9d3f7a20-1c5e-4d7b-8a2f-3e4c5d6f7a81",
    "quote_id": null,
    "invoice_id": null,
    "notes": null,
    "cancellation_reason": null,
    "confirmed_at": "2026-09-14T10:15:00Z",
    "cancelled_at": null,
    "rescheduled_at": null,
    "created_at": "2026-09-14T10:15:00Z",
    "updated_at": "2026-09-14T10:15:00Z"
  }
}

Mogelijke fouten

Daarnaast kan elk endpoint de algemene fouten geven, zoals een ongeldige sleutel of een bereikte limiet. Bekijk alle foutcodes.

Afspraak verwijderen

DELETE /api/v1/appointments/{appointment}

Verwijdert de afspraak definitief, ook uit de gekoppelde Google-agenda. Wil je hem alleen laten vervallen, annuleer hem dan.

Scope
appointments.delete — Afspraken verwijderen
Vereiste functie
appointments

Padparameters

NaamTypeOmschrijving
appointment verplicht string (uuid) De id (UUID) van de afspraak.

Voorbeeldverzoek

cURL
curl -X DELETE "https://app.klantly.com/api/v1/appointments/9d3f6c1e-4b2a-4c8e-9f1a-2b3c4d5e6f70" \
  -H "Authorization: Bearer $KLANTLY_API_KEY"
PHP
$client = new \GuzzleHttp\Client([
    'base_uri' => 'https://app.klantly.com/api/v1/',
    'headers' => ['Authorization' => 'Bearer ' . getenv('KLANTLY_API_KEY')],
]);

$response = $client->request('DELETE', 'appointments/9d3f6c1e-4b2a-4c8e-9f1a-2b3c4d5e6f70');

$data = json_decode((string) $response->getBody(), true)['data'];
JavaScript
const response = await fetch('https://app.klantly.com/api/v1/appointments/9d3f6c1e-4b2a-4c8e-9f1a-2b3c4d5e6f70', {
  method: 'DELETE',
  headers: {
    Authorization: `Bearer ${process.env.KLANTLY_API_KEY}`,
  },
});

const { data } = await response.json();
Python
import os

import requests

response = requests.delete(
    "https://app.klantly.com/api/v1/appointments/9d3f6c1e-4b2a-4c8e-9f1a-2b3c4d5e6f70",
    headers={
        "Authorization": f"Bearer {os.environ['KLANTLY_API_KEY']}",
    },
)
data = response.json()["data"]

Antwoord 200

Voorbeeldantwoord
{
  "data": {
    "object": "note",
    "id": "9d3f7b41-2d6f-4e8c-9b3a-4f5d6e7a8b92",
    "deleted": true
  }
}

Mogelijke fouten

Daarnaast kan elk endpoint de algemene fouten geven, zoals een ongeldige sleutel of een bereikte limiet. Bekijk alle foutcodes.

Het object

Alle velden zijn altijd aanwezig; een veld zonder waarde is null.

VeldTypeOmschrijving
object string Altijd "appointment".
id string (uuid) Unieke id (UUID).
title string Titel van de afspraak.
description string Omschrijving. kan leeg zijn (null)
status string pending (nog niet bevestigd), confirmed, cancelled (geannuleerd) of completed (afgerond). Bij aanmaken pending of confirmed (standaard). een van: pending, confirmed, cancelled, completed
starts_at string (date-time) Begin (UTC). Leeg bij een uitnodiging waarvoor de klant nog een tijd kiest. Bij invoer: ISO 8601 mét tijdzone. kan leeg zijn (null)
ends_at string (date-time) Einde (UTC). Zonder ends_at bij aanmaken: de duur van het afspraaktype of de standaardduur. kan leeg zijn (null)
all_day boolean Een afspraak voor de hele dag. Tijden staan in het antwoord in UTC: reken voor de datum terug naar de tijdzone van het bedrijf (Europe/Amsterdam), anders valt een afspraak die om 00:00 begint op de dag ervoor.
location string Locatie, bijvoorbeeld het adres van de klant. kan leeg zijn (null)
customer_id string (uuid) De klant van de afspraak. Verplicht bij aanmaken. kan leeg zijn (null)
contact object De contactgegevens waarmee de afspraak is gemaakt.
contact.name string Naam. kan leeg zijn (null)
contact.email string E-mailadres; hierheen gaan berichten aan de klant. kan leeg zijn (null)
contact.phone string Telefoonnummer. kan leeg zijn (null)
user_id string De gebruiker die de afspraak heeft, of null. kan leeg zijn (null)
appointment_type_id string (uuid) Het afspraaktype, of null. kan leeg zijn (null)
deal_id string (uuid) De deal op het pipelinebord waar de afspraak bij hoort (koppelt Klantly zelf). kan leeg zijn (null)
quote_id string (uuid) De gekoppelde offerte, of null. kan leeg zijn (null)
invoice_id string (uuid) De gekoppelde factuur, of null. kan leeg zijn (null)
notes string Interne notitie bij de afspraak. kan leeg zijn (null)
cancellation_reason string Waarom de afspraak is geannuleerd, of null. kan leeg zijn (null)
confirmed_at string (date-time) Wanneer de afspraak werd bevestigd. kan leeg zijn (null)
cancelled_at string (date-time) Wanneer de afspraak werd geannuleerd. kan leeg zijn (null)
rescheduled_at string (date-time) Wanneer de afspraak voor het laatst werd verzet. kan leeg zijn (null)
created_at string (date-time) Aangemaakt op (UTC).
updated_at string (date-time) Laatst gewijzigd op (UTC).