Ringa en kund från ett n8n-workflow
September 2, 2026 · 7 min läsning
Från n8n går det att ringa en kund utan en enda rad kod: lägg till en HTTP Request-nod i workflowet, ställ in den på POST https://volai.cz/v1/calls med headern Authorization: Bearer vk_... och en body med {to, agentId} - så ringer röstagenten upp numret exakt när workflowet behöver det. Nedan finns hela upplägget: hur data från workflowet mappas in i agentens prompt, hur samtalets resultat tas tillbaka in i n8n och hur man ringer helt utan agent, genom att koppla ihop två nummer direkt.
Det här behövs
- En n8n-instans - molnet eller egen drift, vilken aktuell version som helst.
- Ett konto i volai och en API-nyckel från portalen (Inställningar -> API och MCP), på formen
vk_.... Spara den i n8n som en credential av typen Header Auth (headerAuthorization, värdeBearer vk_...) så slipper nyckeln kopieras in i varje nod för sig. - Ett eget telefonnummer med en röstagent - skapa det i portalen eller via /docs/agent. Utan agent går det ändå att ringa genom att koppla ihop två nummer direkt (varianten
fromnedan).
1Lägg till en HTTP Request-nod
Metod POST, URL https://volai.cz/v1/calls, autentisering via den sparade credentialen, Body Content Type JSON. I bodyn ska to (kundens nummer) och agentId (agentens ID från portalen) finnas med - båda är obligatoriska, och exakt ETT av agentId/from/systemPrompt ska anges, aldrig flera samtidigt.
{
"to": "={{ $json.phone }}",
"agentId": "ag_kx91fa2b",
"variables": {
"customer_name": "={{ $json.name }}",
"order_number": "={{ $json.order }}"
},
"ringingTimeoutSecs": 30
}Värden som skrivs som ={{...}} är n8n-uttryck - $json läser fält från föregående nod i workflowet (till exempel en webhook för "ny order" eller en rad i ett kalkylblad).
2Mappa data från workflowet in i agentens prompt
variables är ett objekt av typen sträng till sträng som agenten tar emot som dynamiska variabler - i systemprompten hänvisas det till dem som {{customer_name}}. Begränsningar: högst 20 nycklar, nycklar upp till 64 tecken, värden upp till 512 tecken. Namnen attempt_id, caller_number och called_number är reserverade - volai fyller i dem själv, och värden med samma namn från workflowet skulle kasseras.
ringingTimeoutSecs (5 till 60 sekunder, standard 25) anger hur länge telefonen får ringa innan ett obesvarat samtal avslutas med endReason: "no_answer". En längre tidsgräns ökar chansen att kunden hinner svara, men håller också en utgående plats upptagen längre.
3Läs svaret och vänta eventuellt på resultatet
Ett lyckat svar kommer direkt, men samtalet har då precis bara börjat - status är initiated, inte en slutstatus:
{
"id": "c_9d4e2b7f",
"status": "initiated"
}Om resultatet ska avvaktas i samma körning av workflowet i stället för via en separat webhook, lägg till en andra nod direkt efter HTTP Request-noden som anropar GET /v1/calls/{id} med parametern waitSecs (0 till 45 sekunder) - servern svarar när samtalet har avslutats eller när tidsgränsen nåtts, beroende på vilket som inträffar först:
curl "https://volai.cz/v1/calls/c_9d4e2b7f?waitSecs=30" \
-H "Authorization: Bearer vk_YOUR_KEY"Resultatet tillbaka: en webhook in i n8n
För ett produktionsworkflow är det oftast praktiskare att inte vänta i samma körning utan i stället få resultatet levererat separat: lägg till en Webhook-nod i n8n (ett nytt workflow fungerar bra), kopiera dess Production URL och registrera den en gång i volai:
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"]
}'Svaret innehåller en secret (på formen whsec_...) - spara den, den behövs för att verifiera signaturen på varje inkommande förfrågan. volai skickar en header Volai-Signature på formen t=<unix>,v1=<hex> - den fullständiga verifieringskoden i TypeScript och Python finns på /docs/webhooky. Den går inte att flytta oförändrad till en Code-nod i n8n: HMAC beräknas över den RÅA förfrågningskroppen, så alternativet Raw Body måste slås på på Webhook-noden (utan det lämnar n8n över redan tolkad JSON och signaturen stämmer aldrig), och modulen crypto ska importeras i Code-noden med require, inte med import. Bearbeta inte bodyn innan signaturen är verifierad.
Det här kommer in när samtalet är klart:
{
"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": "Hej, jag ringer angående order A-42." },
{ "role": "caller", "message": "Ja, jag vet, tack för påminnelsen." }
],
"summary": "Kunden bekräftade att order A-42 har mottagits.",
"data": {
"order_confirmed": true
}
}
}Nyckeln data inuti data är valfri och innehåller exakt de fält som konfigurerats för agenten i dess dataFields - exemplet ovan (order_confirmed) är enbart illustrativt, de egna fälten blir andra. En följande n8n-nod kan sedan förgrena på de här fälten, till exempel för att uppdatera en CRM-post eller boka om samtalet.
Hur ringer man utan agent?
När ingen röstagent behövs, bara en direkt förbindelse mellan två nummer (till exempel en säljare och en kund), skickas from i stället för agentId:
{
"to": "+420777123456",
"from": "+420601234567"
}volai ringer först upp from, och så fort någon svarar slås to. Båda samtalsbenen debiteras separat med 0,92 kr per minut (utan agenttillägg). from är numret där DU svarar - vanligtvis den egna mobilen - och det kan vara vilket tjeckiskt eller slovakiskt nummer som helst, det behöver inte tillhöra kontot i volai. Det verkliga kravet är ett annat: kontot måste ha minst ett eget nummer i volai, eftersom samtalet debiteras via det och eftersom det är det nummer som visas i displayen för båda parter (utan det returnerar volai felet bridge_needs_number). Lägg bara inte in ett volai-nummer som är dirigerat till en agent eller till SIP i from - nätet skulle koppla det första benet till agenten i stället för till dig, och samtalet skulle aldrig ringa på din telefon.
Vad kostar ett sådant samtal?
Ett utgående samtal via en agent debiteras som summan av två taxor: den utgående minuten (0,92 kr) plus agenttillägget OVANPÅ den (2,50 kr), båda enligt prislistan per den 2 september 2026. Ett samtal på 90 sekunder blir därmed 5,13 kr:
| Post | Taxa | Samtal på 90 s |
|---|---|---|
| Utgående minut | 0,92 kr/min | 1,38 kr |
| Agenttillägg | 2,50 kr/min | 3,75 kr |
| Totalt | 5,13 kr |
Debiteringen sker per sekund, inte per påbörjad minut - ett kortare samtal kostar proportionellt mindre. Hela prislistan (nummer, agent, sms) finns på /cenik.
Säkra omförsök (Idempotency-Key)
n8n kan automatiskt göra om en nod vid fel (Retry On Fail) - utan skydd skulle det betyda två verkliga telefonsamtal till samma kund. Lägg till headern Idempotency-Key med ett värde som är stabilt under en körning av workflowet (n8n erbjuder det som {{ $execution.id }}, eller använd ett eget order-ID) - med samma nyckel inom 24 timmar kommer svaret från det första försöket tillbaka, och samtalet läggs inte två gånger:
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"}'Vad görs när API:t returnerar ett fel?
Tabellen gäller varianterna agentId och from - tillstånd som är specifika för ett provsamtal utan eget nummer (systemPrompt) har medvetet lämnats utanför, det är ett annat flöde.
| Status | Kod | Vad det betyder |
|---|---|---|
| 400 | invalid_number | Fältet to är inte ett giltigt telefonnummer. |
| 400 | validation | agentId/from saknas, eller båda är angivna; eller variables överskrider sina gränser, eller ringingTimeoutSecs ligger utanför intervallet 5 till 60. |
| 400 | on_dnc | Numret finns i ring-inte-listan (/v1/dnc). |
| 400 | destination_auto_blocked | Destinationen har efter upprepade misslyckanden blockerats automatiskt i 30 dagar. |
| 400 | cannot_call_own_number | Skydd mot slingor - det går inte att ringa till det egna volai-numret. |
| 404 | agent_not_found | agentId finns inte eller tillhör inte kontot. |
| 404 | agent_no_number | Agenten har inget tilldelat telefonnummer. |
| 404 | bridge_needs_number | För varianten from: kontot måste ha minst ett eget nummer i volai. |
| 409 | destination_busy | Ett annat samtal till samma nummer pågår redan. |
| 402 | insufficient_credit | Saldot täcker inte minimibeloppet för att starta ett samtal. |
| 503 | capacity_busy | Alla utgående linjer är upptagna just nu, försök igen om en minut. |
Den allmänna API-gränsen
Utöver tabellen ovan gäller en gemensam gräns för hela API:t: högst 60 förfrågningar per minut per API-nyckel (HTTP 429, rate_limited). Det är värt att ha i åtanke i ett workflow som ringer dussintals nummer i följd - samma gräns gäller för POST /v1/messages och alla andra endpoints under samma nyckel.
Nästa steg
En fullständig genomgång av vad som går att göra från n8n (sms, nummer, ring-inte-listan) finns i guiden för n8n-integrationen. Den fullständiga REST-referensen finns på /docs/api, och den fullständiga listan över webhook-händelser med signaturverifiering finns på /docs/webhooky.
Testa volai - de första 50 kr bjuder vi på
Ett konto skapas på en minut och ett startsaldo för samtal och ett nummer finns direkt - sms går att skicka efter den första påfyllningen.
Vad händer härnäst
Relaterade artiklar
Fem frågor innan du skaffar en AI-receptionist
Pris, start på 5 minuter, vidarekoppling av nummer från O2/T-Mobile/Vodafone, slovakiska nummer och moms - fem svar direkt ur volais prislista och inställningar.
Sms-gateway via API på 10 minuter i Node.js
Så skickar du sms från Node.js via REST-API:et hos volai: ett fetch-anrop till POST /v1/messages, idempotens, felstatusar och exakt pris per meddelandesegment.
ElevenLabs-agent på ett tjeckiskt nummer via SIP
Steg för steg: koppla en ElevenLabs-agent i en egen arbetsyta till ett tjeckiskt volai-nummer via SIP-trunk - både inkommande och utgående samtal.