Zum Inhalt springen
smsbulk

Bulk-SMS-API v1

Eine kleine REST-API zum Versenden von Massen-SMS aus Ihrer eigenen Software: JSON ein- und ausgehend, Bearer-Schlüssel, die gleichen Preise und Prüfungen wie in der Konsole und signierte Webhooks für Zustellberichte. Basis-URL https://smsbulk.cc/rest/v1

Übersicht

Senden Sie bis zu 8,000 Nummern pro Anfrage, jede mit ihren eigenen Merge-Werten, und die API berechnet jeden Empfänger mit seinem eigenen zusammengeführten Text, genau wie die Konsole. Fordern Sie zuerst einen Kostenvoranschlag mit demselben Text an, um die Kosten zu kennen; durch einen Kostenvoranschlag wird nichts gesendet oder berechnet. Zeiten sind ISO 8601 in UTC, Geldbeträge sind Zeichenketten in US-Dollar mit fünf Dezimalstellen.

curl https://smsbulk.cc/rest/v1/send \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "recipients": [
      { "to": "+14155550142", "fields": { "name": "Maria" } },
      { "to": "+447400123456", "fields": { "name": "Tom" } }
    ],
    "text": "Hi {{name}}, your order ships today.",
    "client_ref": "order-batch-17"
  }'

Authentifizierung

Erstellen Sie einen Schlüssel in der Konsole unter API und Webhooks; Schlüssel werden nach Ihrer ersten gutgeschriebenen Aufladung freigeschaltet. Senden Sie ihn bei jeder Anfrage als Bearer-Token. Ein Schlüssel wird einmal angezeigt; Sie können bis zu 5 Schlüssel behalten und jeden davon sofort widerrufen.

Authorization: Bearer smsb_live_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

Preise

Öffentlich, kein Schlüssel erforderlich. Der Preis pro SMS-Segment für jedes Ziel oder für einen ISO-Code.

GEThttps://smsbulk.cc/rest/v1/rates

GEThttps://smsbulk.cc/rest/v1/rates/{ISO}

{
  "country": "US",
  "name": "United States",
  "dial_code": "+1",
  "rate": "0.00485",
  "currency": "USD",
  "per": "message segment"
}

Guthaben

GEThttps://smsbulk.cc/rest/v1/credit

{ "credit": "125.40000", "currency": "USD", "account": "A418820037715" }

Kostenvoranschlag

Berechnet den Versand, ohne ihn zu senden. Verwendet denselben Text wie Senden.

POSThttps://smsbulk.cc/rest/v1/quote

FeldBedeutung
toEine Nummer oder eine Liste. Die internationale Form mit + ist am sichersten; lokale Nummern benötigen default_country.
recipientsAnstelle von to: eine Liste von { to, fields }, wobei fields Merge-Felder wie {{name}} ausfüllen.
textDie Nachricht, bis zu 2,000 Zeichen und 10 Segmenten nach dem Zusammenführen.
default_countryISO-Code für Nummern, die ohne + geschrieben sind, wie GB. Greift auf den in den Einstellungen gespeicherten Standard zurück.
opt_outFügt Ihren gespeicherten Abmeldehinweis als letzte Zeile hinzu (speichern Sie ihn zuerst in den Einstellungen).
{
  "recipients": 2,
  "messages": 2,
  "segments": { "min": 1, "max": 1 },
  "encoding": "GSM-7",
  "total": "0.01240",
  "currency": "USD",
  "credit": "125.40000",
  "credit_after": "125.38760",
  "countries": [
    { "country": "US", "recipients": 1, "rate": "0.00485", "segments": 1, "subtotal": "0.00485" },
    { "country": "GB", "recipients": 1, "rate": "0.00755", "segments": 1, "subtotal": "0.00755" }
  ],
  "left_out": []
}

Senden

Erstellt eine Kampagne, zieht den Gesamtbetrag von Ihrem Guthaben ab und reiht die Nachrichten ein. Antwortet mit 201 und der Kampagne. Nummern, die nicht gesendet werden können, werden in left_out aufgeführt und nie berechnet.

POSThttps://smsbulk.cc/rest/v1/send

