Send an SMS

Send one transactional SMS.

POSThttps://app.usenotix.dev/api/v1/sms

Full access and sending access keys can call this. Key permissions lists the extra rules some calls have.

Send one transactional SMS. The message is charged to your wallet when it is queued and delivered by the route Notix has configured for the destination country. Delivery status arrives through the sms.sent, sms.delivered and sms.failed webhooks, or by reading the message back.

Pricing

One GSM-7 message is up to 160 characters; longer text is billed per 153 character segment. Text with characters outside GSM-7 is billed per 70 characters (67 when concatenated). SMS needs no paid plan: it is prepaid from your wallet.

Sender ID

senderId is optional. It defaults to your team's own approved sender ID for the destination country, or to the shared Notix sender ID when you have none. Only a sender ID approved for your team is accepted. See SMS and sender IDs.

Errors

StatusCodeMeaning
400BAD_REQUESTThe number is not valid E.164, the text is empty or over 1,600 characters, or the sender ID is not one you may use.
402INSUFFICIENT_BALANCEYour wallet cannot cover the message. Nothing was sent.
403FORBIDDENSMS is not enabled for your team.
409NOT_UNIQUEThe idempotency key was used with a different body.
422RISK_REFUSEDRisk scoring refused the request.

Idempotency

Pass an Idempotency-Key header to make a retry safe for 24 hours. The same key and body answers the original result without sending again, with the response header Idempotent-Replayed: true. The same key with a different body answers 409 NOT_UNIQUE; the same key while the first request is still running answers 409 too, so retry shortly. Keys are scoped to the API key.

Dry run

Send the header Notix-Dry-Run: true to see what the request would do without doing it. The answer is 200 with dryRun: true: who it would reach, what they would see, what it would cost, a verdict (allowed and every reasons it would be refused for) and the limits it would count against. Nothing is sent, charged, reserved or written, and the call is recorded in the audit log as a dry run. A write route that cannot preview answers 400.

Body parameters

tostringrequired

The recipient phone number with its country code.

textstringrequired

The message. Up to 1600 characters. GSM-7 text is billed in 160 character segments (153 when concatenated); text with other characters in 70 (67).

At most 1,600 characters.

senderIdstring

A sender ID approved for this team. Defaults to the team's own approved sender ID for the country, or to the shared Notix sender ID when it has none.

At most 11 characters.

clientIpstring (ip)

The IPv4 or IPv6 address the end user made the request from. Used by risk scoring. Notix stores only a keyed hash of it.

Headers

Authorizationstringrequired

Bearer followed by your API key.

Idempotency-Keystring

Makes the request safe to retry. Same key and same body returns the original message, with the response header Idempotent-Replayed: true. Same key and a different body answers 409 NOT_UNIQUE.

Notix-Dry-Runstring

Set to true to preview the request instead of running it. The answer is 200 with dryRun: true: who it would reach, what they would see, what it would cost, whether policy allows it and the limits it counts against. Nothing is sent, charged, reserved or written. A write route that cannot preview answers 400.

Errors

400

Invalid input: the number, the text length or the sender ID.

402

The team wallet cannot cover the message. Nothing was sent. The message names the shortfall only to a key a team admin or the owner made.

403

SMS is not enabled for this team, the environment refuses this destination, or the key may not spend the wallet on SMS (created by a team member without admin rights, or a send-only key where those are not allowed SMS).

409

The Idempotency-Key was used with a different body, or a request with it is in progress.

422

Risk scoring refused the request, or too many messages went to this number in the last hour. Nothing was sent.

429

The team reached its daily SMS spending limit (UTC day). Nothing was sent. Contact support to raise it.

503

SMS is briefly unavailable (its spend checks cannot run), so the message was not sent. Try again shortly. One-time codes from POST /v1/verify/send are not affected.

Every error has the same shape. See all error codes.

curl -X POST "https://app.usenotix.dev/api/v1/sms" \
  -H "Authorization: Bearer $NOTIX_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
  "to": "+2348012345678",
  "text": "Your order 4471 has shipped."
}'
Response200
{
  "dryRun": true,
  "kind": "string",
  "verdict": {
    "allowed": true,
    "reasons": [
      "string"
    ]
  },
  "checks": [
    "string"
  ]
}
Open in ClaudeOpen in ChatGPT