ZevSend Docs
Sign up

API Reference

Send SMS

POST /v1/sms — send a transactional SMS using a pre-approved template.

Send a transactional SMS to a phone number in international format.

POST /v1/sms

Request

curl https://api.zevsend.com/v1/sms \
  -H "Authorization: Bearer sk_live_..." \
  -H "Content-Type: application/json" \
  -d '{
    "to": "+2348012345678",
    "template_id": "tpl_01HXYZ...",
    "variables": {
      "code": "847291"
    }
  }'

Body parameters

FieldTypeRequiredDescription
tostringyesRecipient phone in E.164 (+ then country code then number, no spaces or dashes).
template_idstringyesTemplate public id (tpl_…). Must be an sms template.
variablesobjectsometimesValues for the template’s declared customer.* variables.
brand_domain_idstringnoPin the send to a specific verified domain (dom_…) for brand variables like {{brand.name}}.

Phone format

We accept international format only. Examples:

CountryFormat example
Nigeria+2348012345678
Kenya+254712345678
Ghana+233241234567
USA+12025550100

Sending without the + and country code returns 400 invalid_phone.

Response

HTTP/1.1 202 Accepted
Content-Type: application/json

{
  "id": "sms_01HXYZ...",
  "to": "+2348012345678",
  "status": "sending",
  "sandbox": false,
  "created_at": "2025-05-24T12:34:56.789Z"
}

Lifecycle

StateMeaning
queuedPersisted but not yet handed off.
sendingHanded off to the network; awaiting accept.
sentAccepted by the network and in transit.
deliveredConfirmed at the recipient’s handset.
failedRejected at submit or permanent delivery failure (out-of-window, etc.).

SMS has no bounced or complained state. Permanent failures land on failed.

Length limits

The rendered body is capped at 1600 characters. Longer bodies return 400 body_too_long. Two notes:

  • Standard GSM-7 messages are 160 characters per segment. Going over 160 splits across segments and is billed per segment.
  • Templates with lots of Unicode (emoji, non-Latin scripts) fall back to UCS-2, which drops the per-segment limit to 70 characters.

The dashboard preview shows the rendered length so you can spot accidental segment splits.

Pricing

SMS is priced per template, in your team’s billing currency. Open the template in the dashboard to see the rate. Each template carries a default per-send price plus any per-country overrides: sending to a recipient in a country with an override charges the override rate; everything else uses the default. The customer-facing rate already accounts for the underlying carrier and route, so you only ever read one number.

Credit drains the moment the carrier accepts the send. Carrier rejections never drain credit. See the Pricing guide for the full charge cascade (plan gate, credit check, dispatch, debit).

Errors

StatusCodeCause
400invalid_phoneto isn’t a valid E.164 number.
400body_too_longRendered SMS exceeds 1600 characters.
400template_id_requiredtemplate_id was missing.
404template_not_foundNo such template on this team.
409wrong_template_channelThe template is for email or WhatsApp.
422missing_variableA required variable was missing.
422unknown_variableYou passed a variable the template doesn’t declare.
403no_approved_brand_domainYou’re live but no approved domain exists for the team.
403recipient_not_allowedSandbox-only: recipient hasn’t been verified on this team.
503no_carrier_availableNo enabled carrier serves the destination region right now.

Sender ID

A sender ID is the label the recipient sees as the “from” on the message. Every send uses one of three:

  1. Your team-scope sender ID, when you’ve registered one through the dashboard and it’s been approved for the destination country.
  2. A ZevSend platform default, when your team hasn’t registered a country-matched sender ID yet. This is a pre-approved transactional sender we maintain so new teams can send OTPs and alerts on day one without waiting for their own sender ID to be reviewed.
  3. A network-provided ID, on routes where the carrier appends one regardless of submission.

The platform default lets you ship immediately. Once you want your own brand in the from field, register a team-scope sender ID under Settings → SMS → Sender IDs in the dashboard. We’ll review and approve it for the countries you select.

Costs and regions

SMS pricing varies by destination country. The dashboard Usage page shows your per-country breakdown. Some regions require local sender ID registration before delivery is allowed — your dashboard shows which sender ID we’ll use per country.

Updated at, Thursday, October 1, 2026