SMS-API-Dokumentation
REST-API des SMS-Gateways TopSMS: SMS-Versand in wenigen Minuten in Ihre Anwendung integriert. Einfache HTTP/JSON-API: ein POST sendet die Nachricht, ein GET liefert den Zustellstatus. Authentifizierung per API-Schlüssel, kein SDK und keine Abhängigkeiten, es genügt der HTTP-Client, den Ihre Programmiersprache ohnehin mitbringt.
Die Basis-URL der API lautet immer https://www.topsms.cz. Diese Dokumentation gibt es auch auf Englisch und Tschechisch.
In zwei Minuten starten
Eine HTTP-Anfrage, und die SMS ist unterwegs. Kein SDK, keine Abhängigkeiten.
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":"Vas overovaci kod je 482910","from":"MojeFirma"}'Ersetzen Sie CLIENT_ID:SECRET durch Ihren API-Schlüssel aus dem Dashboard. Weiter unten auf dieser Seite: Codebeispiele in sechs Sprachen, Zustellstatus, Webhooks und Fehlercodes.
- Kostenloser Testschlüssel: sendet und berechnet nichts, simuliert aber Zustellberichte und Webhooks. Mit dem Produktivschlüssel haben Sie nach der Registrierung 10 Test-SMS.
- Ab 0,036 € pro SMS in tschechische Netze, ohne Grundgebühr und ohne API-Gebühren. Preise für Deutschland, Österreich und weitere Länder: Preisliste.
- Bestätigungscodes (OTP, 2FA): die fertige Verify API sendet den Code und prüft ihn, inklusive Limits gegen Missbrauch.
- Zustellberichte per Webhook, Massen- und geplanter Versand, Idempotency-Key, OpenAPI, MCP-Server für KI-Assistenten.
Grundlagen: Endpoint und Authentifizierung
Die API ist reines HTTP/JSON über HTTPS. Die Basis-URL für den Produktivbetrieb lautet https://www.topsms.cz. Sie benötigen keine Bibliothek und kein SDK, es genügt der HTTP-Client, den Sie bereits einsetzen (curl, Guzzle, requests, fetch).
Die Authentifizierung erfolgt über einen API-Schlüssel im Header Authorization. Der Schlüssel besteht aus dem Paar clientId und secret, das Sie im Dashboard im Bereich API-Zugang erzeugen (das Secret wird bei uns nur als Hash gespeichert, notieren Sie es sich daher direkt beim Erstellen):
Authorization: Bearer <clientId>:<secret> Content-Type: application/json
Zu jedem Schlüssel gehören Berechtigungen (Scopes), send für den Versand und read für das Lesen des Status, sowie optional eine IP-Whitelist, mit der Sie den Schlüssel auf bestimmte Adressen Ihres Servers beschränken.
SMS senden
POST https://www.topsms.cz/api/sms/send, erfordert Scope send.
Anfragekörper (JSON):
| Feld | Pflicht | Beschreibung |
|---|---|---|
to | ja | Rufnummer im internationalen Format (z. B. +420600000000 oder +49170…). Wir unterstützen mehr als 200 Länder und Gebiete; der Preis richtet sich nach dem Zielland, siehe Preisliste. |
text | ja | Nachrichtentext in UTF-8. Zeichen außerhalb des GSM-Alphabets (Emoji, typografische Anführungszeichen, tschechische oder polnische Buchstaben) schalten die Kodierung auf Unicode um (70/67 Zeichen pro Teil); deutsche Umlaute und ß gehören zum GSM-Alphabet, Teile und Preis berechnet der SMS-Längenrechner. Die Textlänge ist nicht begrenzt, eine längere Nachricht wird aufgeteilt und pro Teil berechnet. |
from | nein | Absendername (Sender ID), max. 11 Zeichen. Es muss ein freigegebener Absendername Ihres Kundenkontos sein; ohne Angabe wird der Standardabsender des Kontos verwendet (Dashboard → Sender ID → „Als Standard festlegen“), andernfalls „TopSMS“. Ein freigegebener Name, den die Netzbetreiber noch nicht aktiviert haben, wird durch den Standardabsender ersetzt (siehe senderFallback unten). |
Der Text wird genau so gesendet, wie Sie ihn übergeben; Variablen wie {name} ersetzt die API nicht. Die Personalisierung (Variablen, Anrede, Werte aus einer CSV-Datei) übernimmt das Kampagnenmodul im Dashboard; beim Versand über die API setzt Ihre Anwendung die Werte vor dem Aufruf ein.
Anfrage:
POST /api/sms/send
{
"to": "+420600000000",
"text": "Vas overovaci kod je 482910",
"from": "MojeFirma"
}Erfolgreiche Antwort (HTTP 200):
{
"ok": true,
"id": "cmp7a1b2c3...",
"externalId": "a1b2c3d4",
"to": "+420600000000",
"from": "MojeFirma",
"smsCount": 1,
"price": 0.9,
"status": "sent"
}id ist die interne Kennung der Nachricht (für die Statusabfrage), externalId die Kennung beim Netzbetreiber, smsCount die Anzahl der berechneten Teile und price der Preis, der in diesem Moment vom Guthaben abgezogen wird. Die API liefert Beträge in CZK, der internen Abrechnungswährung der Plattform.
Noch nicht aktiver Absendername. Ist der Absendername im Feld from freigegeben, aber von den Netzbetreibern noch nicht aktiviert, wird die Nachricht mit dem Standardabsender „TopSMS“ gesendet, und die Antwort enthält "from": "TopSMS", "senderFallback": true und "requestedFrom": "MojeFirma". Dasselbe gilt für den Massenversand. Nach der Aktivierung wird unter Ihrem Namen gesendet, ohne dass Sie etwas ändern müssen.
Fehler 500 mit dem Code record_failed bedeutet, dass die SMS gesendet wurde, aber nicht in unserem System gespeichert werden konnte. Das Guthaben haben wir gutgeschrieben. Wiederholen Sie die Nachricht nicht, sondern schreiben Sie uns. Mit dem Header Idempotency-Key ist eine Wiederholung unkritisch: Sie erhalten dieselbe Antwort, und die SMS wird nicht erneut gesendet.
Massenversand (mehrere Empfänger auf einmal)
POST https://www.topsms.cz/api/sms/send-bulk, erfordert Scope send. Bis zu 500 Empfänger pro Anfrage.
Derselbe Text an mehrere Empfänger:
POST /api/sms/send-bulk
{
"to": ["+420600000000", "+420600000001"],
"text": "Zitra mame zavreno.",
"from": "MojeFirma"
}Oder ein eigener Text für jeden Empfänger, die Personalisierung bereitet Ihre Anwendung vor:
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"
}Die Antwort enthält das Ergebnis für jeden Empfänger einzeln, in derselben Reihenfolge, in der Sie sie gesendet haben:
{
"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…)." }
]
}Berechnet werden nur Nachrichten mit dem Status sent. Ungültige Nummern, Nummern auf der Blacklist und vom Netzbetreiber abgelehnte Nachrichten werden nicht vom Guthaben abgezogen. Das Guthaben wird vorab für den gesamten Stapel geprüft: Reicht es nicht aus, wird nichts gesendet, und wir geben den Code 402 zurück.
Den Zustellstatus der einzelnen Nachrichten fragen Sie über die id ab, genau wie beim Einzelversand, oder Sie erhalten ihn per Push-Webhook.
Große Stapel laufen asynchron. Bei mehr als 50 Empfängern (oder wenn Sie "async": true senden) antwortet die API sofort mit 202 Accepted und einer jobId; das Guthaben wird vorab abgezogen, und unsere Warteschlange übernimmt den Versand innerhalb von Sekunden bis Minuten. Den Fortschritt fragen Sie über GET /api/sms/jobs/{jobId} (Scope read) ab: Status queued / scheduled / running / done / failed / cancelled, Zähler sent / failed / queued und Ergebnisse je Nachricht (?results=0 liefert nur die Zähler). Vom Gateway abgelehnte Nachrichten werden dem Guthaben automatisch gutgeschrieben; Zustellberichte kommen per Webhook wie beim synchronen Versand.
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 }, ... ]
}Geplanter Versand (send_at)
Ergänzen Sie bei /api/sms/send und /api/sms/send-bulk das Feld send_at, und die Nachricht wird zur angegebenen Zeit gesendet. Praktisch für Terminerinnerungen, morgendliche Aussendungen oder um Nachrichten nicht mitten in der Nacht zuzustellen.
{
"to": "+420601234567",
"text": "Pripominame zitrejsi termin v 10:00.",
"send_at": "2026-10-01T09:00:00+02:00"
}Die Antwort ist 202 mit dem Status scheduled und einer 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..." }- Format: ISO 8601 mit Zeitzone (
+02:00oderZ), alternativ ein Unix-Timestamp. Höchstens 30 Tage im Voraus; liegt der Zeitpunkt weniger als 1 Minute in der Zukunft, wird sofort gesendet. - Das Guthaben wird bei der Planung abgezogen. Den Status verfolgen Sie über
GET /api/sms/jobs/{jobId}. - Stornierung:
DELETE /api/sms/jobs/{jobId}(Scopesend) storniert einen geplanten Versand oder einen Stapel in der Warteschlange, dessen Versand noch nicht begonnen hat. Der Preis wird dem Guthaben gutgeschrieben. Läuft der Versand bereits, wird409mitcode: "not_cancellable"zurückgegeben.
Idempotenz (Idempotency-Key)
Bei einem Netzwerkfehler wissen Sie nicht, ob die Anfrage angekommen ist. Senden Sie sie erneut mit demselben Header Idempotency-Key, und die SMS wird nicht doppelt gesendet: Sie erhalten die ursprüngliche Antwort mit dem Header 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."}'- Gilt für
/api/sms/send,/api/sms/send-bulkund/api/verify/send. Der Schlüssel besteht aus 1–255 druckbaren ASCII-Zeichen ohne Leerzeichen (wir empfehlen eine UUID oder die Bestellnummer), andernfalls geben wir400(invalid_idempotency_key) zurück; er gilt 24 Stunden und ist an Ihren API-Schlüssel gebunden. - Derselbe Schlüssel mit anderem Anfragekörper oder Endpoint liefert
422(idempotency_mismatch); läuft die ursprüngliche Anfrage noch,409(idempotency_in_progress). - Die Fehler
401,402,403,408,409,429und5xxwerden nicht gespeichert, sodass Sie es nach Beseitigung der Ursache mit demselben Schlüssel erneut versuchen können. Ausnahme ist500mit dem Coderecord_failed(SMS gesendet, nur nicht gespeichert): Diesen merken wir uns, damit eine Wiederholung die SMS nicht ein zweites Mal sendet. - Alle übrigen Antworten einschließlich
400und404werden gespeichert. Verwenden Sie nach der Korrektur einer ungültigen Anfrage daher einen neuen Schlüssel.
Testmodus
Aktivieren Sie beim Erstellen des API-Schlüssels im Dashboard die Option Testschlüssel. Ein solcher Schlüssel sendet und berechnet nichts, liefert aber dieselben Antworten wie ein Produktivschlüssel (zusätzlich "test": true; einzige Ausnahme ist der geplante Versand, bei dem ein Testschlüssel mit send_at 200 mit "scheduled": true und ohne jobId zurückgibt). Nach 2 bis 4 Sekunden ändert er den Status der Nachricht und sendet einen Zustellbericht mit "test": true an den Webhook. Den Status erhalten Sie auch über /api/sms/status/{id}.
- Nummern mit der Endung
0000simulieren einen Fehlschlag (ungültige Nummer),0001einen Ablauf der Gültigkeit, alle übrigen eine erfolgreiche Zustellung - Alles andere wird regulär geprüft: Nummernformat, Blacklist, Freigabe des Absendernamens, Berechtigungen des Schlüssels
- Das Feld
pricezeigt, was die Nachricht kosten würde; das Guthaben ändert sich nicht
Protokoll der Anfragen und Webhooks
Im Dashboard öffnen Sie im Bereich API-Zugang bei jedem Schlüssel Protokoll und Webhook: Sie sehen die letzten 100 Aufrufe (Zeitpunkt, Endpoint, Statuscode, Fehler, Anfragekörper) und die Zustellversuche der Webhooks inklusive der Antwort Ihres Servers. Dort legen Sie auch die Webhook-URL fest oder ändern sie und senden einen Test-Webhook. Das Protokoll wird 30 Tage aufbewahrt; das Secret und der Header Authorization werden nicht gespeichert.
Verify API: Bestätigungscodes
Für Anmeldung, Registrierung oder die Bestätigung von Aktionen: POST /api/verify/send sendet den Code, POST /api/verify/check prüft ihn. Den Code erzeugen und überwachen wir (Gültigkeitsdauer, 5 Versuche, Limits pro Rufnummer). Details und Beispiele auf der Seite Verify API; eine Schritt-für-Schritt-Anleitung finden Sie im Artikel OTP per SMS: sichere Implementierung.
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" }Zustellstatus abfragen (Zustellbericht)
GET https://www.topsms.cz/api/sms/status/{id}, erfordert Scope read.
Setzen Sie für {id} entweder die interne id oder die externalId aus der Antwort auf den Versand ein. Wir empfehlen die id, denn die externalId ändert sich bei der automatischen Wiederholung einer Nachricht nach Deutschland. Der Zustellbericht (Delivery Report) des Netzbetreibers trifft asynchron ein (typischerweise innerhalb einiger Sekunden bis Minuten), danach wird der Status aktualisiert. Empfohlen ist kurzes Polling: Fragen Sie den Status nach dem Versand in Abständen ab.
{
"id": "cmp7a1b2c3...",
"externalId": "a1b2c3d4",
"to": "+420600000000",
"from": "MojeFirma",
"status": "delivered",
"price": 0.9,
"carrier": "230.1",
"createdAt": "2026-08-10T09:12:00.000Z",
"deliveredAt": "2026-08-10T09:12:03.000Z",
"failedAt": null,
"errorMessage": null,
"errorCode": null
}carrier ist der Netzcode des Empfängers im Format MCC.MNC, zum Beispiel 230.1 T-Mobile CZ, 230.2 O2 CZ, 230.3 Vodafone CZ, 231.6 O2 Slowakei.
Werte des Feldes status:
pending: angenommen, wird gerade gesendet (Sekundenbruchteile)queued: in der Warteschlange oder wartet auf den geplanten Versandzeitpunktsent: angenommen und an den Netzbetreiber übergebendelivered: auf dem Telefon zugestellt (siehedeliveredAt)failed: nicht zugestellt (Grund inerrorMessageunderrorCode, Zeitpunkt infailedAt)expired: Gültigkeit abgelaufen, der Netzbetreiber konnte die Nachricht nicht zustellen
Bei einer langen, mehrteiligen Nachricht ist der Status erst delivered, wenn alle Teile zugestellt sind. Kommt ein Teil nicht an, endet die Nachricht als failed, weil das Telefon sie nicht zusammensetzen kann.
Grund der Nichtzustellung im Feld errorCode (dasselbe Feld gibt es auch im Webhook und in den Ergebnissen eines Stapels):
expired | Gültigkeit abgelaufen, das Telefon war die ganze Zeit ausgeschaltet oder ohne Empfang. Sie können es später noch einmal versuchen. |
undelivered | Der Netzbetreiber hat die Nachricht als unzustellbar zurückgegeben: Die Nummer existiert nicht, ist nicht aktiv oder das Telefon empfängt keine SMS. Manche ausländischen Netze melden so auch ein vorübergehend nicht erreichbares Telefon (ausgeschaltet, ohne Empfang), statt zu warten; bei wichtigen Nachrichten empfehlen wir, den Versand nach einigen Minuten mit demselben Idempotency-Key, ergänzt um die Nummer des Versuchs, zu wiederholen. |
rejected | Der Netzbetreiber hat die Nachricht abgelehnt (Sperre von Firmen-SMS beim Empfänger, Absendername oder Inhalt). Die Nummer selbst ist nicht falsch. |
deleted | Der Netzbetreiber hat die Nachricht vor der Zustellung verworfen. |
unknown | Der Netzbetreiber hat kein Zustellergebnis zurückgemeldet. |
repeated_failure | An dieselbe Nummer ist die Zustellung innerhalb von 90 Tagen mindestens zum dritten Mal fehlgeschlagen. Die Nummer existiert wahrscheinlich nicht, wir empfehlen, sie aus der Liste zu entfernen. |
not_sent | Die Nachricht konnte nicht an den Netzbetreiber übergeben werden; der Preis wurde dem Guthaben gutgeschrieben. |
Webhooks (Push-Zustellberichte)
Kein Polling gewünscht? Legen Sie beim API-Schlüssel im Dashboard eine Webhook-URL fest. Bei Zustellung, Fehlschlag oder Ablauf einer Nachricht senden wir einen 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"
}Signatur: Header X-TopSMS-Signature: sha256=HMAC-SHA256(body, webhookSecret). Das Secret zeigen wir beim Erstellen eines Schlüssels mit Webhook-URL an. Prüfen Sie die Signatur über den rohen Anfragekörper, nicht über das geparste JSON. Zustellung: 3 Versuche (sofort, +30 s, +2 min), Timeout 5 s, wir erwarten HTTP 2xx. Details: Webhooks.
Integrationen ohne Code und Plugins
Sie möchten die API nicht selbst aufrufen? Die gängigsten Anbindungen gibt es fertig, oder Sie richten sie ohne Programmierung ein:
- WooCommerce: das offizielle Plugin sendet SMS zum Bestellstatus und zu neuen Bestellungen, Installation aus einer ZIP-Datei in zwei Minuten.
- Fakturoid und iDoklad: SMS-Mahnungen für überfällige Rechnungen richten Sie im Dashboard ein, ohne Code.
- Shoptet: das Add-on ist in Vorbereitung; bis zur Veröffentlichung läuft die Anbindung über Make oder diese API.
- Make: offizielle TopSMS-App mit Modulen für Versand, Massenversand, Nachrichtenstatus und Guthaben sowie einem Trigger für Zustellberichte, ohne Code.
- Zapier, n8n: ein HTTP-Modul ruft
POST /api/sms/sendmit dem HeaderAuthorization: Bearer clientId:secretauf, siehe die Beispiele unten. - CSV-Import: einmalige und Marketing-Nachrichten senden Sie aus einer Kampagne mit Variablen aus dem Export Ihres Systems.
Eine Übersicht aller Anbindungen und ihres aktuellen Stands finden Sie auf der Seite Integrationen und Plugins.
Bibliotheken, OpenAPI und KI-Assistenten
PHP: composer require topsms/topsms-php, github.com/topsms-ghb/topsms-php (Versand, Status, Guthaben und Prüfung der Webhook-Signatur). Maschinenlesbare Beschreibung der API für den Import in Postman/Insomnia: OpenAPI-Spezifikation.
KI-Assistenten (Claude, Cursor, ChatGPT): Der offizielle MCP-Server (npm-Paket topsms-mcp) ruft dieselbe REST-API auf; es gelten dieselben Preise, Limits und Abrechnungsregeln. Eine kompakte Zusammenfassung der API für Sprachmodelle liegt unter topsms.cz/llms.txt.
Guthaben abfragen
GET https://www.topsms.cz/api/credit, erfordert Scope read.
Liefert den aktuellen Guthabenstand mit Währung und Ihren Preis pro SMS. Praktisch für die automatische Überwachung des Guthabens, z. B. eine Warnung in Ihrem System, wenn der Stand unter den Wochenverbrauch fällt.
{
"ok": true,
"credit": 1482.96,
"currency": "CZK",
"smsPrice": 0.98
}Fehlercodes
Ein Fehler liefert JSON { "error": "Beschreibung" } mit dem passenden HTTP-Statuscode, bei den meisten Fehlern auch mit dem maschinenlesbaren Feld "code". Ausnahme ist ein Massenversand, in dem alle Nummern ungültig sind: Er liefert 400 mit dem Feld results (Grund je Empfänger) statt error. Die Endpoints der Verify API liefern ebenfalls einen maschinenlesbaren "code" (zum Beispiel rate_limited, cooldown, insufficient_credit, invalid_number, not_found), über den Sie den Fehler in Ihrem Code gezielt behandeln.
| HTTP | Bedeutung |
|---|---|
202 | Kein Fehler: Ein Massenstapel mit mehr als 50 Empfängern (oder mit "async": true) wurde in die Warteschlange aufgenommen, Fortschritt über GET /api/sms/jobs/{jobId}. |
400 | to oder text fehlt, ungültige Nummer, Nummer auf der Blacklist (abgemeldeter Kontakt), ungültiges send_at (invalid_send_at) oder ungültiges Format des Idempotency-Key (invalid_idempotency_key). |
401 | Fehlende oder ungültige Authentifizierung (prüfen Sie das Format Bearer clientId:secret). |
402 | Nicht genügend Guthaben auf dem Kundenkonto. |
403 | Kundenkonto nicht aktiv oder nicht freigegeben, IP-Adresse außerhalb der Whitelist, Schlüssel ohne den erforderlichen Scope oder nicht freigegebener Absendername im Feld from. |
404 | Nachricht nicht gefunden (bei der Statusabfrage). |
409 | Konflikt: Eine Anfrage mit demselben Idempotency-Key läuft noch, oder der Job lässt sich nicht mehr stornieren (not_cancellable). Von einer Kampagne erzeugte Jobs stornieren Sie im Dashboard (campaign_job). |
422 | Der Idempotency-Key wurde bereits mit einer anderen Anfrage verwendet (idempotency_mismatch). |
429 | Rate-Limit des Schlüssels überschritten, oder bei der Verify API mehr als 5 Codes an eine Nummer pro Stunde (rate_limited) bzw. ein weiterer Code früher als nach 30 s (cooldown, Feld retryAfter in Sekunden). Jede 429-Antwort enthält einen Header Retry-After mit der Anzahl der Sekunden bis zum nächsten Versuch. |
500 | record_failed: Die SMS wurde gesendet, konnte aber nicht gespeichert werden; das Guthaben haben wir gutgeschrieben. Nicht wiederholen, sondern uns schreiben. Andere 500-Fehler wiederholen Sie mit demselben Idempotency-Key. |
502 | Der Netzbetreiber hat die Nachricht nicht angenommen; das Guthaben wurde gutgeschrieben, und Sie können es erneut versuchen. Bei der Verify API endet so auch ein nicht freigegebener Absendername oder eine Nummer auf der Blacklist (send_failed). |
Nachrichtenlänge und Preis
Der Preis richtet sich nach der Anzahl der Teile (Segmente) einer Nachricht. Das Limit pro SMS hängt davon ab, welche Zeichen der Text enthält:
- Ohne Sonderzeichen (GSM-7): 160 Zeichen pro SMS, bei längeren Nachrichten 153 Zeichen pro Teil. Hinweis: Die deutschen Umlaute ä, ö, ü und das ß gehören zum GSM-7-Alphabet und zählen als normale Zeichen.
- Mit anderen diakritischen Zeichen oder Emoji (Unicode): 70 Zeichen pro SMS, bei längeren Nachrichten 67 Zeichen pro Teil.
Die Antwort auf den Versand liefert smsCount (Anzahl der berechneten Teile) und price (Preis nach Ihrem Tarif), sodass Sie die Kosten sofort kennen. Preise je Zielland: Preisliste. Details zur Zählung im Artikel Wie viele Zeichen hat eine SMS.
Zeilenumbruch: Übergeben Sie das Zeilenende im Feld text als Zeilenumbruchzeichen, in JSON geschrieben als \n (zum Beispiel "Guten Tag,\nIhre Bestellung ist abholbereit."). Wir senden die Nachricht so, wie Sie sie übergeben; jeder Zeilenumbruch zählt als ein Zeichen.
SMS senden: curl, PHP, Python, Node.js, C#, Java
Ersetzen Sie in allen Beispielen CLIENT_ID:SECRET durch Ihren API-Schlüssel.
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())C# (.NET 6+, HttpClient)
using var http = new HttpClient();
http.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", "CLIENT_ID:SECRET");
var res = await http.PostAsJsonAsync("https://www.topsms.cz/api/sms/send",
new { to = "+420600000000", text = "Ahoj z .NET", from = "MojeFirma" });
Console.WriteLine(await res.Content.ReadAsStringAsync());Java (11+, java.net.http)
var req = HttpRequest.newBuilder(URI.create("https://www.topsms.cz/api/sms/send"))
.header("Authorization", "Bearer CLIENT_ID:SECRET")
.header("Content-Type", "application/json")
.POST(HttpRequest.BodyPublishers.ofString(
"{\"to\":\"+420600000000\",\"text\":\"Ahoj z Javy\",\"from\":\"MojeFirma\"}"))
.build();
var res = HttpClient.newHttpClient().send(req, HttpResponse.BodyHandlers.ofString());
System.out.println(res.body());Weitere Praxisbeispiele (Bestellbestätigung, Verify API, Terminerinnerung mit send_at, Rechnungsmahnungen per Massenversand, Statusabfrage, Webhook mit Signaturprüfung), jeweils in sechs Programmiersprachen, finden Sie in der tschechischen Dokumentation; der Code selbst ist sprachunabhängig.
Limits, IP-Whitelist und Absendername
- Rate-Limit: wird je Schlüssel einzeln festgelegt (Standard 60 Anfragen/min, im Dashboard bis 1000 einstellbar). Eine Massenanfrage zählt als eine Anfrage, auch wenn sie bis zu 500 Nachrichten enthält.
- IP-Whitelist: Beim Schlüssel können Sie optional nur bestimmte IP-Adressen Ihres Servers zulassen. Eine Anfrage von einer anderen IP-Adresse erhält 403.
- Absendername (Sender ID): eigener Absendername statt einer Rufnummer (Feld
from). Die meisten europäischen Netze, auch in Deutschland und Österreich, stellen alphanumerische Absendernamen ohne Registrierung zu. Für die tschechischen und slowakischen Netze geben die Netzbetreiber neue Absendernamen gesammelt etwa einmal im Monat frei (rechnen Sie mit ca. 3 Wochen), einmalige Gebühr 20,58 €. Die API akzeptiert nur freigegebene Absendernamen Ihres Kundenkontos (oder den Standard „TopSMS“); ein nicht freigegebener Name liefert 403. Ein freigegebener Name, den die Netzbetreiber noch nicht aktiviert haben, wird durch den Standard „TopSMS“ ersetzt, und die Antwort kennzeichnet dies im FeldsenderFallback. Details auf der Seite Eigener Absendername. - Blacklist: Als abgemeldet gekennzeichnete Nummern (manuell in den Kontaktdetails oder gesammelt per CSV-Import mit der Spalte optOut) weist die API automatisch mit dem Code 400 ab. Die Abmeldungen pflegen Sie, wir setzen sie durch.
- Nummernformat: Wir empfehlen E.164 (
+49…,+420…). Die API akzeptiert auch00420…, die Ländervorwahl ohne Plus und eine tschechische Nummer ohne Vorwahl; in der Antwort gibt sie die normalisierte Nummer im Feldtozurück. - Wiederholung nach Deutschland: Manche deutschen Netze melden „nicht zugestellt“ sofort, wenn das Telefon ausgeschaltet ist. In den Kontoeinstellungen können Sie die automatische Wiederholung aktivieren (bis zu 6 Versuche innerhalb von 8 Stunden); jeder Versuch wird als neue SMS berechnet, die Anzahl der Versuche und ihren Preis sehen Sie in der Historie. Das Feld
externalIdgehört dann zum letzten Versuch. - Schlüssel und Scopes: verwalten Sie im Dashboard im Bereich API-Zugang: Erstellen, Berechtigungen
send/read, IP-Whitelist, Webhook-URL, Aufrufprotokoll und Widerruf. Ein Testschlüssel (beim Erstellen ankreuzen) sendet und berechnet nichts. - Verify API: Der Code gilt 60 bis 1800 s (Standard 5 min), pro Code 5 Versuche, pro Rufnummer höchstens 5 Codes pro Stunde und 30 s Abstand zwischen zwei Codes. Ein neuer Code an dieselbe Nummer macht den vorherigen ungültig.
- Mehrere Schlüssel und Kostenverteilung: Im Kundenkonto können Sie bis zu 10 aktive Schlüssel mit eigenen Namen anlegen (z. B. nach Projekten oder Kostenstellen). Jede gesendete SMS wird einem konkreten Schlüssel zugeordnet.
- Nachweis der Quelle: In der Historie hat jede Nachricht eine Spalte „Quelle“ („API · Name des Schlüssels“, „Kampagne“, „Manuell“), nach der sich filtern lässt und die im CSV-Export enthalten ist, ideal für die interne Kostenverteilung.
https://www.topsms.cz.