FeldBedeutung
to / recipients / text / default_country / opt_outWie in Quote.
send_atISO 8601-Zeit zum Starten, 5 Minuten bis 90 Tage im Voraus. Lassen Sie es weg, um jetzt zu senden.
nameIhr Label für die Kampagne, bis zu 80 Zeichen.
client_refIhr eigener Verweis, bis zu 64 Zeichen, wird bei jeder Nachricht und jedem Webhook zurückgegeben.
HTTP/1.1 201 Created
{
  "campaign": {
    "id": "C507318264409",
    "name": null,
    "status": "sending",
    "source": "api",
    "test": false,
    "recipients": 2,
    "cost": "0.01240",
    "refunded": "0.00000",
    "net_cost": "0.01240",
    "currency": "USD",
    "send_at": null,
    "created_at": "2026-11-07T14:02:11.000Z",
    "started_at": "2026-11-07T14:02:11.000Z",
    "finished_at": null,
    "client_ref": "order-batch-17"
  },
  "messages": 2,
  "left_out": []
}

Kampagnen

GEThttps://smsbulk.cc/rest/v1/campaigns?limit=25&before={id}

GEThttps://smsbulk.cc/rest/v1/campaigns/{id}

GEThttps://smsbulk.cc/rest/v1/campaigns/{id}/messages?status=failed&limit=100&after={message id}

Eine einzelne Kampagne enthält Zählungen pro Status: eingereiht, gesendet, zugestellt, fehlgeschlagen und abgebrochen. Nachrichtenlisten-Seite mit after und has_more; bis zu 1.000 pro Seite.

Nachrichten

GEThttps://smsbulk.cc/rest/v1/messages/{id}

GEThttps://smsbulk.cc/rest/v1/messages?to=%2B14155550142&status=delivered&client_ref=order-batch-17&limit=50

{
  "id": "M220947781305",
  "campaign": "C507318264409",
  "to": "+14155550142",
  "country": "US",
  "segments": 1,
  "encoding": "GSM-7",
  "price": "0.00485",
  "status": "delivered",
  "reason": null,
  "reason_text": null,
  "refunded": false,
  "client_ref": "order-batch-17",
  "created_at": "2026-11-07T14:02:11.000Z",
  "sent_at": "2026-11-07T14:02:12.000Z",
  "finished_at": "2026-11-07T14:02:16.000Z"
}

Eine geplante Kampagne abbrechen

POSThttps://smsbulk.cc/rest/v1/campaigns/{id}/cancel

Funktioniert bis zum Startzeitpunkt. Die gesamten Kosten werden in einer Buchungszeile auf Ihr Guthaben zurückerstattet und der Kampagnenstatus wird auf abgebrochen gesetzt.

Webhooks

Setzen Sie eine Endpunkt-URL in der Konsole. Wir POSTEN JSON für message.delivered, message.failed und campaign.done, plus Test, wenn Sie Testereignis senden drücken. Jedes Ereignis trägt vier Header, und jede 2xx-Antwort innerhalb von 10 Sekunden gilt als empfangen.

FeldBedeutung
Smsbulk-EventEreignisname, wie message.delivered.
Smsbulk-DeliveryLieferungs-ID, die bei jedem erneuten Versuch eines Ereignisses gleich ist.
Smsbulk-TimestampUnix-Sekunden, als dieser Versuch signiert wurde.
Smsbulk-Signaturesha256= gefolgt von der base64 HMAC-SHA256 von Zeitstempel, einer neuen Zeile und dem rohen Body, mit Ihrem sbw_ Geheimnis verschlüsselt.

Die Zustellung wird 8 Mal versucht: sofort, dann nach 1 Minute, 5 Minuten, 15 Minuten, 1 Stunde, 3 Stunden, 6 Stunden und 12 Stunden. Jeder Versuch wird im Zustellungsprotokoll der Konsole mit seinem HTTP-Status und dem Anfang Ihrer Antwort angezeigt.

{
  "id": "dlv_3f9a1c07b2e44d58a6c1",
  "event": "message.failed",
  "created": "2026-11-07T14:02:16.000Z",
  "data": {
    "message": "M220947781305",
    "campaign": "C507318264409",
    "to": "+447400123456",
    "country": "GB",
    "status": "failed",
    "reason": "not_in_service",
    "segments": 1,
    "price": "0.00755",
    "client_ref": "order-batch-17"
  }
}

