Klantly Developers

Changelog

Alle wijzigingen aan de Klantly API, nieuwste eerst.

Binnen versie 1 komen er alleen dingen bij. Een wijziging die bestaande koppelingen kan breken, komt pas in een nieuwe versie en wordt ruim vooraf aangekondigd met de headers Deprecation en Sunset.

14 oktober 2026

Nieuw event: message.not_delivered. WhatsApp heeft een bericht dat jij of het bedrijf verstuurde niet bezorgd. Meta meldt dat via zijn statuswebhook, soms pas minuten na het versturen, dus message.sent alleen zegt niet dat het is aangekomen.

  • Scope messages.read, net als message.received en message.sent. De payload is het bericht zelf.
  • Vaakst voorkomende redenen: het nummer kan geen WhatsApp ontvangen, of het is meer dan 24 uur geleden dat de klant schreef (dan komt alleen een goedgekeurd sjabloon nog aan).
  • Bestaande endpoints met ["*"] krijgen dit event er vanzelf bij; abonneer je op een vaste lijst, dan voeg je message.not_delivered zelf toe.

13 oktober 2026

Afspraken uit de Google-agenda. Een bedrijf kan zijn Google-agenda nu de andere kant op laten lopen: de items uit de gekozen Google-agenda's staan dan als afspraak in Klantly.

  • Elke afspraak draagt source: klantly (het normale geval) of google (opgehaald uit de Google-agenda van het bedrijf). Dit veld komt erbij in elk antwoord met een afspraak, dus ook de ETag van een afspraak verandert eenmalig — een If-Match met een oude waarde geeft dan 412; haal de afspraak opnieuw op.
  • Een afspraak met source: "google" is alleen-lezen. PATCH, DELETE en de acties confirm, cancel, complete en notify geven 409 met de code conflict: in Google wordt eraan gewerkt, dus daar hoort de wijziging. Lezen kan gewoon, en voor de bezetting van de agenda telt hij mee.
  • Zulke afspraken geven geen webhook-events. Een agenda van een bedrijf kan honderden items bevatten; die als appointment.created doorsturen zou je endpoint vullen met werk dat niet uit Klantly komt.
  • GET /availability telt ze wél mee, want het zijn gewone afspraken. Stond het ophalen uit, dan verandert er niets.
  • Beschikbaarheid: een afspraak voor de hele dag blokkeert nu de hele dag. GET /v1/availability las bij all_day de kale begin- en eindtijd, en die staan bij zo'n afspraak allebei op 00:00 van de laatste dag — het tijdvak was dus leeg en de dag kwam als volledig vrij terug. Datzelfde geldt nu voor een afspraak die over middernacht loopt: die telt mee op élke dag die hij raakt. Je Google-agenda telt hier nog steeds niet mee; dat blijft de bewuste uitzondering.

27 september 2026

Serviceverzoeken. Een nieuwe resource: de MELDING die aan het werk voorafgaat — een storing, een garantiegeval, een klacht of een vraag van een klant. Het uitvoerende werk met uren en bedragen blijft de werkbon; een melding heeft geen regels en komt nooit op een factuur.

  • GET|POST /v1/services, GET|PATCH|DELETE /v1/services/{id} en POST /v1/services/{id}/status (concept → ingepland → bezig → afgerond, plus geannuleerd).
  • Foto's onder /v1/services/{id}/photos: GET, POST (multipart) en DELETE. Per foto hoort een kind: issue (de melding), progress, completion (de oplevering) of other. Dezelfde grenzen als de werkbonfoto's: 10 MB per foto, 30 per melding, en een downloadlink die een kwartier geldig is.
  • Scopes services.read, services.write en services.delete; ze horen bij de functie werkbonnen, dus een sleutel die werkbonnen mag, kan ze toekennen.
  • Events service.created, service.updated, service.status_changed, service.completed, service.signed en service.deleted.
  • Ondertekenen, het inplannen van de afspraak en het omzetten naar een werkbon gaan bewust niet via de API: dat zijn handelingen van een mens op locatie. Een afspraak koppel je wél zelf met appointment_id.

20 september 2026

Sorteren.

  • sort accepteert bij deals, afspraken, gesprekken en reviews nog alleen created_at en updated_at (met of zonder min-teken). stage_changed_at, starts_at, last_message_at en reviewed_at zijn vervallen: die kolommen kunnen leeg zijn, en dan sloeg de cursor de rest van de lijst over — rijen zonder waarde waren onbereikbaar. Een vervallen waarde geeft nu 422.
  • De standaardsortering van gesprekken en reviews is daardoor -created_at geworden (was -last_message_at respectievelijk -reviewed_at).
  • Gebruik voor een agendavolgorde filter[starts_from] en filter[starts_until] en sorteer zelf.

