Skip to content
DocsStart free

Public API (v1)

The public REST API is served at https://api.sip.io/v1. It’s JSON in and out, authenticated with an API key or session token, and authorized by scope. The account is always taken from your credential, never a path or query parameter.

Terminal window
curl https://api.sip.io/v1/whoami -H 'x-api-key: sk_…'
# → { "accountId": "acc_acme", "scopes": ["*"], "via": "key" }
ResourceMethod · PathScopeNotes
IdentityGET /v1/whoamianyWho the credential is.
AccountGET /v1/accountanyName, status, timezone, language, CAC ceilings.
Calls / CDRGET /v1/callscdrCall records; ?since=&until=&limit=&cursor=&format=csv (paginated).
AgentsGET /v1/agentsagentsLive agent state (?userId=).
AgentsPOST /v1/agents/stateagentsDrive an agent: { userId, event, queues? }.
QueuesGET /v1/queuesqueuesQueues + KPIs (?since=).
NumbersGET /v1/numbersnumbersYour DIDs.
DNCGET·POST·DELETE /v1/dncdncDo-not-call list: { e164, reason?, source? }.
WebhooksGET·POST·DELETE /v1/webhookswebhooksSubscriptions.
WebhooksPOST /v1/webhooks/testwebhooksFire a test event to your endpoints.
Campaigns/v1/campaigns…campaignDialer campaigns: create, contacts, start, pause, disposition, KPIs.
Terminal window
# create a webhook subscription
curl -X POST https://api.sip.io/v1/webhooks \
-H 'x-api-key: sk_…' -H 'content-type: application/json' \
-d '{ "url": "https://acme.com/hooks/sipio", "events": "call.started,call.ended" }'

The spec is published at GET /v1/openapi.json (OpenAPI 3.0, no auth). Point your generator at it for a typed client in any language. Security schemes: apiKey (x-api-key) and bearer (JWT).

Terminal window
curl https://api.sip.io/v1/openapi.json -o sipio-openapi.json

GET /v1/calls is keyset-paginated (stable and cursor-based, with no offset drift). When a page is full, the response includes a next_cursor; pass it back as ?cursor= (with the same limit) to get the next page. A response without a next_cursor is the last page.

Terminal window
curl 'https://api.sip.io/v1/calls?limit=500&cursor=…' -H 'x-api-key: sk_…'

The authed /v1 surface is limited to 100 requests / 60s per API key (per-IP for unkeyed requests), enforced by a layered edge gate plus a precise quota. Over the limit returns 429 with a Retry-After header:

{ "ok": false, "error": "rate_limited", "hint": "100 requests / 60s", "retry_after_sec": 42 }

The open /v1 index and /v1/openapi.json are not rate-limited.

Responses are JSON. Errors are uniform:

StatusBody
401{ "ok": false, "error": "unauthorized" }: missing/invalid credential.
403{ "ok": false, "error": "forbidden", "need": "<scope>" }: credential lacks the scope.
404{ "ok": false, "error": "not_found" }.
429{ "ok": false, "error": "rate_limited", "retry_after_sec": … }: see Rate limits.

The /v1 surface above is live. On the roadmap: write CRUD for the full resource model (numbers, queues, flows, trunks), Idempotency-Key on writes, cursor pagination, and published SDKs / an MCP server generated from the OpenAPI spec.