Entwickler
API-Referenz
Ein Endpunkt zum Senden, einer zum Abfragen des Status, HMAC-signierte Webhooks für Quittungen. API-Schlüssel werden ausgestellt, sobald das Konto existiert — es gibt nichts zu genehmigen und niemanden, dem man eine E-Mail schreiben müsste.
Erste Schritte
Drei Dinge stehen zwischen einem neuen Konto und einer zugestellten Nachricht: ein Token, etwas Guthaben und ein Schlüssel. Keines davon erfordert einen Menschen.
- Erstellen Sie ein Konto — Ihr Browser generiert den Token, und dieser Token ist das Konto.
- Laden Sie es auf. $40 Minimum, in jeder der Kryptowährungen auf die Zahlungsseite.
- Erstellen Sie einen API-Schlüssel im Dashboard. Er wird einmal angezeigt; wir speichern nur seinen Hash, genau wie beim Token.
Ein Schlüssel ohne Guthaben kann nicht senden
Die Schlüsselerstellung ist absichtlich hinter ein aufgeladenes Konto gesperrt. Ein ungenutztes Zugangsmerkmal, das herumliegt, ist eine Haftung ohne Nutzen, daher erzeugt das Dashboard keinen, bevor es etwas zu verwenden gibt.
Authentifizierung
Bearer-Token bei jeder Anfrage. Der Schlüssel identifiziert das Konto; es gibt keinen zweiten Faktor, keine Signatur der Anfrage und keine IP-Allowlist — der Schlüssel ist das gesamte Berechtigungsmerkmal, behandeln Sie ihn also so.
Authorization: Bearer ws_live_9f2c…
| Transport | Nur HTTPS. Eine Anfrage über einfaches HTTP wird abgelehnt, nicht weitergeleitet — eine Weiterleitung hätte den Schlüssel bereits preisgegeben. |
|---|---|
| Umfang | Ein Schlüssel belastet den Kontostand eines Kontos. Erstellen Sie einen Schlüssel pro sendendem System, damit ein Leak gezielt widerrufen werden kann. |
| Widerruf | Sofort. Ein widerrufener Schlüssel liefert bei der nächsten Anfrage 401; bereits angenommene laufende Batches werden noch abgeschlossen. |
| Wiederherstellung | Keine. Wir speichern einen Hash. Ein verlorener Schlüssel wird ersetzt, niemals wiederhergestellt. |
Nachrichten senden
POST/v1/messages
Ein Aufruf, ein oder mehrere Empfänger, gemischte Zielländer. Jeder Empfänger wird zum Preis seines eigenen Ziellands berechnet, pro Segment abgerechnet. Der Aufruf wird als Ganzes angenommen oder abgelehnt; er berechnet Ihnen nie nur einen Teil.
Request-Body
| Feld | Typ | Notizen |
|---|---|---|
to | string[] | Erforderlich. E.164, bis zu 5.000 pro Aufruf. Nummern, die sich keinem bepreisten Zielland zuordnen lassen, werden vor der Abrechnung abgelehnt. |
text | string | Erforderlich. UTF-8. Die Segmentanzahl folgt GSM 03.38 — siehe Segmente. |
from | string | Alphanumerische Absenderkennung, bis zu 11 Zeichen. Wird übertragen, wo die Route es zulässt; siehe Absenderkennungen. |
vars | object[] | Optionale Merge-Werte, ein Objekt pro Empfänger, die vor der Segmentzählung in die {{name}}-Platzhalter eingesetzt werden. |
callback_url | string | Optionale Überschreibung des Konto-Webhooks pro Batch. |
reference | string | Optional. Wird auf jeder Zustellbestätigung zurückgegeben, damit Sie es Ihren eigenen Datensätzen zuordnen können. |
Beispiel
# one call, many recipients, mixed destinations
curl -X POST https://api.worldsms.io/v1/messages \
-H "Authorization: Bearer $WORLDSMS_KEY" \
-H "Content-Type: application/json" \
-d '{
"from": "ACME",
"to": ["+447700900123", "+33612345678"],
"text": "Your code is 480913"
}'
{
"batch_id": "b_7Kq2xR9wLm",
"accepted": 2,
"rejected": 0,
"segments": 1,
"cost_usd": 0.0353
}
0,0137 $ ins Zielland Vereinigtes Königreich plus 0,0216 $ ins Zielland Frankreich — die Preisliste wird pro Ziel angewendet, nicht als Mischdurchschnitt.
Stapelverarbeitung
Ein Batch wird sofort angenommen und läuft mit 200 Nachrichten pro Minute und Konto ab, sodass 50.000 Empfänger etwa 4 Std. 10 Min dauern. Zeitkritischer Traffic sollte nicht hinter einem Marketing-Versand in der Warteschlange stehen: Verwenden Sie dafür einen separaten Schlüssel.
Nachrichtenstatus
GET/v1/messages/{batch_id}
Polling wird unterstützt und ist ratenbegrenzt; Webhooks sind der vorgesehene Weg. Die Antwort fasst den Batch zusammen und listet den Status je Empfänger auf.
{
"batch_id": "b_7Kq2xR9wLm",
"status": "done",
"sending": 0,
"delivered": 1,
"undelivered": 1,
"refund_usd": 0.0216
}
refund_usd wird einmal abgerechnet, wenn der Batch abgeschlossen ist. Es ist bereits wieder in Ihrem Kontostand, sobald Sie es lesen können.
Kontostand
GET/v1/balance
Prüfen Sie das vor einem großen Versand. Guthaben wird intern in ganzzahligen Mikro-Dollar geführt — Preise gehen auf vier Nachkommastellen, und eine Gleitkommazahl hat in einem Buchungsjournal nichts verloren — und hier auf sechs Stellen gerundet zurückgegeben.
{ "balance_usd": 412.905400, "currency": "USD" }
Zustellbestätigungen
Pro Empfänger wird eine Zustellbestätigung ausgegeben, sobald der Netzbetreiber sie meldet. Das sind die einzigen vier Zustände; es gibt keine Kategorie „unbekannt“, die stillschweigend „wir haben sie verloren“ bedeutet.
| Zustand | Bedeutung | Abgerechnet |
|---|---|---|
queued | Angenommen und wartet in der Warteschlange auf die Reihe. | Ja |
sent | An den Netzbetreiber übergeben, noch keine Bestätigung. | Ja |
delivered | Das Gerät hat es bestätigt. | Ja |
undelivered | Tot, gesperrt, oder der Absender wurde abgelehnt. | Erstattet |
Nummern, die sich nie einem bepreisten Ziel zuordnen lassen, werden schon bei der Übermittlung abgelehnt und treten in diesen Lebenszyklus gar nicht erst ein — sie werden nicht erst berechnet und dann erstattet, sie werden schlicht nicht berechnet.
Webhooks
Legen Sie im Dashboard oder pro Batch mit callback_url einen Endpunkt fest. Wir senden JSON per POST und erwarten einen 2xx innerhalb von 5 Sekunden. Nicht-2xx wird sechsmal mit exponentiellem Backoff über etwa eine Stunde wiederholt und dann verworfen.
Payload
{
"event": "message.delivered",
"batch_id": "b_7Kq2xR9wLm",
"to": "+447700900123",
"destination": "gb",
"segments": 1,
"cost_usd": 0.0137,
"reference": "order-4471",
"ts": 1785312041
}
Signatur wird überprüft
Jede Zustellung trägt X-WorldSMS-Signature und X-WorldSMS-Timestamp. Die Signatur ist HMAC-SHA256(timestamp + "." + body) unter Verwendung Ihres Webhook-Secrets. Vergleichen Sie in konstanter Zeit und lehnen Sie einen mehr als fünf Minuten alten Zeitstempel ab, damit eine abgefangene Zustellung Ihnen nicht später erneut vorgespielt werden kann.
// $secret is the webhook secret from the dashboard
$raw = file_get_contents('php://input');
$ts = $_SERVER['HTTP_X_WORLDSMS_TIMESTAMP'] ?? '';
$sig = $_SERVER['HTTP_X_WORLDSMS_SIGNATURE'] ?? '';
// A stale timestamp is a replay, however well it is signed.
if (abs(time() - (int) $ts) > 300) { http_response_code(408); exit; }
$mine = hash_hmac('sha256', $ts . '.' . $raw, $secret);
if (!hash_equals($mine, $sig)) { http_response_code(401); exit; }
http_response_code(204);
Idempotent sein
Ein erneuter Versuch nach einem Timeout Ihres Endpunkts sieht identisch mit einer ersten Zustellung aus. Verwenden Sie batch_id + to + event als Schlüssel und behandeln Sie eine Wiederholung als No-Op.
Fehler
Jeder Fehler liefert einen JSON-Body mit einem stabilen error-Slug zurück. Werten Sie den Slug aus, niemals den Text — der Text darf sich verbessern.
| HTTP | Slug | Was zu tun ist |
|---|---|---|
| 400 | invalid_body | Fehlerhaftes JSON oder ein fehlendes Pflichtfeld. |
| 401 | key_rejected | Fehlender, widerrufener oder falsch eingegebener Schlüssel. Nicht wiederholbar. |
| 402 | insufficient_credit | Der Stapel kostet mehr als der Kontostand. Es wurde nichts gesendet; aufladen und erneut einreichen. |
| 422 | no_valid_recipients | Keine einzige Nummer konnte einem bepreisten Zielland zugeordnet werden. |
| 422 | sender_id_invalid | from ist länger als 11 Zeichen oder enthält eine reine Ziffernfolge, die als Zahl gelesen würde. |
| 429 | rate_limited | Bremsen Sie ab. Retry-After enthält die Anzahl der Sekunden. |
| 503 | route_unavailable | Ein Zielland ist vorübergehend nicht erreichbar. Wiederholbar. |
{
"error": "insufficient_credit",
"message": "Batch costs $84.20, balance is $12.05.",
"required_usd": 84.20,
"balance_usd": 12.05
}
Limits
| Anfragen | 60 pro Minute pro Schlüssel, Spitze 20. Danach 429 mit Retry-After. |
|---|---|
| Empfänger pro Aufruf | 5,000. Größere Listen auf mehrere Aufrufe verteilen oder die Datei im Dashboard hochladen. |
| Nachrichtengröße | 2 MB. |
| Durchsatz | 200 Nachrichten pro Minute und Konto, unabhängig davon, wie viele Schlüssel senden. |
| Schlüssel | Kein Limit. Vorgesehen ist einer pro Sendesystem. |
Ratenlimits gelten für API-Aufrufe, nicht für Nachrichten: Ein Aufruf mit 5.000 Empfängern zählt als eine Anfrage gegen das Limit.
Schlüssel werden sofort ausgestellt. Es gibt keinen Freigabeschritt.
Laden Sie ein Konto auf, und das Dashboard erstellt sofort eines.