Klantly Developers

Référence de l'API

Rendez-vous

Les rendez-vous de l’agenda : planifier, déplacer, confirmer, annuler et terminer, et envoyer un message au client.

Endpoints

Lister les rendez-vous

GET /api/v1/appointments

Une liste de rendez-vous, du plus récent au plus ancien. Filtrez par statut, client, utilisateur, heure de début ou date de modification. Triez sur starts_at pour l’ordre de l’agenda ; les rendez-vous sans date (une invitation) sont alors exclus.

Scope
appointments.read — Lire les rendez-vous (avec le nom, l'e-mail et le téléphone du client), les types de rendez-vous et les disponibilités
Fonctionnalité requise
appointments

Paramètres de requête

NomTypeDescription
limit integer Nombre de résultats par page. de 1 à 100 · par défaut : 50
cursor string Le next_cursor ou prev_cursor de meta dans la réponse précédente.
sort string Tri sur created_at, updated_at ou starts_at ; un signe moins devant signifie décroissant. Avec starts_at, les rendez-vous sans date sont exclus. l'une des valeurs : -created_at, created_at, -updated_at, updated_at, -starts_at, starts_at · par défaut : -created_at
filter[status] string Uniquement les rendez-vous de ce statut : pending (pas encore confirmé), confirmed, cancelled ou completed. l'une des valeurs : pending, confirmed, cancelled, completed
filter[customer_id] string (uuid) Uniquement ce qui appartient à ce client.
filter[user_id] string Uniquement les rendez-vous de cet utilisateur (l’id de Lister les utilisateurs).
filter[starts_from] string (date-time) Uniquement les rendez-vous qui commencent à ce moment ou après : ISO 8601 avec fuseau horaire.
filter[starts_until] string (date-time) Uniquement les rendez-vous qui commencent avant ce moment : ISO 8601 avec fuseau horaire.
filter[updated_since] string (date-time) Uniquement ce qui a changé depuis ce moment : ISO 8601 avec fuseau horaire, par exemple 2026-09-14T10:15:00Z. Pratique pour synchroniser.

Exemple de requête

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"]

Réponse 200

La réponse est une liste avec pagination par curseur : data contient les objets, meta la pagination.

Exemple de réponse
{
  "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
  }
}

Erreurs possibles

En outre, chaque endpoint peut renvoyer les erreurs générales, comme une clé invalide ou une limite atteinte. Voir tous les codes d'erreur.

Récupérer un rendez-vous

GET /api/v1/appointments/{appointment}

Un rendez-vous par id. La réponse contient un ETag que vous pouvez renvoyer dans If-Match lors d’une modification.

Scope
appointments.read — Lire les rendez-vous (avec le nom, l'e-mail et le téléphone du client), les types de rendez-vous et les disponibilités
Fonctionnalité requise
appointments

Paramètres de chemin

NomTypeDescription
appointment obligatoire string (uuid) L’id (UUID) du rendez-vous.

Exemple de requête

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"]

Réponse 200

Exemple de réponse
{
  "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"
  }
}

Erreurs possibles

En outre, chaque endpoint peut renvoyer les erreurs générales, comme une clé invalide ou une limite atteinte. Voir tous les codes d'erreur.

Planifier un rendez-vous

POST /api/v1/appointments

Planifie un rendez-vous avec un client ; le nom, l’e-mail et le téléphone viennent du client. Sans ends_at, le rendez-vous dure autant que son type, sinon la durée par défaut des paramètres des rendez-vous. Klantly ne vérifie pas la disponibilité ici : votre planning fait foi. L’API n’envoie elle-même aucun e-mail au client ; utilisez pour cela Envoyer un message au client. Si l’entreprise a des automatisations sur « rendez-vous planifié », elles s’exécutent, comme pour un rendez-vous dans l’agenda.

Scope
appointments.write — Créer, modifier, confirmer, annuler et terminer des rendez-vous (les automatisations de l'entreprise s'exécutent aussi)
Fonctionnalité requise
appointments

