Klantly Developers

API-Referenz

Webhook-Endpunkte

Adressen, an die Klantly sofort eine Nachricht sendet, sobald sich etwas ändert. Signaturen und Wiederholungen erklärt der Leitfaden zu Webhooks.

Endpunkte

Webhook-Endpunkte auflisten

GET /api/v1/webhook-endpoints

Alle Webhook-Endpunkte Ihres Unternehmens, älteste zuerst. Das Secret ist nie enthalten.

Scope
webhooks.manage — Webhook-Endpunkte verwalten

Beispielanfrage

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

Antwort 200

Die Antwort ist eine Liste mit Cursor-Paginierung: data enthält die Objekte, meta die Paginierung.

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

Mögliche Fehler

Zusätzlich kann jeder Endpunkt die allgemeinen Fehler zurückgeben, etwa einen ungültigen Schlüssel oder ein erreichtes Limit. Alle Fehlercodes ansehen.

Webhook-Endpunkt abrufen

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

Ein Endpunkt nach ID, mit Status und dem Zeitpunkt der letzten erfolgreichen und fehlgeschlagenen Zustellung.

Scope
webhooks.manage — Webhook-Endpunkte verwalten

Pfadparameter

NameTypBeschreibung
endpoint erforderlich string Die ID des Webhook-Endpunkts.

Beispielanfrage

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

Antwort 200

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

Mögliche Fehler

Zusätzlich kann jeder Endpunkt die allgemeinen Fehler zurückgeben, etwa einen ungültigen Schlüssel oder ein erreichtes Limit. Alle Fehlercodes ansehen.

Webhook-Endpunkt erstellen

POST /api/v1/webhook-endpoints

Registriert eine https-Adresse, die Events empfängt. Die Antwort enthält das Secret zum Prüfen der Signatur: Speichern Sie es sofort, Sie sehen es danach nicht mehr. Sie können nur Events zu Daten wählen, auf die Ihr Schlüssel Leserechte hat; * bedeutet alle Events darunter, auch künftige. Höchstens 10 Endpunkte pro Unternehmen.

Scope
webhooks.manage — Webhook-Endpunkte verwalten

Senden Sie einen Idempotency-Key mit, dann erzeugt ein erneuter Versuch nach einem Timeout keinen doppelten Datensatz.

Body (JSON)

FeldTypBeschreibung
url erforderlich string (uri) Die https-Adresse, an die Klantly die Events sendet. Keine internen Adressen und nur Port 443, 80 oder 8443. höchstens 2048 Zeichen
description optional string Eigene Beschreibung, zum Beispiel wofür der Endpunkt dient. kann leer sein (null) · höchstens 255 Zeichen
events erforderlich array Die Event-Typen, die dieser Endpunkt empfängt, oder ["*"] für alle Events, auf die der Schlüssel oder Benutzer Leserechte hat.

Beispielanfrage

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

Antwort 201

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

Mögliche Fehler

Zusätzlich kann jeder Endpunkt die allgemeinen Fehler zurückgeben, etwa einen ungültigen Schlüssel oder ein erreichtes Limit. Alle Fehlercodes ansehen.

Webhook-Endpunkt bearbeiten

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

Ändert nur die Felder, die Sie mitsenden. Mit status schalten Sie den Endpunkt aus oder wieder ein; das Wiedereinschalten setzt den Fehlerzähler zurück.

Scope
webhooks.manage — Webhook-Endpunkte verwalten

Senden Sie das ETag in If-Match mit, dann überschreiben Sie nie versehentlich eine neuere Version.

Pfadparameter

NameTypBeschreibung
endpoint erforderlich string Die ID des Webhook-Endpunkts.

Body (JSON)

FeldTypBeschreibung
url optional string (uri) Die https-Adresse, an die Klantly die Events sendet. Keine internen Adressen und nur Port 443, 80 oder 8443. höchstens 2048 Zeichen
description optional string Eigene Beschreibung, zum Beispiel wofür der Endpunkt dient. kann leer sein (null) · höchstens 255 Zeichen
events optional array Die Event-Typen, die dieser Endpunkt empfängt, oder ["*"] für alle Events, auf die der Schlüssel oder Benutzer Leserechte hat.
status optional string active oder disabled (deaktiviert). einer von: active, disabled

