API-Referenz
Posteingang
Unterhaltungen mit Kunden über das Chat-Widget, WhatsApp und E-Mail, mit ihren Nachrichten. Mitlesen, im Namen des Unternehmens antworten und eine Unterhaltung schließen.
Endpunkte
-
GET
/conversationsUnterhaltungen abrufen -
GET
/conversations/{conversation}Unterhaltung abrufen -
GET
/conversations/{conversation}/messagesNachrichten abrufen -
POST
/conversations/{conversation}/messagesNachricht senden -
POST
/conversations/{conversation}/closeUnterhaltung schließen
Unterhaltungen abrufen
/api/v1/conversations
Eine Liste der Unterhaltungen, letzte Nachricht zuerst. Filtern nach Status, Kanal, Kunde oder Änderungsdatum. Mit filter[status]=open erhalten Sie, was noch offen ist.
- Scope
-
messages.read— Unterhaltungen und Nachrichten im Posteingang lesen - Erforderliche Funktion
chat_widget|email|whatsapp
Query-Parameter
| Name | Typ | Beschreibung |
|---|---|---|
limit
|
integer | Anzahl der Ergebnisse pro Seite. von 1 bis 100 · Standard: 50 |
cursor
|
string | Der next_cursor oder prev_cursor aus meta der vorherigen Antwort. |
sort
|
string | Sortierung nach created_at oder updated_at; ein Minuszeichen davor sortiert absteigend. einer von: -last_message_at, last_message_at, -created_at, created_at, -updated_at, updated_at · Standard: -last_message_at |
filter[status]
|
string | Nur Unterhaltungen mit diesem Status: open, waiting_on_customer, waiting_on_team, snoozed oder closed. einer von: open, waiting_on_customer, waiting_on_team, snoozed, closed |
filter[channel]
|
string | Nur Unterhaltungen über diesen Kanal: web (Chat-Widget), whatsapp oder email. einer von: web, whatsapp, email |
filter[customer_id]
|
string (uuid) | Nur was zu diesem Kunden gehört. |
filter[updated_since]
|
string (date-time) | Nur was seit diesem Zeitpunkt geändert wurde: ISO 8601 mit Zeitzone, zum Beispiel 2026-09-14T10:15:00Z. Praktisch zum Synchronisieren. |
Beispielanfrage
curl "https://app.klantly.com/api/v1/conversations?filter[status]=open&sort=-last_message_at" \
-H "Authorization: Bearer $KLANTLY_API_KEY"$client = new \GuzzleHttp\Client([
'base_uri' => 'https://app.klantly.com/api/v1/',
'headers' => ['Authorization' => 'Bearer ' . getenv('KLANTLY_API_KEY')],
]);
$response = $client->request('GET', 'conversations', [
'query' => [
'filter[status]' => 'open',
'sort' => '-last_message_at',
],
]);
$data = json_decode((string) $response->getBody(), true)['data'];const response = await fetch('https://app.klantly.com/api/v1/conversations?filter[status]=open&sort=-last_message_at', {
headers: {
Authorization: `Bearer ${process.env.KLANTLY_API_KEY}`,
},
});
const { data } = await response.json();import os
import requests
response = requests.get(
"https://app.klantly.com/api/v1/conversations",
headers={
"Authorization": f"Bearer {os.environ['KLANTLY_API_KEY']}",
},
params={
"filter[status]": "open",
"sort": "-last_message_at"
},
)
data = response.json()["data"]Antwort 200
Die Antwort ist eine Liste mit Cursor-Paginierung: data enthält die Objekte, meta die Paginierung.
{
"data": [
{
"object": "conversation",
"id": "9d3f9a12-6b7c-4d8e-9f01-a2b3c4d5e6f1",
"status": "open",
"channel": "web",
"priority": "normal",
"subject": "Vraag over mijn offerte",
"summary": null,
"page_url": "https://example.com/verandas",
"customer_id": "9d3f6c1e-4b2a-4c8e-9f1a-2b3c4d5e6f70",
"customer": {
"name": "Jan de Vries",
"email": "jan@example.com",
"phone": "+31 6 12345678"
},
"assigned_user_id": null,
"quote_id": null,
"invoice_id": null,
"appointment_id": null,
"message_count": 4,
"last_message_at": null,
"closed_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
-
403
insufficient_scope— Dieser API-Schlüssel hat keinen Zugriff auf diese Aktion. -
422
validation_failed— Die Eingabe ist ungültig.
Unterhaltung abrufen
/api/v1/conversations/{conversation}
Eine Unterhaltung anhand der ID, mit den Kundendaten, dem Kanal und der Anzahl der Nachrichten.
- Scope
-
messages.read— Unterhaltungen und Nachrichten im Posteingang lesen - Erforderliche Funktion
chat_widget|email|whatsapp
Pfadparameter
| Name | Typ | Beschreibung |
|---|---|---|
conversation erforderlich |
string (uuid) | Die ID (UUID) der Unterhaltung. |
Beispielanfrage
curl "https://app.klantly.com/api/v1/conversations/9d3f6c1e-4b2a-4c8e-9f1a-2b3c4d5e6f70" \
-H "Authorization: Bearer $KLANTLY_API_KEY"$client = new \GuzzleHttp\Client([
'base_uri' => 'https://app.klantly.com/api/v1/',
'headers' => ['Authorization' => 'Bearer ' . getenv('KLANTLY_API_KEY')],
]);
$response = $client->request('GET', 'conversations/9d3f6c1e-4b2a-4c8e-9f1a-2b3c4d5e6f70');
$data = json_decode((string) $response->getBody(), true)['data'];const response = await fetch('https://app.klantly.com/api/v1/conversations/9d3f6c1e-4b2a-4c8e-9f1a-2b3c4d5e6f70', {
headers: {
Authorization: `Bearer ${process.env.KLANTLY_API_KEY}`,
},
});
const { data } = await response.json();import os
import requests
response = requests.get(
"https://app.klantly.com/api/v1/conversations/9d3f6c1e-4b2a-4c8e-9f1a-2b3c4d5e6f70",
headers={
"Authorization": f"Bearer {os.environ['KLANTLY_API_KEY']}",
},
)
data = response.json()["data"]Antwort 200
{
"data": {
"object": "conversation",
"id": "9d3f9a12-6b7c-4d8e-9f01-a2b3c4d5e6f1",
"status": "open",
"channel": "web",
"priority": "normal",
"subject": "Vraag over mijn offerte",
"summary": null,
"page_url": "https://example.com/verandas",
"customer_id": "9d3f6c1e-4b2a-4c8e-9f1a-2b3c4d5e6f70",
"customer": {
"name": "Jan de Vries",
"email": "jan@example.com",
"phone": "+31 6 12345678"
},
"assigned_user_id": null,
"quote_id": null,
"invoice_id": null,
"appointment_id": null,
"message_count": 4,
"last_message_at": null,
"closed_at": null,
"created_at": "2026-09-14T10:15:00Z",
"updated_at": "2026-09-14T10:15:00Z"
}
}Mögliche Fehler
-
403
insufficient_scope— Dieser API-Schlüssel hat keinen Zugriff auf diese Aktion. -
404
not_found— Nicht gefunden.
Nachrichten abrufen
/api/v1/conversations/{conversation}/messages
Die Nachrichten einer Unterhaltung, älteste zuerst, sodass Sie sie von oben nach unten lesen. Mit sort=-created_at erhalten Sie die neueste zuerst.
- Scope
-
messages.read— Unterhaltungen und Nachrichten im Posteingang lesen - Erforderliche Funktion
chat_widget|email|whatsapp
Pfadparameter
| Name | Typ | Beschreibung |
|---|---|---|
conversation erforderlich |
string (uuid) | Die ID (UUID) der Unterhaltung. |
Query-Parameter
| Name | Typ | Beschreibung |
|---|---|---|
limit
|
integer | Anzahl der Ergebnisse pro Seite. von 1 bis 100 · Standard: 50 |
cursor
|
string | Der next_cursor oder prev_cursor aus meta der vorherigen Antwort. |
sort
|
string | created_at (Standard) liest die Unterhaltung von oben nach unten, -created_at zeigt die neueste zuerst. einer von: created_at, -created_at · Standard: created_at |
Beispielanfrage
curl "https://app.klantly.com/api/v1/conversations/9d3f6c1e-4b2a-4c8e-9f1a-2b3c4d5e6f70/messages" \
-H "Authorization: Bearer $KLANTLY_API_KEY"$client = new \GuzzleHttp\Client([
'base_uri' => 'https://app.klantly.com/api/v1/',
'headers' => ['Authorization' => 'Bearer ' . getenv('KLANTLY_API_KEY')],
]);
$response = $client->request('GET', 'conversations/9d3f6c1e-4b2a-4c8e-9f1a-2b3c4d5e6f70/messages');
$data = json_decode((string) $response->getBody(), true)['data'];const response = await fetch('https://app.klantly.com/api/v1/conversations/9d3f6c1e-4b2a-4c8e-9f1a-2b3c4d5e6f70/messages', {
headers: {
Authorization: `Bearer ${process.env.KLANTLY_API_KEY}`,
},
});
const { data } = await response.json();import os
import requests
response = requests.get(
"https://app.klantly.com/api/v1/conversations/9d3f6c1e-4b2a-4c8e-9f1a-2b3c4d5e6f70/messages",
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.
{
"data": [
{
"object": "message",
"id": "9d3f9b23-7c8d-4e9f-8012-b3c4d5e6f7a2",
"conversation_id": "9d3f9a12-6b7c-4d8e-9f01-a2b3c4d5e6f1",
"sender": "customer",
"user_id": null,
"body": "Kan de monteur morgen langskomen?",
"email_subject": null,
"attachment": {
"name": "offerte.pdf",
"mime_type": "application/pdf",
"size": 24680
},
"whatsapp_status": null,
"created_at": "2026-09-14T10:15:00Z"
}
],
"meta": {
"limit": 50,
"next_cursor": "eyJpZCI6IjlkM2Y2YzFlIn0",
"prev_cursor": null
}
}Mögliche Fehler
-
403
insufficient_scope— Dieser API-Schlüssel hat keinen Zugriff auf diese Aktion. -
404
not_found— Nicht gefunden. -
422
validation_failed— Die Eingabe ist ungültig.
Nachricht senden
/api/v1/conversations/{conversation}/messages
Sendet eine Nachricht an den Kunden über den Kanal der Unterhaltung: Chat, WhatsApp oder E-Mail. Nimmt der Kanal sie nicht an, wird nichts gespeichert und Sie erhalten 409 conflict — bei WhatsApp ist dann meist das 24-Stunden-Fenster abgelaufen. Antworten erfordert die Funktion dieses Kanals, und der KI-Agent hört bei dieser Unterhaltung auf, genau wie wenn ein Mitarbeiter antwortet. Ausgehende Nachrichten haben eine Missbrauchsbremse: höchstens 250 pro Stunde je Unternehmen (zusammen mit Angebots- und Rechnungs-E-Mails) und höchstens 20 pro Stunde in derselben Unterhaltung über die API. Darüber hinaus folgt 429 rate_limited.
- Scope
-
messages.send— Nachrichten an Kunden senden und Unterhaltungen schließen - Erforderliche Funktion
chat_widget|email|whatsapp
Senden Sie einen Idempotency-Key mit, dann erzeugt ein erneuter Versuch nach einem Timeout keinen doppelten Datensatz.
Pfadparameter
| Name | Typ | Beschreibung |
|---|---|---|
conversation erforderlich |
string (uuid) | Die ID (UUID) der Unterhaltung. |
Body (JSON)
| Feld | Typ | Beschreibung |
|---|---|---|
body
erforderlich
|
string | Der Text der Nachricht. höchstens 10000 Zeichen |
Beispielanfrage
curl -X POST "https://app.klantly.com/api/v1/conversations/9d3f6c1e-4b2a-4c8e-9f1a-2b3c4d5e6f70/messages" \
-H "Authorization: Bearer $KLANTLY_API_KEY" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: 6f1c2d3e-4a5b-4c6d-8e7f-9a0b1c2d3e4f" \
-d '{
"body": "Dag Jan, we komen morgen tussen 9 en 11 uur langs."
}'$client = new \GuzzleHttp\Client([
'base_uri' => 'https://app.klantly.com/api/v1/',
'headers' => ['Authorization' => 'Bearer ' . getenv('KLANTLY_API_KEY')],
]);
$response = $client->request('POST', 'conversations/9d3f6c1e-4b2a-4c8e-9f1a-2b3c4d5e6f70/messages', [
'headers' => [
'Idempotency-Key' => '6f1c2d3e-4a5b-4c6d-8e7f-9a0b1c2d3e4f',
],
'json' => [
'body' => 'Dag Jan, we komen morgen tussen 9 en 11 uur langs.',
],
]);
$data = json_decode((string) $response->getBody(), true)['data'];const response = await fetch('https://app.klantly.com/api/v1/conversations/9d3f6c1e-4b2a-4c8e-9f1a-2b3c4d5e6f70/messages', {
method: 'POST',
headers: {
Authorization: `Bearer ${process.env.KLANTLY_API_KEY}`,
'Content-Type': 'application/json',
'Idempotency-Key': '6f1c2d3e-4a5b-4c6d-8e7f-9a0b1c2d3e4f',
},
body: JSON.stringify({
"body": "Dag Jan, we komen morgen tussen 9 en 11 uur langs."
}),
});
const { data } = await response.json();import os
import requests
response = requests.post(
"https://app.klantly.com/api/v1/conversations/9d3f6c1e-4b2a-4c8e-9f1a-2b3c4d5e6f70/messages",
headers={
"Authorization": f"Bearer {os.environ['KLANTLY_API_KEY']}",
"Idempotency-Key": "6f1c2d3e-4a5b-4c6d-8e7f-9a0b1c2d3e4f",
},
json={
"body": "Dag Jan, we komen morgen tussen 9 en 11 uur langs."
},
)
data = response.json()["data"]Antwort 201
{
"data": {
"object": "message",
"id": "9d3f9b23-7c8d-4e9f-8012-b3c4d5e6f7a2",
"conversation_id": "9d3f9a12-6b7c-4d8e-9f01-a2b3c4d5e6f1",
"sender": "customer",
"user_id": null,
"body": "Kan de monteur morgen langskomen?",
"email_subject": null,
"attachment": {
"name": "offerte.pdf",
"mime_type": "application/pdf",
"size": 24680
},
"whatsapp_status": null,
"created_at": "2026-09-14T10:15:00Z"
}
}Mögliche Fehler
-
403
insufficient_scope— Dieser API-Schlüssel hat keinen Zugriff auf diese Aktion. -
422
validation_failed— Die Eingabe ist ungültig. -
422
unknown_field— Die Eingabe enthält ein unbekanntes Feld. -
415
unsupported_media_type— Dieses Format wird nicht unterstützt. -
413
payload_too_large— Der Body der Anfrage ist zu groß. -
404
not_found— Nicht gefunden. -
409
invalid_state_transition— Diese Aktion ist im aktuellen Status nicht möglich. -
409
conflict— Dies steht im Widerspruch zum aktuellen Zustand. -
403
account_suspended— Das Konto dieses Unternehmens ist gesperrt. -
429
rate_limited— Zu viele Anfragen. -
422
idempotency_key_reused— Dieser Idempotency-Key wurde bereits für eine andere Anfrage verwendet. -
409
idempotency_in_progress— Eine Anfrage mit diesem Idempotency-Key wird noch verarbeitet.
Unterhaltung schließen
/api/v1/conversations/{conversation}/close
Schließt die Unterhaltung, wie die Schaltfläche im Posteingang. Eine bereits geschlossene Unterhaltung bleibt unverändert.
- Scope
-
messages.send— Nachrichten an Kunden senden und Unterhaltungen schließen - Erforderliche Funktion
chat_widget|email|whatsapp
Senden Sie einen Idempotency-Key mit, dann erzeugt ein erneuter Versuch nach einem Timeout keinen doppelten Datensatz.
Pfadparameter
| Name | Typ | Beschreibung |
|---|---|---|
conversation erforderlich |
string (uuid) | Die ID (UUID) der Unterhaltung. |
Beispielanfrage
curl -X POST "https://app.klantly.com/api/v1/conversations/9d3f6c1e-4b2a-4c8e-9f1a-2b3c4d5e6f70/close" \
-H "Authorization: Bearer $KLANTLY_API_KEY" \
-H "Idempotency-Key: 6f1c2d3e-4a5b-4c6d-8e7f-9a0b1c2d3e4f"$client = new \GuzzleHttp\Client([
'base_uri' => 'https://app.klantly.com/api/v1/',
'headers' => ['Authorization' => 'Bearer ' . getenv('KLANTLY_API_KEY')],
]);
$response = $client->request('POST', 'conversations/9d3f6c1e-4b2a-4c8e-9f1a-2b3c4d5e6f70/close', [
'headers' => [
'Idempotency-Key' => '6f1c2d3e-4a5b-4c6d-8e7f-9a0b1c2d3e4f',
],
]);
$data = json_decode((string) $response->getBody(), true)['data'];const response = await fetch('https://app.klantly.com/api/v1/conversations/9d3f6c1e-4b2a-4c8e-9f1a-2b3c4d5e6f70/close', {
method: 'POST',
headers: {
Authorization: `Bearer ${process.env.KLANTLY_API_KEY}`,
'Idempotency-Key': '6f1c2d3e-4a5b-4c6d-8e7f-9a0b1c2d3e4f',
},
});
const { data } = await response.json();import os
import requests
response = requests.post(
"https://app.klantly.com/api/v1/conversations/9d3f6c1e-4b2a-4c8e-9f1a-2b3c4d5e6f70/close",
headers={
"Authorization": f"Bearer {os.environ['KLANTLY_API_KEY']}",
"Idempotency-Key": "6f1c2d3e-4a5b-4c6d-8e7f-9a0b1c2d3e4f",
},
)
data = response.json()["data"]Antwort 200
{
"data": {
"object": "conversation",
"id": "9d3f9a12-6b7c-4d8e-9f01-a2b3c4d5e6f1",
"status": "open",
"channel": "web",
"priority": "normal",
"subject": "Vraag over mijn offerte",
"summary": null,
"page_url": "https://example.com/verandas",
"customer_id": "9d3f6c1e-4b2a-4c8e-9f1a-2b3c4d5e6f70",
"customer": {
"name": "Jan de Vries",
"email": "jan@example.com",
"phone": "+31 6 12345678"
},
"assigned_user_id": null,
"quote_id": null,
"invoice_id": null,
"appointment_id": null,
"message_count": 4,
"last_message_at": null,
"closed_at": null,
"created_at": "2026-09-14T10:15:00Z",
"updated_at": "2026-09-14T10:15:00Z"
}
}Mögliche Fehler
-
403
insufficient_scope— Dieser API-Schlüssel hat keinen Zugriff auf diese Aktion. -
404
not_found— Nicht gefunden. -
422
idempotency_key_reused— Dieser Idempotency-Key wurde bereits für eine andere Anfrage verwendet. -
409
idempotency_in_progress— Eine Anfrage mit diesem Idempotency-Key wird noch verarbeitet.
Das Objekt
Alle Felder sind immer vorhanden; ein Feld ohne Wert ist null.
| Feld | Typ | Beschreibung |
|---|---|---|
object |
string | Immer "conversation". |
id |
string (uuid) | ID der Unterhaltung. |
status |
string | open, waiting_on_customer, waiting_on_team, snoozed oder closed. einer von: open, waiting_on_customer, waiting_on_team, snoozed, closed |
channel |
string | Wo die Unterhaltung läuft: web (Chat-Widget), whatsapp oder email. einer von: web, whatsapp, email |
priority |
string | low, normal, high oder urgent. kann leer sein (null) · einer von: low, normal, high, urgent |
subject |
string | Der Betreff; bei E-Mail die Betreffzeile. kann leer sein (null) |
summary |
string | Eine kurze Zusammenfassung der Unterhaltung, falls vorhanden. kann leer sein (null) |
page_url |
string | Die Seite, auf der der Kunde den Chat begonnen hat. kann leer sein (null) |
customer_id |
string (uuid) | Der Kunde, zu dem diese Unterhaltung gehört, sofern bekannt. kann leer sein (null) |
customer |
object | Die Kontaktdaten, wie sie zu dieser Unterhaltung gehören. |
customer.name |
string | Name des Kunden. kann leer sein (null) |
customer.email |
string | E-Mail-Adresse des Kunden. kann leer sein (null) |
customer.phone |
string | Telefonnummer des Kunden; bei WhatsApp die Nummer, von der er schreibt. kann leer sein (null) |
assigned_user_id |
string | Der Mitarbeiter, der diese Unterhaltung bearbeitet. kann leer sein (null) |
quote_id |
string (uuid) | Das Angebot, zu dem diese Unterhaltung gehört, falls vorhanden. kann leer sein (null) |
invoice_id |
string (uuid) | Die Rechnung, zu der diese Unterhaltung gehört, falls vorhanden. kann leer sein (null) |
appointment_id |
string (uuid) | Der Termin, zu dem diese Unterhaltung gehört, falls vorhanden. kann leer sein (null) |
message_count |
integer | Die Anzahl der Nachrichten in dieser Unterhaltung. kann leer sein (null) |
last_message_at |
string (date-time) | Wann die letzte Nachricht kam. kann leer sein (null) |
closed_at |
string (date-time) | Wann die Unterhaltung geschlossen wurde. kann leer sein (null) |
created_at |
string (date-time) | Wann die Unterhaltung begann. |
updated_at |
string (date-time) | Wann die Unterhaltung zuletzt geändert wurde. |