Klantly Developers

Référence de l'API

Endpoints de webhook

Des adresses auxquelles Klantly envoie immédiatement un message dès qu'un changement a lieu. Les signatures et les nouvelles tentatives sont expliquées dans le guide des webhooks.

Endpoints

Lister les endpoints de webhook

GET /api/v1/webhook-endpoints

Tous les endpoints de webhook de votre entreprise, le plus ancien en premier. Le secret n'y figure jamais.

Scope
webhooks.manage — Gérer les endpoints de webhook

Exemple de requête

cURL
curl "https://app.klantly.com/api/v1/webhook-endpoints" \
  -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', 'webhook-endpoints');

$data = json_decode((string) $response->getBody(), true)['data'];
JavaScript
const response = await fetch('https://app.klantly.com/api/v1/webhook-endpoints', {
  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/webhook-endpoints",
    headers={
        "Authorization": f"Bearer {os.environ['KLANTLY_API_KEY']}",
    },
)
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": "webhook_endpoint",
      "id": "01j7zr8m2k4n6p8r0t2v4w6y8a",
      "url": "https://example.com/webhooks/klantly",
      "description": "Boekhouding",
      "events": [
        "customer.created",
        "deal.won"
      ],
      "status": "active",
      "disabled_reason": null,
      "disabled_at": null,
      "previous_secret_expires_at": null,
      "last_success_at": "2026-09-14T10:15:02Z",
      "last_failure_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 endpoint de webhook

GET /api/v1/webhook-endpoints/{endpoint}

Un endpoint par id, avec son statut et l'heure de la dernière livraison réussie et de la dernière livraison échouée.

Scope
webhooks.manage — Gérer les endpoints de webhook

Paramètres de chemin

NomTypeDescription
endpoint obligatoire string L'id de l'endpoint de webhook.

Exemple de requête

cURL
curl "https://app.klantly.com/api/v1/webhook-endpoints/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', 'webhook-endpoints/9d3f6c1e-4b2a-4c8e-9f1a-2b3c4d5e6f70');

$data = json_decode((string) $response->getBody(), true)['data'];
JavaScript
const response = await fetch('https://app.klantly.com/api/v1/webhook-endpoints/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/webhook-endpoints/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": "webhook_endpoint",
    "id": "01j7zr8m2k4n6p8r0t2v4w6y8a",
    "url": "https://example.com/webhooks/klantly",
    "description": "Boekhouding",
    "events": [
      "customer.created",
      "deal.won"
    ],
    "status": "active",
    "disabled_reason": null,
    "disabled_at": null,
    "previous_secret_expires_at": null,
    "last_success_at": "2026-09-14T10:15:02Z",
    "last_failure_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.

Créer un endpoint de webhook

POST /api/v1/webhook-endpoints

Enregistre une adresse https qui reçoit les événements. La réponse contient le secret pour vérifier la signature : conservez-le immédiatement, vous ne le reverrez plus. Vous ne pouvez choisir que des événements portant sur des données que votre clé peut lire ; * signifie tous ces événements, y compris les futurs. 10 endpoints au maximum par entreprise.

Scope
webhooks.manage — Gérer les endpoints de webhook

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

Corps (JSON)

ChampTypeDescription
url obligatoire string (uri) L'adresse https à laquelle Klantly envoie les événements. Pas d'adresses internes, et uniquement les ports 443, 80 ou 8443. au maximum 2048 caractères
description facultatif string Votre propre description, par exemple à quoi sert l'endpoint. peut être vide (null) · au maximum 255 caractères
events obligatoire array Les types d'événements que cet endpoint reçoit, ou ["*"] pour tous les événements que la clé ou l'utilisateur peut lire.

Exemple de requête

cURL
curl -X POST "https://app.klantly.com/api/v1/webhook-endpoints" \
  -H "Authorization: Bearer $KLANTLY_API_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: 6f1c2d3e-4a5b-4c6d-8e7f-9a0b1c2d3e4f" \
  -d '{
  "url": "https://example.com/webhooks/klantly",
  "description": "Boekhouding",
  "events": [
    "customer.created",
    "deal.won"
  ]
}'
PHP
$client = new \GuzzleHttp\Client([
    'base_uri' => 'https://app.klantly.com/api/v1/',
    'headers' => ['Authorization' => 'Bearer ' . getenv('KLANTLY_API_KEY')],
]);

$response = $client->request('POST', 'webhook-endpoints', [
    'headers' => [
        'Idempotency-Key' => '6f1c2d3e-4a5b-4c6d-8e7f-9a0b1c2d3e4f',
    ],
    'json' => [
        'url' => 'https://example.com/webhooks/klantly',
        'description' => 'Boekhouding',
        'events' => [
            0 => 'customer.created',
            1 => 'deal.won',
        ],
    ],
]);

$data = json_decode((string) $response->getBody(), true)['data'];
JavaScript
const response = await fetch('https://app.klantly.com/api/v1/webhook-endpoints', {
  method: 'POST',
  headers: {
    Authorization: `Bearer ${process.env.KLANTLY_API_KEY}`,
    'Content-Type': 'application/json',
    'Idempotency-Key': '6f1c2d3e-4a5b-4c6d-8e7f-9a0b1c2d3e4f',
  },
  body: JSON.stringify({
  "url": "https://example.com/webhooks/klantly",
  "description": "Boekhouding",
  "events": [
    "customer.created",
    "deal.won"
  ]
}),
});

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

import requests

response = requests.post(
    "https://app.klantly.com/api/v1/webhook-endpoints",
    headers={
        "Authorization": f"Bearer {os.environ['KLANTLY_API_KEY']}",
        "Idempotency-Key": "6f1c2d3e-4a5b-4c6d-8e7f-9a0b1c2d3e4f",
    },
    json={
        "url": "https://example.com/webhooks/klantly",
        "description": "Boekhouding",
        "events": [
            "customer.created",
            "deal.won"
        ]
    },
)
data = response.json()["data"]

Réponse 201

Exemple de réponse
{
  "data": {
    "object": "webhook_endpoint",
    "id": "01j7zr8m2k4n6p8r0t2v4w6y8a",
    "url": "https://example.com/webhooks/klantly",
    "description": "Boekhouding",
    "events": [
      "customer.created",
      "deal.won"
    ],
    "status": "active",
    "disabled_reason": null,
    "disabled_at": null,
    "previous_secret_expires_at": null,
    "last_success_at": "2026-09-14T10:15:02Z",
    "last_failure_at": null,
    "created_at": "2026-09-14T10:15:00Z",
    "updated_at": "2026-09-14T10:15:00Z",
    "secret": "whsec_MfKQ9r8GKYqrTwjUPD8ILPZIo2LaLaSw"
  }
}

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 endpoint de webhook

PATCH /api/v1/webhook-endpoints/{endpoint}

Modifie uniquement les champs que vous envoyez. Avec status, vous désactivez ou réactivez l'endpoint ; la réactivation remet le compteur d'erreurs à zéro.

Scope
webhooks.manage — Gérer les endpoints de webhook

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

Paramètres de chemin

NomTypeDescription
endpoint obligatoire string L'id de l'endpoint de webhook.

Corps (JSON)

ChampTypeDescription
url facultatif string (uri) L'adresse https à laquelle Klantly envoie les événements. Pas d'adresses internes, et uniquement les ports 443, 80 ou 8443. au maximum 2048 caractères
description facultatif string Votre propre description, par exemple à quoi sert l'endpoint. peut être vide (null) · au maximum 255 caractères
events facultatif array Les types d'événements que cet endpoint reçoit, ou ["*"] pour tous les événements que la clé ou l'utilisateur peut lire.
status facultatif string active ou disabled (désactivé). l'une des valeurs : active, disabled

Exemple de requête

cURL
curl -X PATCH "https://app.klantly.com/api/v1/webhook-endpoints/9d3f6c1e-4b2a-4c8e-9f1a-2b3c4d5e6f70" \
  -H "Authorization: Bearer $KLANTLY_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
  "events": [
    "*"
  ],
  "status": "active"
}'
PHP
$client = new \GuzzleHttp\Client([
    'base_uri' => 'https://app.klantly.com/api/v1/',
    'headers' => ['Authorization' => 'Bearer ' . getenv('KLANTLY_API_KEY')],
]);

