Naar de inhoud springen

Een klant bellen vanuit een n8n-workflow

September 2, 2026 · 7 min leestijd

U kunt een klant bellen vanuit n8n zonder één regel code te schrijven: voeg een HTTP Request-node toe aan uw workflow, richt die op POST https://volai.cz/v1/calls met een header Authorization: Bearer vk_... en een body van {to, agentId} - en uw spraakagent kiest het nummer precies op het moment dat de workflow erom vraagt. Hieronder vindt u de volledige configuratie: workflowgegevens overnemen in de prompt van de agent, het resultaat van het gesprek terughalen naar n8n en bellen zonder agent door twee nummers rechtstreeks te verbinden.

Wat u nodig hebt

  • Een n8n-instantie - cloud of zelfgehost, elke actuele versie.
  • Een volai-account en een API-sleutel uit het portaal (Instellingen -> API & MCP) in de vorm vk_.... Sla die in n8n op als Header Auth-inloggegevens (header Authorization, waarde Bearer vk_...), zodat u de sleutel niet in elke node hoeft te kopiëren.
  • Een eigen nummer met een toegewezen spraakagent - maak die aan in het portaal of via /docs/agent. Nog geen agent? U kunt toch bellen door twee nummers rechtstreeks te verbinden (de variant met from verderop).

1HTTP Request-node toevoegen

Methode POST, URL https://volai.cz/v1/calls, authenticatie via uw opgeslagen inloggegevens, Body Content Type JSON. De body heeft to (het nummer van de klant) en agentId (de ID van de agent uit het portaal) nodig - beide zijn verplicht, en wel precies ÉÉN van agentId/from/systemPrompt, nooit meer dan één.

json
{
  "to": "={{ $json.phone }}",
  "agentId": "ag_kx91fa2b",
  "variables": {
    "customer_name": "={{ $json.name }}",
    "order_number": "={{ $json.order }}"
  },
  "ringingTimeoutSecs": 30
}

Waarden in de vorm ={{...}} zijn n8n-expressies - $json leest velden uit de vorige node van de workflow (bijvoorbeeld uit een webhook "nieuwe bestelling" of een tabelrij).

2Workflowgegevens overnemen in de prompt van de agent

variables is een object van string naar string dat de agent als dynamische variabelen ontvangt - in zijn systeemprompt verwijst u ernaar als {{customer_name}}. Limieten: maximaal 20 sleutels, sleutels tot 64 tekens, waarden tot 512 tekens. De namen attempt_id, caller_number en called_number zijn gereserveerd - volai vult ze zelf in, en waarden met dezelfde naam uit uw workflow worden genegeerd.

ringingTimeoutSecs (5 tot 60 seconden, standaard 25) bepaalt hoelang de telefoon mag overgaan voordat een onbeantwoord gesprek eindigt met endReason: "no_answer". Een langere timeout vergroot de kans dat de klant opneemt, maar bezet ook langer een lijn voor uitgaande gesprekken.

3Antwoord lezen en eventueel op het resultaat wachten

Een geslaagd antwoord komt direct terug, maar het gesprek is net pas begonnen - status is initiated, geen eindstatus:

json
{
  "id": "c_9d4e2b7f",
  "status": "initiated"
}

Wilt u het resultaat in dezelfde workflowrun afwachten in plaats van via een aparte webhook? Voeg direct na de HTTP Request-node een tweede node toe die GET /v1/calls/{id} aanroept met de parameter waitSecs (0 tot 45 seconden) - de server antwoordt zodra het gesprek eindigt of de timeout is bereikt, wat zich het eerst voordoet:

bash
curl "https://volai.cz/v1/calls/c_9d4e2b7f?waitSecs=30" \
  -H "Authorization: Bearer vk_YOUR_KEY"

Het resultaat terughalen: een webhook naar n8n

Voor een productieworkflow is het meestal handiger om niet inline te wachten maar het resultaat apart te laten bezorgen: voeg in n8n een Webhook-node toe (een nieuwe workflow volstaat), kopieer de Production URL en registreer die eenmalig bij volai:

bash
curl -X PUT https://volai.cz/v1/webhook \
  -H "Authorization: Bearer vk_YOUR_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "url": "https://your-instance.app.n8n.cloud/webhook/volai-calls",
    "events": ["call.completed", "call.failed", "call.no_answer"]
  }'

Het antwoord bevat een secret (in de vorm whsec_...) - bewaar die, want u hebt hem nodig om de handtekening van elk binnenkomend verzoek te controleren. volai stuurt een header Volai-Signature in de vorm t=<unix>,v1=<hex> - de volledige verificatiecode in TypeScript en Python vindt u op /docs/webhooky. Die is niet ongewijzigd over te nemen in een n8n Code-node: de HMAC wordt berekend over de RUWE request-body, dus moet u in de Webhook-node de optie Raw Body inschakelen (zonder die optie levert n8n al geparseerde JSON en komt de handtekening nooit overeen), en in de Code-node importeert u crypto met require, niet met import. Verwerk de body niet voordat u de handtekening hebt gecontroleerd.

Dit komt binnen zodra het gesprek is afgelopen:

json
{
  "event": "call.completed",
  "ts": 1756111640000,
  "data": {
    "id": "c_9d4e2b7f",
    "direction": "out",
    "from": "+420601234567",
    "to": "+420777123456",
    "status": "completed",
    "durationSecs": 90,
    "priceHal": 513,
    "answeredBy": "human",
    "endReason": "completed",
    "transcript": [
      { "role": "agent", "message": "Goedendag, ik bel over bestelling A-42." },
      { "role": "caller", "message": "Ja, dat weet ik al, bedankt voor de herinnering." }
    ],
    "summary": "De klant heeft de ontvangst van bestelling A-42 bevestigd.",
    "data": {
      "order_confirmed": true
    }
  }
}

