Klantly Developers

API-referentie

Klanten

Klanten en leads: aanmaken, opzoeken, bijwerken, een lead omzetten naar klant en de tijdlijn bekijken.

Endpoints

Klanten opvragen

GET /api/v1/customers

Een lijst van klanten en leads, nieuwste eerst. Filter op status, type, e-mailadres of wijzigingsdatum, zoek met q en blader met de cursor uit meta.

Scope
customers.read — Klanten en leads lezen

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.
q string Zoek in naam, e-mailadres, bedrijfsnaam en telefoonnummer. minimaal 2 tekens · maximaal 100 tekens
sort string Het veld waarop je sorteert; een min-teken ervoor is aflopend. Welke velden je kunt kiezen en wat de standaard is, staat bij deze parameter. een van: -created_at, created_at, -updated_at, updated_at · standaard: -created_at
filter[status] string Alleen leads of alleen klanten. een van: lead, customer
filter[type] string Alleen particulieren of alleen bedrijven. een van: individual, business
filter[email] string (email) Precies dit e-mailadres (hoofdletters maken niet uit).
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. Neem een overlap van een paar minuten op je vorige moment, omdat de klok van jouw systeem en die van Klantly niet exact gelijk lopen, en omdat een wijziging vlak na je vorige moment anders net buiten de boot valt. De grens is inclusief: iets dat exact op dit tijdstip is gewijzigd, doet mee.

Voorbeeldverzoek

cURL
curl "https://app.klantly.com/api/v1/customers?limit=50&filter[status]=lead" \
  -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', 'customers', [
    'query' => [
        'limit' => 50,
        'filter[status]' => 'lead',
    ],
]);

