SMS brána přes API za 10 minut v Node.js
2. 9. 2026 · 6 minut čtení · Aktualizováno 9. 10. 2026
Abys z Node.js poslal SMS, stačí jeden POST požadavek na https://volai.cz/v1/messages s hlavičkou Authorization: Bearer vk_... a JSON tělem {to, body}. Node 20 má fetch vestavěný, takže nepotřebuješ žádný balíček navíc. Funkční příklad je hned pod tímhle odstavcem, včetně ošetření chyb a idempotence, aby ti výpadek sítě neposlal stejnou zprávu dvakrát.
Co budeš potřebovat
- Node.js 18 nebo novější -
fetchje ve vestavěné knihovně už od téhle verze; doporučujeme aktuální podporovanou LTS řadu (24, stav k 2. 9. 2026). - Účet na volai a API klíč z portálu (Nastavení -> API a MCP), ve tvaru
vk_.... - Aspoň jedno dobití kreditu. SMS jdou až po prvním dobití, uvítací kredit na ně použít nejde - hovory si z něj vyzkoušíš, textovku ne.
- Telefonní číslo příjemce v Česku nebo na Slovensku (
+420nebo+421) - do jiných zemí SMS neposíláme. - Vlastní telefonní číslo NEPOTŘEBUJEŠ. Zprávy odcházejí pod sdíleným jménem
SMSinfo- operátoři pro české sítě povolují jen schválená jména, vlastní jméno odesílatele u sdíleného odesílatele nastavit nejde a na SMSinfo příjemce odpovědět nemůže. Svou identitu proto napiš přímo do textu zprávy, tak jako v příkladu níž. Chceš-li, aby šlo odpovědět, pošli zprávu z vlastního SMS čísla (doplněk, viz upozornění níž).
Pošli první SMS
Requestu stačí dvě pole: to (číslo příjemce) a body (text zprávy). Odpověď vrátí id zprávy, status, cenu v haléřích (priceHal) a počet segmentů (segments) - k oběma se za chvíli vrátíme.
const response = await fetch("https://volai.cz/v1/messages", {
method: "POST",
headers: {
Authorization: "Bearer vk_TVUJ_KLIC",
"Content-Type": "application/json",
},
body: JSON.stringify({
to: "+420777123456",
body: "Ahoj z volai! - Moje Appka",
}),
});
if (!response.ok) {
const { error } = await response.json();
throw new Error("volai " + error.code + ": " + error.message);
}
const message = await response.json();
console.log(message);
// { id: "msg_7c1f9a2e", status: "sent", priceHal: 136, segments: 1 }Kolik stojí SMS a co jsou segmenty?
Jedna SMS do jednoho segmentu stojí 1,36 Kč bez DPH (cena platná k 2. 9. 2026). Kolik segmentů zpráva zabere, závisí na tom, jestli obsahuje diakritiku - operátoři počítají SMS podle standardu GSM 03.38:
| Kódování | Znaků v 1. segmentu | Znaků v dalších dílech |
|---|---|---|
| GSM-7 (bez diakritiky) | 160 | 153 |
| UCS-2 (s diakritikou) | 70 | 67 |
Stačí JEDEN znak mimo základní GSM-7 abecedu - typicky česká diakritika (ě š č ř ž ý á í ů ď ť ň) - a celá zpráva přepne na UCS-2, i kdyby byl ve zprávě jen jeden háček. Tip: chceš-li se spolehlivě vejít do jednoho segmentu, piš bez diakritiky.
Příklad: zpráva s diakritikou nad 70 znaků
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č:
await fetch("https://volai.cz/v1/messages", {
method: "POST",
headers: {
Authorization: "Bearer vk_TVUJ_KLIC",
"Content-Type": "application/json",
},
body: JSON.stringify({
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 }Idempotence: bezpečné opakování požadavku
Pošli navíc hlavičku Idempotency-Key s libovolným vlastním řetězcem, třeba ID objednávky. Když požadavek selže na výpadku sítě a workflow ho zopakuje se STEJNOU hlavičkou, volai vrátí uloženou odpověď z prvního pokusu a zprávu neodešle podruhé - klíč platí 24 hodin.
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": "Vaše objednávka č. 4471 byla přijata."}'Bezpečně zacházej s API klíčem
API klíč (vk_...) má stejnou váhu jako heslo - kdokoli ho zná, může tvým jménem posílat zprávy a utrácet kredit z tvého účtu. Do zdrojového kódu, který commitneš do repozitáře, ho proto nepiš nikdy. Patří do proměnné prostředí (process.env.VOLAI_API_KEY v Node.js) nebo do správce tajemství, který používá tvůj hosting.
// .env.local (nikdy necommituj do repozitáře)
// VOLAI_API_KEY=vk_tvuj_klic
const response = await fetch("https://volai.cz/v1/messages", {
method: "POST",
headers: {
Authorization: "Bearer " + process.env.VOLAI_API_KEY,
"Content-Type": "application/json",
},
body: JSON.stringify({ to, body }),
});Endpoint volej vždy ze serveru, ne z prohlížeče - kdokoli by si klíč přečetl v developerských nástrojích prohlížeče a začal na tvůj účet posílat vlastní zprávy. Uniknul-li klíč (třeba omylem v commitu), vygeneruj si v portálu nový a ten starý zneplatni - stará hodnota přestane fungovat okamžitě.
Vyzkoušej to nejdřív bezpečně
Než napojíš odesílání SMS na skutečný proces (třeba potvrzení objednávky), pošli první pár zpráv na vlastní telefonní číslo. Uvidíš přesně to, co uvidí zákazník - jak vypadá odesílatel SMSinfo, jak dlouho doručení trvá a jestli se diakritika počítá tak, jak čekáš. Teprve pak přepni to na skutečné číslo zákazníka.
Co dělat, když API vrátí chybu?
Neúspěšná odpověď má vždy tvar {error: {code, message}} a HTTP status podle typu chyby:
| Stav | Kód | Co to znamená |
|---|---|---|
| 400 | invalid_number | To není platné české nebo slovenské telefonní číslo. |
| 400 | invalid_body | Text zprávy musí mít 1 až 765 znaků. |
| 400 | unsupported_country | Číslo mimo ČR/SR, SMS tam neposíláme. |
| 400 | recipient_cannot_receive_sms | Pevná linka - SMS by nedorazila. Nic se neúčtuje. |
| 402 | insufficient_credit | Kredit nepokryje cenu všech segmentů zprávy, nebo účet ještě nedobil kredit - SMS jdou až po prvním dobití, uvítací kredit na ně použít nejde. |
| 429 | rate_limited | Víc než 1 SMS za 2 vteřiny, nebo přes 100 SMS na účet denně. |
| 502 | send_failed | Telefonní síť žádost odmítla. Kredit se nestrhl, zkus to znovu. |
| 502 | send_unknown | Zprávu jsme předali síti, potvrzení nedorazilo - účtuje se, neposílej ji prosím znovu naslepo. |
Jaké stavy může zpráva mít?
Pole status ve výpisu (GET /v1/messages) i v detailu jedné zprávy nabývá pěti hodnot: pending (uložená, ještě se odesílá), sent (operátor odeslání potvrdil), failed (operátor odmítl - neúčtuje se), unknown (potvrzení o doručení nedorazilo, typicky timeout na straně operátora - přesto se účtuje plnou cenou, protože zpráva mohla dojít) a received (jen u zpráv přijatých na SMS čísle, tedy s direction=in; odeslané zprávy ho nemají).
Každá zpráva nese i pole direction (out u odeslaných, in u přijatých), smsNumber (SMS číslo, ze kterého zpráva odešla nebo na které přišla; u zpráv pod sdíleným jménem SMSinfo je null) a deliveryStatus (delivered nebo undelivered, doručenka od operátora; vzniká jen u SMS odeslaných ze SMS čísla, u ostatních zpráv je null).
Jak rozeslat víc SMS najednou?
Rate limit dovoluje nejvýš jednu SMS za dvě vteřiny na účet a nejvýš 100 SMS denně. Pro rozeslání víc zpráv najednou (třeba připomínek schůzek) je jednodušší mezi požadavky krátce počkat, než chytat rate_limited a zkoušet znovu:
const messageText = "Připomínáme zítřejší termíny - Moje Appka";
for (const to of recipients) {
const response = await fetch("https://volai.cz/v1/messages", {
method: "POST",
headers: {
Authorization: "Bearer vk_TVUJ_KLIC",
"Content-Type": "application/json",
},
body: JSON.stringify({ to, body: messageText }),
});
if (!response.ok) {
const { error } = await response.json();
console.error("volai " + to + ": " + error.code);
}
// Limit je nejvýš 1 SMS za 2 vteřiny na účet - krátká pauza mezi
// požadavky je jednodušší než řešit rate_limited a zkoušet znovu.
await new Promise((resolve) => setTimeout(resolve, 2100));
}Příjem SMS umí jen doplněk SMS číslo
Hlasová čísla volai SMS nepřijímají, takže odpověď na zprávu odeslanou pod sdíleným jménem SMSinfo se nikde neobjeví. Chceš-li SMS přijímat a odesílat z vlastního čísla, přikup si doplněk SMS číslo: české mobilní číslo jen pro SMS, bez hovorů, 390 Kč na 30 dní bez DPH, přijaté SMS jsou v ceně. Přijaté zprávy přečteš v GET /v1/messages?direction=in, v MCP nástroji list_messages nebo ve webhooku message.received a uchováváme je 90 dní; odeslání z čísla stojí 1,90 Kč za segment a jde jen na česká čísla. Z čísla pošleš SMS polem fromNumber v POST /v1/messages (číslo vezmi z GET /v1/sms-numbers). Denní strop odeslání z čísla je 20 SMS na účet v prvních 30 dnech od koupě čísla, potom 50. Na účtu mohou být nejvýš dvě SMS čísla a koupit je jde až po prvním dobití kreditu. Ověřovací kódy od služeb (banky, Google a podobně) nezaručujeme, číslo je určené pro psaní s lidmi a příjem jsme ověřili na síti O2. Podrobnosti jsou v sekci SMS čísla v dokumentaci API. Kdy je pro příjem SMS lepší volba Twilio, popisuje srovnání Twilio a volai.
Shrnutí: jeden POST /v1/messages s poli to a body pošle SMS, hlavička Idempotency-Key ochrání workflow před dvojím odesláním při opakování požadavku a cena se počítá po segmentech podle toho, jestli text obsahuje diakritiku. Klíč drž mimo repozitář a nejdřív si pošli zprávu sám sobě.
Co dál
Plná reference REST API (čísla, hovory, webhooky, agenti) je na /docs/api. Chceš vědět hned, jakmile volai zprávu předá operátorovi, bez pollování GET /v1/messages? Přihlas se k odběru události message.sent - potvrzuje jen převzetí operátorem, ne doručení do telefonu (u zpráv pod sdíleným jménem to volai nevidí, viz výš; zprávy odeslané z vlastního SMS čísla mají doručenku) - viz dokumentace webhooků. A pokud kromě SMS potřebuješ i telefonní číslo, které samo zvedá hovory, mrkni na AI recepční.
Vyzkoušej volai - prvních 50 Kč na nás
Založíš účet za minutu a rovnou máš na kontě startovní kredit na hovory a číslo - SMS pošleš po prvním dobití.
Související články
Pět otázek, na které se lidé ptají, než si pořídí AI recepční
Cena, spuštění za 5 minut, přesměrování čísla u O2/T-Mobilu/Vodafonu, slovenská čísla a DPH - pět odpovědí přímo z ceníku a nastavení volai.
Jak zavolat zákazníkovi z n8n workflow
Zavolej zákazníkovi přímo z n8n: HTTP Request node na REST API volai, proměnné z workflow v promptu agenta a výsledek hovoru zpátky webhookem.
Jak dát Claude Code telefonní číslo přes MCP
Nainstaluj volai do Claude Code jedním příkazem, dej mu telefonní číslo a nech ho zavolat i poslat SMS jen promptem - bez psaní kódu, bez API dokumentace.