Pentru cine e ghidul
Pentru cine are deja un cont SMS Voxbee și o cheie API (dacă nu, începe cu Cheia API SMS: cum trimiți primul mesaj) și vrea să lege SMS-ul de ce folosește deja: o automatizare în n8n, Make sau Zapier, un magazin online, un CRM, un script. Totul de mai jos este în documentația API; aici e varianta pe pași, cu exemple.
Un singur apel, în orice limbaj
Trimiterea e un POST pe https://smshub.voxbee.ro/api/v1/messages, cu cheia în antetul Authorization: Bearer vxs_… și un corp JSON:
to (unul sau până la 100 de numere), from (expeditorul aprobat), text, opțional ref (referința ta) și validity. Alege tabul cu limbajul tău:
curl -s https://smshub.voxbee.ro/api/v1/messages \
-H "Authorization: Bearer vxs_CHEIA_TA" \
-H "Content-Type: application/json" \
-d '{"to":"+40722000001","from":"FIRMATA","text":"Codul tău este 4821","ref":"order-12345"}'Răspuns
{"messages":[{"to":"40722000001","status":"accepted","id":"01a1…","segments":1,"encoding":"gsm7","price":{"amount":"0.040000","currency":"EUR"}}]}Răspunsul e 202 Accepted și conține, pentru fiecare destinatar, status (accepted sau rejected cu motivul), id-ul mesajului, numărul de
segmente și prețul. Mesajul propriu-zis pleacă spre rețea imediat după răspuns.
n8n, Make, Zapier: nodul HTTP
Nu există (încă) un nod „Voxbee”; nici nu e nevoie, un nod HTTP generic face tot:
| Câmp | Valoare |
|---|---|
| Metodă | POST |
| URL | https://smshub.voxbee.ro/api/v1/messages |
Antet Authorization | Bearer vxs_CHEIA_TA (în n8n: credențial de tip Header Auth, ca să nu stea cheia în workflow) |
Antet Content-Type | application/json |
Antet Idempotency-Key | id-ul comenzii / al rândului (opțional, dar recomandat; vezi mai jos) |
| Corp (JSON) | {"to": "{{telefon}}", "from": "FIRMATA", "text": "Comanda {{nr}} e gata de ridicare.", "ref": "{{nr}}"} |
Câteva lucruri de știut:
- •Numerele:
+40722…,0040722…sau0722…sunt acceptate; un număr fix (021…, 03…) e refuzat (INVALID_DESTINATION), nu există SMS pe fix. - •Diacriticele sunt permise; un mesaj cu diacritice are 70 de caractere pe segment în loc de 160, deci costă mai mult la texte lungi. Dacă vrei să rămâi la un segment, scrie fără diacritice.
- •Expeditorul trebuie să fie unul aprobat pe contul tău (îl vezi în Portal → SMS); altfel
SENDER_NOT_ALLOWED. - •Fără credit primești
402 INSUFFICIENT_BALANCEși nimic nu pleacă; alertele de sold (20 €, 5 €, 0 €) vin pe e-mail.
În Make și Zapier e același lucru: modulul „HTTP → Make a request”, respectiv „Webhooks by Zapier → Custom Request”, cu aceleași antete și corp.
Idempotența: de ce nu trimiți de două ori
Automatizările reîncearcă. Dacă nodul HTTP primește timeout și reia apelul, fără protecție clientul ar primi două SMS-uri (și tu ai plăti două).
Antetul Idempotency-Key rezolvă asta: pui o valoare unică per intenție (id-ul comenzii, al programării), iar la a doua cerere cu aceeași cheie
platforma îți întoarce răspunsul memorat, fără să trimită din nou. Cheile se țin 24 de ore.
Statusul de livrare: portal, API sau webhook
Fiecare mesaj trece prin acceptat → trimis → livrat sau nelivrat / expirat (telefon închis, număr inexistent). Trei feluri de a afla:
- •Portal → SMS → Mesaje: fiecare mesaj cu starea lui, rețeaua reală a destinatarului (și pentru numerele portate), segmente, preț, referința ta.
- •API:
GET /api/v1/messages/{id}sauGET /api/v1/messages?ref=comanda-12345. - •Webhook: platforma îți cheamă URL-ul la fiecare stare finală. E varianta potrivită pentru automatizări: în n8n faci un nod „Webhook” (trigger) și pui URL-ul lui în Portal → SMS → Webhook-uri.
Cum verifici că webhook-ul vine de la noi
La crearea webhook-ului primești un secret (afișat o singură dată). Fiecare apel are antetele X-Voxbee-Event: message.status,
X-Voxbee-Delivery (id unic, pentru deduplicare), X-Voxbee-Attempt și X-Voxbee-Signature: t=<timp unix>,v1=<hex>. Semnătura e
HMAC-SHA256(secret, t + "." + corpul brut); o verifici așa (Node.js):
import { createHmac, timingSafeEqual } from 'node:crypto'
export function verify(secret, rawBody, signatureHeader) {
const p = Object.fromEntries(signatureHeader.split(',').map((x) => x.split('=')))
if (Math.abs(Date.now() / 1000 - Number(p.t)) > 300) return false // mai vechi de 5 minute → refuzat
const expected = createHmac('sha256', secret).update(`${p.t}.${rawBody}`).digest('hex')
return (
expected.length === p.v1.length && timingSafeEqual(Buffer.from(expected), Buffer.from(p.v1))
)
}
Răspunde cu 2xx în cel mult 10 secunde. Dacă serverul tău nu răspunde, platforma reîncearcă la 30 s, 2 min, 10 min, 30 min, 1 h, apoi la 2 h,
timp de 24 de ore; livrările și reîncercările le vezi în portal, la webhook-uri. URL-ul trebuie să fie https, public (nu IP privat, nu localhost).
IP-uri permise și mai multe chei
Două obiceiuri bune, ambele din Portal → SMS:
- •O cheie pe fiecare sistem (
magazin,n8n,crm), maximum 5 active: dacă una ajunge unde nu trebuie, o revoci fără să oprești restul. - •IP-uri permise: lista de IP-uri sau rețele de pe care cheile tale pot trimite. Implicit orice IP; cu IP static pe server, restrânge.
Un apel de pe alt IP primește
403 IP_NOT_ALLOWED. Atenție la Make și Zapier: ele nu au IP fix, deci pentru ele lași lista goală (sau le dai o cheie separată și ții IP-urile doar pe cheia serverului tău).
Limite de care te lovești rar
- •până la 100 de destinatari într-un apel și 500 de segmente în total per cerere;
- •50 de cereri pe secundă per cheie și un număr de mesaje pe secundă per cont (pentru volume mari, scrie-ne);
- •textul: maximum 1 600 de caractere (10 segmente), tăiat sau împărțit după cum ceri (
longMessageMode); - •
validity: cât timp încearcă rețeaua să livreze (între 1 minut și 48 de ore; implicit 48 h).
Când ai nevoie și de campanii
Pentru promoții sau anunțuri către o listă de clienți nu trebuie să programezi nimic: în portal urci lista din CSV/Excel, personalizezi mesajul și vezi costul înainte să pornești. API-ul rămâne pentru mesajele pe care le generează aplicația ta, unul câte unul.
Întrebări sau un caz mai special (numere dedicate, răspunsuri de la clienți, volume mari)? Scrie-ne sau deschide un tichet din portal.