API
De REST-API geeft je eigen systemen toegang tot de gesprekken, leads, contacten en afspraken van je bedrijf. Gebruik hem om gesprekken in een CRM te zetten, uitgaande gesprekken te starten vanuit je planningspakket, of contacten te synchroniseren.
Authenticatie
Een API-sleutel aanmaken
- Ga naar Instellingen → Koppelingen (rol Beheerder vereist).
- Vul onder API-sleutels een naam in (bijvoorbeeld
Make) en klik op Aanmaken. - Kopieer de sleutel direct. Hij begint met
pk_en wordt maar één keer getoond; daarna toont het dashboard alleen de eerste 10 tekens, zodat je hem later herkent.
Verwijder een sleutel op dezelfde pagina als je hem niet meer nodig hebt. Je kunt maximaal 200 sleutels hebben. Rechten per sleutel bestaan niet: elke sleutel kan alles wat deze API voor je bedrijf kan, dus bewaar hem als een wachtwoord. Een sleutel aanmaken of verwijderen kan alleen binnen 2 uur na het inloggen, en alleen met je eigen login, zie Wijzigingen waarvoor je opnieuw inlogt. De sleutels werken niet meer als je abonnement onbetaald, opgeschort of opgezegd is.
Met een Enterprise-abonnement kun je sleutels beperken tot bepaalde IP-adressen: vul onder Instellingen → Toegangsbeheer, bij Beveiligingsregels, de toegestane IP-reeksen in en zet API-sleutels ook tot deze IP-reeksen beperken aan. Een verzoek vanaf een ander adres krijgt dan een 403.
Verzoeken doen
Stuur de sleutel mee als bearer-token. De basis-URL is je API-domein (zichtbaar onder Instellingen → Koppelingen, bij API-sleutels).
curl https://<api-domein>/v1/me \
-H "Authorization: Bearer pk_..."Verzoeken en antwoorden zijn JSON. Een geslaagd verzoek geeft altijd status 200, ook bij POST. Telefoonnummers zijn in E.164-formaat (+31612345678). Tijdstippen zijn ISO 8601 in UTC.
Rate limit
Per API-sleutel mag je 600 verzoeken per minuut doen; daarboven krijg je 429 met code ERR-50022. Alle API-klanten samen delen bovendien een platformlimiet van 50 verzoeken per seconde, met pieken tot 100. Vraag niet vaker dan één keer per minuut gegevens op; gebruik voor realtime gegevens webhooks.
Fouten
Fouten geven een HTTP-status en een JSON-body:
{ "error": "lead not found", "code": "ERR-56004", "errorId": "…" }error is een Engelse omschrijving en code de foutcode. errorId is het kenmerk van deze ene fout; geef dat door als je een probleem meldt. Sommige fouten hebben ook een veld details.
| Status | code | Betekenis |
|---|---|---|
400 | ERR-50020, ERR-50023–ERR-50028, ERR-50010 | Ongeldige invoer. De code noemt het eerste probleem: ERR-50023 tekst te lang en ERR-50028 te kort (details.max / details.min), ERR-50024 te veel onderdelen in een lijst, ERR-50025 verplicht veld leeg of ontbreekt, ERR-50026 ongeldig e-mailadres, ERR-50027 ongeldig webadres, en ERR-50020 al het andere. details.field en error noemen het veld. ERR-50010 is ongeldige JSON. Sommige endpoints hebben een eigen code; die staat hieronder bij het endpoint. |
401 | ERR-51004, ERR-51005 | API-sleutel ontbreekt of is ongeldig. |
402 | ERR-52250, ERR-56007 | Het abonnement is onbetaald, opgeschort of opgezegd (ERR-52250, bij elk verzoek). Uitgaand bellen zit niet in het abonnement (ERR-56007, alleen POST /v1/calls). |
403 | ERR-52056, ERR-56008 | Niet toegestaan: het IP-adres staat niet op de lijst van je bedrijf (ERR-52056), of uitgaand bellen is geblokkeerd (ERR-56008). |
404 | ERR-56000, ERR-56002, ERR-56004, ERR-56006, ERR-51044 | Object niet gevonden. Een pad dat niet bestaat geeft 404 zonder code. |
413 | ERR-50021 | De body is groter dan 8 MB. |
429 | ERR-50022 | Te veel verzoeken met deze sleutel. Een 429 zonder code betekent dat de gedeelde platformlimiet is bereikt. Probeer het na korte tijd opnieuw. |
500 | ERR-50000 | Onverwachte fout; probeer het later opnieuw. |
Endpoints
GET /v1/me
Geeft het bedrijf waar de sleutel bij hoort.
{
"business": { "id": "…", "name": "Pipes & Co", "slug": "pipes-co-1a2b", "timezone": "Europe/Amsterdam" },
"apiKey": { "id": "…", "name": "Make" }
}GET /v1/assistants
Lijst van assistenten: id, name, language.
[{ "id": "01J…", "name": "Sam", "language": "nl-NL" }]POST /v1/calls
Start een uitgaand gesprek met een assistent. Vereist een nummer dat kan uitbellen (zie Uitgaande gesprekken).
{
"to": "+31612345678",
"assistantId": "01J…",
"from": "+31201234567",
"variables": { "name": "Jan", "order": "BP20260016" }
}from is optioneel (het eerste nummer dat kan uitbellen wordt gebruikt). variables is ook optioneel: maximaal 200 variabelen, namen tot 64 tekens, waarden als tekst tot 2000 tekens, getal of true/false. Ze vullen {{name}} en {{order}} in de Begroeting bij uitbellen, de assistent krijgt de waarden tijdens het gesprek als gegevens mee, en je kunt ze na afloop gebruiken in je acties. In de tekst van de prompt zelf worden ze niet ingevuld: {{name}} wordt daar leeg. Schrijf in de prompt dus "de naam van de klant" in plaats van {{name}}.
Antwoord:
{ "conversationId": "v3:…", "status": "dialing" }Dit endpoint kan ook deze fouten geven:
| Status | code | Betekenis |
|---|---|---|
400 | ERR-56001 | Er is geen nummer beschikbaar: geen enkel nummer kan uitbellen, of de from is niet van jou of kan niet uitbellen. |
402 | ERR-56007 | Uitgaand bellen zit niet in het abonnement van dit bedrijf. |
403 | ERR-56008 | Uitgaand bellen is voor dit bedrijf geblokkeerd. Neem contact op met support. |
404 | ERR-56000 | De assistent is niet gevonden. |
GET /v1/conversations
Queryparameters: from, to (ISO-tijdstippen in UTC op startedAt), channel (voice, sms, whatsapp, webchat), outcome, assistantId, sentiment (positive, neutral, negative), flag (een van de markeringen hieronder, of any voor elk gemarkeerd gesprek), limit (standaard 100, maximaal 500). Een onbekende sentiment of flag geeft 400 met code ERR-52121. Geeft een lijst van gespreksobjecten, nieuwste eerst. Gearchiveerde gesprekken worden niet teruggegeven.
GET /v1/conversations/
Eén gespreksobject plus:
| Veld | Betekenis |
|---|---|
transcript | Lijst van { "role": "user" | "assistant" | "system", "text": "…", "createdAt": "…" }. user is de klant, assistant de assistent of een collega die het gesprek overnam, system zijn platformregels zoals de begroeting. In text kunnen markeringen staan, zoals [image] voor een afbeelding of de naam van een gebruikte tool tussen haken. |
recordingUrl | Tijdelijke downloadlink van de opname (één uur geldig), of null. Opnamen worden na 30 dagen verwijderd; daarna werkt de link niet meer. |
Leads
Leads zijn de aanvragen die je in het dashboard onder Inbox → Aanvragen ziet, zie Aanvragen. new en qualified tonen daar allebei als Open, contacted als Contact gehad, booked als Afspraak gemaakt en lost als Afgesloten.
GET /v1/leads?status=&limit=— lijst van leads, nieuwste eerst (limitstandaard 200, maximaal 500).statusmag in elke schrijfwijze:new,qualified,contacted,booked,lost. Een andere waarde geeft400met codeERR-56003.GET /v1/leads/{id}PATCH /v1/leads/{id}met{ "status": "contacted", "notes": "Teruggebeld, offerte gestuurd" }(beide optioneel;notesis maximaal 4000 tekens en magnullzijn).
Lead-object:
{
"id": "01J…",
"businessId": "01J…",
"conversationId": "v3:…",
"channel": "voice",
"status": "QUALIFIED",
"customerName": "Jan de Vries",
"customerPhone": "+31612345678",
"address": "Damrak 1, Amsterdam",
"problem": "Lekkende keukenkraan",
"urgency": "urgent",
"preferredTime": "morgenochtend",
"summary": "Lekkende kraan, wil morgenochtend een bezoek",
"notes": null,
"phoneProof": null,
"customerPhoneVerified": false,
"customerPhoneVerifiedBy": null,
"createdAt": "2026-09-11T10:00:00.000Z",
"updatedAt": "2026-09-11T10:00:00.000Z"
}urgency is emergency, urgent, routine of unknown. status wordt in hoofdletters teruggegeven. Een lead uit Uitproberen met Acties echt uitvoeren staat hier ook tussen; zijn conversationId begint met test:. customerPhoneVerified is true als de klant het nummer in het gesprek heeft bewezen, false als dat niet zo is, en null bij een lead van vóór dit veld. customerPhoneVerifiedBy (en phoneProof.by) zegt hoe: caller_id (de klant belde vanaf dat nummer), sms_code, email_code, call_code, whatsapp of phone_change.
Contacten
GET /v1/contacts?phone=&limit=— contacten, nieuwste eerst (limitstandaard 500, maximaal 2000). Metphonekrijg je een lijst met het contact dat precies dat E.164-nummer heeft, of een lege lijst; schrijf de+in de URL als%2B.POST /v1/contacts— body metphoneen/ofemail(één is verplicht), en optioneelname(maximaal 160 tekens, wordt gesplitst in voor- en achternaam) offirstName/lastName,company,notes,tags,blocked,fields. Zonderphoneenemailkrijg je400met codeERR-56005. Bij het maximum van 1.000.000 contacten per bedrijf krijg je400met codeERR-52058;details.countbevat het maximum. Er is geen controle op dubbele contacten: zoek eerst met?phone=als het nummer al kan bestaan.GET /v1/contacts/{id}PATCH /v1/contacts/{id}— dezelfde velden als bij aanmaken, behalvename;blocked: trueweigert toekomstige oproepen en sms- en WhatsApp-berichten van dat nummer.
Een contact bevat ook id, businessId, lastSeenAt, conversationCount, createdAt en updatedAt.
GET /v1/appointments
Queryparameters from en to (ISO-tijdstippen in UTC op startAt; standaard nu tot 90 dagen vooruit). Geeft maximaal 500 afspraken die op een dienst in Yarla zijn geboekt, vroegste eerst en inclusief geannuleerde. Boekingen via Cal.com of eTermin staan hier niet in.
[{
"id": "01J…",
"businessId": "01J…",
"eventTypeId": "01J…",
"startAt": "2026-09-15T07:00:00.000Z",
"endAt": "2026-09-15T08:00:00.000Z",
"timezone": "Europe/Amsterdam",
"status": "confirmed",
"guestName": "Jan de Vries",
"guestEmail": "jan@example.com",
"guestPhone": "+31612345678",
"fields": { "address": "Damrak 1" },
"source": "voice",
"conversationId": "v3:…",
"contactId": null,
"externalEventId": null,
"meetingUrl": "",
"remindersSent": [],
"phoneProof": { "phone": "+31612345678", "by": "caller_id", "at": "2026-09-11T09:58:00.000Z" },
"guestPhoneVerified": true,
"guestPhoneVerifiedBy": "caller_id",
"createdAt": "2026-09-11T10:00:00.000Z",
"updatedAt": "2026-09-11T10:00:00.000Z"
}]status is confirmed, rescheduled, cancelled, completed of no_show. source is voice, sms, whatsapp, webchat, web, dashboard of api. De privélink waarmee de klant de afspraak beheert wordt nooit meegegeven. Een afspraak uit Uitproberen met Acties echt uitvoeren staat hier ook tussen; zijn conversationId begint met test:. guestPhoneVerified is true of false als de afspraak in een gesprek is geboekt of gewijzigd, en anders null. guestPhoneVerifiedBy zegt hoe, zoals bij een lead.
Het conversation-object
| Veld | Betekenis |
|---|---|
id | Gespreks-id; ook gebruikt in conversationLink-variabelen. |
assistantId | Assistent die het gesprek voerde. |
channel | voice, sms, whatsapp of webchat. |
direction | inbound of outbound. |
customerPhone | E.164-nummer. Bij webchat meestal null: de widget en de chatpagina geven geen nummer door. |
customerPhoneVerified | true als de klant het nummer in dit gesprek heeft bewezen (de klant belde vanaf dat nummer, een code, of WhatsApp), false als niet, null zonder nummer. |
customerPhoneVerifiedBy | Hoe: caller_id, sms_code, email_code, call_code, whatsapp of phone_change, of null. |
agentNumber | Je nummer waarop het gesprek liep, of null bij webchat. |
contactId | Herkend contact, of null. |
status | active, handed_over (een collega antwoordt) of ended. |
outcome | resolved, transferred, appointment_booked, callback_requested, voicemail, abandoned, no_interaction, spam. Vaak nog null zolang het gesprek loopt, maar appointment_booked, callback_requested, transferred en voicemail kunnen tijdens het gesprek al gezet zijn. De definitieve waarde volgt na afloop. |
summary | AI-samenvatting, gevuld na afloop. |
leadId, appointmentId | Gekoppelde lead en afspraak, of null. |
durationSeconds | Gesprekslengte; null bij tekstkanalen. |
variables | De variabelen die bij de start zijn meegegeven (POST /v1/calls, een campagne, of de naam van het contact als name als je een contact belt vanuit het dashboard), plus de Extra variabelen om te extraheren die de assistent na afloop uit het gesprek haalde. De widget en de chatpagina geven bij de start geen variabelen mee. |
inboundContext | Velden die je webhook vóór het gesprek teruggaf. |
analysis | De beoordeling van de assistent na het gesprek, of null zolang die er nog niet is: sentiment (positive, neutral, negative), score (0 tot 100), flags (geen of meer van off_topic, not_grounded, failed_task, frustrated, wants_human, manipulation_attempt) en checks (eigen controles bij Enterprise: { "id", "question", "passed" }, waarbij passed null is als de vraag niet van toepassing was). |
campaignId | Gevuld bij gesprekken uit een uitgaande campagne. |
startedAt, endedAt | ISO-tijdstippen; endedAt is null zolang het gesprek loopt. |
De API gebruikt eigen veldnamen (customerPhone, startedAt, recordingUrl). Webhook-payloads gebruiken de namen van sjabloonvariabelen (personNumber voor het klantnummer, startTimestamp, audioLink). De id van het gespreksobject is de conversationId in de webhook; koppel de twee daarop. Zie Webhooks.