Envoyez une Idempotency-Key : une nouvelle tentative après un délai d'attente ne crée alors jamais de doublon.

Corps (JSON)

ChampTypeDescription
customer_id obligatoire string (uuid) Le client du rendez-vous. Obligatoire à la création.
title facultatif string Titre du rendez-vous. peut être vide (null) · au maximum 255 caractères · obligatoire sans appointment_type_id
description facultatif string Description. peut être vide (null) · au maximum 2000 caractères
location facultatif string Lieu, par exemple l’adresse du client. peut être vide (null) · au maximum 255 caractères
starts_at obligatoire string (date-time) Début (UTC). Vide pour une invitation où le client doit encore choisir une heure. En entrée : ISO 8601 avec fuseau horaire.
ends_at facultatif string (date-time) Fin (UTC). Sans ends_at à la création : la durée du type de rendez-vous ou la durée par défaut. peut être vide (null)
all_day facultatif boolean Un rendez-vous sur toute la journée. Les heures de la réponse sont en UTC : reconvertissez-les dans le fuseau de l’entreprise (Europe/Amsterdam) pour la date, sinon un rendez-vous commençant à 00:00 tombe la veille.
appointment_type_id facultatif string (uuid) Le type de rendez-vous, ou null. peut être vide (null)
user_id facultatif string L’utilisateur qui a le rendez-vous, ou null. peut être vide (null)
status facultatif string pending (pas encore confirmé), confirmed, cancelled (annulé) ou completed (terminé). À la création : pending ou confirmed (par défaut). l'une des valeurs : pending, confirmed
notes facultatif string Note interne sur le rendez-vous. peut être vide (null) · au maximum 2000 caractères

Exemple de requête

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"]

Réponse 201

Exemple de réponse
{
  "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"
  }
}

Erreurs possibles

En outre, chaque endpoint peut renvoyer les erreurs générales, comme une clé invalide ou une limite atteinte. Voir tous les codes d'erreur.

Modifier un rendez-vous

PATCH /api/v1/appointments/{appointment}

Ne modifie que les champs envoyés. Un nouveau starts_at est un déplacement : rescheduled_at est renseigné et, sans ends_at, la durée reste identique. Si un rendez-vous sans date reçoit un starts_at, ends_at est ajouté comme à la création ; un ends_at sans heure de début n’est pas possible (422). Pour changer le statut, utilisez confirmer, annuler ou terminer.

Scope
appointments.write — Créer, modifier, confirmer, annuler et terminer des rendez-vous (les automatisations de l'entreprise s'exécutent aussi)
Fonctionnalité requise
appointments

Envoyez l'ETag dans If-Match : vous n'écraserez jamais par erreur une version plus récente.

Paramètres de chemin

NomTypeDescription
appointment obligatoire string (uuid) L’id (UUID) du rendez-vous.

Corps (JSON)

ChampTypeDescription
title facultatif string Titre du rendez-vous. au maximum 255 caractères
description facultatif string Description. peut être vide (null) · au maximum 2000 caractères
location facultatif string Lieu, par exemple l’adresse du client. peut être vide (null) · au maximum 255 caractères
starts_at facultatif string (date-time) Début (UTC). Vide pour une invitation où le client doit encore choisir une heure. En entrée : ISO 8601 avec fuseau horaire.
ends_at facultatif string (date-time) Fin (UTC). Sans ends_at à la création : la durée du type de rendez-vous ou la durée par défaut.
all_day facultatif boolean Un rendez-vous sur toute la journée. Les heures de la réponse sont en UTC : reconvertissez-les dans le fuseau de l’entreprise (Europe/Amsterdam) pour la date, sinon un rendez-vous commençant à 00:00 tombe la veille.
appointment_type_id facultatif string (uuid) Le type de rendez-vous, ou null. peut être vide (null)
user_id facultatif string L’utilisateur qui a le rendez-vous, ou null. peut être vide (null)
notes facultatif string Note interne sur le rendez-vous. peut être vide (null) · au maximum 2000 caractères

