Klantly Developers

API-referentie

Klanten

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

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 Sortering op created_at of updated_at; een min-teken ervoor is aflopend. 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.

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.

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