Klantly Developers

API-Referenz

Kunden

Kunden und Leads: erstellen, suchen, bearbeiten und einen Lead in einen Kunden umwandeln.

Endpunkte

Kunden auflisten

GET /api/v1/customers

Eine Liste von Kunden und Leads, die neuesten zuerst. Filtern Sie nach Status, Typ, E-Mail-Adresse oder Änderungsdatum, suchen Sie mit q und blättern Sie mit dem Cursor aus meta.

Scope
customers.read — Kunden und Leads lesen

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.
q string Suche in Name, E-Mail-Adresse, Firmenname und Telefonnummer. mindestens 2 Zeichen · höchstens 100 Zeichen
sort string Sortierung nach created_at oder updated_at; ein Minuszeichen davor sortiert absteigend. einer von: -created_at, created_at, -updated_at, updated_at · Standard: -created_at
filter[status] string Nur Leads oder nur Kunden. einer von: lead, customer
filter[type] string Nur Privatpersonen oder nur Unternehmen. einer von: individual, business
filter[email] string (email) Genau diese E-Mail-Adresse (ohne Beachtung der Groß- und Kleinschreibung).
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/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"]

Antwort 200

Die Antwort ist eine Liste mit Cursor-Paginierung: data enthält die Objekte, meta die Paginierung.

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

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.

Kunden abrufen

GET /api/v1/customers/{customer}

Ein einzelner Kunde anhand der ID. Die Antwort enthält ein ETag, das Sie beim Bearbeiten in If-Match mitsenden können.

Scope
customers.read — Kunden und Leads lesen

Pfadparameter

NameTypBeschreibung
customer erforderlich string (uuid) Die ID (UUID) des Kunden.

Beispielanfrage

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

Antwort 200

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

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.

Kunden erstellen

POST /api/v1/customers

Erstellt einen neuen Lead. Die E-Mail-Adresse ist erforderlich und innerhalb Ihres Unternehmens eindeutig: Eine vorhandene Adresse ergibt einen Validierungsfehler. Automationen und die Kundenhistorie funktionieren genau wie beim Erstellen in Klantly selbst.

Scope
customers.write — Kunden und Leads erstellen und bearbeiten

Senden Sie einen Idempotency-Key mit, dann erzeugt ein erneuter Versuch nach einem Timeout keinen doppelten Datensatz.

Body (JSON)

FeldTypBeschreibung
email erforderlich string (email) E-Mail-Adresse; eindeutig innerhalb Ihres Unternehmens. höchstens 255 Zeichen · eindeutig innerhalb Ihres Unternehmens
type optional string individual (Privatperson) oder business (Unternehmen). einer von: individual, business
name optional string Name der Kontaktperson. kann leer sein (null) · höchstens 255 Zeichen
phone optional string Telefonnummer. kann leer sein (null) · höchstens 255 Zeichen
address optional string Straße und Hausnummer. kann leer sein (null) · höchstens 255 Zeichen
city optional string Ort. kann leer sein (null) · höchstens 255 Zeichen
postal_code optional string Postleitzahl. kann leer sein (null) · höchstens 64 Zeichen
country optional string Land. kann leer sein (null) · mindestens 2 Zeichen · höchstens 2 Zeichen
company_name optional string Firmenname, bei einem Geschäftskunden. kann leer sein (null) · höchstens 255 Zeichen
vat_number optional string USt-IdNr. kann leer sein (null) · höchstens 20 Zeichen
coc_number optional string Handelsregisternummer. kann leer sein (null) · höchstens 30 Zeichen

Beispielanfrage

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

Antwort 201

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

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.

Kunden bearbeiten

PATCH /api/v1/customers/{customer}

Ändert nur die Felder, die Sie mitsenden. Der Status ändert sich über diesen Endpunkt nicht; verwenden Sie dafür „Lead in Kunden umwandeln“.

Scope
customers.write — Kunden und Leads erstellen und bearbeiten

