BlogBezpečnostCeníkKontakt
PřihlásitRegistrovat
Tmavý režim
TopSMS.cz›API & Integrace

SMS API
pro vývojáře

Odesílání SMS integrujete do své aplikace za pár minut. Jednoduché HTTP/JSON API: jeden POST odešle zprávu, GET vrátí stav doručení. Autentizace přes API klíč, žádné SDK ani závislosti — stačí HTTP klient, který váš jazyk už má.

0,88 Kč
Cena od
Zdarma
Testovací klíč
10
SMS zdarma na start
Cena za SMS do ČR podle měsíční útraty · bez DPH · bez paušálu · kredit nepropadá
0,98 Kč
do 5 000 Kč / měsíc
0,93 Kč
5 000 – 15 000 Kč
0,88 Kč
15 000 – 50 000 Kč
Individuální
nad 50 000 Kč
Jméno firmy jako odesílatel 500 Kč jednorázově, bez měsíčních poplatků. Celý ceník včetně zahraničí.
Registrovat seZobrazit ceník

Začněte za dvě minuty

Jeden HTTP požadavek a SMS je venku. Žádné SDK, žádné závislosti:

curl -X POST https://www.topsms.cz/api/sms/send \
  -H "Authorization: Bearer <clientId>:<secret>" \
  -H "Content-Type: application/json" \
  -d '{"to":"+420600000000","text":"Vas overovaci kod je 482910","from":"MojeFirma"}'
  • Testovací klíč zdarma: nic neodesílá ani neúčtuje, simuluje doručenky i webhooky. Ostrý klíč má po registraci 10 SMS zdarma.
  • Od 0,88 Kč za SMS do českých sítí, bez paušálu a bez poplatků za API.
  • Ověřovací kódy (OTP, 2FA): hotové Verify API kód pošle i ověří, včetně limitů proti zneužití.
  • Doručenky webhookem, hromadné a plánované odesílání, Idempotency-Key, OpenAPI, MCP server pro AI asistenty.

Získat API klíč →

Základ: endpoint a autentizace

API je čisté HTTP/JSON přes HTTPS. Produkční základ (base URL) je https://www.topsms.cz. Nepotřebujete žádnou knihovnu ani SDK — postačí HTTP klient, který už máte (curl, Guzzle, requests, fetch).

Autentizace probíhá přes API klíč v hlavičce Authorization. Klíč tvoří dvojice clientId a secret, kterou vygenerujete v dashboardu v sekci API přístup (secret se ukládá jen jako hash, takže si ho při vytvoření uschovejte):

Authorization: Bearer <clientId>:<secret>
Content-Type: application/json

Ke každému klíči patří oprávnění (scope) — send pro odesílání a read pro čtení stavu — a volitelně IP whitelist, kterým klíč omezíte na konkrétní adresy vašeho serveru.

Odeslání SMS

POST https://www.topsms.cz/api/sms/send — vyžaduje scope send.

Tělo požadavku (JSON):

PolePovinnéPopis
toanoTelefonní číslo v mezinárodním formátu (např. +420600000000). Podporujeme více než 200 zemí a území — cena dle destinace, viz ceník.
textanoText zprávy v UTF-8. Diakritika přepne kódování na Unicode (70/67 znaků na část) — části i cenu spočítá kalkulačka délky SMS.
fromneJméno odesílatele (Sender ID), max 11 znaků. Musí jít o schválené Sender ID vašeho účtu; bez uvedení se použije výchozí „TopSMS".

Text se odešle přesně tak, jak ho pošlete — proměnné typu {jmeno} API nenahrazuje. Personalizaci (proměnné, oslovení, hodnoty z CSV) provádí kampaňový modul v dashboardu; při odesílání přes API doplní hodnoty vaše aplikace před voláním.

Požadavek:

POST /api/sms/send
{
  "to": "+420600000000",
  "text": "Vas overovaci kod je 482910",
  "from": "MojeFirma"
}

Úspěšná odpověď (HTTP 200):

{
  "ok": true,
  "id": "cmp7a1b2c3...",
  "externalId": "a1b2c3d4",
  "to": "+420600000000",
  "from": "MojeFirma",
  "smsCount": 1,
  "price": 0.9,
  "status": "sent"
}

id je interní identifikátor zprávy (použijete pro dotaz na stav), externalId je ID u operátora, smsCount je počet účtovaných částí a price je cena v Kč, která se v ten moment odečte z kreditu.

Hromadné odeslání (více příjemců najednou)

POST https://www.topsms.cz/api/sms/send-bulk — vyžaduje scope send. Až 500 příjemců na jeden požadavek.

