Към съдържанието

Изпращане на SMS през API за 10 минути в Node.js

September 2, 2026 · 6 мин четене · Обновено на October 9, 2026

За да изпратите SMS от Node.js, е достатъчна една POST заявка към https://volai.cz/v1/messages със заглавие Authorization: Bearer vk_... и JSON тяло {to, body}. Node 20 има fetch вграден, така че не е нужен допълнителен пакет. Работещ пример следва веднага под този абзац, включително обработка на грешки и идемпотентност, за да не изпрати краткотраен срив на мрежата едно и също съобщение два пъти.

Какво ще Ви трябва

  • Node.js 18 или по-нова - fetch е вграден в стандартната библиотека от тази версия; препоръчваме актуалната поддържана LTS версия (24, към 2 септември 2026).
  • Акаунт във volai и API ключ от портала (Настройки -> API и MCP), във вида vk_....
  • Поне едно зареждане на баланса. SMS се изпращат едва след първото зареждане; приветственият баланс не ги покрива - с него можете да изпробвате обаждания, но не и текстови съобщения.
  • Телефонен номер на получателя в Чехия или Словакия (+420 или +421) - към други държави не изпращаме SMS.
  • НЕ Ви е нужен собствен телефонен номер. Съобщенията тръгват под споделеното име SMSinfo - операторите в чешките мрежи позволяват само одобрени имена, затова при споделения изпращач собствено име не може да се зададе, а получателят не може да отговори на SMSinfo. Затова напишете самоличността си направо в текста на съобщението, както в примера по-долу. Ако искате да може да се отговаря, изпращайте от собствен мобилен номер (добавка, вижте бележката по-долу).

Изпратете първото си SMS

На заявката са достатъчни две полета: to (номер на получателя) и body (текст на съобщението). Отговорът връща id на съобщението, status, цената в стотинки на кроната (priceHal) и броя сегменти (segments) - към двете ще се върнем след малко.

javascript
const response = await fetch("https://volai.cz/v1/messages", {
  method: "POST",
  headers: {
    Authorization: "Bearer vk_VASHIYAT_KLYUCH",
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    to: "+420777123456",
    body: "Здравейте от volai! - Моето приложение",
  }),
});

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 }

Колко струва едно SMS и какво са сегментите?

SMS в един сегмент струва 1.36 CZK без ДДС (цена към 2 септември 2026). Колко сегмента заема съобщението, зависи от това дали съдържа знаци извън азбуката GSM-7 - операторите делят SMS по стандарта GSM 03.38:

КодиранеЗнака в 1. сегментЗнака в следващите части
GSM-7 (обикновен латински текст)160153
UCS-2 (знаци с диакритики или нелатински знаци)7067

Достатъчен е ЕДИН знак извън основната азбука GSM-7 (букви с диакритики, емотикони, повечето нелатински писмености), за да премине ЦЯЛОТО съобщение в UCS-2, дори това да е единственият такъв знак в текста. Съвет: за да се вместите надеждно в един сегмент, използвайте само обикновени знаци от GSM-7. Кирилицата е извън GSM-7, затова съобщение на български винаги се брои като UCS-2.

Пример: съобщение над 70 знака

Това съобщение е с дължина 111 знака и съдържа знаци извън GSM-7, затова се брои като UCS-2 (67 знака на сегмент при многочастно съобщение) - излиза 2 сегмента, т.е. 2.72 CZK, а не 1.36 CZK:

javascript
await fetch("https://volai.cz/v1/messages", {
  method: "POST",
  headers: {
    Authorization: "Bearer vk_VASHIYAT_KLYUCH",
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    to: "+420777123456",
    body: "Напомняме Ви за утрешния час в 10:00 - ако датата не Ви е удобна, отговорете на съобщението и ще намерим друга.",
  }),
});
// -> { id: "msg_9a3f1c7d", status: "sent", priceHal: 272, segments: 2 }