Exemple de requête

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"]

Réponse 200

Exemple de réponse
{
  "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"
  }
}

Erreurs possibles

En outre, chaque endpoint peut renvoyer les erreurs générales, comme une clé invalide ou une limite atteinte. Voir tous les codes d'erreur.

Confirmer un rendez-vous

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

Passe un rendez-vous au statut confirmé. S’il est déjà confirmé, rien ne change.

Scope
appointments.write — Créer, modifier, confirmer, annuler et terminer des rendez-vous (les automatisations de l'entreprise s'exécutent aussi)
Fonctionnalité requise
appointments

Envoyez une Idempotency-Key : une nouvelle tentative après un délai d'attente ne crée alors jamais de doublon.

Paramètres de chemin

NomTypeDescription
appointment obligatoire string (uuid) L’id (UUID) du rendez-vous.

Exemple de requête

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"]

Réponse 200

Exemple de réponse
{
  "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"
  }
}

Erreurs possibles

En outre, chaque endpoint peut renvoyer les erreurs générales, comme une clé invalide ou une limite atteinte. Voir tous les codes d'erreur.

Annuler un rendez-vous

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

Annule le rendez-vous, avec un motif facultatif. Un rendez-vous terminé ne peut plus être annulé. Les automatisations sur « rendez-vous annulé » s’exécutent, comme dans l’agenda.

Scope
appointments.write — Créer, modifier, confirmer, annuler et terminer des rendez-vous (les automatisations de l'entreprise s'exécutent aussi)
Fonctionnalité requise
appointments

Envoyez une Idempotency-Key : une nouvelle tentative après un délai d'attente ne crée alors jamais de doublon.

Paramètres de chemin

NomTypeDescription
appointment obligatoire string (uuid) L’id (UUID) du rendez-vous.

Corps (JSON)

ChampTypeDescription
reason facultatif string Le motif de l’annulation (facultatif). peut être vide (null) · au maximum 500 caractères

Exemple de requête

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"]

Réponse 200

Exemple de réponse
{
  "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"
  }
}

Erreurs possibles

En outre, chaque endpoint peut renvoyer les erreurs générales, comme une clé invalide ou une limite atteinte. Voir tous les codes d'erreur.

Terminer un rendez-vous

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

Termine le rendez-vous. Si la conversion des prospects de l’entreprise est réglée sur « rendez-vous terminé », un prospect devient client, comme dans l’agenda ; avec les autres réglages, il reste prospect.

Scope
appointments.write — Créer, modifier, confirmer, annuler et terminer des rendez-vous (les automatisations de l'entreprise s'exécutent aussi)
Fonctionnalité requise
appointments

Envoyez une Idempotency-Key : une nouvelle tentative après un délai d'attente ne crée alors jamais de doublon.

Paramètres de chemin

NomTypeDescription
appointment obligatoire string (uuid) L’id (UUID) du rendez-vous.

Exemple de requête

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"]

Réponse 200

Exemple de réponse
{
  "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"
  }
}

Erreurs possibles

En outre, chaque endpoint peut renvoyer les erreurs générales, comme une clé invalide ou une limite atteinte. Voir tous les codes d'erreur.

Envoyer un message au client

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

Envoie au client par e-mail une confirmation, un déplacement, une annulation ou un rappel, avec le modèle que l’entreprise a configuré dans Klantly. Le message doit correspondre au statut du rendez-vous. Si l’entreprise a désactivé ce modèle, vous recevez une 409 et rien n’est envoyé. Nécessite le scope appointments.send.

Scope
appointments.send — Envoyer par e-mail les messages de rendez-vous aux clients
Fonctionnalité requise
appointments

Envoyez une Idempotency-Key : une nouvelle tentative après un délai d'attente ne crée alors jamais de doublon.

Paramètres de chemin

NomTypeDescription
appointment obligatoire string (uuid) L’id (UUID) du rendez-vous.