Idempotentie.

  • Een Idempotency-Key geldt vanaf nu per bedrijf in plaats van per sleutel. Zo houdt een herhaling zijn waarborg als je koppeling tijdens het vernieuwen van een sleutel op het nieuwe token overstapt. Gebruiken twee koppelingen van hetzelfde bedrijf dezelfde waarde voor een ánder verzoek, dan krijgt de tweede 422 idempotency_key_reused; geef elke koppeling een eigen voorvoegsel.
  • Een 404 of 422 wordt niet meer 24 uur bewaard: dezelfde sleutel met een gecorrigeerde body voert het verzoek gewoon uit.

18 september 2026

Beveiliging.

  • Een webhook-endpoint kan niet meer naar een intern adres wijzen dat als IPv4-in-IPv6 is verpakt (zoals [::ffff:7f00:1] voor 127.0.0.1). Zulke adressen worden nu net zo geweigerd als hun gewone vorm.

Creditnota's.

  • Een verstuurde of betaalde factuur crediteren met POST /invoices/{id}/credit: alles, per regel een aantal, of een vrij bedrag inclusief btw. Het antwoord is de creditnota.
  • Creditnota's staan in GET /invoices naast de facturen, met het nieuwe veld type (invoice of credit_note) en negatieve bedragen. Zonder filter komen ze allebei mee; met filter[type] kies je er één.
  • Nieuwe velden op een factuur: type, credited_amount, credit_note_ids, credited_invoice_id, credited_invoice_number, credit_reason, refund_amount, refunded_at en credit_note_state; op een regel credited_item_id. Nieuwe status credited (volledig gecrediteerd).
  • De terugbetaling van een creditnota vastleggen met POST /invoices/{id}/refunded.
  • Terugbetalen via Mollie met via: mollie op POST /invoices/{id}/refunded, als de factuur via Mollie is betaald.
  • Nieuw event invoice.credited. De creditnota zelf komt als invoice.created met type credit_note.
  • Een (deels) gecrediteerde factuur kan niet meer geannuleerd worden, en op een creditnota kun je geen betaling registreren (409). Versturen laat de status van een creditnota of gecrediteerde factuur ongemoeid.
  • De gids Facturen naar je boekhouding legt uit hoe je creditnota's boekt.

17 september 2026

Inbox, reviews en bijlagen.

  • Inbox: gesprekken en berichten lezen, antwoorden namens het bedrijf via de chatwidget, WhatsApp of e-mail, en een gesprek sluiten. Antwoorden vraagt de functie van het kanaal van dát gesprek.
  • Reviews: reviews en reviewverzoeken opvragen, en een klant om een review vragen met POST /review-requests. Een review zelf aanmaken kan bewust niet — die hoort van de klant te komen.
  • Bijlagen bij een offerte en foto's bij een werkbon: opvragen, uploaden en verwijderen. Uploaden gaat als multipart/form-data met het veld file; downloaden via een ondertekende link die een kwartier geldig is en geen API-sleutel nodig heeft.
  • Nieuwe scopes: messages.read, messages.send, reviews.read en reviews.write.
  • Nieuwe events voor de inbox en reviews, zoals message.received, conversation.closed en review.received.

Verkoop en financieel.

  • Offertes: opvragen, opstellen, bijwerken (alleen concepten), versturen, accepteren, afwijzen en verwijderen, en de pdf ophalen met GET /quotes/{id}/pdf.
  • Facturen: opvragen, aanmaken, bijwerken (alleen concepten), versturen, annuleren, betalingen registreren en verwijderen, en de pdf ophalen met GET /invoices/{id}/pdf.
  • De betaalpagina voor de klant ophalen met GET /invoices/{id}/payment-link (scope invoices.send, functie Online betalen).
  • Een geaccepteerde offerte omzetten naar een conceptfactuur met POST /quotes/{id}/invoice. Een offerte heeft hooguit één factuur: een tweede verzoek, ook via POST /invoices met quote_id, geeft 409 conflict met het id van de bestaande factuur in invoice_id.
  • Offerte- en factuurregels kennen unit_price_incl: een prijs inclusief btw die tot op de cent klopt.
  • Webshopbestellingen: opvragen, de status wijzigen, track and trace doorgeven en notities toevoegen.
  • Events voor offertes, facturen en bestellingen, zoals quote.accepted, invoice.paid en order.status_changed.
  • Nieuwe scopes: quotes.read, quotes.write, quotes.delete, quotes.send, invoices.read, invoices.write, invoices.delete, invoices.send, orders.read en orders.write.
  • Nieuwe gids: Facturen naar je boekhouding.

15 september 2026