Идемпотентност: безопасно повтаряне на заявка

Добавете заглавие Idempotency-Key с произволен низ по Ваш избор, например номер на поръчка. Ако заявката пропадне заради срив на мрежата и Вашият работен процес я повтори със СЪЩОТО заглавие, volai връща запазения отговор от първия опит и не изпраща съобщението втори път - ключът е валиден 24 часа.

bash
curl -X POST https://volai.cz/v1/messages \
  -H "Authorization: Bearer vk_VASHIYAT_KLYUCH" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: porachka-4471" \
  -d '{"to": "+420777123456", "body": "Вашата поръчка №4471 беше приета."}'

Пазете API ключа си

API ключът (vk_...) има същата тежест като парола - всеки, който го знае, може да изпраща съобщения от Ваше име и да харчи баланса на Вашия акаунт. Затова никога не го записвайте в изходен код, който качвате в хранилище. Мястото му е в променлива на средата (process.env.VOLAI_API_KEY в Node.js) или в мениджъра на тайни, който предлага Вашият хостинг.

javascript
// .env.local (никога не го качвайте в хранилището)
// VOLAI_API_KEY=vk_vashiyat_klyuch

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 }),
});

Извиквайте крайната точка винаги от сървър, никога от браузъра - всеки би могъл да прочете ключа в инструментите за разработчици на браузъра и да започне да изпраща съобщения от Вашия акаунт. Ако ключът изтече (например по погрешка в комит), генерирайте нов в портала и отменете стария - старата стойност спира да работи веднага.

Първо изпробвайте безопасно

Преди да вградите изпращането на SMS в реален процес (например потвърждения на поръчки), изпратете първите няколко съобщения на собствения си телефонен номер. Ще видите точно това, което ще види клиентът - как изглежда изпращачът SMSinfo, колко време отнема доставката и дали сегментирането се държи така, както очаквате. Едва тогава сменете to с реален номер на клиент.

Какво да направя, когато API върне грешка?

Неуспешният отговор винаги има вида {error: {code, message}} и HTTP статус според вида на грешката:

СтатусКодКакво означава
400invalid_numberТова не е валиден чешки или словашки телефонен номер.
400invalid_bodyТекстът на съобщението трябва да е от 1 до 765 знака.
400unsupported_countryНомер извън Чехия и Словакия, към тях не изпращаме SMS.
400recipient_cannot_receive_smsСтационарен номер - SMS не би могло да пристигне. Не се таксува.
402insufficient_creditБалансът не покрива цената на всички сегменти или акаунтът още не е зареждан - SMS се изпращат едва след първото зареждане, приветственият баланс не ги покрива.
429rate_limitedПовече от 1 SMS на 2 секунди или над 100 SMS на акаунт на ден.
502send_failedОператорът отхвърли заявката. Балансът не е удържан, опитайте отново.
502send_unknownПредадохме съобщението на оператора, но потвърждение не пристигна - таксува се, затова моля, не го изпращайте отново напосоки.

Какви състояния може да има съобщението?

Полето status както в списъка (GET /v1/messages), така и в детайла на едно съобщение приема пет стойности: pending (запазено, още се изпраща), sent (операторът потвърди изпращането), failed (операторът отхвърли - не се таксува), unknown (потвърждение за доставка не пристигна, обикновено изтичане на времето от страна на оператора - таксува се пълната цена, защото съобщението може да е стигнало) и received (само при входящи съобщения, т.е. с direction=in; изпратените съобщения го нямат).

Всяко съобщение носи и полетата direction (out при изпратените, in при получените), smsNumber (номерът, от който съобщението е изпратено или на който е получено; при съобщения под споделеното име SMSinfo е null) и deliveryStatus (delivered или undelivered, потвърждение за доставка от оператора; съществува само при SMS, изпратени от мобилен номер, а при останалите съобщения е null).

Как да разпратя много SMS наведнъж?

