Klantly Developers

API-referentie

Inbox

Gesprekken met klanten via de chatwidget, WhatsApp en e-mail, met hun berichten. Lees mee, antwoord namens het bedrijf en sluit een gesprek af.

Endpoints

Gesprekken opvragen

GET /api/v1/conversations

Een lijst van gesprekken, laatste bericht eerst. Filter op status, kanaal, klant of wijzigingsdatum. Met filter[status]=open haal je op wat er nog open staat.

Scope
messages.read — Gesprekken en berichten lezen uit de inbox
Vereiste functie
chat_widget|email|whatsapp

Queryparameters

NaamTypeOmschrijving
limit integer Aantal resultaten per pagina. van 1 tot 100 · standaard: 50
cursor string De next_cursor of prev_cursor uit meta van het vorige antwoord.
sort string Sortering op created_at of updated_at; een min-teken ervoor is aflopend. een van: -last_message_at, last_message_at, -created_at, created_at, -updated_at, updated_at · standaard: -last_message_at
filter[status] string Alleen gesprekken met deze status: open, waiting_on_customer, waiting_on_team, snoozed of closed. een van: open, waiting_on_customer, waiting_on_team, snoozed, closed
filter[channel] string Alleen gesprekken via dit kanaal: web (chatwidget), whatsapp of email. een van: web, whatsapp, email
filter[customer_id] string (uuid) Alleen wat bij deze klant hoort.
filter[updated_since] string (date-time) Alleen wat sinds dit tijdstip is gewijzigd: ISO 8601 mét tijdzone, bijvoorbeeld 2026-09-14T10:15:00Z. Handig om te synchroniseren.

Voorbeeldverzoek

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

Antwoord 200

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

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

Mogelijke fouten

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

Gesprek ophalen

GET /api/v1/conversations/{conversation}

Eén gesprek op id, met de klantgegevens, het kanaal en het aantal berichten.

Scope
messages.read — Gesprekken en berichten lezen uit de inbox
Vereiste functie
chat_widget|email|whatsapp

Padparameters

NaamTypeOmschrijving
conversation verplicht string (uuid) De id (UUID) van het gesprek.

Voorbeeldverzoek

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

Antwoord 200

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

Mogelijke fouten

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

Berichten opvragen

GET /api/v1/conversations/{conversation}/messages

De berichten van een gesprek, oudste eerst, zodat je het gesprek van boven naar beneden leest. Met sort=-created_at krijg je het nieuwste eerst.

Scope
messages.read — Gesprekken en berichten lezen uit de inbox
Vereiste functie
chat_widget|email|whatsapp

Padparameters

NaamTypeOmschrijving
conversation verplicht string (uuid) De id (UUID) van het gesprek.

Queryparameters

NaamTypeOmschrijving
limit integer Aantal resultaten per pagina. van 1 tot 100 · standaard: 50
cursor string De next_cursor of prev_cursor uit meta van het vorige antwoord.
sort string created_at (standaard) leest het gesprek van boven naar beneden, -created_at toont het nieuwste eerst. een van: created_at, -created_at · standaard: created_at

Voorbeeldverzoek

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

Antwoord 200

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

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

Mogelijke fouten

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

Bericht sturen

POST /api/v1/conversations/{conversation}/messages

Stuurt een bericht naar de klant over het kanaal van het gesprek: chat, WhatsApp of e-mail. Neemt het kanaal het bericht niet aan, dan wordt er niets bewaard en volgt 409 conflict — bij WhatsApp is dan meestal het venster van 24 uur verlopen. Antwoorden vraagt de functie van dat kanaal, en de AI-agent gaat op dit gesprek uit, net als wanneer een medewerker antwoordt. Uitgaande berichten hebben een rem tegen misbruik: maximaal 250 per uur per bedrijf (samen met offerte- en factuurmail) en hoogstens 20 per uur in hetzelfde gesprek via de API. Daarboven volgt 429 rate_limited.

Scope
messages.send — Berichten naar klanten sturen en gesprekken sluiten
Vereiste functie
chat_widget|email|whatsapp

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

Padparameters

NaamTypeOmschrijving
conversation verplicht string (uuid) De id (UUID) van het gesprek.

Body (JSON)

VeldTypeOmschrijving
body verplicht string De tekst van het bericht. maximaal 10000 tekens

Voorbeeldverzoek

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

Antwoord 201

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

Mogelijke fouten

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

Gesprek sluiten

POST /api/v1/conversations/{conversation}/close

Sluit het gesprek af, zoals de knop in de inbox. Een al gesloten gesprek verandert niet.

Scope
messages.send — Berichten naar klanten sturen en gesprekken sluiten
Vereiste functie
chat_widget|email|whatsapp

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

Padparameters

NaamTypeOmschrijving
conversation verplicht string (uuid) De id (UUID) van het gesprek.

Voorbeeldverzoek

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

Antwoord 200

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

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 "conversation".
id string (uuid) Id van het gesprek.
status string open, waiting_on_customer, waiting_on_team, snoozed of closed. een van: open, waiting_on_customer, waiting_on_team, snoozed, closed
channel string Waar het gesprek loopt: web (chatwidget), whatsapp of email. een van: web, whatsapp, email
priority string low, normal, high of urgent. kan leeg zijn (null) · een van: low, normal, high, urgent
subject string Het onderwerp, bij e-mail de onderwerpregel. kan leeg zijn (null)
summary string Korte samenvatting van het gesprek, als die er is. kan leeg zijn (null)
page_url string De pagina waar de klant de chat begon. kan leeg zijn (null)
customer_id string (uuid) De klant bij wie dit gesprek hoort, als die bekend is. kan leeg zijn (null)
customer object De contactgegevens zoals ze bij dit gesprek horen.
customer.name string Naam van de klant. kan leeg zijn (null)
customer.email string E-mailadres van de klant. kan leeg zijn (null)
customer.phone string Telefoonnummer van de klant; bij WhatsApp het nummer waarmee hij schrijft. kan leeg zijn (null)
assigned_user_id string De medewerker die dit gesprek behandelt. kan leeg zijn (null)
quote_id string (uuid) De offerte waar dit gesprek bij hoort, als die er is. kan leeg zijn (null)
invoice_id string (uuid) De factuur waar dit gesprek bij hoort, als die er is. kan leeg zijn (null)
appointment_id string (uuid) De afspraak waar dit gesprek bij hoort, als die er is. kan leeg zijn (null)
message_count integer Het aantal berichten in dit gesprek. kan leeg zijn (null)
last_message_at string (date-time) Wanneer het laatste bericht kwam. kan leeg zijn (null)
closed_at string (date-time) Wanneer het gesprek is gesloten. kan leeg zijn (null)
created_at string (date-time) Wanneer het gesprek begon.
updated_at string (date-time) Wanneer het gesprek voor het laatst wijzigde.