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 /dispatch

Send a verification code (OTP) or notification message to a phone number.

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 /verify

Validate 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
}