Skip to main content

Requirements

  • An active paid plan
  • SMS credits in your workspace (purchase them from Billing in the dashboard)

Basic send

The response is 202 Accepted — delivery is asynchronous.

Sender ID (from)

The sender ID is the name or number the recipient sees as the sender of the SMS. Without a custom sender ID, omit from. Your messages go out with the Torpedo platform sender. With an approved custom sender ID (for example AcmePay), pass it in from:
Sender IDs are case-sensitive. from must match your approved sender ID exactly, letter for letter: if AcmePay is approved, acmepay and ACMEPAY are rejected with 422.
How from is resolved: Once your workspace has its own sender ID, the platform sender is no longer accepted in from. Omit from to use your default, or pass one of your approved sender IDs. A from that doesn’t belong to your workspace returns:

Requesting a custom sender ID

Email hello@torpedo.co.mz with:
  • the sender ID you want: up to 11 characters (letters, digits, spaces, ., _ or -, starting with a letter or digit), or a numeric short code;
  • the kind of messages you’ll send (for example verification codes or order updates).
Once it’s approved, we assign it to your workspace. Use the exact capitalization you requested when you send.

Test API keys

SMS sent with a test API key always use the platform sender, even if your workspace has its own sender ID. Omit from when sending with a test key.

Phone number format

The to field must be a valid Mozambican mobile number in E.164 format:
Accepted prefixes: 84, 82, 83, 85, 86, 87 (Vodacom, Movitel, tmcel).

SMS status lifecycle

undelivered usually points to a problem with the number or the phone, so check the number before sending again. failed points to a problem on the sending side, and is usually safe to retry. failureCategory gives the specific reason in both cases.
Before October 2026, operator-reported delivery failures used the failed status. They now use undelivered. If your integration checks status === "failed", also check for "undelivered".

Waiting for delivery confirmation

sent means the operator accepted the message, not that the phone received it. Operators confirm delivery with a delivery receipt, which can take from seconds to hours (for example, when the phone is switched off). Torpedo asks the operator to stop trying after 24 hours. The operator then reports the message as expired, and its status becomes undelivered. Some operators don’t send delivery receipts at all. If no receipt arrives within 25 hours, the status stays sent, deliveryState becomes unknown, and an sms.delivery_unknown webhook fires. A receipt that arrives later still updates the message. The deliveryState field gives more detail while a message is sent:
accepted and in_transit are informational. Not every operator reports them, so a message can go straight from submitted to its final status. Don’t build logic that waits for them.
The response also includes events, the delivery receipts received from the operator in order:
To be notified instead of polling GET /api/v1/sms/{id}, subscribe a webhook to sms.delivered, sms.undelivered, sms.failed and sms.delivery_unknown.

Idempotency

Pass an Idempotency-Key header to prevent duplicate sends on retries:
If a request with the same key was already accepted, Torpedo returns the original 202 without sending again. Keys are scoped to your workspace.

Credits and quota

Each SMS deducts one credit from your workspace balance. If your balance reaches zero, sends return 402:
Purchase additional credits from Billing in your dashboard. See SMS credits.

Suppression

Addresses that permanently fail delivery (UNDELIV, REJECTD SMPP error codes) are automatically added to the suppression list. Sending to a suppressed number returns 422:
Remove an address from the suppression list via DELETE /api/v1/suppressions/{address}?channel=sms.