Signatur überprüfen

import crypto from "node:crypto";

// raw = the request body exactly as received (string), secret = your sbw_ signing secret
export function verify(raw, headers, secret) {
  const ts = headers["smsbulk-timestamp"];
  const want = "sha256=" + crypto.createHmac("sha256", secret).update(ts + "\n" + raw).digest("base64");
  const got = headers["smsbulk-signature"] || "";
  const fresh = Math.abs(Date.now() / 1000 - Number(ts)) < 300;
  return fresh && got.length === want.length && crypto.timingSafeEqual(Buffer.from(got), Buffer.from(want));
}

Fehler und Limits

Fehler verwenden den HTTP-Status und einen JSON-Body: {"error":{"code":"insufficient_credit","message":"..."}}. Es wird nichts berechnet, wenn eine Anfrage fehlschlägt.

FeldBedeutung
400 bad_jsonDer Body ist kein JSON.
401 unauthorizedFehlender, fehlerhafter oder widerrufener Schlüssel.
402 insufficient_creditDer Gesamtbetrag übersteigt Ihr Guthaben. Laden Sie Guthaben in der Konsole auf.
404 not_foundEs gibt keinen solchen Endpunkt, keine Kampagne, keine Nachricht oder keinen ISO-Code in diesem Konto.
409 not_scheduledEs wurde eine Stornierung für eine Kampagne angefordert, die bereits gestartet ist.
422 text_missing, text_too_long, too_many_segmentsNachricht leer, über 2,000 Zeichen oder über 10 Segmente für einen Empfänger.
422 no_recipients, too_many, recipients_missingKeine sendbare Nummer, mehr als 8,000 Nummern oder weder an noch Empfänger.
422 schedule_range, bad_send_atsend_at außerhalb von 5 Minuten bis 90 Tagen oder keine gültige Zeit.
422 opt_out_unsetopt_out ist wahr, aber es ist kein Text in den Einstellungen gespeichert.
429 rate_limitedMehr als 300 Anfragen pro Minute für diesen Schlüssel.

Jede Antwort enthält X-RateLimit-Limit, X-RateLimit-Remaining und X-RateLimit-Reset.

Ausgelassene Codes

Nummern, die vor der Preisberechnung entfernt wurden, werden in left_out mit ihrer Position in Ihrer Liste, dem gesendeten Wert, einem Code und dem Grund zurückgegeben.

FeldBedeutung
no_country_codeKein + und kein Standardland.
too_short / too_longWeniger als 8 oder mehr als 15 Ziffern.
not_a_numberBuchstaben oder Symbole, die nicht Teil einer Nummer sind.
nanp_lengthEine +1 Nummer ohne elf Ziffern.
not_coveredEin Ziel außerhalb unserer Liste.
duplicateDie gleiche Nummer erschien früher in der Anfrage.
suppressedDie Nummer steht auf Ihrer Nicht-Senden-Liste.

Status und Gründe

FeldBedeutung
queuedWarten darauf, unsere Warteschlange zu verlassen.
sentAn das Netzwerk übergeben, warten auf den Zustellbericht. Die meisten Berichte kommen innerhalb von Minuten an; einige Netzwerke benötigen bis zu 24 Stunden.
deliveredDas Netzwerk hat bestätigt, dass das Telefon es erhalten hat.
failedNicht zugestellt. Der Betrag wurde auf Ihr Guthaben zurückerstattet.
canceledNicht gesendet, weil Sie storniert haben. Rückerstattet.
FeldBedeutung
network_errorNetzwerkfehler
switched_offTelefon ausgeschaltet oder außerhalb der Reichweite
not_in_serviceNummer nicht im Dienst
blockedVom Netzwerk oder Empfänger blockiert
landlineFestnetznummer oder Nummer, die keine SMS empfangen kann
content_filterVom Inhaltsfilter des Netzwerks abgelehnt
expiredAbgelaufen: Kein Bericht vor der Zeitbegrenzung des Netzwerks
unknownUnbekannte Netzwerkantwort
canceledVor dem Senden abgebrochen

Fragen zur API? Öffnen Sie ein Ticket in der Konsole oder lesen Sie die FAQ.

Bulk SMS API v1 Dokumentation: Senden, Preisabfrage, Webhooks | SMSBulk