Beispielanfrage

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

Antwort 200

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

Mögliche Fehler

Zusätzlich kann jeder Endpunkt die allgemeinen Fehler zurückgeben, etwa einen ungültigen Schlüssel oder ein erreichtes Limit. Alle Fehlercodes ansehen.

Webhook-Endpunkt löschen

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

Löscht den Endpunkt. Events, die noch unterwegs sind, werden nicht mehr zugestellt.

Scope
webhooks.manage — Webhook-Endpunkte verwalten

Pfadparameter

NameTypBeschreibung
endpoint erforderlich string Die ID des Webhook-Endpunkts.

Beispielanfrage

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

Antwort 200

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

Mögliche Fehler

Zusätzlich kann jeder Endpunkt die allgemeinen Fehler zurückgeben, etwa einen ungültigen Schlüssel oder ein erreichtes Limit. Alle Fehlercodes ansehen.

Testnachricht senden

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

Sendet das Event ping sofort an den Endpunkt, auch wenn er deaktiviert ist, und gibt den Zustellversuch zurück. Eine Testnachricht wird nicht wiederholt.

Scope
webhooks.manage — Webhook-Endpunkte verwalten

Pfadparameter

NameTypBeschreibung
endpoint erforderlich string Die ID des Webhook-Endpunkts.

Beispielanfrage

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

Antwort 200

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

Mögliche Fehler

Zusätzlich kann jeder Endpunkt die allgemeinen Fehler zurückgeben, etwa einen ungültigen Schlüssel oder ein erreichtes Limit. Alle Fehlercodes ansehen.

Secret erneuern

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

Erstellt ein neues Secret und gibt es einmalig zurück. Während der Überlappung signiert Klantly mit dem alten und dem neuen Secret, sodass Ihr Empfänger ohne Unterbrechung umstellen kann.

Scope
webhooks.manage — Webhook-Endpunkte verwalten

Senden Sie einen Idempotency-Key mit, dann erzeugt ein erneuter Versuch nach einem Timeout keinen doppelten Datensatz.

Pfadparameter

NameTypBeschreibung
endpoint erforderlich string Die ID des Webhook-Endpunkts.

Body (JSON)

FeldTypBeschreibung
overlap_hours optional integer Wie lange das alte Secret neben dem neuen weiter funktioniert: 0, 1, 24 (Standard) oder 168 Stunden. einer von: 0, 1, 24, 168

Beispielanfrage

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

Antwort 200

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

Mögliche Fehler

Zusätzlich kann jeder Endpunkt die allgemeinen Fehler zurückgeben, etwa einen ungültigen Schlüssel oder ein erreichtes Limit. Alle Fehlercodes ansehen.

Das Objekt

Alle Felder sind immer vorhanden; ein Feld ohne Wert ist null.

FeldTypBeschreibung
object string Immer „webhook_endpoint“.
id string ID des Endpunkts.
url string (uri) Die https-Adresse, an die Klantly die Events sendet. Keine internen Adressen und nur Port 443, 80 oder 8443.
description string Eigene Beschreibung, zum Beispiel wofür der Endpunkt dient. kann leer sein (null)
events array<string> Die Event-Typen, die dieser Endpunkt empfängt, oder ["*"] für alle Events, auf die der Schlüssel oder Benutzer Leserechte hat.
status string active oder disabled (deaktiviert). einer von: active, disabled
disabled_reason string Warum der Endpunkt aus ist: failing (5 Tage nur Fehler) oder manual (von Hand), sonst null. kann leer sein (null) · einer von: failing, manual
disabled_at string (date-time) Wann der Endpunkt deaktiviert wurde. kann leer sein (null)
previous_secret_expires_at string (date-time) Bis wann nach einer Erneuerung auch das vorherige Secret noch verwendet wird, sonst null. kann leer sein (null)
last_success_at string (date-time) Letzte erfolgreiche Zustellung. kann leer sein (null)
last_failure_at string (date-time) Letzte fehlgeschlagene Zustellung. kann leer sein (null)
created_at string (date-time) Erstellt am (UTC).
updated_at string (date-time) Zuletzt geändert am (UTC).