$data = json_decode((string) $response->getBody(), true)['data'];
JavaScript
const response = await fetch('https://app.klantly.com/api/v1/customers?limit=50&filter[status]=lead', {
  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/customers",
    headers={
        "Authorization": f"Bearer {os.environ['KLANTLY_API_KEY']}",
    },
    params={
        "limit": 50,
        "filter[status]": "lead"
    },
)
data = response.json()["data"]

Antwoord 200

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

Voorbeeldantwoord
{
  "data": [
    {
      "object": "customer",
      "id": "9d3f6c1e-4b2a-4c8e-9f1a-2b3c4d5e6f70",
      "type": "business",
      "status": "lead",
      "name": "Jan de Vries",
      "email": "jan@example.com",
      "phone": "+31 6 12345678",
      "company_name": "De Vries Bouw",
      "vat_number": "NL123456789B01",
      "coc_number": "12345678",
      "address": "Dorpsstraat 1",
      "postal_code": "3511 AB",
      "city": "Utrecht",
      "country": "NL",
      "email_unsubscribed": false,
      "converted_at": null,
      "last_activity_at": "2026-09-14T10:15:00Z",
      "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.

Klant ophalen

GET /api/v1/customers/{customer}

Eén klant op id. Het antwoord bevat een ETag die je bij bijwerken in If-Match kunt meesturen.

Scope
customers.read — Klanten en leads lezen

Padparameters

NaamTypeOmschrijving
customer verplicht string (uuid) De id (UUID) van de klant.

Voorbeeldverzoek

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

$data = json_decode((string) $response->getBody(), true)['data'];
JavaScript
const response = await fetch('https://app.klantly.com/api/v1/customers/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/customers/9d3f6c1e-4b2a-4c8e-9f1a-2b3c4d5e6f70",
    headers={
        "Authorization": f"Bearer {os.environ['KLANTLY_API_KEY']}",
    },
)
data = response.json()["data"]

Antwoord 200

Voorbeeldantwoord
{
  "data": {
    "object": "customer",
    "id": "9d3f6c1e-4b2a-4c8e-9f1a-2b3c4d5e6f70",
    "type": "business",
    "status": "lead",
    "name": "Jan de Vries",
    "email": "jan@example.com",
    "phone": "+31 6 12345678",
    "company_name": "De Vries Bouw",
    "vat_number": "NL123456789B01",
    "coc_number": "12345678",
    "address": "Dorpsstraat 1",
    "postal_code": "3511 AB",
    "city": "Utrecht",
    "country": "NL",
    "email_unsubscribed": false,
    "converted_at": null,
    "last_activity_at": "2026-09-14T10:15:00Z",
    "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.

Klant aanmaken

POST /api/v1/customers

Maakt een nieuwe lead aan. Het e-mailadres is verplicht en uniek binnen je bedrijf: een bestaand adres geeft een validatiefout. Automations en de klanttijdlijn werken precies zoals bij aanmaken in Klantly zelf.

Scope
customers.write — Klanten en leads aanmaken en wijzigen

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

Body (JSON)

VeldTypeOmschrijving
email verplicht string (email) E-mailadres; uniek binnen je bedrijf. maximaal 255 tekens · uniek binnen je bedrijf
type optioneel string individual (particulier) of business (bedrijf). een van: individual, business
name optioneel string Naam van de contactpersoon. kan leeg zijn (null) · maximaal 255 tekens
phone optioneel string Telefoonnummer. kan leeg zijn (null) · maximaal 255 tekens
address optioneel string Straat en huisnummer. kan leeg zijn (null) · maximaal 255 tekens
city optioneel string Plaats. kan leeg zijn (null) · maximaal 255 tekens
postal_code optioneel string Postcode. kan leeg zijn (null) · maximaal 64 tekens
country optioneel string Land. kan leeg zijn (null) · minimaal 2 tekens · maximaal 2 tekens
company_name optioneel string Bedrijfsnaam, bij een zakelijke klant. kan leeg zijn (null) · maximaal 255 tekens
vat_number optioneel string Btw-nummer. kan leeg zijn (null) · maximaal 20 tekens
coc_number optioneel string KvK-nummer. kan leeg zijn (null) · maximaal 30 tekens

Voorbeeldverzoek

cURL
curl -X POST "https://app.klantly.com/api/v1/customers" \
  -H "Authorization: Bearer $KLANTLY_API_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: 6f1c2d3e-4a5b-4c6d-8e7f-9a0b1c2d3e4f" \
  -d '{
  "email": "jan@example.com",
  "name": "Jan de Vries",
  "type": "business",
  "company_name": "De Vries Bouw",
  "city": "Utrecht"
}'
PHP
$client = new \GuzzleHttp\Client([
    'base_uri' => 'https://app.klantly.com/api/v1/',
    'headers' => ['Authorization' => 'Bearer ' . getenv('KLANTLY_API_KEY')],
]);

$response = $client->request('POST', 'customers', [
    'headers' => [
        'Idempotency-Key' => '6f1c2d3e-4a5b-4c6d-8e7f-9a0b1c2d3e4f',
    ],
    'json' => [
        'email' => 'jan@example.com',
        'name' => 'Jan de Vries',
        'type' => 'business',
        'company_name' => 'De Vries Bouw',
        'city' => 'Utrecht',
    ],
]);

$data = json_decode((string) $response->getBody(), true)['data'];
JavaScript
const response = await fetch('https://app.klantly.com/api/v1/customers', {
  method: 'POST',
  headers: {
    Authorization: `Bearer ${process.env.KLANTLY_API_KEY}`,
    'Content-Type': 'application/json',
    'Idempotency-Key': '6f1c2d3e-4a5b-4c6d-8e7f-9a0b1c2d3e4f',
  },
  body: JSON.stringify({
  "email": "jan@example.com",
  "name": "Jan de Vries",
  "type": "business",
  "company_name": "De Vries Bouw",
  "city": "Utrecht"
}),
});

const { data } = await response.json();
Python
import os

import requests

response = requests.post(
    "https://app.klantly.com/api/v1/customers",
    headers={
        "Authorization": f"Bearer {os.environ['KLANTLY_API_KEY']}",
        "Idempotency-Key": "6f1c2d3e-4a5b-4c6d-8e7f-9a0b1c2d3e4f",
    },
    json={
        "email": "jan@example.com",
        "name": "Jan de Vries",
        "type": "business",
        "company_name": "De Vries Bouw",
        "city": "Utrecht"
    },
)
data = response.json()["data"]

Antwoord 201

Voorbeeldantwoord
{
  "data": {
    "object": "customer",
    "id": "9d3f6c1e-4b2a-4c8e-9f1a-2b3c4d5e6f70",
    "type": "business",
    "status": "lead",
    "name": "Jan de Vries",
    "email": "jan@example.com",
    "phone": "+31 6 12345678",
    "company_name": "De Vries Bouw",
    "vat_number": "NL123456789B01",
    "coc_number": "12345678",
    "address": "Dorpsstraat 1",
    "postal_code": "3511 AB",
    "city": "Utrecht",
    "country": "NL",
    "email_unsubscribed": false,
    "converted_at": null,
    "last_activity_at": "2026-09-14T10:15:00Z",
    "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.

Klant bijwerken

PATCH /api/v1/customers/{customer}

Wijzigt alleen de velden die je meestuurt. De status verandert niet via dit endpoint; gebruik daarvoor Lead omzetten naar klant.

Scope
customers.write — Klanten en leads aanmaken en wijzigen

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

Padparameters

NaamTypeOmschrijving
customer verplicht string (uuid) De id (UUID) van de klant.

Body (JSON)

VeldTypeOmschrijving
email optioneel string (email) E-mailadres; uniek binnen je bedrijf. maximaal 255 tekens · uniek binnen je bedrijf
type optioneel string individual (particulier) of business (bedrijf). een van: individual, business
name optioneel string Naam van de contactpersoon. kan leeg zijn (null) · maximaal 255 tekens
phone optioneel string Telefoonnummer. kan leeg zijn (null) · maximaal 255 tekens
address optioneel string Straat en huisnummer. kan leeg zijn (null) · maximaal 255 tekens
city optioneel string Plaats. kan leeg zijn (null) · maximaal 255 tekens
postal_code optioneel string Postcode. kan leeg zijn (null) · maximaal 64 tekens
country optioneel string Land. kan leeg zijn (null) · minimaal 2 tekens · maximaal 2 tekens
company_name optioneel string Bedrijfsnaam, bij een zakelijke klant. kan leeg zijn (null) · maximaal 255 tekens
vat_number optioneel string Btw-nummer. kan leeg zijn (null) · maximaal 20 tekens
coc_number optioneel string KvK-nummer. kan leeg zijn (null) · maximaal 30 tekens

Voorbeeldverzoek

cURL
curl -X PATCH "https://app.klantly.com/api/v1/customers/9d3f6c1e-4b2a-4c8e-9f1a-2b3c4d5e6f70" \
  -H "Authorization: Bearer $KLANTLY_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
  "phone": "+31 6 12345678",
  "city": "Amersfoort"
}'
PHP
$client = new \GuzzleHttp\Client([
    'base_uri' => 'https://app.klantly.com/api/v1/',
    'headers' => ['Authorization' => 'Bearer ' . getenv('KLANTLY_API_KEY')],
]);

$response = $client->request('PATCH', 'customers/9d3f6c1e-4b2a-4c8e-9f1a-2b3c4d5e6f70', [
    'json' => [
        'phone' => '+31 6 12345678',
        'city' => 'Amersfoort',
    ],
]);

$data = json_decode((string) $response->getBody(), true)['data'];
JavaScript
const response = await fetch('https://app.klantly.com/api/v1/customers/9d3f6c1e-4b2a-4c8e-9f1a-2b3c4d5e6f70', {
  method: 'PATCH',
  headers: {
    Authorization: `Bearer ${process.env.KLANTLY_API_KEY}`,
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({
  "phone": "+31 6 12345678",
  "city": "Amersfoort"
}),
});

const { data } = await response.json();
Python
import os

import requests

response = requests.patch(
    "https://app.klantly.com/api/v1/customers/9d3f6c1e-4b2a-4c8e-9f1a-2b3c4d5e6f70",
    headers={
        "Authorization": f"Bearer {os.environ['KLANTLY_API_KEY']}",
    },
    json={
        "phone": "+31 6 12345678",
        "city": "Amersfoort"
    },
)
data = response.json()["data"]

Antwoord 200

Voorbeeldantwoord
{
  "data": {
    "object": "customer",
    "id": "9d3f6c1e-4b2a-4c8e-9f1a-2b3c4d5e6f70",
    "type": "business",
    "status": "lead",
    "name": "Jan de Vries",
    "email": "jan@example.com",
    "phone": "+31 6 12345678",
    "company_name": "De Vries Bouw",
    "vat_number": "NL123456789B01",
    "coc_number": "12345678",
    "address": "Dorpsstraat 1",
    "postal_code": "3511 AB",
    "city": "Utrecht",
    "country": "NL",
    "email_unsubscribed": false,
    "converted_at": null,
    "last_activity_at": "2026-09-14T10:15:00Z",
    "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.

Lead omzetten naar klant

POST /api/v1/customers/{customer}/convert

Zet een lead om naar klant. Is het al een klant, dan verandert er niets en krijg je de klant gewoon terug.

Scope
customers.write — Klanten en leads aanmaken en wijzigen

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

Padparameters

NaamTypeOmschrijving
customer verplicht string (uuid) De id (UUID) van de klant.

Voorbeeldverzoek

cURL
curl -X POST "https://app.klantly.com/api/v1/customers/9d3f6c1e-4b2a-4c8e-9f1a-2b3c4d5e6f70/convert" \
  -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', 'customers/9d3f6c1e-4b2a-4c8e-9f1a-2b3c4d5e6f70/convert', [
    '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/customers/9d3f6c1e-4b2a-4c8e-9f1a-2b3c4d5e6f70/convert', {
  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/customers/9d3f6c1e-4b2a-4c8e-9f1a-2b3c4d5e6f70/convert",
    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": "customer",
    "id": "9d3f6c1e-4b2a-4c8e-9f1a-2b3c4d5e6f70",
    "type": "business",
    "status": "lead",
    "name": "Jan de Vries",
    "email": "jan@example.com",
    "phone": "+31 6 12345678",
    "company_name": "De Vries Bouw",
    "vat_number": "NL123456789B01",
    "coc_number": "12345678",
    "address": "Dorpsstraat 1",
    "postal_code": "3511 AB",
    "city": "Utrecht",
    "country": "NL",
    "email_unsubscribed": false,
    "converted_at": null,
    "last_activity_at": "2026-09-14T10:15:00Z",
    "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.

Tijdlijn van een klant

GET /api/v1/customers/{customer}/activities

De tijdlijn van een klant, nieuwste eerst: offertes, facturen, afspraken, e-mails en meer. Verwijzingen naar gekoppelde records staan onder related. Vandaag staan hier de systeemregels (aangemaakt, factuur/betaling, e-mail); een deal, notitie of fasewissel komt er niet op — volg die met de deal.*- en note.*-events.

Scope
customers.read — Klanten en leads lezen

Padparameters

NaamTypeOmschrijving
customer verplicht string (uuid) De id (UUID) van de klant.

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.
filter[type] string Alleen activiteiten van dit type, bijvoorbeeld quote_sent of invoice_created. maximaal 40 tekens

Voorbeeldverzoek

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

$data = json_decode((string) $response->getBody(), true)['data'];
JavaScript
const response = await fetch('https://app.klantly.com/api/v1/customers/9d3f6c1e-4b2a-4c8e-9f1a-2b3c4d5e6f70/activities', {
  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/customers/9d3f6c1e-4b2a-4c8e-9f1a-2b3c4d5e6f70/activities",
    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": "customer_activity",
      "id": "9d3f7c62-3e7a-4f9d-8c4b-5a6e7f8a9ba3",
      "customer_id": "9d3f6c1e-4b2a-4c8e-9f1a-2b3c4d5e6f70",
      "type": "quote_sent",
      "title": null,
      "description": null,
      "related": {
        "quote_id": null,
        "invoice_id": null,
        "appointment_id": null,
        "work_order_id": null,
        "task_id": null,
        "deal_id": null,
        "order_id": null,
        "conversation_id": null
      },
      "happened_at": "2026-09-14T10:15:00Z",
      "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.

Het object

Alle velden zijn altijd aanwezig; een veld zonder waarde is null.

VeldTypeOmschrijving
object string Altijd "customer".
id string (uuid) Unieke id (UUID).
type string individual (particulier) of business (bedrijf). een van: individual, business
status string lead of customer (klant). een van: lead, customer
name string Naam van de contactpersoon. kan leeg zijn (null)
email string (email) E-mailadres; uniek binnen je bedrijf.
phone string Telefoonnummer. kan leeg zijn (null)
company_name string Bedrijfsnaam, bij een zakelijke klant. kan leeg zijn (null)
vat_number string Btw-nummer. kan leeg zijn (null)
coc_number string KvK-nummer. kan leeg zijn (null)
address string Straat en huisnummer. kan leeg zijn (null)
postal_code string Postcode. kan leeg zijn (null)
city string Plaats. kan leeg zijn (null)
country string Land. kan leeg zijn (null)
email_unsubscribed boolean Heeft zich afgemeld voor e-mail.
converted_at string (date-time) Wanneer de lead klant werd. kan leeg zijn (null)
last_activity_at string (date-time) Laatste activiteit in Klantly. kan leeg zijn (null)
created_at string (date-time) Aangemaakt op (UTC).
updated_at string (date-time) Laatst gewijzigd op (UTC).