API Overview
This page covers the fundamental conventions and patterns used across the SFVoPI API.
Base URL
All API requests are made to:
https://prod-api.superfone.co.in/superfone
Example endpoint:
https://prod-api.superfone.co.in/superfone/sfvopi/apps
Request Format
Content Type
All requests with a body must use JSON format with the Content-Type: application/json header.
Example:
curl -X POST https://prod-api.superfone.co.in/superfone/sfvopi/apps \
-H "X-API-Key: your_api_key_here" \
-H "Content-Type: application/json" \
-d '{"name":"My App","answer_url":"https://example.com/answer"}'
Authentication
Every request requires the X-API-Key header. See Authentication for details.
Response Format
All API responses follow a consistent envelope structure.
Success Response
Successful requests return a 200 OK or 201 Created status with this format:
{
"data": {
// Actual response data (object, array, or primitive)
},
"message": "success"
}
Example (Create App):
{
"data": {
"app_id": "app_abc123xyz",
"org_id": 42,
"name": "My Voice App",
"answer_url": "https://example.com/answer",
"answer_method": "POST",
"status": "ACTIVE",
"created_at": "2026-02-02T10:30:00.000Z"
},
"message": "success"
}
Example (List Apps):
{
"data": [
{
"app_id": "app_abc123",
"name": "App 1",
"status": "ACTIVE"
},
{
"app_id": "app_def456",
"name": "App 2",
"status": "ACTIVE"
}
],
"message": "success"
}
Error Response
Failed requests return an appropriate HTTP status code with this format:
{
"message": "Error description"
}
Example (401 Unauthorized):
{
"message": "UnAuthorized, Please Provide Valid API Key"
}
Example (400 Bad Request):
{
"message": "Invalid phone number"
}
Example (404 Not Found):
{
"message": "App not found"
}
All examples in this documentation show the full response envelope ({ data, message } for success, { message } for errors).
HTTP Status Codes
The API uses standard HTTP status codes to indicate success or failure:
| Status Code | Meaning | Description |
|---|---|---|
200 OK | Success | Request succeeded (GET, PUT, DELETE) |
201 Created | Created | Resource created successfully (POST) |
400 Bad Request | Client Error | Validation failed or invalid request parameters |
401 Unauthorized | Auth Error | Missing or invalid API key |
404 Not Found | Not Found | Requested resource doesn't exist |
409 Conflict | Conflict | Resource conflict (e.g., duplicate number link) |
429 Too Many Requests | Call limit | Call not placed: a number, app or organization call limit was reached. See Call Limits |
500 Internal Server Error | Server Error | Unexpected server error occurred |
502 Bad Gateway | Gateway Error | Webhook failed or unreachable |
Phone Number Format
All phone numbers in the API use E.164 format:
- International format with
+prefix - Country code + subscriber number
- No spaces, dashes, or parentheses
Valid examples:
+918000000001(India)+14155552671(USA)+442071234567(UK)
Invalid examples:
8000000001(missing country code)+91 80000 00001(contains spaces)+91-8000000001(contains dashes)
The API automatically validates and normalizes phone numbers. If you provide an invalid number, you'll receive a 400 Bad Request error with message "Invalid phone number".
Pagination
Currently, pagination is not available on list endpoints. All list endpoints return the complete set of results.
Example (List Apps):
GET /sfvopi/apps
# Returns ALL apps for your organization
Pagination support is planned for a future release. For now, list endpoints return all matching records.
Call Limits
Organization call limits ship with the org-limits release.
Every call, outbound and inbound, is checked against these limits:
| Limit | Applies to | Set by | Direction |
|---|---|---|---|
| Concurrent calls, CPS and peak CPS | Your whole organization: all your SFVoPI apps and SF Trunks together | Superfone, for your account | Inbound and outbound count together |
| Concurrent calls, CPS and peak CPS | Each SFVoPI app. Optional | You, with Update App | Inbound and outbound count together |
| Concurrent calls | Each phone number | Your plan | Inbound and outbound counted separately |
The organization limits are a pool shared by all your apps and trunks. Read them with Get Call Limits. To raise them, contact support.
An app's own limits are concurrent_limit, cps_limit and cps_burst. Each is null by default, which means only the organization pool applies. You can set a lower limit for an app, but never a higher one than your organization's.
Outbound calls over any limit are not placed. Initiate Call returns 429 Too Many Requests:
code | message | Which limit |
|---|---|---|
CHANNEL_LIMIT_REACHED | Concurrent call limit reached for this number. Please retry when a call ends. | The from number's concurrent call limit, or your app's own concurrent_limit |
CPS_LIMIT_REACHED | Calls per second limit exceeded. Please retry after a second. | Your app's own CPS limit |
ORG_CHANNEL_LIMIT_REACHED | Concurrent call limit reached for your organisation | Your organization's total concurrent calls |
ORG_CPS_LIMIT_REACHED | Calls-per-second limit reached for your organisation | Your organization's total CPS |
{
"message": "Calls-per-second limit reached for your organisation",
"code": "ORG_CPS_LIMIT_REACHED"
}
Inbound calls over any limit are rejected with SIP 503 Service Unavailable before they are answered. The caller hears a network-busy tone, and your answer_url is not called.
Other API requests are not rate limited, except where an endpoint says so.
Idempotency
The API does not currently support idempotency keys. Retrying a failed POST request may create duplicate resources.
Best practice: Implement retry logic with exponential backoff and check for existing resources before creating new ones.
Timestamps
All timestamps in API responses use ISO 8601 format with UTC timezone:
2026-02-02T10:30:00.000Z
Fields:
created_at— When the resource was createdupdated_at— When the resource was last modifiedanswered_at— When a call was answeredended_at— When a call ended
Error Handling Best Practices
When consuming the API:
- Always check HTTP status codes before parsing response body
- Handle
401errors by verifying your API key - Handle
400errors by validating input before sending requests - Handle
502errors by ensuring your webhook URLs are accessible - Implement retry logic with exponential backoff for
500errors - Log error messages from the
messagefield for debugging
Example (JavaScript):
const response = await fetch('https://prod-api.superfone.co.in/superfone/sfvopi/apps', {
method: 'POST',
headers: {
'X-API-Key': process.env.SFVOPI_API_KEY,
'Content-Type': 'application/json'
},
body: JSON.stringify({ name: 'My App', answer_url: 'https://example.com/answer' })
});
if (!response.ok) {
const error = await response.json();
console.error(`API Error (${response.status}):`, error.message);
throw new Error(error.message);
}
const { data } = await response.json();
console.log('App created:', data);
Next Steps
Now that you understand the API conventions:
- Apps API — Create and manage voice applications
- Numbers API — Link phone numbers to apps
- Calls API — Initiate and manage calls
- Call Limits — Read your organization's call limits
- Webhooks — Handle call events
- Whatsapp API - Send & receive Whatsapp API messages