Skip to main content

API overview

The SF Trunk API lets you manage the trunks on your Superfone account and the numbers attached to them, with an API key or as the owner or a manager of the account. You can create, list, view, update and delete trunks, and attach and detach numbers.

Superfone sets your organisation's call limits and can suspend a trunk. You can set lower limits for each trunk. Superfone manages the provisioning behind each trunk, and there are no customer endpoints for it.

Base URL​

All requests go to:

https://prod-api.superfone.co.in/superfone

Example endpoint:

https://prod-api.superfone.co.in/superfone/sf-trunks

Authentication​

Every request must carry one of these:

  • An API key in the X-API-Key header. This is the same API key that SFVoPI uses.
  • The session of a Superfone user who is signed in as the owner or a manager of the account. Other roles get 403.

Both give you the same operations. Superfone sets your organisation's call limits and can suspend trunks, so you cannot change those with a key or a session.

The account comes from the key or the session. You can only see and change trunks that belong to that account. No request takes an account ID.

If a request has an X-API-Key header, only the key is checked. A key that is not valid gets 401, even if the request also carries a session.

Create an API key in the web dashboard under Settings → API keys. If your account already has an API key, for example for SFVoPI, the same key works for this API.

Anyone who holds the key can use every operation in this reference on your trunks. Keep it on your servers, never in a browser or app. See Security best practices.

The examples in this reference send an API key with the placeholder your_api_key_here. To use a session instead, send it as a Cookie header in place of X-API-Key.

Request format​

Send request bodies as JSON with the Content-Type: application/json header.

curl -X POST https://prod-api.superfone.co.in/superfone/sf-trunks \
-H "X-API-Key: your_api_key_here" \
-H "Content-Type: application/json" \
-d '{"customer_sip_host":"pbx.example.com"}'

Write phone numbers in E.164 format with a leading + and the country code, for example +91XXXXXXXXXX.

Response format​

Success response​

A successful request returns 200 OK, including when it creates a trunk. The body has this envelope:

{
"data": {
"sf_trunk": {}
},
"message": "success"
}

What is inside data depends on the endpoint. Each endpoint's page shows it.

Error response​

A failed request returns an HTTP error status and a message:

{
"message": "SF trunk not found"
}

HTTP status codes​

Status CodeMeaningWhen It Occurs
200 OKSuccessThe request worked
400 Bad RequestValidation failedA field is missing or invalid, a number is malformed or not on your account, or the trunk ID is not a positive whole number
401 UnauthorizedNo valid key or sessionThe API key is not valid, or the request has no key and no session, the session has expired, or it is not signed in to an account
403 ForbiddenNot allowedYou are signed in with a session, but not as the owner or a manager of the account
404 Not FoundNot foundThe trunk does not exist or belongs to another account, or the number is not attached to this trunk
409 ConflictNumber in useA number is linked to an SFVoPI app, attached to another trunk, or not in service
500 Internal Server ErrorServer errorSomething failed on our side

The messages you will see:

Status CodeMessage
400A validation message, for example Required or customer_sip_host must be a public hostname or IPv4 address. Several failures are joined with commas
400Invalid SF trunk id
400<field> cannot exceed your organisation limit of <n>
401UnAuthorized, Please Provide Valid API Key
401UnAuthorized, Please Login
401UnAuthorized, Please Login to Organisation
403Only owners and managers can perform this action
404SF trunk not found

Errors for attaching and detaching numbers are listed in Numbers.

Send us the real error

If a request fails and you need help, email hello@superfone.in with SF Trunk in the subject. Include the method and path, the request body, the status code and the full response body, exactly as you received them. A copy of the real error lets us find the cause much faster than a description of it. Never send your API key or session cookie.

The trunk object​

Endpoints that return a trunk use this object:

{
"id": 101,
"label": "a1b2c3d4",
"org_id": 12345,
"customer_sip_host": "pbx.example.com",
"customer_sip_port": 5060,
"customer_sip_transport": "udp",
"customer_sip_fallback_host": null,
"customer_sip_fallback_port": null,
"customer_sip_fallback_transport": null,
"cps_limit": 10,
"cps_burst": 20,
"concurrent_limit": 30,
"status": "active",
"call_recording": null,
"created_at": "2026-02-02T10:30:00.000Z",
"updated_at": "2026-02-02T11:05:00.000Z",
"fqdn": "a1b2c3d4.sft.superfone.co.in"
}
FieldTypeWho sets itDescription
idnumberSuperfoneThe trunk ID. Use it in the path of the other endpoints
labelstringSuperfoneEight lowercase characters, generated when the trunk is created. It never changes
org_idnumberSuperfoneYour Superfone account ID
customer_sip_hoststringYouPublic hostname or IPv4 address of your SIP server. We deliver inbound calls here
customer_sip_portnumberYouPort of your SIP server
customer_sip_transportstringYouTransport for calls to your SIP server. Accepts udp, tcp or tls. udp and tcp are supported today, tls is not. See Transport
customer_sip_fallback_hoststring | nullYouPublic hostname or IPv4 address of your fallback server. We try it once when your primary server is down. null means no fallback. See Fallback destination
customer_sip_fallback_portnumber | nullYouPort of your fallback server. 5060 when a fallback host is set
customer_sip_fallback_transportstring | nullYouTransport for calls to your fallback server. null uses the same transport as your primary server
cps_limitnumber | nullYouThe trunk's own limit on new calls per second. null means only your organisation's limit applies
cps_burstnumber | nullYouThe trunk's own peak CPS. null means only your organisation's limit applies
concurrent_limitnumber | nullYouThe trunk's own limit on calls in progress at once. null means only your organisation's limit applies
statusstringSuperfoneactive or suspended. A suspended trunk takes no calls. Read-only
call_recordingboolean | nullYoutrue or false sets call recording for the trunk. null follows the call recording setting of each number
created_atstringSuperfoneISO 8601 timestamp, UTC
updated_atstringSuperfoneISO 8601 timestamp, UTC
fqdnstringSuperfone<label>.sft.superfone.co.in, the address your PBX sends outbound calls to
Org-limits release

Trunk limits you can set, and organisation limits, ship with the org-limits release.

Set the trunk's limits with Update a trunk. They cannot exceed your organisation's limits, which you can read with Get Call Limits. To raise your organisation's limits, or to suspend a trunk, email hello@superfone.in. See Limits and billing.

TypeScript types​

The TypeScript examples in this reference use these types:

type SfTrunkTransport = 'udp' | 'tcp' | 'tls';

interface SfTrunk {
id: number;
label: string;
org_id: number;
customer_sip_host: string;
customer_sip_port: number;
customer_sip_transport: SfTrunkTransport;
customer_sip_fallback_host: string | null;
customer_sip_fallback_port: number | null;
customer_sip_fallback_transport: SfTrunkTransport | null;
cps_limit: number | null;
cps_burst: number | null;
concurrent_limit: number | null;
status: 'active' | 'suspended';
call_recording: boolean | null;
created_at: string;
updated_at: string;
fqdn: string;
}

interface ApiResponse<T> {
data: T;
message: string;
}

Pagination​

List endpoints return every matching record. There is no pagination.

Retries​

The API does not take idempotency keys. If you retry POST /sf-trunks after a timeout, you can end up with two trunks. List your trunks before you retry, and delete any you do not need.

Attaching numbers is safe to retry. See Attach numbers.

Next Steps​