Beveiliging.

  • Een webhook-endpoint wijzigen, uitzetten, verwijderen of een nieuw secret geven kan alleen met een sleutel die alles kan lezen wat het endpoint ontvangt (anders 403 insufficient_scope).
  • Webhooks kunnen niet meer naar het adres van Klantly zelf wijzen, ook niet via een IP-adres of een eigen domeinnaam, en niet naar IPv6-vormen van interne adressen.
  • Een body die geen geldig JSON-object is, geeft 400 bad_request (werd gelezen als een lege body).
  • Tijden buiten 1970–2100 en datums die niet bestaan, zoals 31 februari, geven 422.
  • POST /webhook-endpoints/{id}/test en POST /appointments/{id}/notify vallen onder de limiet voor zware acties.
  • Antwoorden van de API hebben Cache-Control: no-store.
  • Beheerders krijgen een beveiligingsmail als een API-sleutel wordt ingetrokken, rechten erbij krijgt of een andere IP-beperking, en als een webhook-endpoint wordt aangemaakt, een ander adres krijgt of een nieuw secret.
  • Een IP-beperking moet minimaal /8 (IPv4) of /32 (IPv6) zijn.

Verbeteringen na een review.

  • Een webhook-endpoint dat via de API is ingericht, volgt de sleutel die dat deed: trek je die in of haal je er een leesscope af, dan krijgt het endpoint die events niet meer. Een andere URL of een nieuw secret kan alleen met een sleutel die alles kan lezen wat het endpoint ontvangt (anders 403 insufficient_scope).
  • Een herhaalde of opnieuw verstuurde aflevering controleert opnieuw of het event nog mag.
  • Een webhook-URL met een punt aan het eind of met tekens buiten ASCII wordt geweigerd; gebruik de xn--vorm.
  • Cursors zijn versleuteld: gebruik ze zoals je ze krijgt.
  • Een herhaald antwoord (dezelfde Idempotency-Key) bij het aanmaken of vernieuwen van een webhook-endpoint bevat het secret niet meer.
  • Werkbonregels hebben het veld discount_amount (een vaste korting); een te groot bedrag geeft 422 in plaats van een serverfout. PATCH /work-orders/{id} met alleen items geeft nu ook work_order.updated.
  • PATCH /tasks/{id} met links laat koppelingen staan die de API niet toont, en een wijziging komt in de geschiedenis van de taak.
  • POST /appointments/{id}/notify geeft 409 als het bedrijf het sjabloon heeft uitgezet. Een afspraak die bevestigd wordt aangemaakt, heeft confirmed_at.

Afspraken, taken en werkbonnen.

  • Afspraken: opvragen, inplannen, bijwerken, bevestigen, annuleren, afronden en verwijderen, en de klant een bevestiging, verzetting, annulering of herinnering mailen.
  • Bij POST /appointments is title niet meer verplicht als je een appointment_type_id meegeeft: de titel wordt dan de naam van het afspraaktype. Zonder allebei volgt 422.
  • Afspraaktypes en vrije tijdsloten opvragen.
  • Taken: opvragen, aanmaken, koppelen aan klanten en andere records, verplaatsen, afronden, heropenen, annuleren en verwijderen, plus reacties en takenborden.
  • Werkbonnen: opvragen, aanmaken met regels en checklist, bijwerken, de status wijzigen en verwijderen.
  • Events voor afspraken, taken en werkbonnen, zoals appointment.created, task.moved en work_order.completed.
  • Nieuwe scopes: appointments.read, appointments.write, appointments.delete, appointments.send, tasks.read, tasks.write, tasks.delete, work_orders.read, work_orders.write en work_orders.delete.
  • Nieuwe gidsen: Afspraken vanuit je eigen planning en Werkbonnen vanuit je ERP.

Webhooks, deals en meer.

  • Webhooks volgens Standard Webhooks: endpoints beheren in Klantly en via de API, met ondertekening, nieuwe pogingen, een afleverlog en een testbericht. Lees de gids Webhooks.
  • Events: GET /events om gemiste webhooks in te halen.
  • Deals: opvragen, aanmaken, bijwerken, verplaatsen, winnen, verliezen en archiveren, en de pipelinefasen opvragen.
  • Notities bij klanten en deals.
  • De tijdlijn van een klant.
  • Gebruikers en bedrijfsgegevens opvragen.
  • Nieuwe scopes: deals.read, deals.write, users.read, company.read, webhooks.manage en events.read.
  • Nieuwe gidsen: Websiteformulier naar lead en Make en n8n.

14 september 2026

Eerste versie van de Klantly API.

  • Authenticatie met API-sleutels, met scopes, vervaldatum, IP-allowlist en vernieuwen.
  • GET /me om je verbinding te testen.
  • Klanten: opvragen, ophalen, aanmaken, bijwerken en een lead omzetten naar klant.
  • Cursorpaginering, filters, Idempotency-Key en If-Match.
  • Foutmeldingen volgens RFC 9457, in vier talen.
  • OpenAPI 3.1-specificatie in vier talen.

Laatst bijgewerkt op 14 oktober 2026