/Send a code

API docs

Send a code

Already generate your own OTP? Send it with one call and OTPRelay delivers it from the pre-cleared sender, with automatic route and operator failover and SMS-pumping protection. You verify the code on your side.

POST/v1/messages

You generate the OTP; OTPRelay just delivers it. POST the to number and the code you generated, and we wrap it in the pre-cleared template and send the SMS from the OTPRelay sender, with automatic route and operator failover. The response is a message object with status: "sent".

The sender is always OTPRelay and the message template is fixed - your code is injected into the same template described in Sender & message, with the same SMS-pumping protection as the Verify API.

Request body

tostringrequired
The destination phone number in E.164 format, e.g. +966512345678.
codestringrequired
The one-time passcode you generated, 4-10 characters. OTPRelay delivers it as-is inside the pre-cleared template - it never generates or checks it.
webhook_urlstringoptional
An HTTPS URL to receive this message's delivery events. See Webhooks & events.
metadataobjectoptional
Up to 10 key/value pairs echoed back on the message and its webhook events.

Request

POST /v1/messages
curl https://api.otprelay.io/v1/messages \  -H "Authorization: Bearer sk_live_••••" \  -H "Content-Type: application/json" \  -d '{ "to": "+966512345678", "code": "418207" }'

Response

Returns 201 Created with the message. Track delivery via the status field - pending, sent, delivered, or undelivered - and your webhook_url, including any automatic route failover.

201 Created
{  "id": "msg_01HZX9Q2K3M7B8N4P5R6S7T8U9",  "object": "message",  "status": "sent",  "to": "+966512345678",  "country": "SA",  "sender": "OTPRelay",  "code_length": 6,  "carrier": "stc",  "webhook_url": "https://api.yourapp.com/otp/webhook",  "metadata": { "user_id": "u_8842" },  "created_at": "2026-06-16T10:00:00Z"}

You own verification

OTPRelay does not store or check the code in Send mode - compare it on your side. Want it managed instead? Use the Verify API.

New here? Start with the Quickstart.