Přeskočit na obsah

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).

bash
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:

json
{
  "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:

HTTPKódVýznam
401unauthorizedChybí nebo je neplatná hlavička Authorization.
402insufficient_creditNa akci nezbývá dost kreditu.
429rate_limitedPřekročený rate limit - počkej podle hlavičky Retry-After.
500internal_errorChyba 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.

bash
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

bash
curl https://volai.cz/v1/balance \
  -H "Authorization: Bearer vk_TVUJ_KLIC"

Odpověď

json
{
  "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

bash
curl https://volai.cz/v1/numbers \
  -H "Authorization: Bearer vk_TVUJ_KLIC"

Odpověď

json
{
  "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

bash
curl -X POST https://volai.cz/v1/numbers \
  -H "Authorization: Bearer vk_TVUJ_KLIC" \
  -H "Content-Type: application/json" \
  -d '{}'

Odpověď

json
{
  "number": {
    "e164": "+420601234567",
    "routing": { "mode": "none" },
    "monthlyFeeHal": 2500,
    "boughtAt": 1756111640000
  }
}

Chybové stavy

  • 402insufficient_creditKredit nepokryje měsíční poplatek 25,00 Kč.
  • 503pool_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

bash
curl https://volai.cz/v1/numbers/available \
  -H "Authorization: Bearer vk_TVUJ_KLIC"

Odpověď

json
{
  "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

bash
curl -X DELETE "https://volai.cz/v1/numbers/+420601234567" \
  -H "Authorization: Bearer vk_TVUJ_KLIC"

Odpověď

json
{
  "released": true
}

Chybové stavy

  • 404not_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

bash
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ěď

json
{
  "number": {
    "e164": "+420601234567",
    "routing": { "mode": "agent", "agentId": "agent_kx91fa2b" },
    "monthlyFeeHal": 2500,
    "boughtAt": 1756111640000
  }
}

Chybové stavy

  • 400validationrouting.mode vyžaduje odpovídající pole (agentId / forwardTo / sipUri).
  • 404not_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

bash
curl "https://volai.cz/v1/numbers/+420601234567/sip" \
  -H "Authorization: Bearer vk_TVUJ_KLIC"

Odpověď

json
{
  "server": "sip.odorik.cz",
  "username": "123456",
  "password": "a1b2c3d4e5f6"
}

Chybové stavy

  • 404not_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

bash
curl "https://volai.cz/v1/messages?limit=20" \
  -H "Authorization: Bearer vk_TVUJ_KLIC"

Odpověď

json
{
  "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 kun místo Příliš žluťoučký kůň.

Požadavek

bash
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ěď

json
{
  "id": "msg_7c1f9a2e",
  "status": "sent",
  "priceHal": 136,
  "segments": 1
}

Chybové stavy

  • 400invalid_numberTo není platné české nebo slovenské telefonní číslo.
  • 400invalid_bodyText zprávy musí mít 1 až 765 znaků.
  • 400unsupported_countryČíslo mimo ČR/SR - v MVP nepodporujeme.
  • 402insufficient_creditKredit nepokryje cenu všech segmentů zprávy.
  • 429rate_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č:

bash
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."}'
json
{
  "id": "msg_9a3f1c7d",
  "status": "sent",
  "priceHal": 272,
  "segments": 2
}

GET/v1/messages/{id}

Detail jedné zprávy.

Požadavek

bash
curl https://volai.cz/v1/messages/msg_7c1f9a2e \
  -H "Authorization: Bearer vk_TVUJ_KLIC"

Odpověď

json
{
  "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

  • 404not_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

bash
curl "https://volai.cz/v1/calls?limit=20" \
  -H "Authorization: Bearer vk_TVUJ_KLIC"

Odpověď

json
{
  "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

bash
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ěď

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

Chybové stavy

  • 400invalid_numberto není platné telefonní číslo.
  • 404agent_not_foundagentId neexistuje nebo nepatří tvému účtu.
  • 404agent_no_numberAgent nemá přiřazené telefonní číslo.
  • 402insufficient_creditKredit nepokryje minimum pro zahájení hovoru.
  • 503capacity_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.

bash
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

bash
curl https://volai.cz/v1/calls/call_8f2ac1d4 \
  -H "Authorization: Bearer vk_TVUJ_KLIC"

Odpověď

json
{
  "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

  • 404call_not_foundHovor neexistuje nebo nepatří tvému účtu.

Agenti

GET/v1/agents

Seznam hlasových agentů na účtu.

Požadavek

bash
curl https://volai.cz/v1/agents \
  -H "Authorization: Bearer vk_TVUJ_KLIC"

Odpověď

json
{
  "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

bash
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ěď

json
{
  "id": "agent_kx91fa2b"
}

Chybové stavy

  • 400invalid_nameJméno agenta musí mít 1 až 60 znaků.
  • 400invalid_system_promptInstrukce agenta musí mít 10 až 6000 znaků.
  • 400invalid_languagelanguage musí být cs, sk, en, de nebo pl.
  • 400agent_limitNa účtu už je maximální počet agentů.
  • 404not_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

bash
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ěď

json
{
  "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

  • 400invalid_nameJméno agenta musí mít 1 až 60 znaků.
  • 400invalid_system_promptInstrukce agenta musí mít 10 až 6000 znaků.
  • 400invalid_languagelanguage musí být cs, sk, en, de nebo pl.
  • 404agent_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

bash
curl -X DELETE https://volai.cz/v1/agents/agent_kx91fa2b \
  -H "Authorization: Bearer vk_TVUJ_KLIC"

Odpověď

json
{
  "deleted": true
}

Chybové stavy

  • 404agent_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

bash
curl https://volai.cz/v1/webhook \
  -H "Authorization: Bearer vk_TVUJ_KLIC"

Odpověď

json
{
  "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

bash
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ěď

json
{
  "url": "https://tvoje-appka.cz/webhooks/volai",
  "secret": "whsec_9f2b7a1c4e6d8f0a",
  "events": ["call.completed", "call.failed", "message.sent"]
}

Chybové stavy

  • 400invalid_urlURL musí začínat https:// (http:// je povolené jen pro localhost).
  • 400invalid_eventsNěkterá z events není známá (call.completed, call.failed, message.sent).