Stejný text více příjemcům:

POST /api/sms/send-bulk
{
  "to": ["+420600000000", "+420600000001"],
  "text": "Zitra mame zavreno.",
  "from": "MojeFirma"
}

Nebo jiný text pro každého příjemce — personalizaci si připraví vaše aplikace:

POST /api/sms/send-bulk
{
  "messages": [
    { "to": "+420600000000", "text": "Pavle, faktura 2026001 je po splatnosti." },
    { "to": "+420600000001", "text": "Karlo, faktura 2026002 je po splatnosti." }
  ],
  "from": "MojeFirma"
}

Odpověď obsahuje výsledek pro každého příjemce zvlášť ve stejném pořadí, v jakém jste je poslali:

{
  "ok": true,
  "total": 2,
  "accepted": 1,
  "rejected": 1,
  "price": 0.98,
  "results": [
    { "to": "+420600000000", "status": "sent", "id": "cmp7a1b2...", "externalId": "a1b2c3d4", "price": 0.98, "error": null },
    { "to": "+420600000001", "status": "failed", "id": null, "externalId": null, "price": 0, "error": "Invalid phone number. Use international format (+420…)." }
  ]
}

Účtují se pouze zprávy se stavem sent. Neplatná čísla, čísla na blacklistu a zprávy odmítnuté operátorem se nestrhávají z kreditu. Kredit se kontroluje na celou dávku předem — pokud nestačí, nepošle se nic a vrátíme kód 402.

Stav doručení jednotlivých zpráv zjistíte přes id stejně jako u jednotlivého odeslání, nebo je dostanete push webhookem.

Velké dávky běží asynchronně. Nad 50 příjemců (nebo když pošlete "async": true) API odpoví hned 202 Accepted s jobId, kredit se strhne předem a odesílání zajistí naše fronta během sekund až minut. Průběh zjistíte přes GET /api/sms/jobs/{jobId} (scope read): stav queued / running / done / failed, čítače sent / failed / queued a výsledky po zprávách (?results=0 vrátí jen čítače). Zprávy odmítnuté bránou se na kredit vrátí automaticky, doručenky chodí webhookem stejně jako u synchronního odeslání.

HTTP/1.1 202 Accepted
{
  "ok": true,
  "queued": true,
  "jobId": "cmuk6llct0003yqlx8ke6rdt6",
  "statusUrl": "https://www.topsms.cz/api/sms/jobs/cmuk6llct0003yqlx8ke6rdt6",
  "total": 120, "accepted": 118, "rejected": 2, "price": 115.64,
  "results": [ { "to": "+420600000000", "status": "queued", "id": "cmuk...", "price": 0.98, "error": null }, ... ]
}

Plánované odeslání (send_at)

Do /api/sms/send i /api/sms/send-bulk přidejte pole send_at a zpráva odejde v zadaný čas. Hodí se na připomínky termínů, ranní rozesílky nebo zprávy mimo noční klid.

{
  "to": "+420601234567",
  "text": "Pripominame zitrejsi termin v 10:00.",
  "send_at": "2026-10-01T09:00:00+02:00"
}

Odpověď je 202 se stavem scheduled a jobId:

{ "ok": true, "scheduled": true, "id": "cmv...", "jobId": "cmw...", "status": "scheduled",
  "sendAt": "2026-10-01T07:00:00.000Z", "price": 0.98,
  "statusUrl": "https://www.topsms.cz/api/sms/jobs/cmw..." }
  • Formát: ISO 8601 s časovou zónou (+02:00 nebo Z), případně Unix timestamp. Nejvýš 30 dní dopředu; čas do 1 minuty od teď se odešle hned.
  • Kredit se strhne při naplánování. Stav sledujete přes GET /api/sms/jobs/{jobId}.
  • Zrušení: DELETE /api/sms/jobs/{jobId} (scope send) zruší naplánované odeslání nebo dávku ve frontě, která se ještě nezačala odesílat. Cena se vrátí na kredit. Když už se odesílá, vrátí 409 s code: "not_cancellable".

Idempotence (Idempotency-Key)

Při výpadku sítě nevíte, jestli požadavek prošel. Pošlete ho znovu se stejnou hlavičkou Idempotency-Key a SMS neodejde dvakrát: dostanete původní odpověď s hlavičkou Idempotent-Replayed: true.

