Klantly Developers

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

Unterhaltungen abrufen

GET /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

NameTypBeschreibung
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
curl "https://app.klantly.com/api/v1/conversations?filter[status]=open&sort=-last_message_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', 'conversations', [
    'query' => [
        'filter[status]' => 'open',
        'sort' => '-last_message_at',
    ],
]);

$data = json_decode((string) $response->getBody(), true)['data'];
JavaScript
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();
Python
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.

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

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

Unterhaltung abrufen

GET /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

NameTypBeschreibung
conversation erforderlich string (uuid) Die ID (UUID) der Unterhaltung.

Beispielanfrage

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

$data = json_decode((string) $response->getBody(), true)['data'];
JavaScript
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();
Python
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

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

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

Nachrichten abrufen

GET /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

NameTypBeschreibung
conversation erforderlich string (uuid) Die ID (UUID) der Unterhaltung.

Query-Parameter

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

$data = json_decode((string) $response->getBody(), true)['data'];
JavaScript
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();
Python
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.

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

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

Nachricht senden

POST /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

NameTypBeschreibung
conversation erforderlich string (uuid) Die ID (UUID) der Unterhaltung.

Body (JSON)

FeldTypBeschreibung
body erforderlich string Der Text der Nachricht. höchstens 10000 Zeichen

Beispielanfrage

cURL
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."
}'
PHP
$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'];
JavaScript
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();
Python
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

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

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

Unterhaltung schließen

POST /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

NameTypBeschreibung
conversation erforderlich string (uuid) Die ID (UUID) der Unterhaltung.

Beispielanfrage

cURL
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"
PHP
$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'];
JavaScript
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();
Python
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

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

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