API-Referenz
Rechnungen
Rechnungen und Gutschriften mit ihren Positionen und Zahlungen: erstellen, ändern solange sie Entwurf sind, senden, stornieren, Zahlungen erfassen, gutschreiben und das PDF oder den Zahlungslink abrufen.
Endpunkte
-
GET
/invoicesRechnungen abrufen -
GET
/invoices/{invoice}Rechnung abrufen -
POST
/invoicesRechnung erstellen -
PATCH
/invoices/{invoice}Rechnung ändern -
POST
/invoices/{invoice}/sendRechnung senden -
POST
/invoices/{invoice}/mark-sentAls versendet markieren (ohne E-Mail) -
POST
/invoices/{invoice}/cancelRechnung stornieren -
POST
/invoices/{invoice}/paymentsZahlung erfassen -
POST
/invoices/{invoice}/creditRechnung gutschreiben -
POST
/invoices/{invoice}/refundedErstattung erfassen -
GET
/invoices/{invoice}/pdfRechnung als PDF -
GET
/invoices/{invoice}/payment-linkZahlungslink abrufen -
DELETE
/invoices/{invoice}Rechnung löschen
Rechnungen abrufen
/api/v1/invoices
Eine Liste der Rechnungen, neueste zuerst, mit ihren Positionen und den erfassten Zahlungen. Filtern nach Status, Kunde oder Änderungsdatum. Mit filter[status]=paid und filter[updated_since] holen Sie ab, was seit Ihrer letzten Synchronisierung bezahlt wurde. Gutschriften stehen in derselben Liste (type credit_note, mit negativen Beträgen); mit filter[type] holen Sie nur Rechnungen oder nur Gutschriften ab.
- Scope
-
invoices.read— Rechnungen lesen, mit Positionen, Beträgen, Zahlungen und den Kundendaten darauf - Erforderliche Funktion
invoices
Query-Parameter
| Name | Typ | Beschreibung |
|---|---|---|
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 | Das Feld, nach dem sortiert wird; ein Minuszeichen davor bedeutet absteigend. Welche Felder Sie wählen können und was der Standard ist, steht bei diesem Parameter. einer von: -created_at, created_at, -updated_at, updated_at · Standard: -created_at |
filter[status]
|
string | Nur Rechnungen mit diesem Status, zum Beispiel paid, overdue oder credited. einer von: draft, sent, viewed, paid, partial, overdue, cancelled, refunded, credited |
filter[type]
|
string | Nur Rechnungen (invoice) oder nur Gutschriften (credit_note). Ohne diesen Filter kommen beide mit. einer von: invoice, credit_note |
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. Überlappen Sie Ihren vorherigen Zeitpunkt um einige Minuten, weil die Uhr Ihres Systems und die von Klantly nicht exakt gleich laufen und weil eine Änderung kurz nach Ihrem vorherigen Zeitpunkt sonst knapp außerhalb liegen würde. Die Grenze ist inklusiv: etwas, das genau zu diesem Zeitpunkt geändert wurde, zählt mit. |
Beispielanfrage
curl "https://app.klantly.com/api/v1/invoices?filter[status]=paid&sort=-updated_at" \
-H "Authorization: Bearer $KLANTLY_API_KEY"$client = new \GuzzleHttp\Client([
'base_uri' => 'https://app.klantly.com/api/v1/',
'headers' => ['Authorization' => 'Bearer ' . getenv('KLANTLY_API_KEY')],
]);
$response = $client->request('GET', 'invoices', [
'query' => [
'filter[status]' => 'paid',
'sort' => '-updated_at',
],
]);
$data = json_decode((string) $response->getBody(), true)['data'];const response = await fetch('https://app.klantly.com/api/v1/invoices?filter[status]=paid&sort=-updated_at', {
headers: {
Authorization: `Bearer ${process.env.KLANTLY_API_KEY}`,
},
});
const { data } = await response.json();import os
import requests
response = requests.get(
"https://app.klantly.com/api/v1/invoices",
headers={
"Authorization": f"Bearer {os.environ['KLANTLY_API_KEY']}",
},
params={
"filter[status]": "paid",
"sort": "-updated_at"
},
)
data = response.json()["data"]Antwort 200
Die Antwort ist eine Liste mit Cursor-Paginierung: data enthält die Objekte, meta die Paginierung.
{
"data": [
{
"object": "invoice",
"id": "9d3f868b-c1a3-4c8a-9fde-e3f1a2b3c4dd",
"number": "FAC-00042",
"type": "invoice",
"status": "sent",
"title": "Veranda 400 × 300",
"description": null,
"customer_id": "9d3f6c1e-4b2a-4c8e-9f1a-2b3c4d5e6f70",
"customer": {
"type": "business",
"name": "De Vries Bouw",
"email": "jan@example.com",
"phone": "+31 6 12345678",
"address": "Dorpsstraat 1",
"postal_code": "3511 AB",
"city": "Utrecht",
"country": "NL",
"company_name": "De Vries Bouw",
"vat_number": null,
"coc_number": null
},
"quote_id": "9d3f8449-afe1-4a6e-9dbc-c1dfe0f1a2ba",
"deal_id": null,
"language": "nl",
"currency": "EUR",
"invoice_date": "2026-09-16",
"due_date": "2026-10-16",
"payment_term_days": 30,
"is_term_invoice": false,
"term_percentage": null,
"term_amount": null,
"terms_conditions": null,
"notes": null,
"outro_text": null,
"hide_line_amounts": false,
"discount_percentage": "0.00",
"discount_amount": "0.00",
"discount_description": null,
"subtotal": "2450.00",
"tax_amount": "514.50",
"total": "2964.50",
"amount_paid": "0.00",
"amount_due": "2964.50",
"sent_at": null,
"viewed_at": null,
"paid_at": null,
"cancelled_at": null,
"credited_invoice_id": null,
"credited_invoice_number": null,
"credit_reason": null,
"refund_amount": null,
"refunded_at": null,
"credit_note_state": null,
"credited_amount": "0.00",
"credit_note_ids": [],
"items": [
{
"object": "invoice_item",
"id": "9d3f87ac-d2b4-4d9b-8aef-f4a2b3c4d5ee",
"type": "product",
"name": "Veranda",
"description": null,
"sku": null,
"quantity": "1.00",
"unit": "stuk",
"unit_price": "2450.00",
"unit_price_incl": null,
"discount_percentage": "0.00",
"discount_amount": "0.00",
"discount_description": null,
"line_total": "2450.00",
"line_total_incl": null,
"is_taxable": true,
"tax_rate": "21.00",
"credited_item_id": null
}
],
"payments": [
{
"object": "invoice_payment",
"id": "9d3f88cd-e3c5-4eac-9bf0-a5b3c4d5e6ff",
"amount": "2964.50",
"type": "full",
"status": "paid",
"payment_method": "bank_transfer",
"description": null,
"paid_at": "2026-09-16T10:15:00Z",
"created_at": "2026-09-16T10: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
-
403
insufficient_scope— Dieser API-Schlüssel hat keinen Zugriff auf diese Aktion. -
422
validation_failed— Die Eingabe ist ungültig.
Rechnung abrufen
/api/v1/invoices/{invoice}
Eine Rechnung per id, mit Positionen, Beträgen und Zahlungen. Die Antwort enthält ein ETag, das Sie beim Ändern in If-Match mitsenden können.
- Scope
-
invoices.read— Rechnungen lesen, mit Positionen, Beträgen, Zahlungen und den Kundendaten darauf - Erforderliche Funktion
invoices
Pfadparameter
| Name | Typ | Beschreibung |
|---|---|---|
invoice erforderlich |
string (uuid) | Die ID (UUID) der Rechnung. |
Beispielanfrage
curl "https://app.klantly.com/api/v1/invoices/9d3f6c1e-4b2a-4c8e-9f1a-2b3c4d5e6f70" \
-H "Authorization: Bearer $KLANTLY_API_KEY"$client = new \GuzzleHttp\Client([
'base_uri' => 'https://app.klantly.com/api/v1/',
'headers' => ['Authorization' => 'Bearer ' . getenv('KLANTLY_API_KEY')],
]);
$response = $client->request('GET', 'invoices/9d3f6c1e-4b2a-4c8e-9f1a-2b3c4d5e6f70');
$data = json_decode((string) $response->getBody(), true)['data'];const response = await fetch('https://app.klantly.com/api/v1/invoices/9d3f6c1e-4b2a-4c8e-9f1a-2b3c4d5e6f70', {
headers: {
Authorization: `Bearer ${process.env.KLANTLY_API_KEY}`,
},
});
const { data } = await response.json();import os
import requests
response = requests.get(
"https://app.klantly.com/api/v1/invoices/9d3f6c1e-4b2a-4c8e-9f1a-2b3c4d5e6f70",
headers={
"Authorization": f"Bearer {os.environ['KLANTLY_API_KEY']}",
},
)
data = response.json()["data"]Antwort 200
{
"data": {
"object": "invoice",
"id": "9d3f868b-c1a3-4c8a-9fde-e3f1a2b3c4dd",
"number": "FAC-00042",
"type": "invoice",
"status": "sent",
"title": "Veranda 400 × 300",
"description": null,
"customer_id": "9d3f6c1e-4b2a-4c8e-9f1a-2b3c4d5e6f70",
"customer": {
"type": "business",
"name": "De Vries Bouw",
"email": "jan@example.com",
"phone": "+31 6 12345678",
"address": "Dorpsstraat 1",
"postal_code": "3511 AB",
"city": "Utrecht",
"country": "NL",
"company_name": "De Vries Bouw",
"vat_number": null,
"coc_number": null
},
"quote_id": "9d3f8449-afe1-4a6e-9dbc-c1dfe0f1a2ba",
"deal_id": null,
"language": "nl",
"currency": "EUR",
"invoice_date": "2026-09-16",
"due_date": "2026-10-16",
"payment_term_days": 30,
"is_term_invoice": false,
"term_percentage": null,
"term_amount": null,
"terms_conditions": null,
"notes": null,
"outro_text": null,
"hide_line_amounts": false,
"discount_percentage": "0.00",
"discount_amount": "0.00",
"discount_description": null,
"subtotal": "2450.00",
"tax_amount": "514.50",
"total": "2964.50",
"amount_paid": "0.00",
"amount_due": "2964.50",
"sent_at": null,
"viewed_at": null,
"paid_at": null,
"cancelled_at": null,
"credited_invoice_id": null,
"credited_invoice_number": null,
"credit_reason": null,
"refund_amount": null,
"refunded_at": null,
"credit_note_state": null,
"credited_amount": "0.00",
"credit_note_ids": [],
"items": [
{
"object": "invoice_item",
"id": "9d3f87ac-d2b4-4d9b-8aef-f4a2b3c4d5ee",
"type": "product",
"name": "Veranda",
"description": null,
"sku": null,
"quantity": "1.00",
"unit": "stuk",
"unit_price": "2450.00",
"unit_price_incl": null,
"discount_percentage": "0.00",
"discount_amount": "0.00",
"discount_description": null,
"line_total": "2450.00",
"line_total_incl": null,
"is_taxable": true,
"tax_rate": "21.00",
"credited_item_id": null
}
],
"payments": [
{
"object": "invoice_payment",
"id": "9d3f88cd-e3c5-4eac-9bf0-a5b3c4d5e6ff",
"amount": "2964.50",
"type": "full",
"status": "paid",
"payment_method": "bank_transfer",
"description": null,
"paid_at": "2026-09-16T10:15:00Z",
"created_at": "2026-09-16T10:15:00Z"
}
],
"created_at": "2026-09-14T10:15:00Z",
"updated_at": "2026-09-14T10:15:00Z"
}
}Mögliche Fehler
-
403
insufficient_scope— Dieser API-Schlüssel hat keinen Zugriff auf diese Aktion. -
404
not_found— Nicht gefunden.
Rechnung erstellen
/api/v1/invoices
Erstellt eine Rechnung für einen Kunden, immer als Entwurf. Klantly vergibt die Nummer und berechnet die Summen; Name, Adresse und Kontaktdaten kommen vom Kunden. Mit quote_id verknüpfen Sie sie mit einem Angebot.
- Scope
-
invoices.write— Rechnungen erstellen (auch aus einem Angebot) und bearbeiten (nur Entwürfe), stornieren, Zahlungen erfassen, gutschreiben und eine Rückerstattung erfassen - Erforderliche Funktion
invoices
Senden Sie einen Idempotency-Key mit, dann erzeugt ein erneuter Versuch nach einem Timeout keinen doppelten Datensatz.
Body (JSON)
| Feld | Typ | Beschreibung |
|---|---|---|
customer_id
erforderlich
|
string (uuid) | Der Kunde. Beim Erstellen erforderlich; Name, Adresse und Kontaktdaten kommen vom Kunden. |
title
erforderlich
|
string | Titel der Rechnung. Beim Erstellen erforderlich. höchstens 255 Zeichen |
items
erforderlich
|
array | Die Positionen (maximal 200). Beim Senden: eine Liste mit je Position name (erforderlich) und optional type, description, sku, quantity, unit, unit_price, unit_price_incl, discount_percentage, discount_amount, discount_description, tax_rate und is_taxable. Sie ersetzen alle bestehenden Positionen. |
quote_id
optional
|
string (uuid) | Das Angebot, aus dem diese Rechnung hervorgeht, oder null. kann leer sein (null) |
description
optional
|
string | Kurze Beschreibung; steht über den Positionen. kann leer sein (null) · höchstens 20000 Zeichen |
language
optional
|
string | Sprache der Rechnung: nl, en, de oder fr. einer von: nl, en, de, fr |
invoice_date
optional
|
string (date) | Rechnungsdatum (JJJJ-MM-TT). |
due_date
optional
|
string (date) | Fälligkeitsdatum (JJJJ-MM-TT). Ohne Angabe ist es das Rechnungsdatum plus die Zahlungsfrist. |
payment_term_days
optional
|
integer | Zahlungsfrist in Tagen. Ohne Angabe gilt der Standard des Unternehmens. von 0 bis 365 |
terms_conditions
optional
|
string | Bedingungen auf der Rechnung. kann leer sein (null) · höchstens 20000 Zeichen |
notes
optional
|
string | Anmerkungen für den Kunden auf der Rechnung. Beim Erfassen einer Zahlung: eine Notiz zu dieser Zahlung. kann leer sein (null) · höchstens 20000 Zeichen |
outro_text
optional
|
string | Schlusstext unter den Positionen. kann leer sein (null) · höchstens 20000 Zeichen |
hide_line_amounts
optional
|
boolean | Blendet die Beträge je Position aus; der Kunde sieht nur die Summe. |
discount_percentage
optional
|
number | Rabatt auf die Summe, in Prozent. von 0 bis 100 |
discount_amount
optional
|
number | Rabatt auf die Summe, als Betrag. von 0 bis 9999999 |
discount_description
optional
|
string | Warum der Rabatt gewährt wurde; steht auf der Rechnung. kann leer sein (null) · höchstens 500 Zeichen |
Beispielanfrage
curl -X POST "https://app.klantly.com/api/v1/invoices" \
-H "Authorization: Bearer $KLANTLY_API_KEY" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: 6f1c2d3e-4a5b-4c6d-8e7f-9a0b1c2d3e4f" \
-d '{
"customer_id": "9d3f6c1e-4b2a-4c8e-9f1a-2b3c4d5e6f70",
"title": "Veranda 400 × 300",
"items": [
{
"name": "Veranda",
"quantity": 1,
"unit_price": "2450.00",
"tax_rate": "21.00"
}
]
}'$client = new \GuzzleHttp\Client([
'base_uri' => 'https://app.klantly.com/api/v1/',
'headers' => ['Authorization' => 'Bearer ' . getenv('KLANTLY_API_KEY')],
]);
$response = $client->request('POST', 'invoices', [
'headers' => [
'Idempotency-Key' => '6f1c2d3e-4a5b-4c6d-8e7f-9a0b1c2d3e4f',
],
'json' => [
'customer_id' => '9d3f6c1e-4b2a-4c8e-9f1a-2b3c4d5e6f70',
'title' => 'Veranda 400 × 300',
'items' => [
0 => [
'name' => 'Veranda',
'quantity' => 1,
'unit_price' => '2450.00',
'tax_rate' => '21.00',
],
],
],
]);
$data = json_decode((string) $response->getBody(), true)['data'];const response = await fetch('https://app.klantly.com/api/v1/invoices', {
method: 'POST',
headers: {
Authorization: `Bearer ${process.env.KLANTLY_API_KEY}`,
'Content-Type': 'application/json',
'Idempotency-Key': '6f1c2d3e-4a5b-4c6d-8e7f-9a0b1c2d3e4f',
},
body: JSON.stringify({
"customer_id": "9d3f6c1e-4b2a-4c8e-9f1a-2b3c4d5e6f70",
"title": "Veranda 400 × 300",
"items": [
{
"name": "Veranda",
"quantity": 1,
"unit_price": "2450.00",
"tax_rate": "21.00"
}
]
}),
});
const { data } = await response.json();import os
import requests
response = requests.post(
"https://app.klantly.com/api/v1/invoices",
headers={
"Authorization": f"Bearer {os.environ['KLANTLY_API_KEY']}",
"Idempotency-Key": "6f1c2d3e-4a5b-4c6d-8e7f-9a0b1c2d3e4f",
},
json={
"customer_id": "9d3f6c1e-4b2a-4c8e-9f1a-2b3c4d5e6f70",
"title": "Veranda 400 × 300",
"items": [
{
"name": "Veranda",
"quantity": 1,
"unit_price": "2450.00",
"tax_rate": "21.00"
}
]
},
)
data = response.json()["data"]Antwort 201
{
"data": {
"object": "invoice",
"id": "9d3f868b-c1a3-4c8a-9fde-e3f1a2b3c4dd",
"number": "FAC-00042",
"type": "invoice",
"status": "sent",
"title": "Veranda 400 × 300",
"description": null,
"customer_id": "9d3f6c1e-4b2a-4c8e-9f1a-2b3c4d5e6f70",
"customer": {
"type": "business",
"name": "De Vries Bouw",
"email": "jan@example.com",
"phone": "+31 6 12345678",
"address": "Dorpsstraat 1",
"postal_code": "3511 AB",
"city": "Utrecht",
"country": "NL",
"company_name": "De Vries Bouw",
"vat_number": null,
"coc_number": null
},
"quote_id": "9d3f8449-afe1-4a6e-9dbc-c1dfe0f1a2ba",
"deal_id": null,
"language": "nl",
"currency": "EUR",
"invoice_date": "2026-09-16",
"due_date": "2026-10-16",
"payment_term_days": 30,
"is_term_invoice": false,
"term_percentage": null,
"term_amount": null,
"terms_conditions": null,
"notes": null,
"outro_text": null,
"hide_line_amounts": false,
"discount_percentage": "0.00",
"discount_amount": "0.00",
"discount_description": null,
"subtotal": "2450.00",
"tax_amount": "514.50",
"total": "2964.50",
"amount_paid": "0.00",
"amount_due": "2964.50",
"sent_at": null,
"viewed_at": null,
"paid_at": null,
"cancelled_at": null,
"credited_invoice_id": null,
"credited_invoice_number": null,
"credit_reason": null,
"refund_amount": null,
"refunded_at": null,
"credit_note_state": null,
"credited_amount": "0.00",
"credit_note_ids": [],
"items": [
{
"object": "invoice_item",
"id": "9d3f87ac-d2b4-4d9b-8aef-f4a2b3c4d5ee",
"type": "product",
"name": "Veranda",
"description": null,
"sku": null,
"quantity": "1.00",
"unit": "stuk",
"unit_price": "2450.00",
"unit_price_incl": null,
"discount_percentage": "0.00",
"discount_amount": "0.00",
"discount_description": null,
"line_total": "2450.00",
"line_total_incl": null,
"is_taxable": true,
"tax_rate": "21.00",
"credited_item_id": null
}
],
"payments": [
{
"object": "invoice_payment",
"id": "9d3f88cd-e3c5-4eac-9bf0-a5b3c4d5e6ff",
"amount": "2964.50",
"type": "full",
"status": "paid",
"payment_method": "bank_transfer",
"description": null,
"paid_at": "2026-09-16T10:15:00Z",
"created_at": "2026-09-16T10:15:00Z"
}
],
"created_at": "2026-09-14T10:15:00Z",
"updated_at": "2026-09-14T10:15:00Z"
}
}Mögliche Fehler
-
403
insufficient_scope— Dieser API-Schlüssel hat keinen Zugriff auf diese Aktion. -
422
validation_failed— Die Eingabe ist ungültig. -
422
unknown_field— Die Eingabe enthält ein unbekanntes Feld. -
415
unsupported_media_type— Dieses Format wird nicht unterstützt. -
413
payload_too_large— Der Body der Anfrage ist zu groß. -
403
limit_reached— Das Limit des Abonnements ist erreicht. -
422
idempotency_key_reused— Dieser Idempotency-Key wurde bereits für eine andere Anfrage verwendet. -
409
idempotency_in_progress— Eine Anfrage mit diesem Idempotency-Key wird noch verarbeitet.
Rechnung ändern
/api/v1/invoices/{invoice}
Ändert nur die Felder, die Sie mitsenden. items ersetzt alle Positionen als Ganzes. Nur ein Entwurf kann sich noch ändern: Ist die Rechnung gesendet, liegt sie in der Buchhaltung des Kunden, und Sie erhalten 409.
- Scope
-
invoices.write— Rechnungen erstellen (auch aus einem Angebot) und bearbeiten (nur Entwürfe), stornieren, Zahlungen erfassen, gutschreiben und eine Rückerstattung erfassen - Erforderliche Funktion
invoices
Senden Sie das ETag in If-Match mit, dann überschreiben Sie nie versehentlich eine neuere Version.
Pfadparameter
| Name | Typ | Beschreibung |
|---|---|---|
invoice erforderlich |
string (uuid) | Die ID (UUID) der Rechnung. |
Body (JSON)
| Feld | Typ | Beschreibung |
|---|---|---|
title
optional
|
string | Titel der Rechnung. Beim Erstellen erforderlich. höchstens 255 Zeichen |
description
optional
|
string | Kurze Beschreibung; steht über den Positionen. kann leer sein (null) · höchstens 20000 Zeichen |
language
optional
|
string | Sprache der Rechnung: nl, en, de oder fr. einer von: nl, en, de, fr |
invoice_date
optional
|
string (date) | Rechnungsdatum (JJJJ-MM-TT). |
due_date
optional
|
string (date) | Fälligkeitsdatum (JJJJ-MM-TT). Ohne Angabe ist es das Rechnungsdatum plus die Zahlungsfrist. |
payment_term_days
optional
|
integer | Zahlungsfrist in Tagen. Ohne Angabe gilt der Standard des Unternehmens. von 0 bis 365 |
terms_conditions
optional
|
string | Bedingungen auf der Rechnung. kann leer sein (null) · höchstens 20000 Zeichen |
notes
optional
|
string | Anmerkungen für den Kunden auf der Rechnung. Beim Erfassen einer Zahlung: eine Notiz zu dieser Zahlung. kann leer sein (null) · höchstens 20000 Zeichen |
outro_text
optional
|
string | Schlusstext unter den Positionen. kann leer sein (null) · höchstens 20000 Zeichen |
hide_line_amounts
optional
|
boolean | Blendet die Beträge je Position aus; der Kunde sieht nur die Summe. |
discount_percentage
optional
|
number | Rabatt auf die Summe, in Prozent. von 0 bis 100 |
discount_amount
optional
|
number | Rabatt auf die Summe, als Betrag. von 0 bis 9999999 |
discount_description
optional
|
string | Warum der Rabatt gewährt wurde; steht auf der Rechnung. kann leer sein (null) · höchstens 500 Zeichen |
items
optional
|
array | Die Positionen (maximal 200). Beim Senden: eine Liste mit je Position name (erforderlich) und optional type, description, sku, quantity, unit, unit_price, unit_price_incl, discount_percentage, discount_amount, discount_description, tax_rate und is_taxable. Sie ersetzen alle bestehenden Positionen. |
Beispielanfrage
curl -X PATCH "https://app.klantly.com/api/v1/invoices/9d3f6c1e-4b2a-4c8e-9f1a-2b3c4d5e6f70" \
-H "Authorization: Bearer $KLANTLY_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"notes": "Graag betalen binnen 14 dagen."
}'$client = new \GuzzleHttp\Client([
'base_uri' => 'https://app.klantly.com/api/v1/',
'headers' => ['Authorization' => 'Bearer ' . getenv('KLANTLY_API_KEY')],
]);
$response = $client->request('PATCH', 'invoices/9d3f6c1e-4b2a-4c8e-9f1a-2b3c4d5e6f70', [
'json' => [
'notes' => 'Graag betalen binnen 14 dagen.',
],
]);
$data = json_decode((string) $response->getBody(), true)['data'];const response = await fetch('https://app.klantly.com/api/v1/invoices/9d3f6c1e-4b2a-4c8e-9f1a-2b3c4d5e6f70', {
method: 'PATCH',
headers: {
Authorization: `Bearer ${process.env.KLANTLY_API_KEY}`,
'Content-Type': 'application/json',
},
body: JSON.stringify({
"notes": "Graag betalen binnen 14 dagen."
}),
});
const { data } = await response.json();import os
import requests
response = requests.patch(
"https://app.klantly.com/api/v1/invoices/9d3f6c1e-4b2a-4c8e-9f1a-2b3c4d5e6f70",
headers={
"Authorization": f"Bearer {os.environ['KLANTLY_API_KEY']}",
},
json={
"notes": "Graag betalen binnen 14 dagen."
},
)
data = response.json()["data"]Antwort 200
{
"data": {
"object": "invoice",
"id": "9d3f868b-c1a3-4c8a-9fde-e3f1a2b3c4dd",
"number": "FAC-00042",
"type": "invoice",
"status": "sent",
"title": "Veranda 400 × 300",
"description": null,
"customer_id": "9d3f6c1e-4b2a-4c8e-9f1a-2b3c4d5e6f70",
"customer": {
"type": "business",
"name": "De Vries Bouw",
"email": "jan@example.com",
"phone": "+31 6 12345678",
"address": "Dorpsstraat 1",
"postal_code": "3511 AB",
"city": "Utrecht",
"country": "NL",
"company_name": "De Vries Bouw",
"vat_number": null,
"coc_number": null
},
"quote_id": "9d3f8449-afe1-4a6e-9dbc-c1dfe0f1a2ba",
"deal_id": null,
"language": "nl",
"currency": "EUR",
"invoice_date": "2026-09-16",
"due_date": "2026-10-16",
"payment_term_days": 30,
"is_term_invoice": false,
"term_percentage": null,
"term_amount": null,
"terms_conditions": null,
"notes": null,
"outro_text": null,
"hide_line_amounts": false,
"discount_percentage": "0.00",
"discount_amount": "0.00",
"discount_description": null,
"subtotal": "2450.00",
"tax_amount": "514.50",
"total": "2964.50",
"amount_paid": "0.00",
"amount_due": "2964.50",
"sent_at": null,
"viewed_at": null,
"paid_at": null,
"cancelled_at": null,
"credited_invoice_id": null,
"credited_invoice_number": null,
"credit_reason": null,
"refund_amount": null,
"refunded_at": null,
"credit_note_state": null,
"credited_amount": "0.00",
"credit_note_ids": [],
"items": [
{
"object": "invoice_item",
"id": "9d3f87ac-d2b4-4d9b-8aef-f4a2b3c4d5ee",
"type": "product",
"name": "Veranda",
"description": null,
"sku": null,
"quantity": "1.00",
"unit": "stuk",
"unit_price": "2450.00",
"unit_price_incl": null,
"discount_percentage": "0.00",
"discount_amount": "0.00",
"discount_description": null,
"line_total": "2450.00",
"line_total_incl": null,
"is_taxable": true,
"tax_rate": "21.00",
"credited_item_id": null
}
],
"payments": [
{
"object": "invoice_payment",
"id": "9d3f88cd-e3c5-4eac-9bf0-a5b3c4d5e6ff",
"amount": "2964.50",
"type": "full",
"status": "paid",
"payment_method": "bank_transfer",
"description": null,
"paid_at": "2026-09-16T10:15:00Z",
"created_at": "2026-09-16T10:15:00Z"
}
],
"created_at": "2026-09-14T10:15:00Z",
"updated_at": "2026-09-14T10:15:00Z"
}
}Mögliche Fehler
-
403
insufficient_scope— Dieser API-Schlüssel hat keinen Zugriff auf diese Aktion. -
422
validation_failed— Die Eingabe ist ungültig. -
422
unknown_field— Die Eingabe enthält ein unbekanntes Feld. -
415
unsupported_media_type— Dieses Format wird nicht unterstützt. -
413
payload_too_large— Der Body der Anfrage ist zu groß. -
404
not_found— Nicht gefunden. -
412
precondition_failed— Der Datensatz wurde inzwischen geändert. -
409
invalid_state_transition— Diese Aktion ist im aktuellen Status nicht möglich.
Rechnung senden
/api/v1/invoices/{invoice}/send
Sendet die Rechnung per E-Mail an den Kunden über die Benachrichtigungsvorlage des Unternehmens und setzt den Status auf gesendet. Erneutes Senden zählt als Mahnung: reminder_count erhöht sich. Bei einer Gutschrift oder einer (teilweise) gutgeschriebenen Rechnung bleibt der Status; nur sent_at wird aktualisiert.
- Scope
-
invoices.send— Rechnungen per E-Mail an Kunden senden und den Zahlungslink für den Kunden abrufen - Erforderliche Funktion
invoices
Senden Sie einen Idempotency-Key mit, dann erzeugt ein erneuter Versuch nach einem Timeout keinen doppelten Datensatz.
Pfadparameter
| Name | Typ | Beschreibung |
|---|---|---|
invoice erforderlich |
string (uuid) | Die ID (UUID) der Rechnung. |
Body (JSON)
| Feld | Typ | Beschreibung |
|---|---|---|
message
optional
|
string | Persönliche Nachricht in der E-Mail an den Kunden. kann leer sein (null) · höchstens 5000 Zeichen |
Beispielanfrage
curl -X POST "https://app.klantly.com/api/v1/invoices/9d3f6c1e-4b2a-4c8e-9f1a-2b3c4d5e6f70/send" \
-H "Authorization: Bearer $KLANTLY_API_KEY" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: 6f1c2d3e-4a5b-4c6d-8e7f-9a0b1c2d3e4f" \
-d '{
"message": "Bijgaand de factuur voor de geplaatste veranda."
}'$client = new \GuzzleHttp\Client([
'base_uri' => 'https://app.klantly.com/api/v1/',
'headers' => ['Authorization' => 'Bearer ' . getenv('KLANTLY_API_KEY')],
]);
$response = $client->request('POST', 'invoices/9d3f6c1e-4b2a-4c8e-9f1a-2b3c4d5e6f70/send', [
'headers' => [
'Idempotency-Key' => '6f1c2d3e-4a5b-4c6d-8e7f-9a0b1c2d3e4f',
],
'json' => [
'message' => 'Bijgaand de factuur voor de geplaatste veranda.',
],
]);
$data = json_decode((string) $response->getBody(), true)['data'];const response = await fetch('https://app.klantly.com/api/v1/invoices/9d3f6c1e-4b2a-4c8e-9f1a-2b3c4d5e6f70/send', {
method: 'POST',
headers: {
Authorization: `Bearer ${process.env.KLANTLY_API_KEY}`,
'Content-Type': 'application/json',
'Idempotency-Key': '6f1c2d3e-4a5b-4c6d-8e7f-9a0b1c2d3e4f',
},
body: JSON.stringify({
"message": "Bijgaand de factuur voor de geplaatste veranda."
}),
});
const { data } = await response.json();import os
import requests
response = requests.post(
"https://app.klantly.com/api/v1/invoices/9d3f6c1e-4b2a-4c8e-9f1a-2b3c4d5e6f70/send",
headers={
"Authorization": f"Bearer {os.environ['KLANTLY_API_KEY']}",
"Idempotency-Key": "6f1c2d3e-4a5b-4c6d-8e7f-9a0b1c2d3e4f",
},
json={
"message": "Bijgaand de factuur voor de geplaatste veranda."
},
)
data = response.json()["data"]Antwort 200
{
"data": {
"object": "invoice",
"id": "9d3f868b-c1a3-4c8a-9fde-e3f1a2b3c4dd",
"number": "FAC-00042",
"type": "invoice",
"status": "sent",
"title": "Veranda 400 × 300",
"description": null,
"customer_id": "9d3f6c1e-4b2a-4c8e-9f1a-2b3c4d5e6f70",
"customer": {
"type": "business",
"name": "De Vries Bouw",
"email": "jan@example.com",
"phone": "+31 6 12345678",
"address": "Dorpsstraat 1",
"postal_code": "3511 AB",
"city": "Utrecht",
"country": "NL",
"company_name": "De Vries Bouw",
"vat_number": null,
"coc_number": null
},
"quote_id": "9d3f8449-afe1-4a6e-9dbc-c1dfe0f1a2ba",
"deal_id": null,
"language": "nl",
"currency": "EUR",
"invoice_date": "2026-09-16",
"due_date": "2026-10-16",
"payment_term_days": 30,
"is_term_invoice": false,
"term_percentage": null,
"term_amount": null,
"terms_conditions": null,
"notes": null,
"outro_text": null,
"hide_line_amounts": false,
"discount_percentage": "0.00",
"discount_amount": "0.00",
"discount_description": null,
"subtotal": "2450.00",
"tax_amount": "514.50",
"total": "2964.50",
"amount_paid": "0.00",
"amount_due": "2964.50",
"sent_at": null,
"viewed_at": null,
"paid_at": null,
"cancelled_at": null,
"credited_invoice_id": null,
"credited_invoice_number": null,
"credit_reason": null,
"refund_amount": null,
"refunded_at": null,
"credit_note_state": null,
"credited_amount": "0.00",
"credit_note_ids": [],
"items": [
{
"object": "invoice_item",
"id": "9d3f87ac-d2b4-4d9b-8aef-f4a2b3c4d5ee",
"type": "product",
"name": "Veranda",
"description": null,
"sku": null,
"quantity": "1.00",
"unit": "stuk",
"unit_price": "2450.00",
"unit_price_incl": null,
"discount_percentage": "0.00",
"discount_amount": "0.00",
"discount_description": null,
"line_total": "2450.00",
"line_total_incl": null,
"is_taxable": true,
"tax_rate": "21.00",
"credited_item_id": null
}
],
"payments": [
{
"object": "invoice_payment",
"id": "9d3f88cd-e3c5-4eac-9bf0-a5b3c4d5e6ff",
"amount": "2964.50",
"type": "full",
"status": "paid",
"payment_method": "bank_transfer",
"description": null,
"paid_at": "2026-09-16T10:15:00Z",
"created_at": "2026-09-16T10:15:00Z"
}
],
"created_at": "2026-09-14T10:15:00Z",
"updated_at": "2026-09-14T10:15:00Z"
}
}Mögliche Fehler
-
403
insufficient_scope— Dieser API-Schlüssel hat keinen Zugriff auf diese Aktion. -
422
validation_failed— Die Eingabe ist ungültig. -
422
unknown_field— Die Eingabe enthält ein unbekanntes Feld. -
415
unsupported_media_type— Dieses Format wird nicht unterstützt. -
413
payload_too_large— Der Body der Anfrage ist zu groß. -
404
not_found— Nicht gefunden. -
403
forbidden— Kein Zugriff. -
409
invalid_state_transition— Diese Aktion ist im aktuellen Status nicht möglich. -
422
idempotency_key_reused— Dieser Idempotency-Key wurde bereits für eine andere Anfrage verwendet. -
409
idempotency_in_progress— Eine Anfrage mit diesem Idempotency-Key wird noch verarbeitet.
Als versendet markieren (ohne E-Mail)
/api/v1/invoices/{invoice}/mark-sent
Setzt einen Entwurf auf versendet, ohne dass Klantly eine E-Mail an den Kunden schickt, wie der Button in der App. Nutzen Sie dies, wenn Sie die Rechnung selbst zugestellt haben: per eigener E-Mail, auf Papier oder über Ihre Buchhaltung. sent_at wird gefüllt und das Event invoice.sent folgt. Danach können Sie eine Zahlung darauf erfassen. Ist die Rechnung bereits versendet oder weiter, kommt sie unverändert zurück; ein stornierter Entwurf ergibt 409. Senden Sie einen Idempotency-Key mit.
- Scope
-
invoices.write— Rechnungen erstellen (auch aus einem Angebot) und bearbeiten (nur Entwürfe), stornieren, Zahlungen erfassen, gutschreiben und eine Rückerstattung erfassen - Erforderliche Funktion
invoices
Senden Sie einen Idempotency-Key mit, dann erzeugt ein erneuter Versuch nach einem Timeout keinen doppelten Datensatz.
Pfadparameter
| Name | Typ | Beschreibung |
|---|---|---|
invoice erforderlich |
string (uuid) | Die ID (UUID) der Rechnung. |
Beispielanfrage
curl -X POST "https://app.klantly.com/api/v1/invoices/9d3f6c1e-4b2a-4c8e-9f1a-2b3c4d5e6f70/mark-sent" \
-H "Authorization: Bearer $KLANTLY_API_KEY" \
-H "Idempotency-Key: 6f1c2d3e-4a5b-4c6d-8e7f-9a0b1c2d3e4f"$client = new \GuzzleHttp\Client([
'base_uri' => 'https://app.klantly.com/api/v1/',
'headers' => ['Authorization' => 'Bearer ' . getenv('KLANTLY_API_KEY')],
]);
$response = $client->request('POST', 'invoices/9d3f6c1e-4b2a-4c8e-9f1a-2b3c4d5e6f70/mark-sent', [
'headers' => [
'Idempotency-Key' => '6f1c2d3e-4a5b-4c6d-8e7f-9a0b1c2d3e4f',
],
]);
$data = json_decode((string) $response->getBody(), true)['data'];const response = await fetch('https://app.klantly.com/api/v1/invoices/9d3f6c1e-4b2a-4c8e-9f1a-2b3c4d5e6f70/mark-sent', {
method: 'POST',
headers: {
Authorization: `Bearer ${process.env.KLANTLY_API_KEY}`,
'Idempotency-Key': '6f1c2d3e-4a5b-4c6d-8e7f-9a0b1c2d3e4f',
},
});
const { data } = await response.json();import os
import requests
response = requests.post(
"https://app.klantly.com/api/v1/invoices/9d3f6c1e-4b2a-4c8e-9f1a-2b3c4d5e6f70/mark-sent",
headers={
"Authorization": f"Bearer {os.environ['KLANTLY_API_KEY']}",
"Idempotency-Key": "6f1c2d3e-4a5b-4c6d-8e7f-9a0b1c2d3e4f",
},
)
data = response.json()["data"]Antwort 200
{
"data": {
"object": "invoice",
"id": "9d3f868b-c1a3-4c8a-9fde-e3f1a2b3c4dd",
"number": "FAC-00042",
"type": "invoice",
"status": "sent",
"title": "Veranda 400 × 300",
"description": null,
"customer_id": "9d3f6c1e-4b2a-4c8e-9f1a-2b3c4d5e6f70",
"customer": {
"type": "business",
"name": "De Vries Bouw",
"email": "jan@example.com",
"phone": "+31 6 12345678",
"address": "Dorpsstraat 1",
"postal_code": "3511 AB",
"city": "Utrecht",
"country": "NL",
"company_name": "De Vries Bouw",
"vat_number": null,
"coc_number": null
},
"quote_id": "9d3f8449-afe1-4a6e-9dbc-c1dfe0f1a2ba",
"deal_id": null,
"language": "nl",
"currency": "EUR",
"invoice_date": "2026-09-16",
"due_date": "2026-10-16",
"payment_term_days": 30,
"is_term_invoice": false,
"term_percentage": null,
"term_amount": null,
"terms_conditions": null,
"notes": null,
"outro_text": null,
"hide_line_amounts": false,
"discount_percentage": "0.00",
"discount_amount": "0.00",
"discount_description": null,
"subtotal": "2450.00",
"tax_amount": "514.50",
"total": "2964.50",
"amount_paid": "0.00",
"amount_due": "2964.50",
"sent_at": null,
"viewed_at": null,
"paid_at": null,
"cancelled_at": null,
"credited_invoice_id": null,
"credited_invoice_number": null,
"credit_reason": null,
"refund_amount": null,
"refunded_at": null,
"credit_note_state": null,
"credited_amount": "0.00",
"credit_note_ids": [],
"items": [
{
"object": "invoice_item",
"id": "9d3f87ac-d2b4-4d9b-8aef-f4a2b3c4d5ee",
"type": "product",
"name": "Veranda",
"description": null,
"sku": null,
"quantity": "1.00",
"unit": "stuk",
"unit_price": "2450.00",
"unit_price_incl": null,
"discount_percentage": "0.00",
"discount_amount": "0.00",
"discount_description": null,
"line_total": "2450.00",
"line_total_incl": null,
"is_taxable": true,
"tax_rate": "21.00",
"credited_item_id": null
}
],
"payments": [
{
"object": "invoice_payment",
"id": "9d3f88cd-e3c5-4eac-9bf0-a5b3c4d5e6ff",
"amount": "2964.50",
"type": "full",
"status": "paid",
"payment_method": "bank_transfer",
"description": null,
"paid_at": "2026-09-16T10:15:00Z",
"created_at": "2026-09-16T10:15:00Z"
}
],
"created_at": "2026-09-14T10:15:00Z",
"updated_at": "2026-09-14T10:15:00Z"
}
}Mögliche Fehler
-
403
insufficient_scope— Dieser API-Schlüssel hat keinen Zugriff auf diese Aktion. -
404
not_found— Nicht gefunden. -
409
invalid_state_transition— Diese Aktion ist im aktuellen Status nicht möglich. -
422
idempotency_key_reused— Dieser Idempotency-Key wurde bereits für eine andere Anfrage verwendet. -
409
idempotency_in_progress— Eine Anfrage mit diesem Idempotency-Key wird noch verarbeitet.
Rechnung stornieren
/api/v1/invoices/{invoice}/cancel
Setzt die Rechnung auf storniert. Eine bezahlte oder (teilweise) gutgeschriebene Rechnung kann nicht storniert werden (409); korrigieren Sie eine versendete Rechnung mit Rechnung gutschreiben.
- Scope
-
invoices.write— Rechnungen erstellen (auch aus einem Angebot) und bearbeiten (nur Entwürfe), stornieren, Zahlungen erfassen, gutschreiben und eine Rückerstattung erfassen - Erforderliche Funktion
invoices
Senden Sie einen Idempotency-Key mit, dann erzeugt ein erneuter Versuch nach einem Timeout keinen doppelten Datensatz.
Pfadparameter
| Name | Typ | Beschreibung |
|---|---|---|
invoice erforderlich |
string (uuid) | Die ID (UUID) der Rechnung. |
Beispielanfrage
curl -X POST "https://app.klantly.com/api/v1/invoices/9d3f6c1e-4b2a-4c8e-9f1a-2b3c4d5e6f70/cancel" \
-H "Authorization: Bearer $KLANTLY_API_KEY" \
-H "Idempotency-Key: 6f1c2d3e-4a5b-4c6d-8e7f-9a0b1c2d3e4f"$client = new \GuzzleHttp\Client([
'base_uri' => 'https://app.klantly.com/api/v1/',
'headers' => ['Authorization' => 'Bearer ' . getenv('KLANTLY_API_KEY')],
]);
$response = $client->request('POST', 'invoices/9d3f6c1e-4b2a-4c8e-9f1a-2b3c4d5e6f70/cancel', [
'headers' => [
'Idempotency-Key' => '6f1c2d3e-4a5b-4c6d-8e7f-9a0b1c2d3e4f',
],
]);
$data = json_decode((string) $response->getBody(), true)['data'];const response = await fetch('https://app.klantly.com/api/v1/invoices/9d3f6c1e-4b2a-4c8e-9f1a-2b3c4d5e6f70/cancel', {
method: 'POST',
headers: {
Authorization: `Bearer ${process.env.KLANTLY_API_KEY}`,
'Idempotency-Key': '6f1c2d3e-4a5b-4c6d-8e7f-9a0b1c2d3e4f',
},
});
const { data } = await response.json();import os
import requests
response = requests.post(
"https://app.klantly.com/api/v1/invoices/9d3f6c1e-4b2a-4c8e-9f1a-2b3c4d5e6f70/cancel",
headers={
"Authorization": f"Bearer {os.environ['KLANTLY_API_KEY']}",
"Idempotency-Key": "6f1c2d3e-4a5b-4c6d-8e7f-9a0b1c2d3e4f",
},
)
data = response.json()["data"]Antwort 200
{
"data": {
"object": "invoice",
"id": "9d3f868b-c1a3-4c8a-9fde-e3f1a2b3c4dd",
"number": "FAC-00042",
"type": "invoice",
"status": "sent",
"title": "Veranda 400 × 300",
"description": null,
"customer_id": "9d3f6c1e-4b2a-4c8e-9f1a-2b3c4d5e6f70",
"customer": {
"type": "business",
"name": "De Vries Bouw",
"email": "jan@example.com",
"phone": "+31 6 12345678",
"address": "Dorpsstraat 1",
"postal_code": "3511 AB",
"city": "Utrecht",
"country": "NL",
"company_name": "De Vries Bouw",
"vat_number": null,
"coc_number": null
},
"quote_id": "9d3f8449-afe1-4a6e-9dbc-c1dfe0f1a2ba",
"deal_id": null,
"language": "nl",
"currency": "EUR",
"invoice_date": "2026-09-16",
"due_date": "2026-10-16",
"payment_term_days": 30,
"is_term_invoice": false,
"term_percentage": null,
"term_amount": null,
"terms_conditions": null,
"notes": null,
"outro_text": null,
"hide_line_amounts": false,
"discount_percentage": "0.00",
"discount_amount": "0.00",
"discount_description": null,
"subtotal": "2450.00",
"tax_amount": "514.50",
"total": "2964.50",
"amount_paid": "0.00",
"amount_due": "2964.50",
"sent_at": null,
"viewed_at": null,
"paid_at": null,
"cancelled_at": null,
"credited_invoice_id": null,
"credited_invoice_number": null,
"credit_reason": null,
"refund_amount": null,
"refunded_at": null,
"credit_note_state": null,
"credited_amount": "0.00",
"credit_note_ids": [],
"items": [
{
"object": "invoice_item",
"id": "9d3f87ac-d2b4-4d9b-8aef-f4a2b3c4d5ee",
"type": "product",
"name": "Veranda",
"description": null,
"sku": null,
"quantity": "1.00",
"unit": "stuk",
"unit_price": "2450.00",
"unit_price_incl": null,
"discount_percentage": "0.00",
"discount_amount": "0.00",
"discount_description": null,
"line_total": "2450.00",
"line_total_incl": null,
"is_taxable": true,
"tax_rate": "21.00",
"credited_item_id": null
}
],
"payments": [
{
"object": "invoice_payment",
"id": "9d3f88cd-e3c5-4eac-9bf0-a5b3c4d5e6ff",
"amount": "2964.50",
"type": "full",
"status": "paid",
"payment_method": "bank_transfer",
"description": null,
"paid_at": "2026-09-16T10:15:00Z",
"created_at": "2026-09-16T10:15:00Z"
}
],
"created_at": "2026-09-14T10:15:00Z",
"updated_at": "2026-09-14T10:15:00Z"
}
}Mögliche Fehler
-
403
insufficient_scope— Dieser API-Schlüssel hat keinen Zugriff auf diese Aktion. -
404
not_found— Nicht gefunden. -
409
invalid_state_transition— Diese Aktion ist im aktuellen Status nicht möglich. -
422
idempotency_key_reused— Dieser Idempotency-Key wurde bereits für eine andere Anfrage verwendet. -
409
idempotency_in_progress— Eine Anfrage mit diesem Idempotency-Key wird noch verarbeitet.
Zahlung erfassen
/api/v1/invoices/{invoice}/payments
Erfasst eine Zahlung, die außerhalb von Klantly eingegangen ist, zum Beispiel eine Überweisung. Der Betrag kann nie höher sein als der offene Betrag. Ist die Rechnung damit vollständig beglichen, wechselt sie auf bezahlt und das Event invoice.paid folgt.
- Scope
-
invoices.write— Rechnungen erstellen (auch aus einem Angebot) und bearbeiten (nur Entwürfe), stornieren, Zahlungen erfassen, gutschreiben und eine Rückerstattung erfassen - Erforderliche Funktion
invoices
Senden Sie einen Idempotency-Key mit, dann erzeugt ein erneuter Versuch nach einem Timeout keinen doppelten Datensatz.
Pfadparameter
| Name | Typ | Beschreibung |
|---|---|---|
invoice erforderlich |
string (uuid) | Die ID (UUID) der Rechnung. |
Body (JSON)
| Feld | Typ | Beschreibung |
|---|---|---|
amount
erforderlich
|
number | Der Betrag der Zahlung, die Sie erfassen. Nie mehr als der offene Betrag. von 0 bis 9999999 |
payment_method
optional
|
string | Wie bezahlt wurde: bank_transfer, cash, card, ideal, credit_card, paypal, bancontact oder other. einer von: bank_transfer, cash, card, ideal, credit_card, paypal, bancontact, other |
reference
optional
|
string | Ihr eigenes Kennzeichen zur Zahlung, zum Beispiel der Kontoauszug oder die Transaktions-id. kann leer sein (null) · höchstens 255 Zeichen |
notes
optional
|
string | Anmerkungen für den Kunden auf der Rechnung. Beim Erfassen einer Zahlung: eine Notiz zu dieser Zahlung. kann leer sein (null) · höchstens 1000 Zeichen |
Beispielanfrage
curl -X POST "https://app.klantly.com/api/v1/invoices/9d3f6c1e-4b2a-4c8e-9f1a-2b3c4d5e6f70/payments" \
-H "Authorization: Bearer $KLANTLY_API_KEY" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: 6f1c2d3e-4a5b-4c6d-8e7f-9a0b1c2d3e4f" \
-d '{
"amount": "2964.50",
"payment_method": "bank_transfer",
"reference": "NL02ABNA0123456789"
}'$client = new \GuzzleHttp\Client([
'base_uri' => 'https://app.klantly.com/api/v1/',
'headers' => ['Authorization' => 'Bearer ' . getenv('KLANTLY_API_KEY')],
]);
$response = $client->request('POST', 'invoices/9d3f6c1e-4b2a-4c8e-9f1a-2b3c4d5e6f70/payments', [
'headers' => [
'Idempotency-Key' => '6f1c2d3e-4a5b-4c6d-8e7f-9a0b1c2d3e4f',
],
'json' => [
'amount' => '2964.50',
'payment_method' => 'bank_transfer',
'reference' => 'NL02ABNA0123456789',
],
]);
$data = json_decode((string) $response->getBody(), true)['data'];const response = await fetch('https://app.klantly.com/api/v1/invoices/9d3f6c1e-4b2a-4c8e-9f1a-2b3c4d5e6f70/payments', {
method: 'POST',
headers: {
Authorization: `Bearer ${process.env.KLANTLY_API_KEY}`,
'Content-Type': 'application/json',
'Idempotency-Key': '6f1c2d3e-4a5b-4c6d-8e7f-9a0b1c2d3e4f',
},
body: JSON.stringify({
"amount": "2964.50",
"payment_method": "bank_transfer",
"reference": "NL02ABNA0123456789"
}),
});
const { data } = await response.json();import os
import requests
response = requests.post(
"https://app.klantly.com/api/v1/invoices/9d3f6c1e-4b2a-4c8e-9f1a-2b3c4d5e6f70/payments",
headers={
"Authorization": f"Bearer {os.environ['KLANTLY_API_KEY']}",
"Idempotency-Key": "6f1c2d3e-4a5b-4c6d-8e7f-9a0b1c2d3e4f",
},
json={
"amount": "2964.50",
"payment_method": "bank_transfer",
"reference": "NL02ABNA0123456789"
},
)
data = response.json()["data"]Antwort 200
{
"data": {
"object": "invoice",
"id": "9d3f868b-c1a3-4c8a-9fde-e3f1a2b3c4dd",
"number": "FAC-00042",
"type": "invoice",
"status": "sent",
"title": "Veranda 400 × 300",
"description": null,
"customer_id": "9d3f6c1e-4b2a-4c8e-9f1a-2b3c4d5e6f70",
"customer": {
"type": "business",
"name": "De Vries Bouw",
"email": "jan@example.com",
"phone": "+31 6 12345678",
"address": "Dorpsstraat 1",
"postal_code": "3511 AB",
"city": "Utrecht",
"country": "NL",
"company_name": "De Vries Bouw",
"vat_number": null,
"coc_number": null
},
"quote_id": "9d3f8449-afe1-4a6e-9dbc-c1dfe0f1a2ba",
"deal_id": null,
"language": "nl",
"currency": "EUR",
"invoice_date": "2026-09-16",
"due_date": "2026-10-16",
"payment_term_days": 30,
"is_term_invoice": false,
"term_percentage": null,
"term_amount": null,
"terms_conditions": null,
"notes": null,
"outro_text": null,
"hide_line_amounts": false,
"discount_percentage": "0.00",
"discount_amount": "0.00",
"discount_description": null,
"subtotal": "2450.00",
"tax_amount": "514.50",
"total": "2964.50",
"amount_paid": "0.00",
"amount_due": "2964.50",
"sent_at": null,
"viewed_at": null,
"paid_at": null,
"cancelled_at": null,
"credited_invoice_id": null,
"credited_invoice_number": null,
"credit_reason": null,
"refund_amount": null,
"refunded_at": null,
"credit_note_state": null,
"credited_amount": "0.00",
"credit_note_ids": [],
"items": [
{
"object": "invoice_item",
"id": "9d3f87ac-d2b4-4d9b-8aef-f4a2b3c4d5ee",
"type": "product",
"name": "Veranda",
"description": null,
"sku": null,
"quantity": "1.00",
"unit": "stuk",
"unit_price": "2450.00",
"unit_price_incl": null,
"discount_percentage": "0.00",
"discount_amount": "0.00",
"discount_description": null,
"line_total": "2450.00",
"line_total_incl": null,
"is_taxable": true,
"tax_rate": "21.00",
"credited_item_id": null
}
],
"payments": [
{
"object": "invoice_payment",
"id": "9d3f88cd-e3c5-4eac-9bf0-a5b3c4d5e6ff",
"amount": "2964.50",
"type": "full",
"status": "paid",
"payment_method": "bank_transfer",
"description": null,
"paid_at": "2026-09-16T10:15:00Z",
"created_at": "2026-09-16T10:15:00Z"
}
],
"created_at": "2026-09-14T10:15:00Z",
"updated_at": "2026-09-14T10:15:00Z"
}
}Mögliche Fehler
-
403
insufficient_scope— Dieser API-Schlüssel hat keinen Zugriff auf diese Aktion. -
422
validation_failed— Die Eingabe ist ungültig. -
422
unknown_field— Die Eingabe enthält ein unbekanntes Feld. -
415
unsupported_media_type— Dieses Format wird nicht unterstützt. -
413
payload_too_large— Der Body der Anfrage ist zu groß. -
404
not_found— Nicht gefunden. -
409
invalid_state_transition— Diese Aktion ist im aktuellen Status nicht möglich. -
422
idempotency_key_reused— Dieser Idempotency-Key wurde bereits für eine andere Anfrage verwendet. -
409
idempotency_in_progress— Eine Anfrage mit diesem Idempotency-Key wird noch verarbeitet.
Rechnung gutschreiben
/api/v1/invoices/{invoice}/credit
Erstellt eine Gutschrift zu einer versendeten oder bezahlten Rechnung, wie der Button in der App. mode=full schreibt alles gut, was noch nicht gutgeschrieben ist, mode=lines eine Menge pro Position (lines[].item_id und lines[].quantity) und mode=amount einen freien Betrag inklusive MwSt. zu einem MwSt.-Satz, der auf der Rechnung vorkommt. Die Antwort (201) ist die Gutschrift: eine invoice mit type credit_note, negativen Positionen und Summen und credited_invoice_id. Der Teil, der mit dem offenen Betrag verrechnet werden kann, wird verrechnet; der Rest steht als refund_amount auf der Gutschrift und muss dem Kunden erstattet werden. Mehr gutschreiben als noch auf der Rechnung steht, ergibt 422 bei amount, lines oder lines.N.quantity; ein Entwurf, eine stornierte oder bereits vollständig gutgeschriebene Rechnung oder eine Gutschrift ergibt 409. Danach folgen die Events invoice.created (die Gutschrift) und invoice.credited (die Rechnung). Senden Sie immer einen Idempotency-Key mit.
- Scope
-
invoices.write— Rechnungen erstellen (auch aus einem Angebot) und bearbeiten (nur Entwürfe), stornieren, Zahlungen erfassen, gutschreiben und eine Rückerstattung erfassen - Erforderliche Funktion
invoices
Senden Sie einen Idempotency-Key mit, dann erzeugt ein erneuter Versuch nach einem Timeout keinen doppelten Datensatz.
Pfadparameter
| Name | Typ | Beschreibung |
|---|---|---|
invoice erforderlich |
string (uuid) | Die ID (UUID) der Rechnung. |
Body (JSON)
| Feld | Typ | Beschreibung |
|---|---|---|
mode
erforderlich
|
string | Was Sie gutschreiben: full (alles, was noch nicht gutgeschrieben ist), lines (eine Menge pro Position) oder amount (ein freier Betrag). einer von: full, lines, amount |
reason
erforderlich
|
string | Der Grund der Gutschrift (Pflicht, höchstens 500 Zeichen); steht auf der Gutschrift. höchstens 500 Zeichen |
lines
optional
|
array | Bei mode=lines: die Positionen, die Sie gutschreiben, jeweils mit item_id und quantity. |
amount
optional
|
number | Bei mode=amount: der Betrag inklusive MwSt., den Sie gutschreiben. Nie mehr als auf der Rechnung noch gutgeschrieben werden kann. von 0 bis 9999999 |
tax_rate
optional
|
number | Bei mode=amount: der MwSt.-Satz dieses Betrags. Muss auf der Rechnung vorkommen; ohne Angabe der erste Satz der Rechnung. kann leer sein (null) · von 0 bis 100 |
invoice_date
optional
|
string (date) | Datum der Gutschrift (JJJJ-MM-TT); standardmäßig heute. |
Beispielanfrage
curl -X POST "https://app.klantly.com/api/v1/invoices/9d3f6c1e-4b2a-4c8e-9f1a-2b3c4d5e6f70/credit" \
-H "Authorization: Bearer $KLANTLY_API_KEY" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: 6f1c2d3e-4a5b-4c6d-8e7f-9a0b1c2d3e4f" \
-d '{
"mode": "amount",
"reason": "Korting na klacht over de montage",
"amount": "150.00",
"tax_rate": "21.00"
}'$client = new \GuzzleHttp\Client([
'base_uri' => 'https://app.klantly.com/api/v1/',
'headers' => ['Authorization' => 'Bearer ' . getenv('KLANTLY_API_KEY')],
]);
$response = $client->request('POST', 'invoices/9d3f6c1e-4b2a-4c8e-9f1a-2b3c4d5e6f70/credit', [
'headers' => [
'Idempotency-Key' => '6f1c2d3e-4a5b-4c6d-8e7f-9a0b1c2d3e4f',
],
'json' => [
'mode' => 'amount',
'reason' => 'Korting na klacht over de montage',
'amount' => '150.00',
'tax_rate' => '21.00',
],
]);
$data = json_decode((string) $response->getBody(), true)['data'];const response = await fetch('https://app.klantly.com/api/v1/invoices/9d3f6c1e-4b2a-4c8e-9f1a-2b3c4d5e6f70/credit', {
method: 'POST',
headers: {
Authorization: `Bearer ${process.env.KLANTLY_API_KEY}`,
'Content-Type': 'application/json',
'Idempotency-Key': '6f1c2d3e-4a5b-4c6d-8e7f-9a0b1c2d3e4f',
},
body: JSON.stringify({
"mode": "amount",
"reason": "Korting na klacht over de montage",
"amount": "150.00",
"tax_rate": "21.00"
}),
});
const { data } = await response.json();import os
import requests
response = requests.post(
"https://app.klantly.com/api/v1/invoices/9d3f6c1e-4b2a-4c8e-9f1a-2b3c4d5e6f70/credit",
headers={
"Authorization": f"Bearer {os.environ['KLANTLY_API_KEY']}",
"Idempotency-Key": "6f1c2d3e-4a5b-4c6d-8e7f-9a0b1c2d3e4f",
},
json={
"mode": "amount",
"reason": "Korting na klacht over de montage",
"amount": "150.00",
"tax_rate": "21.00"
},
)
data = response.json()["data"]Antwort 201
{
"data": {
"object": "invoice",
"id": "9d3f868b-c1a3-4c8a-9fde-e3f1a2b3c4dd",
"number": "FAC-00042",
"type": "invoice",
"status": "sent",
"title": "Veranda 400 × 300",
"description": null,
"customer_id": "9d3f6c1e-4b2a-4c8e-9f1a-2b3c4d5e6f70",
"customer": {
"type": "business",
"name": "De Vries Bouw",
"email": "jan@example.com",
"phone": "+31 6 12345678",
"address": "Dorpsstraat 1",
"postal_code": "3511 AB",
"city": "Utrecht",
"country": "NL",
"company_name": "De Vries Bouw",
"vat_number": null,
"coc_number": null
},
"quote_id": "9d3f8449-afe1-4a6e-9dbc-c1dfe0f1a2ba",
"deal_id": null,
"language": "nl",
"currency": "EUR",
"invoice_date": "2026-09-16",
"due_date": "2026-10-16",
"payment_term_days": 30,
"is_term_invoice": false,
"term_percentage": null,
"term_amount": null,
"terms_conditions": null,
"notes": null,
"outro_text": null,
"hide_line_amounts": false,
"discount_percentage": "0.00",
"discount_amount": "0.00",
"discount_description": null,
"subtotal": "2450.00",
"tax_amount": "514.50",
"total": "2964.50",
"amount_paid": "0.00",
"amount_due": "2964.50",
"sent_at": null,
"viewed_at": null,
"paid_at": null,
"cancelled_at": null,
"credited_invoice_id": null,
"credited_invoice_number": null,
"credit_reason": null,
"refund_amount": null,
"refunded_at": null,
"credit_note_state": null,
"credited_amount": "0.00",
"credit_note_ids": [],
"items": [
{
"object": "invoice_item",
"id": "9d3f87ac-d2b4-4d9b-8aef-f4a2b3c4d5ee",
"type": "product",
"name": "Veranda",
"description": null,
"sku": null,
"quantity": "1.00",
"unit": "stuk",
"unit_price": "2450.00",
"unit_price_incl": null,
"discount_percentage": "0.00",
"discount_amount": "0.00",
"discount_description": null,
"line_total": "2450.00",
"line_total_incl": null,
"is_taxable": true,
"tax_rate": "21.00",
"credited_item_id": null
}
],
"payments": [
{
"object": "invoice_payment",
"id": "9d3f88cd-e3c5-4eac-9bf0-a5b3c4d5e6ff",
"amount": "2964.50",
"type": "full",
"status": "paid",
"payment_method": "bank_transfer",
"description": null,
"paid_at": "2026-09-16T10:15:00Z",
"created_at": "2026-09-16T10:15:00Z"
}
],
"created_at": "2026-09-14T10:15:00Z",
"updated_at": "2026-09-14T10:15:00Z"
}
}Mögliche Fehler
-
403
insufficient_scope— Dieser API-Schlüssel hat keinen Zugriff auf diese Aktion. -
422
validation_failed— Die Eingabe ist ungültig. -
422
unknown_field— Die Eingabe enthält ein unbekanntes Feld. -
415
unsupported_media_type— Dieses Format wird nicht unterstützt. -
413
payload_too_large— Der Body der Anfrage ist zu groß. -
404
not_found— Nicht gefunden. -
409
invalid_state_transition— Diese Aktion ist im aktuellen Status nicht möglich. -
422
idempotency_key_reused— Dieser Idempotency-Key wurde bereits für eine andere Anfrage verwendet. -
409
idempotency_in_progress— Eine Anfrage mit diesem Idempotency-Key wird noch verarbeitet.
Erstattung erfassen
/api/v1/invoices/{invoice}/refunded
Erfasst, dass der zu erstattende Teil einer Gutschrift (refund_amount) an den Kunden überwiesen wurde; refunded_at wird gefüllt und credit_note_state wird refunded. Nur bei einer Gutschrift mit credit_note_state refund_pending, sonst 409. Mit via=mollie erstattet Klantly den Betrag tatsächlich über Mollie (nur wenn die Rechnung ausreichend über Mollie bezahlt wurde, sonst 409); lehnt Mollie ab, dann 422 auf refund. Nach einer Teilerstattung bleibt credit_note_state refund_pending und ein neuer Aufruf erstattet nur den Rest.
- Scope
-
invoices.write— Rechnungen erstellen (auch aus einem Angebot) und bearbeiten (nur Entwürfe), stornieren, Zahlungen erfassen, gutschreiben und eine Rückerstattung erfassen - Erforderliche Funktion
invoices
Senden Sie einen Idempotency-Key mit, dann erzeugt ein erneuter Versuch nach einem Timeout keinen doppelten Datensatz.
Pfadparameter
| Name | Typ | Beschreibung |
|---|---|---|
invoice erforderlich |
string (uuid) | Die ID (UUID) der Rechnung. |
Body (JSON)
| Feld | Typ | Beschreibung |
|---|---|---|
via
optional
|
string | manual (Standard): nur erfassen, dass Sie selbst erstattet haben. mollie: tatsächlich über die Mollie-Zahlung(en) der ursprünglichen Rechnung erstatten. einer von: manual, mollie |
payment_method
optional
|
string | Wie erstattet wurde: bank_transfer, cash, card, ideal, credit_card, paypal, bancontact oder other. einer von: bank_transfer, cash, card, ideal, credit_card, paypal, bancontact, other |
reference
optional
|
string | Ihre eigene Referenz zur Erstattung, zum Beispiel der Kontoauszug. kann leer sein (null) · höchstens 255 Zeichen |
Beispielanfrage
curl -X POST "https://app.klantly.com/api/v1/invoices/9d3f6c1e-4b2a-4c8e-9f1a-2b3c4d5e6f70/refunded" \
-H "Authorization: Bearer $KLANTLY_API_KEY" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: 6f1c2d3e-4a5b-4c6d-8e7f-9a0b1c2d3e4f" \
-d '{
"payment_method": "bank_transfer",
"reference": "NL02ABNA0123456789"
}'$client = new \GuzzleHttp\Client([
'base_uri' => 'https://app.klantly.com/api/v1/',
'headers' => ['Authorization' => 'Bearer ' . getenv('KLANTLY_API_KEY')],
]);
$response = $client->request('POST', 'invoices/9d3f6c1e-4b2a-4c8e-9f1a-2b3c4d5e6f70/refunded', [
'headers' => [
'Idempotency-Key' => '6f1c2d3e-4a5b-4c6d-8e7f-9a0b1c2d3e4f',
],
'json' => [
'payment_method' => 'bank_transfer',
'reference' => 'NL02ABNA0123456789',
],
]);
$data = json_decode((string) $response->getBody(), true)['data'];const response = await fetch('https://app.klantly.com/api/v1/invoices/9d3f6c1e-4b2a-4c8e-9f1a-2b3c4d5e6f70/refunded', {
method: 'POST',
headers: {
Authorization: `Bearer ${process.env.KLANTLY_API_KEY}`,
'Content-Type': 'application/json',
'Idempotency-Key': '6f1c2d3e-4a5b-4c6d-8e7f-9a0b1c2d3e4f',
},
body: JSON.stringify({
"payment_method": "bank_transfer",
"reference": "NL02ABNA0123456789"
}),
});
const { data } = await response.json();import os
import requests
response = requests.post(
"https://app.klantly.com/api/v1/invoices/9d3f6c1e-4b2a-4c8e-9f1a-2b3c4d5e6f70/refunded",
headers={
"Authorization": f"Bearer {os.environ['KLANTLY_API_KEY']}",
"Idempotency-Key": "6f1c2d3e-4a5b-4c6d-8e7f-9a0b1c2d3e4f",
},
json={
"payment_method": "bank_transfer",
"reference": "NL02ABNA0123456789"
},
)
data = response.json()["data"]Antwort 200
{
"data": {
"object": "invoice",
"id": "9d3f868b-c1a3-4c8a-9fde-e3f1a2b3c4dd",
"number": "FAC-00042",
"type": "invoice",
"status": "sent",
"title": "Veranda 400 × 300",
"description": null,
"customer_id": "9d3f6c1e-4b2a-4c8e-9f1a-2b3c4d5e6f70",
"customer": {
"type": "business",
"name": "De Vries Bouw",
"email": "jan@example.com",
"phone": "+31 6 12345678",
"address": "Dorpsstraat 1",
"postal_code": "3511 AB",
"city": "Utrecht",
"country": "NL",
"company_name": "De Vries Bouw",
"vat_number": null,
"coc_number": null
},
"quote_id": "9d3f8449-afe1-4a6e-9dbc-c1dfe0f1a2ba",
"deal_id": null,
"language": "nl",
"currency": "EUR",
"invoice_date": "2026-09-16",
"due_date": "2026-10-16",
"payment_term_days": 30,
"is_term_invoice": false,
"term_percentage": null,
"term_amount": null,
"terms_conditions": null,
"notes": null,
"outro_text": null,
"hide_line_amounts": false,
"discount_percentage": "0.00",
"discount_amount": "0.00",
"discount_description": null,
"subtotal": "2450.00",
"tax_amount": "514.50",
"total": "2964.50",
"amount_paid": "0.00",
"amount_due": "2964.50",
"sent_at": null,
"viewed_at": null,
"paid_at": null,
"cancelled_at": null,
"credited_invoice_id": null,
"credited_invoice_number": null,
"credit_reason": null,
"refund_amount": null,
"refunded_at": null,
"credit_note_state": null,
"credited_amount": "0.00",
"credit_note_ids": [],
"items": [
{
"object": "invoice_item",
"id": "9d3f87ac-d2b4-4d9b-8aef-f4a2b3c4d5ee",
"type": "product",
"name": "Veranda",
"description": null,
"sku": null,
"quantity": "1.00",
"unit": "stuk",
"unit_price": "2450.00",
"unit_price_incl": null,
"discount_percentage": "0.00",
"discount_amount": "0.00",
"discount_description": null,
"line_total": "2450.00",
"line_total_incl": null,
"is_taxable": true,
"tax_rate": "21.00",
"credited_item_id": null
}
],
"payments": [
{
"object": "invoice_payment",
"id": "9d3f88cd-e3c5-4eac-9bf0-a5b3c4d5e6ff",
"amount": "2964.50",
"type": "full",
"status": "paid",
"payment_method": "bank_transfer",
"description": null,
"paid_at": "2026-09-16T10:15:00Z",
"created_at": "2026-09-16T10:15:00Z"
}
],
"created_at": "2026-09-14T10:15:00Z",
"updated_at": "2026-09-14T10:15:00Z"
}
}Mögliche Fehler
-
403
insufficient_scope— Dieser API-Schlüssel hat keinen Zugriff auf diese Aktion. -
422
validation_failed— Die Eingabe ist ungültig. -
422
unknown_field— Die Eingabe enthält ein unbekanntes Feld. -
415
unsupported_media_type— Dieses Format wird nicht unterstützt. -
413
payload_too_large— Der Body der Anfrage ist zu groß. -
404
not_found— Nicht gefunden. -
409
conflict— Dies steht im Widerspruch zum aktuellen Zustand. -
409
invalid_state_transition— Diese Aktion ist im aktuellen Status nicht möglich. -
422
idempotency_key_reused— Dieser Idempotency-Key wurde bereits für eine andere Anfrage verwendet. -
409
idempotency_in_progress— Eine Anfrage mit diesem Idempotency-Key wird noch verarbeitet.
Rechnung als PDF
/api/v1/invoices/{invoice}/pdf
Liefert die Rechnung als PDF, so wie der Kunde sie erhält: im Design des Unternehmens und in der Sprache der Rechnung. Praktisch, um sie in der Buchhaltung zur Buchung abzulegen. Beim ersten Mal erstellt Klantly sie; danach kommt sie aus dem Cache, bis sich die Rechnung ändert. Zählt zum strengeren Limit.
- Scope
-
invoices.read— Rechnungen lesen, mit Positionen, Beträgen, Zahlungen und den Kundendaten darauf - Erforderliche Funktion
invoices
Pfadparameter
| Name | Typ | Beschreibung |
|---|---|---|
invoice erforderlich |
string (uuid) | Die ID (UUID) der Rechnung. |
Beispielanfrage
curl "https://app.klantly.com/api/v1/invoices/9d3f6c1e-4b2a-4c8e-9f1a-2b3c4d5e6f70/pdf" \
-H "Authorization: Bearer $KLANTLY_API_KEY" \
-o document.pdf$client = new \GuzzleHttp\Client([
'base_uri' => 'https://app.klantly.com/api/v1/',
'headers' => ['Authorization' => 'Bearer ' . getenv('KLANTLY_API_KEY')],
]);
$response = $client->request('GET', 'invoices/9d3f6c1e-4b2a-4c8e-9f1a-2b3c4d5e6f70/pdf');
file_put_contents('document.pdf', (string) $response->getBody());import { writeFile } from 'node:fs/promises';
const response = await fetch('https://app.klantly.com/api/v1/invoices/9d3f6c1e-4b2a-4c8e-9f1a-2b3c4d5e6f70/pdf', {
headers: {
Authorization: `Bearer ${process.env.KLANTLY_API_KEY}`,
},
});
await writeFile('document.pdf', Buffer.from(await response.arrayBuffer()));import os
import requests
response = requests.get(
"https://app.klantly.com/api/v1/invoices/9d3f6c1e-4b2a-4c8e-9f1a-2b3c4d5e6f70/pdf",
headers={
"Authorization": f"Bearer {os.environ['KLANTLY_API_KEY']}",
},
)
with open("document.pdf", "wb") as pdf:
pdf.write(response.content)Antwort 200
Die Antwort ist die Datei selbst (application/pdf), kein JSON. Content-Disposition enthält den Dateinamen.
Mögliche Fehler
-
403
insufficient_scope— Dieser API-Schlüssel hat keinen Zugriff auf diese Aktion. -
404
not_found— Nicht gefunden.
Zahlungslink abrufen
/api/v1/invoices/{invoice}/payment-link
Liefert die Seite, auf der der Kunde die Rechnung online mit Mollie bezahlt, zum Teilen durch Sie selbst, zum Beispiel in einer eigenen Erinnerung oder per WhatsApp. Bei einem Zahlungsplan wählt der Kunde dort die nächste Rate. Nur bei einer versendeten, noch nicht vollständig bezahlten Rechnung (sonst 409 invalid_state_transition) und wenn das Unternehmen Mollie verbunden hat (sonst 409 conflict). Erfordert die Funktion Online-Zahlungen. Wer den Link hat, kann die Rechnung ansehen und bezahlen: deshalb der Scope invoices.send.
- Scope
-
invoices.send— Rechnungen per E-Mail an Kunden senden und den Zahlungslink für den Kunden abrufen - Erforderliche Funktion
invoices, invoice_payments
Pfadparameter
| Name | Typ | Beschreibung |
|---|---|---|
invoice erforderlich |
string (uuid) | Die ID (UUID) der Rechnung. |
Beispielanfrage
curl "https://app.klantly.com/api/v1/invoices/9d3f6c1e-4b2a-4c8e-9f1a-2b3c4d5e6f70/payment-link" \
-H "Authorization: Bearer $KLANTLY_API_KEY"$client = new \GuzzleHttp\Client([
'base_uri' => 'https://app.klantly.com/api/v1/',
'headers' => ['Authorization' => 'Bearer ' . getenv('KLANTLY_API_KEY')],
]);
$response = $client->request('GET', 'invoices/9d3f6c1e-4b2a-4c8e-9f1a-2b3c4d5e6f70/payment-link');
$data = json_decode((string) $response->getBody(), true)['data'];const response = await fetch('https://app.klantly.com/api/v1/invoices/9d3f6c1e-4b2a-4c8e-9f1a-2b3c4d5e6f70/payment-link', {
headers: {
Authorization: `Bearer ${process.env.KLANTLY_API_KEY}`,
},
});
const { data } = await response.json();import os
import requests
response = requests.get(
"https://app.klantly.com/api/v1/invoices/9d3f6c1e-4b2a-4c8e-9f1a-2b3c4d5e6f70/payment-link",
headers={
"Authorization": f"Bearer {os.environ['KLANTLY_API_KEY']}",
},
)
data = response.json()["data"]Antwort 200
{
"data": {
"object": "invoice_payment_link",
"invoice_id": "9d3f868b-c1a3-4c8a-9fde-e3f1a2b3c4dd",
"url": "https://app.klantly.com/invoice/Xk2p9Qm4Rt7vB1nC8dE5fG3hJ6kL0mN2pQ4rS7tU9vW1xY3zA5bC7dE9fG1hJ3kL/pay",
"amount_due": "1943.00",
"currency": "EUR"
}
}Mögliche Fehler
-
403
insufficient_scope— Dieser API-Schlüssel hat keinen Zugriff auf diese Aktion. -
404
not_found— Nicht gefunden. -
409
invalid_state_transition— Diese Aktion ist im aktuellen Status nicht möglich. -
409
conflict— Dies steht im Widerspruch zum aktuellen Zustand.
Rechnung löschen
/api/v1/invoices/{invoice}
Löscht die Rechnung. Nur ein Entwurf kann weg: Eine gesendete Rechnung bleibt bestehen.
- Scope
-
invoices.delete— Rechnungsentwürfe löschen - Erforderliche Funktion
invoices
Pfadparameter
| Name | Typ | Beschreibung |
|---|---|---|
invoice erforderlich |
string (uuid) | Die ID (UUID) der Rechnung. |
Beispielanfrage
curl -X DELETE "https://app.klantly.com/api/v1/invoices/9d3f6c1e-4b2a-4c8e-9f1a-2b3c4d5e6f70" \
-H "Authorization: Bearer $KLANTLY_API_KEY"$client = new \GuzzleHttp\Client([
'base_uri' => 'https://app.klantly.com/api/v1/',
'headers' => ['Authorization' => 'Bearer ' . getenv('KLANTLY_API_KEY')],
]);
$response = $client->request('DELETE', 'invoices/9d3f6c1e-4b2a-4c8e-9f1a-2b3c4d5e6f70');
$data = json_decode((string) $response->getBody(), true)['data'];const response = await fetch('https://app.klantly.com/api/v1/invoices/9d3f6c1e-4b2a-4c8e-9f1a-2b3c4d5e6f70', {
method: 'DELETE',
headers: {
Authorization: `Bearer ${process.env.KLANTLY_API_KEY}`,
},
});
const { data } = await response.json();import os
import requests
response = requests.delete(
"https://app.klantly.com/api/v1/invoices/9d3f6c1e-4b2a-4c8e-9f1a-2b3c4d5e6f70",
headers={
"Authorization": f"Bearer {os.environ['KLANTLY_API_KEY']}",
},
)
data = response.json()["data"]Antwort 200
{
"data": {
"object": "note",
"id": "9d3f7b41-2d6f-4e8c-9b3a-4f5d6e7a8b92",
"deleted": true
}
}Mögliche Fehler
-
403
insufficient_scope— Dieser API-Schlüssel hat keinen Zugriff auf diese Aktion. -
404
not_found— Nicht gefunden. -
409
invalid_state_transition— Diese Aktion ist im aktuellen Status nicht möglich.
Das Objekt
Alle Felder sind immer vorhanden; ein Feld ohne Wert ist null.
| Feld | Typ | Beschreibung |
|---|---|---|
object |
string | Immer "invoice". |
id |
string (uuid) | Eindeutige id (UUID). |
number |
string | Rechnungsnummer, zum Beispiel FAC-00042; vergibt Klantly selbst. |
type |
string | invoice (Rechnung) oder credit_note (Gutschrift). Eine Gutschrift hat negative Positionen und Summen. einer von: invoice, credit_note |
status |
string | draft (Entwurf), sent (gesendet), viewed (angesehen), paid (bezahlt), partial (teilweise bezahlt), overdue (überfällig), cancelled (storniert), refunded (erstattet) oder credited (gutgeschrieben: vollständig gegengebucht, zählt weder als bezahlt noch als offen). einer von: draft, sent, viewed, paid, partial, overdue, cancelled, refunded, credited |
title |
string | Titel der Rechnung. Beim Erstellen erforderlich. kann leer sein (null) |
description |
string | Kurze Beschreibung; steht über den Positionen. kann leer sein (null) |
customer_id |
string (uuid) | Der Kunde. Beim Erstellen erforderlich; Name, Adresse und Kontaktdaten kommen vom Kunden. kann leer sein (null) |
customer |
object | Die Kundendaten auf der Rechnung, wie sie beim Erstellen waren. |
customer.type |
string | individual (Privatperson) oder business (Unternehmen). kann leer sein (null) |
customer.name |
string | Name; bei einem Unternehmen der Firmenname. kann leer sein (null) |
customer.email |
string | E-Mail-Adresse. kann leer sein (null) |
customer.phone |
string | Telefonnummer. kann leer sein (null) |
customer.address |
string | Straße und Hausnummer. kann leer sein (null) |
customer.postal_code |
string | Postleitzahl. kann leer sein (null) |
customer.city |
string | Ort. kann leer sein (null) |
customer.country |
string | Land. kann leer sein (null) |
customer.company_name |
string | Firmenname. kann leer sein (null) |
customer.vat_number |
string | USt-IdNr. kann leer sein (null) |
customer.coc_number |
string | Handelsregisternummer. kann leer sein (null) |
quote_id |
string (uuid) | Das Angebot, aus dem diese Rechnung hervorgeht, oder null. kann leer sein (null) |
deal_id |
string (uuid) | Der Deal auf dem Pipeline-Board, zu dem diese Rechnung gehört, oder null. kann leer sein (null) |
language |
string | Sprache der Rechnung: nl, en, de oder fr. einer von: nl, en, de, fr |
currency |
string | Immer "EUR". |
invoice_date |
string (date) | Rechnungsdatum (JJJJ-MM-TT). kann leer sein (null) |
due_date |
string (date) | Fälligkeitsdatum (JJJJ-MM-TT). Ohne Angabe ist es das Rechnungsdatum plus die Zahlungsfrist. kann leer sein (null) |
payment_term_days |
integer | Zahlungsfrist in Tagen. Ohne Angabe gilt der Standard des Unternehmens. kann leer sein (null) |
is_term_invoice |
boolean | Ob dies eine Teilrechnung zu einem Angebot ist. |
term_percentage |
string | Welchen Anteil des Angebots diese Teilrechnung abdeckt, in Prozent; sonst null. kann leer sein (null) |
term_amount |
string | Fester Teilbetrag inkl. MwSt. (entspricht dem Rechnungsbetrag), wenn die Rate als Betrag statt als Prozentsatz festgelegt ist; sonst null. kann leer sein (null) |
terms_conditions |
string | Bedingungen auf der Rechnung. kann leer sein (null) |
notes |
string | Anmerkungen für den Kunden auf der Rechnung. Beim Erfassen einer Zahlung: eine Notiz zu dieser Zahlung. kann leer sein (null) |
outro_text |
string | Schlusstext unter den Positionen. kann leer sein (null) |
hide_line_amounts |
boolean | Blendet die Beträge je Position aus; der Kunde sieht nur die Summe. |
discount_percentage |
string | Rabatt auf die Summe, in Prozent. |
discount_amount |
string | Rabatt auf die Summe, als Betrag. |
discount_description |
string | Warum der Rabatt gewährt wurde; steht auf der Rechnung. kann leer sein (null) |
subtotal |
string | Summe ohne MwSt., als Text mit zwei Dezimalstellen. |
tax_amount |
string | MwSt.-Betrag. |
total |
string | Summe inklusive MwSt. |
amount_paid |
string | Was bisher bezahlt wurde. |
amount_due |
string | Was noch offen ist. Nach einer Gutschrift auf eine bezahlte Rechnung ist dies auf 0,00 begrenzt; der zu erstattende Betrag steht dann auf der Gutschrift (refund_amount, credit_note_state). |
sent_at |
string (date-time) | Wann die Rechnung an den Kunden gesendet wurde. kann leer sein (null) |
viewed_at |
string (date-time) | Wann der Kunde sie geöffnet hat. kann leer sein (null) |
paid_at |
string (date-time) | Wann die Rechnung vollständig beglichen wurde. kann leer sein (null) |
cancelled_at |
string (date-time) | Wann die Rechnung storniert wurde. kann leer sein (null) |
credited_invoice_id |
string (uuid) | Bei einer Gutschrift: die Rechnung, die sie gegenbucht; sonst null. kann leer sein (null) |
credited_invoice_number |
string | Bei einer Gutschrift: die Nummer der gutgeschriebenen Rechnung, beim Erstellen festgehalten; sonst null. kann leer sein (null) |
credit_reason |
string | Bei einer Gutschrift: der Grund der Gutschrift; sonst null. kann leer sein (null) |
refund_amount |
string | Bei einer Gutschrift: der Teil, der nicht mit dem offenen Betrag verrechnet werden konnte und dem Kunden erstattet werden muss (positiv); bei einer Rechnung null. kann leer sein (null) |
refunded_at |
string (date-time) | Bei einer Gutschrift: wann die Erstattung erfasst wurde; sonst null. kann leer sein (null) |
credit_note_state |
string | Bei einer Gutschrift: refund_pending (es muss noch Geld zurück), refunded (erstattet) oder settled (vollständig mit der Rechnung verrechnet); bei einer Rechnung null. kann leer sein (null) · einer von: refund_pending, refunded, settled |
credited_amount |
string | Bei einer Rechnung: was insgesamt mit Gutschriften gegengebucht wurde, inklusive MwSt. (positiv). amount_due ist Summe minus bezahlt minus gutgeschrieben. |
credit_note_ids |
array<string> | Bei einer Rechnung: die IDs ihrer Gutschriften, älteste zuerst; bei einer Gutschrift eine leere Liste. |
items |
array<object> | Die Positionen (maximal 200). Beim Senden: eine Liste mit je Position name (erforderlich) und optional type, description, sku, quantity, unit, unit_price, unit_price_incl, discount_percentage, discount_amount, discount_description, tax_rate und is_taxable. Sie ersetzen alle bestehenden Positionen. |
items.object |
string | Immer "invoice_item". |
items.id |
string (uuid) | Eindeutige id der Position (UUID). |
items.type |
string | product, service, expense, discount oder custom (ein freier Betrag auf einer Gutschrift). einer von: product, service, expense, discount, custom |
items.name |
string | Name der Position. |
items.description |
string | Beschreibung unter der Position. kann leer sein (null) |
items.sku |
string | Artikelnummer. kann leer sein (null) |
items.quantity |
string | Menge. |
items.unit |
string | Einheit, zum Beispiel Stück oder Stunde. kann leer sein (null) |
items.unit_price |
string | Preis je Einheit, ohne MwSt. |
items.unit_price_incl |
string | Preis pro Einheit inklusive MwSt., wie eingegeben. Ist er gesetzt, wird die Position von diesem Betrag aus berechnet (unit_price und line_total werden daraus abgeleitet), und die Summe stimmt auf den Cent mit dem eingegebenen Preis überein. null = die Position wird von unit_price aus berechnet. kann leer sein (null) |
items.discount_percentage |
string | Rabatt auf diese Position, in Prozent. |
items.discount_amount |
string | Rabatt auf diese Position, als Betrag. |
items.discount_description |
string | Warum der Rabatt auf diese Position gewährt wurde. kann leer sein (null) |
items.line_total |
string | Positionssumme ohne MwSt., nach Rabatt. |
items.line_total_incl |
string | Positionssumme inklusive MwSt., nach Rabatt. Nur gesetzt, wenn die Position von unit_price_incl aus berechnet wird; sonst null. kann leer sein (null) |
items.is_taxable |
boolean | Ob diese Position für die MwSt. zählt. |
items.tax_rate |
string | MwSt.-Satz dieser Position, in Prozent. |
items.credited_item_id |
string (uuid) | Auf einer Gutschrift: die Rechnungsposition, die diese Position gegenbucht; null bei einem freien Betrag oder auf einer Rechnung. kann leer sein (null) |
payments |
array<object> | Die auf dieser Rechnung erfassten Zahlungen, älteste zuerst. |
payments.object |
string | Immer "invoice_payment". |
payments.id |
string (uuid) | Eindeutige id der Zahlung. |
payments.amount |
string | Der gezahlte Betrag. |
payments.type |
string | full (vollständig), deposit (Anzahlung) oder partial (Teilzahlung). einer von: full, deposit, partial |
payments.status |
string | open, pending, paid, failed, expired, cancelled oder refunded. einer von: open, pending, paid, failed, expired, cancelled, refunded |
payments.payment_method |
string | Wie bezahlt wurde, zum Beispiel bank_transfer oder ideal. kann leer sein (null) |
payments.description |
string | Notiz zur Zahlung. kann leer sein (null) |
payments.paid_at |
string (date-time) | Wann die Zahlung eingegangen ist. kann leer sein (null) |
payments.created_at |
string (date-time) | Wann die Zahlung erfasst wurde. |
created_at |
string (date-time) | Wann die Rechnung erstellt wurde. |
updated_at |
string (date-time) | Wann die Rechnung zuletzt geändert wurde. |