$response = $client->request('PATCH', 'webhook-endpoints/9d3f6c1e-4b2a-4c8e-9f1a-2b3c4d5e6f70', [
    'json' => [
        'events' => [
            0 => '*',
        ],
        'status' => 'active',
    ],
]);

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

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

import requests

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

Réponse 200

Exemple de réponse
{
  "data": {
    "object": "webhook_endpoint",
    "id": "01j7zr8m2k4n6p8r0t2v4w6y8a",
    "url": "https://example.com/webhooks/klantly",
    "description": "Boekhouding",
    "events": [
      "customer.created",
      "deal.won"
    ],
    "status": "active",
    "disabled_reason": null,
    "disabled_at": null,
    "previous_secret_expires_at": null,
    "last_success_at": "2026-09-14T10:15:02Z",
    "last_failure_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 endpoint de webhook

DELETE /api/v1/webhook-endpoints/{endpoint}

Supprime l'endpoint. Les événements encore en cours d'envoi ne sont plus livrés.

Scope
webhooks.manage — Gérer les endpoints de webhook

Paramètres de chemin

NomTypeDescription
endpoint obligatoire string L'id de l'endpoint de webhook.

Exemple de requête

cURL
curl -X DELETE "https://app.klantly.com/api/v1/webhook-endpoints/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', 'webhook-endpoints/9d3f6c1e-4b2a-4c8e-9f1a-2b3c4d5e6f70');

$data = json_decode((string) $response->getBody(), true)['data'];
JavaScript
const response = await fetch('https://app.klantly.com/api/v1/webhook-endpoints/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/webhook-endpoints/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.

Envoyer un message de test

POST /api/v1/webhook-endpoints/{endpoint}/test

Envoie immédiatement l'événement ping à l'endpoint, même s'il est désactivé, et renvoie la tentative de livraison. Un message de test n'est pas renvoyé en cas d'échec.

Scope
webhooks.manage — Gérer les endpoints de webhook

Paramètres de chemin

NomTypeDescription
endpoint obligatoire string L'id de l'endpoint de webhook.

Exemple de requête

cURL
curl -X POST "https://app.klantly.com/api/v1/webhook-endpoints/9d3f6c1e-4b2a-4c8e-9f1a-2b3c4d5e6f70/test" \
  -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('POST', 'webhook-endpoints/9d3f6c1e-4b2a-4c8e-9f1a-2b3c4d5e6f70/test');

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

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

import requests

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

Réponse 200

Exemple de réponse
{
  "data": {
    "object": "webhook_delivery",
    "id": "1834",
    "webhook_endpoint_id": "01j7zr8m2k4n6p8r0t2v4w6y8a",
    "event_id": "evt_01j7zs1a2b3c4d5e6f7g8h9j0k",
    "event_type": "ping",
    "attempt": 1,
    "status": "succeeded",
    "response_status": 200,
    "error": null,
    "duration_ms": 184,
    "created_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.

Renouveler le secret

POST /api/v1/webhook-endpoints/{endpoint}/rotate-secret

Crée un nouveau secret et le renvoie une seule fois. Pendant le chevauchement, Klantly signe avec l'ancien et le nouveau secret, pour que votre récepteur puisse basculer sans interruption.

Scope
webhooks.manage — Gérer les endpoints de webhook

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
endpoint obligatoire string L'id de l'endpoint de webhook.

Corps (JSON)

ChampTypeDescription
overlap_hours facultatif integer Combien de temps l'ancien secret reste valable à côté du nouveau : 0, 1, 24 (par défaut) ou 168 heures. l'une des valeurs : 0, 1, 24, 168

Exemple de requête

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

$response = $client->request('POST', 'webhook-endpoints/9d3f6c1e-4b2a-4c8e-9f1a-2b3c4d5e6f70/rotate-secret', [
    'headers' => [
        'Idempotency-Key' => '6f1c2d3e-4a5b-4c6d-8e7f-9a0b1c2d3e4f',
    ],
    'json' => [
        'overlap_hours' => 24,
    ],
]);

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

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

import requests

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

Réponse 200

Exemple de réponse
{
  "data": {
    "object": "webhook_endpoint",
    "id": "01j7zr8m2k4n6p8r0t2v4w6y8a",
    "url": "https://example.com/webhooks/klantly",
    "description": "Boekhouding",
    "events": [
      "customer.created",
      "deal.won"
    ],
    "status": "active",
    "disabled_reason": null,
    "disabled_at": null,
    "previous_secret_expires_at": null,
    "last_success_at": "2026-09-14T10:15:02Z",
    "last_failure_at": null,
    "created_at": "2026-09-14T10:15:00Z",
    "updated_at": "2026-09-14T10:15:00Z",
    "secret": "whsec_MfKQ9r8GKYqrTwjUPD8ILPZIo2LaLaSw"
  }
}

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 « webhook_endpoint ».
id string Id de l'endpoint.
url string (uri) L'adresse https à laquelle Klantly envoie les événements. Pas d'adresses internes, et uniquement les ports 443, 80 ou 8443.
description string Votre propre description, par exemple à quoi sert l'endpoint. peut être vide (null)
events array<string> Les types d'événements que cet endpoint reçoit, ou ["*"] pour tous les événements que la clé ou l'utilisateur peut lire.
status string active ou disabled (désactivé). l'une des valeurs : active, disabled
disabled_reason string Pourquoi l'endpoint est désactivé : failing (uniquement des erreurs pendant 5 jours) ou manual (à la main), sinon null. peut être vide (null) · l'une des valeurs : failing, manual
disabled_at string (date-time) Quand l'endpoint a été désactivé. peut être vide (null)
previous_secret_expires_at string (date-time) Jusqu'à quand l'ancien secret est encore utilisé après un renouvellement, sinon null. peut être vide (null)
last_success_at string (date-time) Dernière livraison réussie. peut être vide (null)
last_failure_at string (date-time) Dernière livraison échouée. peut être vide (null)
created_at string (date-time) Créé le (UTC).
updated_at string (date-time) Dernière modification le (UTC).