curl -X POST https://www.topsms.cz/api/sms/send \
  -H "Authorization: Bearer CLIENT_ID:SECRET" \
  -H "Idempotency-Key: 5f0c7a1e-9d2b-4c55-8f7e-2b1d3c4e5a6f" \
  -H "Content-Type: application/json" \
  -d '{"to": "+420601234567", "text": "Objednavka 1234 odeslana."}'
  • Platí pro /api/sms/send, /api/sms/send-bulk a /api/verify/send. Klíč je libovolný řetězec do 255 znaků (doporučujeme UUID nebo ID objednávky), platí 24 hodin a je vázaný na váš API klíč.
  • Stejný klíč s jiným tělem nebo endpointem vrátí 422 (idempotency_mismatch); pokud původní požadavek ještě běží, 409 (idempotency_in_progress).
  • Chyby 401, 402, 403, 429 a 5xx se neukládají, takže po odstranění příčiny můžete se stejným klíčem zkusit znovu.

Testovací režim

Při vytváření API klíče v dashboardu zaškrtněte Testovací klíč. Takový klíč nic neodešle ani neúčtuje, ale vrací stejné odpovědi jako ostrý (navíc "test": true) a za 2 až 4 sekundy změní stav zprávy a pošle doručenku na webhook s "test": true. Stav zjistíte i přes /api/sms/status/{id}.

  • Čísla končící 0000 simulují selhání (neplatné číslo), 0001 expiraci, ostatní doručení
  • Kontroluje se vše ostatní: formát čísla, blacklist, schválení odesílatele, oprávnění klíče
  • Pole price ukazuje, kolik by zpráva stála, kredit se nemění

Log požadavků a webhooků

V dashboardu v sekci API přístup u každého klíče otevřete Log a webhook: uvidíte posledních 100 volání (čas, endpoint, stavový kód, chyba, tělo požadavku) a pokusy o doručení webhooků včetně odpovědi vašeho serveru. Tamtéž nastavíte nebo změníte webhook URL a pošlete testovací webhook. Log se uchovává 30 dní, secret ani hlavička Authorization se neukládají.

Verify API: ověřovací kódy

Pro přihlášení, registraci nebo potvrzení akcí: POST /api/verify/send pošle kód, POST /api/verify/check ho ověří. Kód generujeme a hlídáme my (platnost, 5 pokusů, limity na číslo). Podrobnosti a příklady na stránce Verify API.

POST /api/verify/send
{ "to": "+420601234567", "brand": "MojeFirma" }
→ { "ok": true, "id": "cmv...", "status": "pending", "expiresAt": "...", "price": 0.98 }

POST /api/verify/check
{ "id": "cmv...", "code": "482913" }
→ { "valid": true, "status": "approved" }

Zjištění stavu doručení (delivery report)

GET https://www.topsms.cz/api/sms/status/{id} — vyžaduje scope read.

Do {id} dosaďte buď interní id, nebo externalId z odpovědi na odeslání. Delivery report od operátora dorazí asynchronně (typicky do několika sekund až minut) a stav se pak aktualizuje. Doporučený postup je krátký polling — po odeslání se čas od času zeptejte na stav.

{
  "id": "cmp7a1b2c3...",
  "externalId": "a1b2c3d4",
  "to": "+420600000000",
  "from": "MojeFirma",
  "status": "delivered",
  "price": 0.9,
  "carrier": "T-Mobile CZ",
  "createdAt": "2026-08-10T09:12:00.000Z",
  "deliveredAt": "2026-08-10T09:12:03.000Z",
  "failedAt": null,
  "errorMessage": null,
  "errorCode": null
}

Hodnoty pole status:

  • queued — ve frontě nebo čeká na naplánovaný čas odeslání
  • sent — přijato a předáno operátorovi
  • delivered — doručeno na telefon (viz deliveredAt)
  • failed — nedoručeno (důvod v errorMessage a errorCode, čas v failedAt)
  • expired — vypršela platnost, operátor zprávu nedoručil

Důvod nedoručení v poli errorCode (stejné pole je i ve webhooku a ve výsledcích dávky):

expiredVypršela platnost, telefon byl po celou dobu vypnutý nebo mimo signál. Můžete zkusit poslat později.
undeliveredOperátor zprávu vrátil jako nedoručitelnou: číslo neexistuje, není aktivní nebo telefon SMS nepřijímá. Některé zahraniční sítě takto vracejí i dočasně nedostupný telefon (vypnutý, bez signálu) místo čekání; u důležitých zpráv doporučujeme po několika minutách zopakovat odeslání se stejným Idempotency-Key rozšířeným o číslo pokusu.
rejectedOperátor zprávu odmítl (blokace SMS od firem u příjemce, odesílatel nebo obsah). Neznamená špatné číslo.
deletedOperátor zprávu před doručením zrušil.
unknownOperátor nevrátil výsledek doručení.
repeated_failureNa stejné číslo selhalo doručení nejméně potřetí za 90 dní. Číslo pravděpodobně neexistuje, doporučujeme ho vyřadit ze seznamu.
not_sentZprávu se nepodařilo předat operátorovi, cena byla vrácena na kredit.