Senden Sie das ETag in If-Match mit, dann überschreiben Sie nie versehentlich eine neuere Version.

Pfadparameter

NameTypBeschreibung
customer erforderlich string (uuid) Die ID (UUID) des Kunden.

Body (JSON)

FeldTypBeschreibung
email optional string (email) E-Mail-Adresse; eindeutig innerhalb Ihres Unternehmens. höchstens 255 Zeichen · eindeutig innerhalb Ihres Unternehmens
type optional string individual (Privatperson) oder business (Unternehmen). einer von: individual, business
name optional string Name der Kontaktperson. kann leer sein (null) · höchstens 255 Zeichen
phone optional string Telefonnummer. kann leer sein (null) · höchstens 255 Zeichen
address optional string Straße und Hausnummer. kann leer sein (null) · höchstens 255 Zeichen
city optional string Ort. kann leer sein (null) · höchstens 255 Zeichen
postal_code optional string Postleitzahl. kann leer sein (null) · höchstens 64 Zeichen
country optional string Land. kann leer sein (null) · mindestens 2 Zeichen · höchstens 2 Zeichen
company_name optional string Firmenname, bei einem Geschäftskunden. kann leer sein (null) · höchstens 255 Zeichen
vat_number optional string USt-IdNr. kann leer sein (null) · höchstens 20 Zeichen
coc_number optional string Handelsregisternummer. kann leer sein (null) · höchstens 30 Zeichen

Beispielanfrage

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

Antwort 200

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

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.

Lead in Kunden umwandeln

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

Wandelt einen Lead in einen Kunden um. Ist es bereits ein Kunde, ändert sich nichts und Sie erhalten den Kunden einfach zurück.

Scope
customers.write — Kunden und Leads erstellen und bearbeiten

Senden Sie einen Idempotency-Key mit, dann erzeugt ein erneuter Versuch nach einem Timeout keinen doppelten Datensatz.

Pfadparameter

NameTypBeschreibung
customer erforderlich string (uuid) Die ID (UUID) des Kunden.

Beispielanfrage

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

Antwort 200

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

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.

Zeitleiste eines Kunden

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

Die Zeitleiste eines Kunden, neueste zuerst: Angebote, Rechnungen, Termine, E-Mails und mehr. Verweise auf verknüpfte Datensätze stehen unter related.

Scope
customers.read — Kunden und Leads lesen

Pfadparameter

NameTypBeschreibung
customer erforderlich string (uuid) Die ID (UUID) des Kunden.

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.
filter[type] string Nur Aktivitäten dieses Typs, zum Beispiel quote_sent oder invoice_created. höchstens 40 Zeichen

Beispielanfrage

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

Antwort 200

Die Antwort ist eine Liste mit Cursor-Paginierung: data enthält die Objekte, meta die Paginierung.

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

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 „customer“.
id string (uuid) Eindeutige ID (UUID).
type string individual (Privatperson) oder business (Unternehmen). einer von: individual, business
status string lead oder customer (Kunde). einer von: lead, customer
name string Name der Kontaktperson. kann leer sein (null)
email string (email) E-Mail-Adresse; eindeutig innerhalb Ihres Unternehmens.
phone string Telefonnummer. kann leer sein (null)
company_name string Firmenname, bei einem Geschäftskunden. kann leer sein (null)
vat_number string USt-IdNr. kann leer sein (null)
coc_number string Handelsregisternummer. kann leer sein (null)
address string Straße und Hausnummer. kann leer sein (null)
postal_code string Postleitzahl. kann leer sein (null)
city string Ort. kann leer sein (null)
country string Land. kann leer sein (null)
email_unsubscribed boolean Hat sich von E-Mails abgemeldet.
converted_at string (date-time) Wann der Lead zum Kunden wurde. kann leer sein (null)
last_activity_at string (date-time) Letzte Aktivität in Klantly. kann leer sein (null)
created_at string (date-time) Erstellt am (UTC).
updated_at string (date-time) Zuletzt geändert am (UTC).