Corps (JSON)

ChampTypeDescription
message obligatoire string Quel message : confirmation, reschedule (déplacement), cancellation (annulation) ou reminder (rappel). l'une des valeurs : confirmation, reschedule, cancellation, reminder

Exemple de requête

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"]

Réponse 200

Exemple de réponse
{
  "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"
  }
}

Erreurs possibles

En outre, chaque endpoint peut renvoyer les erreurs générales, comme une clé invalide ou une limite atteinte. Voir tous les codes d'erreur.

Supprimer un rendez-vous

DELETE /api/v1/appointments/{appointment}

Supprime définitivement le rendez-vous, y compris de l’agenda Google lié. Pour simplement l’annuler, utilisez plutôt Annuler un rendez-vous.

Scope
appointments.delete — Supprimer des rendez-vous
Fonctionnalité requise
appointments

Paramètres de chemin

NomTypeDescription
appointment obligatoire string (uuid) L’id (UUID) du rendez-vous.

Exemple de requête

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"]

Réponse 200

Exemple de réponse
{
  "data": {
    "object": "note",
    "id": "9d3f7b41-2d6f-4e8c-9b3a-4f5d6e7a8b92",
    "deleted": true
  }
}

Erreurs possibles

En outre, chaque endpoint peut renvoyer les erreurs générales, comme une clé invalide ou une limite atteinte. Voir tous les codes d'erreur.

L'objet

Tous les champs sont toujours présents ; un champ sans valeur vaut null.

ChampTypeDescription
object string Toujours « appointment ».
id string (uuid) Id unique (UUID).
title string Titre du rendez-vous.
description string Description. peut être vide (null)
status string pending (pas encore confirmé), confirmed, cancelled (annulé) ou completed (terminé). À la création : pending ou confirmed (par défaut). l'une des valeurs : pending, confirmed, cancelled, completed
starts_at string (date-time) Début (UTC). Vide pour une invitation où le client doit encore choisir une heure. En entrée : ISO 8601 avec fuseau horaire. peut être vide (null)
ends_at string (date-time) Fin (UTC). Sans ends_at à la création : la durée du type de rendez-vous ou la durée par défaut. peut être vide (null)
all_day boolean Un rendez-vous sur toute la journée. Les heures de la réponse sont en UTC : reconvertissez-les dans le fuseau de l’entreprise (Europe/Amsterdam) pour la date, sinon un rendez-vous commençant à 00:00 tombe la veille.
location string Lieu, par exemple l’adresse du client. peut être vide (null)
customer_id string (uuid) Le client du rendez-vous. Obligatoire à la création. peut être vide (null)
contact object Les coordonnées avec lesquelles le rendez-vous a été pris.
contact.name string Nom. peut être vide (null)
contact.email string Adresse e-mail ; les messages au client y sont envoyés. peut être vide (null)
contact.phone string Numéro de téléphone. peut être vide (null)
user_id string L’utilisateur qui a le rendez-vous, ou null. peut être vide (null)
appointment_type_id string (uuid) Le type de rendez-vous, ou null. peut être vide (null)
deal_id string (uuid) Le deal du tableau pipeline auquel le rendez-vous appartient (lié par Klantly lui-même). peut être vide (null)
quote_id string (uuid) Le devis lié, ou null. peut être vide (null)
invoice_id string (uuid) La facture liée, ou null. peut être vide (null)
notes string Note interne sur le rendez-vous. peut être vide (null)
cancellation_reason string Pourquoi le rendez-vous a été annulé, ou null. peut être vide (null)
confirmed_at string (date-time) Date de confirmation du rendez-vous. peut être vide (null)
cancelled_at string (date-time) Date d’annulation du rendez-vous. peut être vide (null)
rescheduled_at string (date-time) Date du dernier déplacement du rendez-vous. peut être vide (null)
created_at string (date-time) Créé le (UTC).
updated_at string (date-time) Dernière modification (UTC).