Klantly Developers

API-referentie

Webhook-endpoints

Adressen waar Klantly direct een bericht naartoe stuurt zodra er iets verandert. Ondertekening en herhalingen staan uitgelegd in de gids over webhooks.

Endpoints

Webhook-endpoints opvragen

GET /api/v1/webhook-endpoints

Alle webhook-endpoints van je bedrijf, oudste eerst. Het secret staat er nooit in.

Scope
webhooks.manage — Webhook-endpoints beheren

Voorbeeldverzoek

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

Antwoord 200

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

Voorbeeldantwoord
{
  "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
  }
}

Mogelijke fouten

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

Webhook-endpoint ophalen

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

Eén endpoint op id, met de status en het tijdstip van de laatste geslaagde en mislukte aflevering.

Scope
webhooks.manage — Webhook-endpoints beheren

Padparameters

NaamTypeOmschrijving
endpoint verplicht string De id van het webhook-endpoint.

Voorbeeldverzoek

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

Antwoord 200

Voorbeeldantwoord
{
  "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"
  }
}

Mogelijke fouten

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

Webhook-endpoint aanmaken

POST /api/v1/webhook-endpoints

Registreert een https-adres dat events ontvangt. Het antwoord bevat het secret om de handtekening te controleren: bewaar het direct, je ziet het hierna niet meer. Je kunt alleen events kiezen over gegevens waar je sleutel leesrecht op heeft; * betekent alle events die daaronder vallen, ook toekomstige. Maximaal 10 endpoints per bedrijf.

Scope
webhooks.manage — Webhook-endpoints beheren

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

Body (JSON)

VeldTypeOmschrijving
url verplicht string (uri) Het https-adres waar Klantly de events naartoe stuurt. Geen interne adressen, en alleen poort 443, 80 of 8443. maximaal 2048 tekens
description optioneel string Eigen omschrijving, bijvoorbeeld waar het endpoint voor dient. kan leeg zijn (null) · maximaal 255 tekens
events verplicht array De eventtypes die dit endpoint ontvangt, of ["*"] voor alle events waar de sleutel of gebruiker leesrecht op heeft.

Voorbeeldverzoek

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

Antwoord 201

Voorbeeldantwoord
{
  "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"
  }
}

Mogelijke fouten

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

Webhook-endpoint bijwerken

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

Wijzigt alleen de velden die je meestuurt. Met status zet je het endpoint uit of weer aan; weer aanzetten zet de foutenteller op nul.

Scope
webhooks.manage — Webhook-endpoints beheren

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

Padparameters

NaamTypeOmschrijving
endpoint verplicht string De id van het webhook-endpoint.

Body (JSON)

VeldTypeOmschrijving
url optioneel string (uri) Het https-adres waar Klantly de events naartoe stuurt. Geen interne adressen, en alleen poort 443, 80 of 8443. maximaal 2048 tekens
description optioneel string Eigen omschrijving, bijvoorbeeld waar het endpoint voor dient. kan leeg zijn (null) · maximaal 255 tekens
events optioneel array De eventtypes die dit endpoint ontvangt, of ["*"] voor alle events waar de sleutel of gebruiker leesrecht op heeft.
status optioneel string active of disabled (uitgeschakeld). een van: active, disabled

Voorbeeldverzoek

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

Antwoord 200

Voorbeeldantwoord
{
  "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"
  }
}

Mogelijke fouten

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

Webhook-endpoint verwijderen

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

Verwijdert het endpoint. Events die nog onderweg zijn, worden niet meer afgeleverd.

Scope
webhooks.manage — Webhook-endpoints beheren

Padparameters

NaamTypeOmschrijving
endpoint verplicht string De id van het webhook-endpoint.

Voorbeeldverzoek

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

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.

Testbericht versturen

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

Stuurt direct het event ping naar het endpoint, ook als het uitstaat, en geeft de afleverpoging terug. Een testbericht wordt niet herhaald.

Scope
webhooks.manage — Webhook-endpoints beheren

Padparameters

NaamTypeOmschrijving
endpoint verplicht string De id van het webhook-endpoint.

Voorbeeldverzoek

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

Antwoord 200

Voorbeeldantwoord
{
  "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"
  }
}

Mogelijke fouten

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

Secret vernieuwen

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

Maakt een nieuw secret aan en geeft het eenmalig terug. Tijdens de overlap ondertekent Klantly met het oude én het nieuwe secret, zodat je ontvanger zonder onderbreking kan overstappen.

Scope
webhooks.manage — Webhook-endpoints beheren

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

Padparameters

NaamTypeOmschrijving
endpoint verplicht string De id van het webhook-endpoint.

Body (JSON)

VeldTypeOmschrijving
overlap_hours optioneel integer Hoe lang het oude secret naast het nieuwe blijft werken: 0, 1, 24 (standaard) of 168 uur. een van: 0, 1, 24, 168

Voorbeeldverzoek

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

Antwoord 200

Voorbeeldantwoord
{
  "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"
  }
}

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 "webhook_endpoint".
id string Id van het endpoint.
url string (uri) Het https-adres waar Klantly de events naartoe stuurt. Geen interne adressen, en alleen poort 443, 80 of 8443.
description string Eigen omschrijving, bijvoorbeeld waar het endpoint voor dient. kan leeg zijn (null)
events array<string> De eventtypes die dit endpoint ontvangt, of ["*"] voor alle events waar de sleutel of gebruiker leesrecht op heeft.
status string active of disabled (uitgeschakeld). een van: active, disabled
disabled_reason string Waarom het endpoint uitstaat: failing (5 dagen alleen fouten) of manual (handmatig), anders null. kan leeg zijn (null) · een van: failing, manual
disabled_at string (date-time) Wanneer het endpoint werd uitgeschakeld. kan leeg zijn (null)
previous_secret_expires_at string (date-time) Tot wanneer na een vernieuwing ook het vorige secret nog wordt gebruikt, anders null. kan leeg zijn (null)
last_success_at string (date-time) Laatste geslaagde aflevering. kan leeg zijn (null)
last_failure_at string (date-time) Laatste mislukte aflevering. kan leeg zijn (null)
created_at string (date-time) Aangemaakt op (UTC).
updated_at string (date-time) Laatst gewijzigd op (UTC).