Fazer chamadas a partir de um workflow do n8n
September 2, 2026 · 7 min de leitura
É possível ligar a um cliente a partir do n8n sem escrever uma única linha de código: adicione ao workflow um nó HTTP Request, aponte-o para POST https://volai.cz/v1/calls com o cabeçalho Authorization: Bearer vk_... e um corpo com {to, agentId} - e o seu agente de voz marca o número exatamente quando o workflow o exigir. Segue-se a configuração completa: como passar os dados do workflow para o prompt do agente, como devolver o resultado da chamada ao n8n e como ligar sem agente, unindo diretamente dois números.
O que vai precisar
- Uma instância do n8n - na cloud ou auto-alojada, qualquer versão recente.
- Uma conta volai e uma chave de API do portal (Definições -> API e MCP), no formato
vk_.... Guarde-a no n8n como credencial Header Auth (cabeçalhoAuthorization, valorBearer vk_...), para não ter de copiar a chave para cada nó. - Um número próprio com um agente de voz associado - crie-o no portal ou através de /docs/agent. Ainda não tem agente? Pode ligar na mesma, unindo diretamente dois números (a variante com
fromabaixo).
1Adicionar um nó HTTP Request
Método POST, URL https://volai.cz/v1/calls, autenticação através da credencial guardada, Body Content Type JSON. O corpo precisa de to (o número do cliente) e agentId (o id do agente no portal) - ambos obrigatórios - e de exatamente UM de agentId/from/systemPrompt, nunca mais do que um.
{
"to": "={{ $json.phone }}",
"agentId": "ag_kx91fa2b",
"variables": {
"customer_name": "={{ $json.name }}",
"order_number": "={{ $json.order }}"
},
"ringingTimeoutSecs": 30
}Os valores escritos como ={{...}} são expressões do n8n - $json lê campos do nó anterior do workflow (por exemplo, um webhook de «nova encomenda» ou uma linha de uma folha de cálculo).
2Passar os dados do workflow para o prompt do agente
variables é um objeto de texto para texto que o agente recebe como variáveis dinâmicas - no prompt de sistema, refira-se a elas como {{customer_name}}. Limites: no máximo 20 chaves, chaves até 64 carateres, valores até 512 carateres. Os nomes attempt_id, caller_number e called_number são reservados - a volai preenche-os por si, e os valores equivalentes vindos do workflow seriam descartados.
ringingTimeoutSecs (de 5 a 60 segundos, por omissão 25) define durante quanto tempo o telefone toca antes de uma chamada sem resposta terminar com endReason: "no_answer". Um tempo limite maior aumenta a probabilidade de o cliente atender, mas também ocupa mais tempo uma linha de saída.
3Ler a resposta e, se quiser, aguardar o resultado
A resposta de sucesso chega logo, mas a chamada acabou de começar - status é initiated, não um estado final:
{
"id": "c_9d4e2b7f",
"status": "initiated"
}Prefere esperar pelo resultado na mesma execução do workflow, em vez de um webhook separado? Adicione um segundo nó logo a seguir ao HTTP Request, que chame GET /v1/calls/{id} com o parâmetro waitSecs (de 0 a 45 segundos) - o servidor responde quando a chamada termina ou quando o tempo limite é atingido, o que acontecer primeiro:
curl "https://volai.cz/v1/calls/c_9d4e2b7f?waitSecs=30" \
-H "Authorization: Bearer vk_YOUR_KEY"Receber o resultado: um webhook para o n8n
Num workflow de produção costuma ser mais prático não esperar em linha e receber o resultado em separado: adicione um nó Webhook no n8n (um workflow novo serve), copie o respetivo Production URL e registe-o uma só vez na 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"]
}'A resposta inclui um secret (no formato whsec_...) - guarde-o, pois vai precisar dele para verificar a assinatura de cada pedido recebido. A volai envia um cabeçalho Volai-Signature no formato t=<unix>,v1=<hex> - o código completo de verificação em TypeScript e Python encontra-se em /docs/webhooky. Não pode ser transposto sem alterações para um nó Code do n8n: o HMAC é calculado sobre o corpo BRUTO do pedido, pelo que tem de ativar a opção Raw Body no nó Webhook (sem ela, o n8n entrega JSON já interpretado e a assinatura nunca coincide) e importar crypto no nó Code com require, não com import. Não processe o corpo antes de verificar a assinatura.
O que chega quando a chamada termina:
{
"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": "Boa tarde, ligo a propósito da encomenda A-42." },
{ "role": "caller", "message": "Sim, já sei, obrigado pelo lembrete." }
],
"summary": "O cliente confirmou a receção da encomenda A-42.",
"data": {
"order_confirmed": true
}
}
}A chave data aninhada dentro de data é opcional e contém exatamente os campos que configurou no agente em dataFields - o exemplo acima (order_confirmed) é apenas ilustrativo, os seus serão outros. Um nó seguinte do n8n pode então ramificar com base nesses campos, por exemplo para atualizar um registo no CRM ou reagendar a chamada.
Como ligar sem agente?
Quando não precisa de um agente de voz, apenas de uma ligação direta entre dois números (por exemplo, um comercial e um cliente), envie from em vez de agentId:
{
"to": "+420777123456",
"from": "+420601234567"
}A volai liga primeiro para from e, quando alguém atende, marca to. Os dois troços são faturados em separado a 0.92 CZK por minuto (sem suplemento do agente). from é o número onde ATENDE - normalmente o seu telemóvel - e pode ser qualquer número checo ou eslovaco, não tem de pertencer à sua conta volai. O requisito real é outro: a conta precisa de pelo menos um número volai próprio, porque é por ele que a chamada é faturada e é ele que os dois lados veem no ecrã (sem isso, a volai devolve bridge_needs_number). Apenas não coloque em from um número volai encaminhado para um agente ou para SIP - a rede ligaria esse primeiro troço ao agente em vez de a si, e a chamada nunca tocaria no seu telefone.
Quanto custa uma chamada destas?
Uma chamada efetuada através de um agente é faturada como a soma de duas tarifas: o minuto de chamada efetuada (0.92 CZK) mais o suplemento do agente POR CIMA (2.50 CZK), ambos segundo a tabela de preços de 2 de setembro de 2026. Uma chamada de 90 segundos sai por 5.13 CZK:
| Item | Tarifa | Chamada de 90 s |
|---|---|---|
| Minuto de chamada efetuada | 0.92 CZK/min | 1.38 CZK |
| Suplemento do agente | 2.50 CZK/min | 3.75 CZK |
| Total | 5.13 CZK |
A faturação é feita ao segundo, não por minuto inteiro - uma chamada mais curta custa proporcionalmente menos. A tabela de preços completa (números, agente, SMS) está em /cenik.
Repetir em segurança (Idempotency-Key)
O n8n pode repetir automaticamente um nó em caso de falha (Retry On Fail) - sem salvaguarda, isso significaria duas chamadas telefónicas reais ao mesmo cliente. Adicione um cabeçalho Idempotency-Key com um valor estável durante uma execução do workflow (o n8n expõe-no como {{ $execution.id }}, ou use o id da sua encomenda) - com a mesma chave, nas 24 horas seguintes recebe a resposta da primeira tentativa e a chamada não é efetuada duas vezes:
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"}'O que fazer quando a API devolve um erro?
Esta tabela cobre as variantes agentId e from - os estados específicos de uma chamada de teste sem número próprio ( systemPrompt) ficam propositadamente de fora, por ser outro fluxo.
| Estado | Código | Significado |
|---|---|---|
| 400 | invalid_number | O campo to não é um número de telefone válido. |
| 400 | validation | Falta agentId/from, ou ambos estão definidos; ou variables excede os limites, ou ringingTimeoutSecs está fora do intervalo de 5 a 60. |
| 400 | on_dnc | O número está na sua lista de números a não contactar (/v1/dnc). |
| 400 | destination_auto_blocked | Este destino foi bloqueado automaticamente durante 30 dias após falhas repetidas. |
| 400 | cannot_call_own_number | Proteção contra ciclos - não pode ligar para o seu próprio número volai. |
| 404 | agent_not_found | agentId não existe ou não pertence à sua conta. |
| 404 | agent_no_number | O agente não tem nenhum número de telefone atribuído. |
| 404 | bridge_needs_number | Para a variante from: a conta precisa de pelo menos um número volai. |
| 409 | destination_busy | Já tem outra chamada em curso para esse mesmo número. |
| 402 | insufficient_credit | O seu saldo não cobre o mínimo necessário para iniciar uma chamada. |
| 503 | capacity_busy | Todas as linhas de saída estão ocupadas neste momento, tente de novo dentro de um minuto. |
O limite geral da API
Além da tabela acima, aplica-se um limite em toda a API: no máximo 60 pedidos por minuto por chave de API (HTTP 429, rate_limited). Tenha-o em conta num workflow que marque dezenas de números seguidos - o mesmo limite aplica-se a POST /v1/messages e a todos os outros endpoints sob a mesma chave.
Próximos passos
Um resumo completo do que pode fazer a partir do n8n (SMS, números, lista de números a não contactar) encontra-se no guia de integração com o n8n. A referência REST completa está em /docs/api, e a lista completa de eventos de webhook com verificação de assinatura em /docs/webhooky.
Experimente a volai - os primeiros 50 kr são nossos
Registe-se em um minuto e a sua conta já tem saldo inicial para chamadas e um número - os SMS funcionam depois do primeiro carregamento.
O que se segue
Artigos relacionados
Cinco perguntas antes de adquirir uma rececionista com IA
Preço, arranque em 5 minutos, reencaminhamento na O2/T-Mobile/Vodafone, números eslovacos e IVA - cinco respostas diretamente do preçário e das definições.
Enviar SMS por API em 10 minutos com Node.js
Envie SMS a partir de Node.js com a API REST da volai: uma chamada fetch a POST /v1/messages, idempotência, tratamento de erros e o preço exato por segmento.
Agente ElevenLabs num número checo através de SIP
Passo a passo: ligue um agente ElevenLabs do seu próprio workspace a um número checo da volai através de SIP trunk - chamadas recebidas e efetuadas.