Napojení
REST API
Kompletní reference API v1. Vše je JSON, chyby mají jednotný tvar a peníze jsou vždy v haléřích - žádné desetinné zaokrouhlování na vlastní pěst.
Autentizace
Každý požadavek nese API klíč v hlavičce Authorization: Bearer vk_.... Klíč získáš v portálu v sekci API a MCP (podrobněji v Quickstartu).
curl https://volai.cz/v1/balance \
-H "Authorization: Bearer vk_TVUJ_KLIC"Formát chyb
Neúspěch má vždy stejný tvar, ať selže cokoli:
{
"error": {
"code": "insufficient_credit",
"message": "Nedostatečný kredit. Dobij si na /kredit."
}
}Tyhle čtyři se mohou objevit prakticky kdekoli - u jednotlivých endpointů níž jsou dopsané jen situační kódy navíc:
| HTTP | Kód | Význam |
|---|---|---|
| 401 | unauthorized | Chybí nebo je neplatná hlavička Authorization. |
| 402 | insufficient_credit | Na akci nezbývá dost kreditu. |
| 429 | rate_limited | Překročený rate limit - počkej podle hlavičky Retry-After. |
| 500 | internal_error | Chyba na naší straně - zkus to prosím znovu. |
400 (neplatný vstup) a 404 (záznam neexistuje) taky můžou přijít prakticky kdekoli, ale jejich code je specifický pro dané pole nebo endpoint - přesný výčet je vždy u konkrétního volání níž. Pár akcí navíc může vrátit 502 (chyba u externího poskytovatele - Odorik, ElevenLabs) nebo 503 (dočasně nedostupné, zkus to za chvíli).
Idempotence
POST /v1/messages a POST /v1/calls umí hlavičku Idempotency-Key. Pošli stejnou hodnotu při opakování požadavku (typicky po timeoutu, kdy nevíš, jestli první pokus prošel) a do 24 hodin dostaneš zpátky přesně tu samou odpověď jako napoprvé - SMS se neodešle ani hovor nezavolá podruhé. Klidně použij ID objednávky ze své appky.
curl -X POST https://volai.cz/v1/messages \
-H "Authorization: Bearer vk_TVUJ_KLIC" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: objednavka-4471" \
-d '{"to": "+420777123456", "body": "Děkujeme za objednávku."}'Rate limity
60 požadavků za minutu na jeden API klíč (MCP sdílí stejný limit - používá tentýž klíč). Po překročení přijde 429 a hlavička Retry-After s počtem vteřin do dalšího pokusu.
POST /v1/messages má navíc vlastní strop: nejvýš jedna SMS za 2 vteřiny a 100 SMS denně na účet.
Stránkování
GET /v1/messages a GET /v1/calls berou limit (kolik záznamů max) a before (ms timestamp - vrátí jen starší záznamy). Pro další stránku pošli jako before časové razítko posledního záznamu z předchozí stránky.
Kredit
GET/v1/balance
Aktuální zůstatek kreditu na účtu.
Požadavek
curl https://volai.cz/v1/balance \
-H "Authorization: Bearer vk_TVUJ_KLIC"Odpověď
{
"balanceHal": 8730,
"balanceCzk": 87.30,
"currency": "CZK"
}Čísla
GET/v1/numbers
Seznam telefonních čísel na účtu, u\u00A0každého aktuální směrování.
Požadavek
curl https://volai.cz/v1/numbers \
-H "Authorization: Bearer vk_TVUJ_KLIC"Odpověď
{
"numbers": [
{
"e164": "+420601234567",
"routing": { "mode": "agent", "agentId": "agent_kx91fa2b" },
"monthlyFeeHal": 2500,
"boughtAt": 1756111640000
}
]
}POST/v1/numbers
Koupí číslo. Prázdné tělo {} přiřadí kterékoli volné z aktuální nabídky, nebo pošli konkrétní { "e164": "..." } z GET /v1/numbers/available. Strhne se měsíční poplatek 25,00 Kč, směrování začíná na none - nastav ho hned dál přes PATCH.
Požadavek
curl -X POST https://volai.cz/v1/numbers \
-H "Authorization: Bearer vk_TVUJ_KLIC" \
-H "Content-Type: application/json" \
-d '{}'Odpověď
{
"number": {
"e164": "+420601234567",
"routing": { "mode": "none" },
"monthlyFeeHal": 2500,
"boughtAt": 1756111640000
}
}Chybové stavy
- 402
insufficient_creditKredit nepokryje měsíční poplatek 25,00 Kč. - 503
pool_emptyČísla nám právě došla, do hodiny doplníme.
GET/v1/numbers/available
Nabídka volných čísel k\u00A0zakoupení (max 5).
Požadavek
curl https://volai.cz/v1/numbers/available \
-H "Authorization: Bearer vk_TVUJ_KLIC"Odpověď
{
"numbers": ["+420601234567", "+420601234589", "+420601234610"]
}DELETE/v1/numbers/{e164}
Uvolní číslo zpátky do zásoby - odpojí směrování i\u00A0registraci u\u00A0agenta. Zaplacený měsíc se nevrací.
Požadavek
curl -X DELETE "https://volai.cz/v1/numbers/+420601234567" \
-H "Authorization: Bearer vk_TVUJ_KLIC"Odpověď
{
"released": true
}Chybové stavy
- 404
not_foundČíslo neexistuje nebo nepatří tvému účtu.
PATCH/v1/numbers/{e164}
Změní směrování čísla.
mode: "agent"+agentId- hovory bere hlasový agent.mode: "forward"+forwardTo(E.164) - přesměrování, platíš obě nohy.mode: "sip"+sipUri- směruje na tvůj SIP server (viz SIP).mode: "none"- číslo jen přijímá, nikam nesměruje.
Požadavek
curl -X PATCH "https://volai.cz/v1/numbers/+420601234567" \
-H "Authorization: Bearer vk_TVUJ_KLIC" \
-H "Content-Type: application/json" \
-d '{"routing": {"mode": "agent", "agentId": "agent_kx91fa2b"}}'Odpověď
{
"number": {
"e164": "+420601234567",
"routing": { "mode": "agent", "agentId": "agent_kx91fa2b" },
"monthlyFeeHal": 2500,
"boughtAt": 1756111640000
}
}Chybové stavy
- 400
validationrouting.mode vyžaduje odpovídající pole (agentId / forwardTo / sipUri). - 404
not_foundČíslo neexistuje nebo nepatří tvému účtu.
GET/v1/numbers/{e164}/sip
SIP přihlašovací údaje čísla - pro vlastní softphone nebo PBX. Nastavení krok za krokem je na stránce SIP.
Požadavek
curl "https://volai.cz/v1/numbers/+420601234567/sip" \
-H "Authorization: Bearer vk_TVUJ_KLIC"Odpověď
{
"server": "sip.odorik.cz",
"username": "123456",
"password": "a1b2c3d4e5f6"
}Chybové stavy
- 404
not_foundČíslo neexistuje nebo nepatří tvému účtu.
Zprávy
Příchozí SMS API nevidí
Operátor doručuje příchozí SMS jen na SIM kartu, ne do API - takže odpověď na tvoji zprávu se v GET /v1/messages ani ve webhooku neobjeví. Na obousměrnou komunikaci přes SMS zatím nespoléhej.
GET/v1/messages
Historie odeslaných SMS, od nejnovější.
Požadavek
curl "https://volai.cz/v1/messages?limit=20" \
-H "Authorization: Bearer vk_TVUJ_KLIC"Odpověď
{
"messages": [
{
"id": "msg_7c1f9a2e",
"to": "+420777123456",
"from": "volai",
"body": "Ahoj z volai! - Moje Appka",
"status": "sent",
"priceHal": 136,
"segments": 1,
"createdAt": 1756111500000,
"source": "api"
}
]
}POST/v1/messages
Odešle SMS. Jen česká a slovenská čísla (+420 / +421). Cena 1,36 Kč za segment - delší (nebo znaky mimo GSM-7 abecedu, typicky česká diakritika) zprávy se dělí na víc segmentů a platí se za každý zvlášť, viz segments v odpovědi.
Pole from je vždy pevné („volai“) - operátoři nedovolují nastavit vlastní jméno odesílatele SMS. Svou identitu proto napiš přímo do textu zprávy, tak jako v příkladu níž.
- Bez diakritiky (GSM-7 abeceda) se do jednoho segmentu vejde 160 znaků, delší text se dělí po 153.
- S diakritikou nebo jiným znakem mimo GSM-7 (UCS-2) je limit 70 znaků na segment, delší text se dělí po 67.
- Tip: chceš-li se vejít do jednoho segmentu, piš bez diakritiky -
Prilis zlutoucky kunmístoPříliš žluťoučký kůň.
Požadavek
curl -X POST https://volai.cz/v1/messages \
-H "Authorization: Bearer vk_TVUJ_KLIC" \
-H "Content-Type: application/json" \
-d '{"to": "+420777123456", "body": "Ahoj z volai! - Moje Appka"}'Odpověď
{
"id": "msg_7c1f9a2e",
"status": "sent",
"priceHal": 136,
"segments": 1
}Chybové stavy
- 400
invalid_numberTo není platné české nebo slovenské telefonní číslo. - 400
invalid_bodyText zprávy musí mít 1 až 765 znaků. - 400
unsupported_countryČíslo mimo ČR/SR - v MVP nepodporujeme. - 402
insufficient_creditKredit nepokryje cenu všech segmentů zprávy. - 429
rate_limitedVíc než 1 SMS za 2 vteřiny, nebo přes 100 SMS na účet dnes.
Příklad: zpráva s\u00A0diakritikou nad 70 znaků = víc segmentů
Tahle zpráva má 112 znaků a obsahuje diakritiku, takže se počítá jako UCS-2 (limit 67 znaků na segment u vícedílné zprávy) - vyjde na 2 segmenty, tedy 2,72 Kč, ne 1,36 Kč:
curl -X POST https://volai.cz/v1/messages \
-H "Authorization: Bearer vk_TVUJ_KLIC" \
-H "Content-Type: application/json" \
-d '{"to": "+420777123456", "body": "Příliš žluťoučký kůň úpěl ďábelské ódy - a tahle věta má přes sedmdesát znaků, takže spadne do druhého segmentu."}'{
"id": "msg_9a3f1c7d",
"status": "sent",
"priceHal": 272,
"segments": 2
}GET/v1/messages/{id}
Detail jedné zprávy.
Požadavek
curl https://volai.cz/v1/messages/msg_7c1f9a2e \
-H "Authorization: Bearer vk_TVUJ_KLIC"Odpověď
{
"message": {
"id": "msg_7c1f9a2e",
"to": "+420777123456",
"from": "volai",
"body": "Ahoj z volai! - Moje Appka",
"status": "sent",
"priceHal": 136,
"segments": 1,
"createdAt": 1756111500000,
"source": "api"
}
}Chybové stavy
- 404
not_foundZpráva neexistuje nebo nepatří tvému účtu.
Hovory
GET/v1/calls
Historie hovorů, od nejnovějšího. Volitelný parametr direction (in nebo out) omezí výpis jen na příchozí, nebo jen na odchozí hovory.
Požadavek
curl "https://volai.cz/v1/calls?limit=20" \
-H "Authorization: Bearer vk_TVUJ_KLIC"Odpověď
{
"calls": [
{
"id": "call_8f2ac1d4",
"direction": "in",
"from": "+420777123456",
"to": "+420601234567",
"status": "completed",
"startedAt": 1756111400000,
"durationSecs": 47,
"priceHal": 236,
"agentId": "agent_kx91fa2b",
"source": "inbound"
}
]
}POST/v1/calls
Odchozí hovor s hlasovým agentem - zavolá na to a vede konverzaci podle svého systemPrompt.
Požadavek
curl -X POST https://volai.cz/v1/calls \
-H "Authorization: Bearer vk_TVUJ_KLIC" \
-H "Content-Type: application/json" \
-d '{"to": "+420777123456", "agentId": "agent_kx91fa2b"}'Odpověď
{
"id": "call_9d4e2b7f",
"status": "initiated"
}Chybové stavy
- 400
invalid_numberto není platné telefonní číslo. - 404
agent_not_foundagentId neexistuje nebo nepatří tvému účtu. - 404
agent_no_numberAgent nemá přiřazené telefonní číslo. - 402
insufficient_creditKredit nepokryje minimum pro zahájení hovoru. - 503
capacity_busyVšechny odchozí linky jsou právě obsazené, zkus to za minutu.
Bez agenta: přímé spojení dvou čísel (bridge)
Místo agentId pošli from - vlastní číslo nebo jiné číslo zákazníka. volai nejdřív zavolá na from, a jakmile ho někdo zvedne, vytočí to. Obě nohy se účtují zvlášť po 0,92 Kč/min.
curl -X POST https://volai.cz/v1/calls \
-H "Authorization: Bearer vk_TVUJ_KLIC" \
-H "Content-Type: application/json" \
-d '{"to": "+420777123456", "from": "+420601234567"}'GET/v1/calls/{id}
Detail hovoru. U hovorů s agentem obsahuje navíc transcript (přepis po replikách) a summary (krátké shrnutí) - viz Webhooky pro stejný tvar doručený automaticky po skončení hovoru.
Požadavek
curl https://volai.cz/v1/calls/call_8f2ac1d4 \
-H "Authorization: Bearer vk_TVUJ_KLIC"Odpověď
{
"call": {
"id": "call_8f2ac1d4",
"direction": "in",
"from": "+420777123456",
"to": "+420601234567",
"status": "completed",
"startedAt": 1756111400000,
"durationSecs": 47,
"priceHal": 236,
"agentId": "agent_kx91fa2b",
"source": "inbound",
"transcript": [
{ "role": "agent", "message": "Dobrý den, tady recepce kavárny Nula, jak vám mohu pomoct?" },
{ "role": "caller", "message": "Chtěl bych si objednat dva latte s sebou." },
{ "role": "agent", "message": "Jasně, dva latte na vyzvednutí, bude to za patnáct minut." }
],
"summary": "Zákazník si objednal dva latte s sebou, vyzvednutí za 15 minut."
}
}Chybové stavy
- 404
call_not_foundHovor neexistuje nebo nepatří tvému účtu.
Agenti
GET/v1/agents
Seznam hlasových agentů na účtu.
Požadavek
curl https://volai.cz/v1/agents \
-H "Authorization: Bearer vk_TVUJ_KLIC"Odpověď
{
"agents": [
{
"id": "agent_kx91fa2b",
"name": "Recepční",
"systemPrompt": "Jsi recepční kavárny Nula. Přijímáš objednávky na vyzvednutí...",
"firstMessage": "Dobrý den, tady recepce kavárny Nula, jak vám mohu pomoct?",
"language": "cs",
"voiceId": "MpbYQvoTmXjHkaxtLiSh",
"numberE164": "+420601234567",
"createdAt": 1756111000000,
"status": "active"
}
]
}POST/v1/agents
Vytvoří nového hlasového agenta. Povinný je jen name a systemPrompt - jak takový prompt napsat dobře je na stránce Hlasový agent. Když pošleš numberE164, agent se na číslo rovnou napojí (nahradí jeho dosavadní směrování).
Požadavek
curl -X POST https://volai.cz/v1/agents \
-H "Authorization: Bearer vk_TVUJ_KLIC" \
-H "Content-Type: application/json" \
-d '{
"name": "Recepční",
"systemPrompt": "Jsi recepční kavárny Nula. Přijímáš objednávky na vyzvednutí a odpovídáš na otázky o otevírací době. Nikdy nevymýšlej ceny, které neznáš. Hovor ukonči shrnutím objednávky.",
"firstMessage": "Dobrý den, tady recepce kavárny Nula, jak vám mohu pomoct?",
"language": "cs",
"numberE164": "+420601234567"
}'Odpověď
{
"id": "agent_kx91fa2b"
}Chybové stavy
- 400
invalid_nameJméno agenta musí mít 1 až 60 znaků. - 400
invalid_system_promptInstrukce agenta musí mít 10 až 6000 znaků. - 400
invalid_languagelanguage musí být cs, sk, en, de nebo pl. - 400
agent_limitNa účtu už je maximální počet agentů. - 404
not_foundnumberE164 neexistuje nebo nepatří tvému účtu.
PATCH/v1/agents/{id}
Upraví existujícího agenta - stejná pole jako při vytvoření, všechna nepovinná. Pošli jen to, co se má změnit.
Požadavek
curl -X PATCH https://volai.cz/v1/agents/agent_kx91fa2b \
-H "Authorization: Bearer vk_TVUJ_KLIC" \
-H "Content-Type: application/json" \
-d '{"firstMessage": "Dobrý den, kavárna Nula, co si dáte?"}'Odpověď
{
"agent": {
"id": "agent_kx91fa2b",
"name": "Recepční",
"systemPrompt": "Jsi recepční kavárny Nula. Přijímáš objednávky na vyzvednutí...",
"firstMessage": "Dobrý den, kavárna Nula, co si dáte?",
"language": "cs",
"voiceId": "MpbYQvoTmXjHkaxtLiSh",
"numberE164": "+420601234567",
"createdAt": 1756111000000,
"status": "active"
}
}Chybové stavy
- 400
invalid_nameJméno agenta musí mít 1 až 60 znaků. - 400
invalid_system_promptInstrukce agenta musí mít 10 až 6000 znaků. - 400
invalid_languagelanguage musí být cs, sk, en, de nebo pl. - 404
agent_not_foundAgent neexistuje nebo nepatří tvému účtu.
DELETE/v1/agents/{id}
Smaže agenta u\u00A0volai i\u00A0u\u00A0ElevenLabs. Číslo, které na něj bylo navěšené, zůstává tvoje - jen mu nastav nové směrování přes PATCH /v1/numbers/{e164}.
Požadavek
curl -X DELETE https://volai.cz/v1/agents/agent_kx91fa2b \
-H "Authorization: Bearer vk_TVUJ_KLIC"Odpověď
{
"deleted": true
}Chybové stavy
- 404
agent_not_foundAgent neexistuje nebo nepatří tvému účtu.
Webhook
GET/v1/webhook
Aktuální nastavení odchozích webhooků - bez podpisového secretu, ten se vrací jen z\u00A0PUT.
Požadavek
curl https://volai.cz/v1/webhook \
-H "Authorization: Bearer vk_TVUJ_KLIC"Odpověď
{
"url": "https://tvoje-appka.cz/webhooks/volai",
"events": ["call.completed", "call.failed", "message.sent"]
}PUT/v1/webhook
Nastaví (nebo přepíše) cílovou URL a odebírané události. V odpovědi dostaneš i podpisový secret - ulož si ho hned, později ho GET už nevrátí. Postup ověření podpisu je na stránce Webhooky.
Požadavek
curl -X PUT https://volai.cz/v1/webhook \
-H "Authorization: Bearer vk_TVUJ_KLIC" \
-H "Content-Type: application/json" \
-d '{"url": "https://tvoje-appka.cz/webhooks/volai", "events": ["call.completed", "call.failed", "message.sent"]}'Odpověď
{
"url": "https://tvoje-appka.cz/webhooks/volai",
"secret": "whsec_9f2b7a1c4e6d8f0a",
"events": ["call.completed", "call.failed", "message.sent"]
}Chybové stavy
- 400
invalid_urlURL musí začínat https:// (http:// je povolené jen pro localhost). - 400
invalid_eventsNěkterá z events není známá (call.completed, call.failed, message.sent).