Quick Start
Get Your API Key
Navigate to the API Keys section in your console and create a new key. You'll receive a key starting with otp_live_ for production or otp_test_ for sandbox mode.
Send Your First OTP
Make a POST request to send an OTP to your user's phone number.
curl -X POST https://api.flowauxi.com/v1/otp/send \
-H "Authorization: Bearer otp_live_YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"to": "+919876543210",
"purpose": "login",
"channel": "whatsapp"
}'Verify the OTP
After your user enters the OTP, verify it using the request_id from the send response.
curl -X POST https://api.flowauxi.com/v1/otp/verify \
-H "Authorization: Bearer otp_live_YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"request_id": "otp_req_abc123",
"otp": "123456"
}'Authentication
Bearer Token Authentication
All API requests must include your API key in the Authorization header. API keys are project-specific and can be managed from your console.
Authorization: Bearer otp_live_YOUR_API_KEYAPI Key Types
| Prefix | Environment | Description |
|---|---|---|
otp_live_ | Production | Live API key for production use. OTPs are actually delivered. |
otp_test_ | Sandbox | Test API key for development. OTPs are returned in response but not delivered. |
Rate Limits
Rate limits protect against abuse and ensure fair usage. Limits are applied per API key and per phone number.
| Limit Type | Default | Description |
|---|---|---|
| Per API Key | 60/minute | Total requests per minute across all phone numbers |
| Per Phone Number | 5/minute | OTP send requests to the same phone number |
| Per Phone (Hourly) | 10/hour | Maximum OTPs to same number per hour |
| Verification Attempts | 5 per OTP | Maximum wrong attempts before OTP is invalidated |
Send OTP
Request Headers
| Header | Required | Description |
|---|---|---|
| Authorization | Required | Bearer token with your API key |
| Idempotency-Key | Optional | UUID to prevent duplicate requests |
Request Body
| Parameter | Type | Required | Description |
|---|---|---|---|
| to | string | Required | Phone number in E.164 format (e.g., +919876543210) |
| purpose | string | Required | One of: login, signup, password_reset, transaction |
| channel | string | Optional | Delivery channel: whatsapp (default) or sms |
| otp_length | integer | Optional | OTP length: 4-8 digits (default: 6) |
| ttl | integer | Optional | Time to live in seconds: 60-600 (default: 300) |
| metadata | object | Optional | Custom metadata to store with the OTP request |
Example Request
{
"to": "+919876543210",
"purpose": "login",
"channel": "whatsapp",
"otp_length": 6,
"ttl": 300,
"metadata": {
"user_id": "usr_123",
"session_id": "sess_456"
}
}Success Response (200)
{
"success": true,
"request_id": "otp_req_abc123def456",
"expires_in": 300
}Sandbox Response (200)
{
"success": true,
"request_id": "otp_req_abc123def456",
"expires_in": 300,
"sandbox": true,
"otp": "123456"
}Verify OTP
Request Body
| Parameter | Type | Required | Description |
|---|---|---|---|
| request_id | string | Required | The request_id from the send response |
| otp | string | Required | The OTP code entered by the user |
Success Response (200)
{
"success": true,
"verified": true
}Failed Response (400)
{
"success": false,
"verified": false,
"error": "INVALID_OTP",
"message": "The OTP entered is incorrect",
"attempts_remaining": 4
}Resend OTP
Request Body
| Parameter | Type | Required | Description |
|---|---|---|---|
| request_id | string | Required | The request_id from the original send |
| channel | string | Optional | Force specific channel (whatsapp or sms) |
Success Response (200)
{
"success": true,
"request_id": "otp_req_abc123def456",
"expires_in": 300,
"channel": "sms",
"resend_count": 1
}Check Status
Path Parameters
| Parameter | Description |
|---|---|
| request_id | The request_id from the send response |
Success Response (200)
{
"success": true,
"request_id": "otp_req_abc123def456",
"status": "pending",
"delivery_status": "delivered",
"expires_at": "2024-01-01T12:05:00Z",
"attempts": 0,
"resend_count": 0
}Status Values
| Status | Description |
|---|---|
pending | OTP sent, waiting for verification |
verified | OTP successfully verified |
expired | OTP has expired |
failed | Max attempts exceeded |
Error Codes
Webhooks
Delivery Status Webhooks
Configure webhooks in your project settings to receive real-time delivery status updates. Webhooks are sent as POST requests with HMAC-SHA256 signature verification.
Webhook Payload
{
"event": "otp.delivered",
"request_id": "otp_req_abc123def456",
"phone": "+919876543210",
"channel": "whatsapp",
"status": "delivered",
"timestamp": "2024-01-01T12:00:00Z"
}Event Types
| Event | Description |
|---|---|
otp.sent | OTP has been sent to the delivery channel |
otp.delivered | OTP successfully delivered to recipient |
otp.failed | OTP delivery failed |
otp.verified | OTP has been verified successfully |
otp.expired | OTP has expired without verification |
Sandbox Mode
Testing Without Real Deliveries
Use test API keys (otp_test_) to test your integration without sending real OTP messages. In sandbox mode, the OTP is returned directly in the API response.
Sandbox Features
- OTPs are returned in the response (not delivered)
- No charges for sandbox requests
- Same rate limits as production
- Full webhook support