Need a Sandbox?
Create a free account to access Test Numbers and create custom OTP templates.
Developer API
Integrate SMS verification into your application in minutes. Our API is RESTful, accepts JSON payloads, and returns JSON responses.
Base URL: https://gatewire.raystate.com/api/v1
Authentication
Authenticate requests by passing your **API Token** in the `Authorization` header.
Authorization: Bearer YOUR_API_TOKEN
You can generate or revoke tokens in your Account Settings.
Send SMS
POST /dispatchSend a verification code (OTP) or notification message to a phone number.
New: Message Templates
Pass a
template_key instead of raw text. The system automatically inserts the OTP
code into your defined placeholder.
Body Parameters
| Field | Type | Description |
|---|---|---|
| recipient | string | Required Phone number in
international format (e.g. +213555...) |
| template_key | string |
The unique key of your approved template (e.g. login_otp).
Recommended for compliance. |
| body | string |
The raw message content.
Required only if template_key is
omitted.
|
curl -X POST "https://gatewire.raystate.com/api/v1/dispatch" \
-H "Authorization: Bearer YOUR_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"recipient": "+2135550123",
"template_key": "login_otp"
}'
$client = new \GuzzleHttp\Client();
$response = $client->post('https://gatewire.raystate.com/api/v1/dispatch', [
'headers' => [
'Authorization' => 'Bearer YOUR_TOKEN',
'Accept' => 'application/json',
],
'json' => [
'recipient' => '+2135550123',
// Option 1: Use Template (Recommended)
'template_key' => 'login_otp',
// Option 2: Raw Body (Legacy)
// 'body' => 'Your code is 123456',
],
]);
echo $response->getBody();
import requests
url = "https://gatewire.raystate.com/api/v1/dispatch"
headers = {
"Authorization": "Bearer YOUR_TOKEN",
"Content-Type": "application/json"
}
# Use template_key for approved messages
data = {
"recipient": "+2135550123",
"template_key": "login_otp"
}
response = requests.post(url, json=data, headers=headers)
print(response.json())
const response = await fetch('https://gatewire.raystate.com/api/v1/dispatch', {
method: 'POST',
headers: {
'Authorization': 'Bearer YOUR_TOKEN',
'Content-Type': 'application/json'
},
body: JSON.stringify({
recipient: '+2135550123',
template_key: 'login_otp'
// Or use body: 'Raw message...'
})
});
const data = await response.json();
console.log(data);
Response
{
"success": true,
"data": {
"reference_id": "9b1deb4d-3b7d...", // Save this for verification
"status": "queued",
"using_template": "login_otp"
}
}
Verify Code
POST /verifyValidate the code the user entered against the reference ID returned from the dispatch endpoint.
Body Parameters
| Field | Type | Description |
|---|---|---|
| reference_id | string | The ID returned by the /dispatch endpoint. |
| code | string | The 4-8 digit code entered by the user. |
curl -X POST "https://gatewire.raystate.com/api/v1/verify" \
-H "Authorization: Bearer YOUR_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"reference_id": "YOUR_REFERENCE_ID",
"code": "123456"
}'
$response = $client->post('https://gatewire.raystate.com/api/v1/verify', [
'headers' => ['Authorization' => 'Bearer TOKEN'],
'json' => [
'reference_id' => 'YOUR_REFERENCE_ID',
'code' => '123456',
],
]);
echo $response->getBody();
const response = await fetch('https://gatewire.raystate.com/api/v1/verify', {
method: 'POST',
headers: {
'Authorization': 'Bearer YOUR_TOKEN',
'Content-Type': 'application/json'
},
body: JSON.stringify({
reference_id: 'YOUR_REFERENCE_ID',
code: '123456'
})
});
Response
// 200 OK
{
"status": "verified",
"message": "Phone number verified..."
}
// 400 Bad Request
{
"status": "failed",
"error": "Invalid code.",
"attempts_remaining": 4
}