De sleutel data binnen data is optioneel en bevat precies de velden die u bij de agent hebt ingesteld in zijn dataFields - het voorbeeld hierboven (order_confirmed) is alleen ter illustratie, uw velden zullen anders heten. Een volgende n8n-node kan dan op basis van die velden vertakken, bijvoorbeeld om een CRM-record bij te werken of het gesprek opnieuw te plannen.

Hoe belt u zonder agent?

Als u geen spraakagent nodig hebt, maar alleen een directe verbinding tussen twee nummers (bijvoorbeeld een verkoper en een klant), stuur dan from in plaats van agentId:

json
{
  "to": "+420777123456",
  "from": "+420601234567"
}

volai belt eerst from, en zodra iemand opneemt, kiest het to. Beide gespreksdelen worden apart afgerekend tegen 0.92 CZK per minuut (zonder agenttoeslag). from is het nummer waarop U opneemt - doorgaans uw mobiele telefoon - en kan elk Tsjechisch of Slowaaks nummer zijn; het hoeft niet bij uw volai-account te horen. De eigenlijke voorwaarde is een andere: uw account heeft minstens één eigen volai-nummer nodig, want daarmee wordt het gesprek afgerekend en dat zien beide kanten op het display (zonder dat geeft volai bridge_needs_number terug). Vul alleen geen volai-nummer in from in dat naar een agent of naar SIP is doorgezet - het netwerk zou dat eerste deel dan niet naar u maar naar de agent verbinden, en uw telefoon zou nooit overgaan.

Wat kost zo'n gesprek?

Een uitgaand gesprek via een agent wordt afgerekend als de som van twee tarieven: de uitgaande minuut (0.92 CZK) plus de agenttoeslag ERBOVENOP (2.50 CZK), beide volgens de prijslijst van 2 september 2026. Een gesprek van 90 seconden komt op 5.13 CZK:

PostTariefGesprek van 90 s
Uitgaande minuut0.92 CZK/min.1.38 CZK
Agenttoeslag2.50 CZK/min.3.75 CZK
Totaal5.13 CZK

Er wordt per seconde afgerekend, niet per begonnen minuut - een korter gesprek kost dienovereenkomstig minder. De volledige prijslijst (nummers, agent, sms) vindt u op /cenik.

Veilig herhalen (Idempotency-Key)

n8n kan een node bij een fout automatisch opnieuw proberen (Retry On Fail) - zonder beveiliging zou dat twee echte gesprekken met dezelfde klant betekenen. Voeg een header Idempotency-Key toe met een waarde die stabiel blijft voor één workflowrun (n8n biedt daarvoor {{ $execution.id }}, of gebruik uw eigen bestel-ID) - met dezelfde sleutel krijgt u binnen 24 uur het antwoord van de eerste poging terug en wordt het gesprek niet dubbel gestart:

bash
curl -X POST https://volai.cz/v1/calls \
  -H "Authorization: Bearer vk_YOUR_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: reminder-order-A-42" \
  -d '{"to": "+420777123456", "agentId": "ag_kx91fa2b"}'

Wat te doen als de API een fout teruggeeft?

Deze tabel dekt de varianten agentId en from - de statussen die alleen gelden voor een testgesprek zonder eigen nummer (systemPrompt) ontbreken bewust, dat is een andere werkwijze.

StatusCodeBetekenis
400invalid_numberHet veld to is geen geldig telefoonnummer.
400validationagentId/from ontbreekt of beide zijn ingesteld; of variables overschrijden hun limieten, of ringingTimeoutSecs ligt buiten 5 tot 60.
400on_dncHet nummer staat op uw bel-me-niet-lijst (/v1/dnc).
400destination_auto_blockedDeze bestemming is na herhaalde mislukkingen automatisch voor 30 dagen geblokkeerd.
400cannot_call_own_numberLusbeveiliging - u kunt uw eigen volai-nummer niet bellen.
404agent_not_foundagentId bestaat niet of hoort niet bij uw account.
404agent_no_numberAan de agent is geen telefoonnummer toegewezen.
404bridge_needs_numberVoor de variant met from: u hebt minstens één volai-nummer in uw account nodig.
409destination_busyNaar precies dit nummer loopt al een ander gesprek van u.
402insufficient_creditUw tegoed dekt het minimum voor het starten van een gesprek niet.
503capacity_busyAlle lijnen voor uitgaande gesprekken zijn nu bezet, probeer het over een minuut opnieuw.

De algemene API-limiet

Naast de tabel hierboven geldt voor de hele API één limiet: maximaal 60 verzoeken per minuut per API-sleutel (HTTP 429, rate_limited). Houd daar rekening mee in een workflow die tientallen nummers direct na elkaar belt - dezelfde limiet geldt voor POST /v1/messages en elk ander endpoint onder dezelfde sleutel.

Hoe nu verder

Een volledig overzicht van wat u vanuit n8n kunt doen (sms, nummers, bel-me-niet-lijst) vindt u in de handleiding voor de n8n-integratie. De volledige REST-referentie staat op /docs/api, de volledige lijst van webhookgebeurtenissen inclusief handtekeningcontrole op /docs/webhooky.

Probeer volai - de eerste 50 kr zijn van ons

U maakt in een minuut een account aan en hebt direct starttegoed voor gesprekken en een nummer - sms'en kunt u na de eerste opwaardering.

Gratis proberen