Webhooky (push doručenky)

Nechcete polling? U API klíče si v dashboardu nastavte webhook URL — při doručení, selhání či expiraci zprávy pošleme HTTP POST:

{
  "event": "sms.status",
  "id": "cmp7a1b2c3...",
  "externalId": "a1b2c3d4",
  "to": "+420600000000",
  "from": "MojeFirma",
  "status": "delivered",
  "price": 0.9,
  "deliveredAt": "2026-09-07T09:12:03.000Z",
  "failedAt": null,
  "errorMessage": null,
  "errorCode": null,
  "sentAt": "2026-09-07T09:12:04.100Z"
}

Podpis: hlavička X-TopSMS-Signature: sha256=HMAC-SHA256(body, webhookSecret) — secret zobrazíme při vytvoření klíče s webhook URL. Doručování: 3 pokusy (ihned, +30 s, +2 min), timeout 5 s, očekáváme HTTP 2xx. Detaily: Webhooky.

Integrace bez kódu a pluginy

Nechcete volat API sami? Většinu běžných napojení máme hotovou nebo ji zvládnete bez programování:

  • WooCommerce: oficiální plugin posílá SMS o stavu objednávky a o nové objednávce, instalace ze ZIP za dvě minuty.
  • Fakturoid a iDoklad: SMS upomínky faktur po splatnosti se nastavují v dashboardu, žádný kód.
  • Shoptet: doplněk připravujeme, do jeho vydání funguje napojení přes Make nebo tuto API.
  • Make: oficiální app TopSMS s moduly pro odeslání, hromadné odeslání, stav zprávy, kredit a trigger doručenek, bez kódu.
  • Zapier, n8n: HTTP modul zavolá POST /api/sms/send s hlavičkou Authorization: Bearer clientId:secret, viz příklady níže.
  • CSV import: jednorázové a marketingové zprávy pošlete z kampaně s proměnnými z exportu vašeho systému.

Přehled všech napojení a jejich stavu je na stránce Pluginy a integrace.

Knihovny, OpenAPI a AI asistenti

PHP: composer require topsms/topsms-php — github.com/topsms-ghb/topsms-php (odeslání, stav, kredit i ověření webhook podpisu). Strojově čitelný popis API pro import do Postman/Insomnia: OpenAPI specifikace.

Zjištění zůstatku kreditu

GET https://www.topsms.cz/api/credit — vyžaduje scope read.

Vrací aktuální zůstatek v Kč a vaši cenu za SMS. Hodí se pro automatické hlídání kreditu — např. upozornění ve vašem systému, když zůstatek klesne pod týdenní spotřebu.

{
  "ok": true,
  "credit": 1482.96,
  "currency": "CZK",
  "smsPrice": 0.98
}

Chybové kódy

Chyba vždy vrací JSON { "error": "popis" } s odpovídajícím HTTP kódem. Endpointy Verify API přidávají i strojový "code" (například rate_limited, cooldown, insufficient_credit, invalid_number, not_found), podle kterého chybu snadno obsloužíte v kódu.

HTTPVýznam
202Není chyba: hromadná dávka nad 50 příjemců (nebo s "async": true) byla přijata do fronty, průběh přes GET /api/sms/jobs/{jobId}.
400Chybí to nebo text, neplatné číslo, nebo je číslo na blacklistu (odhlášený kontakt).
401Chybějící nebo neplatná autentizace (zkontrolujte formát Bearer clientId:secret).
402Nedostatečný kredit na účtu.
403Účet není aktivní/schválený, IP mimo whitelist, klíč nemá potřebný scope, nebo neschválené Sender ID v poli from.
404Zpráva nenalezena (u dotazu na stav).
409Konflikt: požadavek se stejným Idempotency-Key ještě běží, nebo úlohu už nejde zrušit (not_cancellable).
422Idempotency-Key už byl použit s jiným požadavkem (idempotency_mismatch).
429Překročen rate limit klíče, nebo u Verify API víc než 5 kódů na jedno číslo za hodinu (rate_limited) či další kód dřív než za 30 s (cooldown, pole retryAfter v sekundách).
502Chyba na straně operátora při doručování.