Лимитът позволява най-много едно SMS на две секунди на акаунт и най-много 100 SMS на ден. При разпращане на много съобщения наведнъж (например напомняния за срещи) е по-просто да изчакате кратко между заявките, отколкото да хващате rate_limited и да опитвате отново:

javascript
const message = "Напомняме за утрешните часове - Моето приложение";

for (const to of recipients) {
  const response = await fetch("https://volai.cz/v1/messages", {
    method: "POST",
    headers: {
      Authorization: "Bearer vk_VASHIYAT_KLYUCH",
      "Content-Type": "application/json",
    },
    body: JSON.stringify({ to, body: message }),
  });

  if (!response.ok) {
    const { error } = await response.json();
    console.error("volai " + to + ": " + error.code);
  }

  // Лимитът е най-много 1 SMS на 2 секунди на акаунт - кратка пауза между
  // заявките е по-проста от обработката на rate_limited и повторните опити.
  await new Promise((resolve) => setTimeout(resolve, 2100));
}

SMS приемат два вида номера

Гласовите номера на volai не приемат SMS, така че отговор на съобщение, изпратено под споделеното име SMSinfo, никъде не се появява. За да приемате SMS и да изпращате от собствен номер, изберете добавката мобилен номер: чешки номер само за SMS, без обаждания, 290 CZK на 30 дни без ДДС. Или поръчайте номер: номер за обаждания и SMS - пражка стационарна линия, на която приемате и обаждания, и SMS, 49 CZK на 30 дни без ДДС (таксата се удържа едва след активирането, което обикновено отнема до 1 работен ден). И при двата вида приетите SMS са включени в цената. Приетите съобщения четете в GET /v1/messages?direction=in, в MCP инструмента list_messages или в webhook message.received и ги пазим 90 дни; изпращането от мобилен номер струва 1.90 CZK за сегмент, от номер: номер за обаждания и SMS 2.50 CZK за сегмент, и е възможно само към чешки номера. SMS от номер изпращате с полето fromNumber в POST /v1/messages (номерът се взема от GET /v1/sms-numbers или от GET /v1/voice-sms-numbers). Дневният лимит за изпращане от номер е 20 SMS на акаунт през първите 30 дни след закупуването на номера, след това 50. В акаунта могат да има най-много два мобилни номера и те могат да се купят едва след първото зареждане на баланса; същото важи за номерата: номер за обаждания и SMS - най-много два на акаунт и могат да се поръчат едва след първото зареждане. Кодове за потвърждение от услуги (банки, Google и подобни) не гарантираме, номерата са предназначени за писане с хора, а приемът е проверен в мрежата на O2. Подробностите са в разделите Мобилни номера и Номера: номер за обаждания и SMS в документацията на API. Кога за приемане на SMS Twilio е по-добрият избор, описва сравнението на Twilio и volai.

Накратко: едно извикване POST /v1/messages с полета to и body изпраща SMS, заглавието Idempotency-Key пази повтарящия се работен процес от двойно изпращане, а цената се смята на сегмент според това дали текстът съдържа знаци извън GSM-7. Пазете ключа извън хранилището и първо изпратете съобщение на себе си.

Какво следва

Пълният справочник на REST API (номера, обаждания, webhooks, агенти) е на /docs/api. Искате да разберете веднага щом volai предаде съобщението на оператора, без да питате GET /v1/messages на кратки интервали? Абонирайте се за събитието message.sent - то потвърждава само приемането от оператора, а не стигането до телефона (при съобщения под споделеното име volai това не вижда, вижте по-горе; съобщенията, изпратени от собствен мобилен номер, имат потвърждение за доставка) - вижте документацията на webhooks. А ако освен SMS Ви трябва и телефонен номер, който сам вдига обажданията, погледнете AI рецепционист.

Изпробвайте volai - първите 50 kr са от нас

Създавате акаунт за минута и в него вече има начален баланс за обаждания и номер - SMS изпращате след първото зареждане.

Изпробвайте безплатно