Délka zprávy a cena

Cena se počítá podle počtu částí zprávy (segmentů). Limit na jednu SMS závisí na tom, jestli text obsahuje diakritiku:

  • Bez diakritiky (GSM-7): 160 znaků na 1 SMS, u delších 153 znaků na část.
  • S diakritikou nebo emoji (Unicode): 70 znaků na 1 SMS, u delších 67 znaků na část.

Odpověď na odeslání vrací smsCount (počet účtovaných částí) i price (cena v Kč dle vašeho tarifu), takže cenu znáte hned. Detail počítání najdete v článku Kolik znaků má SMS.

Příklady: curl, PHP, Python, Node.js

Ve všech příkladech nahraďte CLIENT_ID:SECRET svým klíčem.

curl

curl -X POST https://www.topsms.cz/api/sms/send \
  -H "Authorization: Bearer CLIENT_ID:SECRET" \
  -H "Content-Type: application/json" \
  -d '{"to":"+420600000000","text":"Ahoj","from":"MojeFirma"}'

PHP (cURL)

$ch = curl_init('https://www.topsms.cz/api/sms/send');
curl_setopt_array($ch, [
  CURLOPT_POST => true,
  CURLOPT_RETURNTRANSFER => true,
  CURLOPT_HTTPHEADER => [
    'Authorization: Bearer CLIENT_ID:SECRET',
    'Content-Type: application/json',
  ],
  CURLOPT_POSTFIELDS => json_encode([
    'to'   => '+420600000000',
    'text' => 'Ahoj z PHP',
    'from' => 'MojeFirma',
  ]),
]);
$response = curl_exec($ch);
echo $response;

Python (requests)

import requests

r = requests.post(
    "https://www.topsms.cz/api/sms/send",
    headers={"Authorization": "Bearer CLIENT_ID:SECRET"},
    json={"to": "+420600000000", "text": "Ahoj z Pythonu", "from": "MojeFirma"},
)
print(r.json())

Node.js (fetch)

const res = await fetch("https://www.topsms.cz/api/sms/send", {
  method: "POST",
  headers: {
    "Authorization": "Bearer CLIENT_ID:SECRET",
    "Content-Type": "application/json",
  },
  body: JSON.stringify({ to: "+420600000000", text: "Ahoj z Node", from: "MojeFirma" }),
})
console.log(await res.json())

Limity, IP whitelist a Sender ID

  • Rate limit — nastaven na každý klíč zvlášť (výchozí 60 požadavků/min). Vyšší limity pro velké objemy na vyžádání.
  • IP whitelist — u klíče volitelně povolíte jen konkrétní IP adresy vašeho serveru. Požadavek z jiné IP dostane 403.
  • Sender ID — vlastní jméno odesílatele místo čísla (pole from). Operátoři schvalují nové odesílatele hromadně několikrát měsíčně (počítejte s 1–2 týdny), jednorázový poplatek 500 Kč. API přijme jen schválené Sender ID vašeho účtu (nebo výchozí „TopSMS") — neschválené jméno vrátí 403. Detail na stránce Vlastní Sender ID.
  • Blacklist — čísla označená jako odhlášená (ručně v detailu kontaktu nebo hromadně importem CSV se sloupcem optOut) API automaticky odmítne s kódem 400. Odhlášení nastavujete na své straně, my ho respektujeme.
  • Klíče a scope — spravujete v dashboardu (sekce API přístup): vytvoření, oprávnění send/read, IP whitelist, webhook URL, log volání a revokace. Testovací klíč (zaškrtnete při vytvoření) nic neodesílá ani neúčtuje.
  • Verify API — kód platí 60 až 1800 s (výchozí 5 min), na kód 5 pokusů, na jedno číslo nejvýš 5 kódů za hodinu a 30 s mezi dvěma kódy. Nový kód na stejné číslo zneplatní předchozí.
  • Více klíčů a rozúčtování — na účtu můžete mít až 10 aktivních klíčů s vlastními názvy (např. podle projektů či účetních středisek). Každá odeslaná SMS se přiřadí ke konkrétnímu klíči.
  • Evidence zdroje — v Historii má každá zpráva sloupec Zdroj („API · název klíče", „Kampaň", „Ručně"), dá se podle něj filtrovat a je součástí exportu CSV — ideální pro interní rozúčtování.
// další řešení
◷ 24/7 podpora zdarma — vždy připraveni pomoci

Připraveni začít?

Vyzkoušejte TopSMS zdarma. 10 SMS na začátek, bez závazků, bez kreditní karty.

Registrovat seZobrazit ceník