Skip to content
DocsStart free

Authentication

There are three kinds of auth in SIP.IO: API credentials (how you call the API), SIP device authentication (how a phone proves who it is), and internal gating (how the platform’s own edge endpoints are protected).

Every request to the public API carries one of two credentials in a header, and is authorized against per-resource scopes.

Terminal window
curl https://api.sip.io/v1/whoami -H 'x-api-key: sk_…'
  • Created per account; the secret is shown once at creation (sk_…) and stored only as a hash, so keep it safe.
  • Each key carries a set of scopes (below). A key never expires until revoked.
  • Presented as the x-api-key header.

A console login exchanges email + password for a short-lived JSON Web Token:

Terminal window
curl -X POST https://console.sip.io/login \
-H 'content-type: application/json' \
-d '{ "email": "you@acme.com", "password": "…" }'
# → { "ok": true, "token": "…", "token_type": "Bearer", "expires_in": 43200, "scopes": ["*"] }

Use the token on subsequent requests:

Terminal window
curl https://api.sip.io/v1/account -H 'Authorization: Bearer <jwt>'

Tokens are stateless (HS256), carry the account, user, and scopes, and expire in 12 hours.

Each credential is limited to a set of scopes; a request to a resource requires the matching scope (a missing scope returns 403 with the scope it needs). * grants all.

ScopeGrants
cdrCalls / CDR read & export
agentsRead agent state; drive agent state
queuesRead queues & KPIs
numbersRead numbers
dncManage the do-not-call list
campaignManage dialer campaigns
webhooksManage webhooks
messagingSend messages (the messaging service)
caller_idManage per-user caller-ID (console)
wallboardThe realtime wallboard data & socket
*Everything

Credentials are header-only; there’s no query-string key. (The one exception is the wallboard WebSocket, which can’t send headers; it uses a short-lived single-use ticket minted from a scoped request.)

Phones authenticate to register and place calls using SIP digest auth: the credential is a digest hash, never a plaintext password.

  1. A device sends REGISTER/INVITE; the signaling layer issues the 401 challenge.
  2. The device responds with the digest Authorization.
  3. The signaling layer asks the control plane (/auth) to verify it.
  4. The platform looks up the device by (auth_username, realm), verifies the stored ha1, checks that device and account are active, and returns the account context to bind to the registration.
{ "ok": true, "account_id": "acc_acme", "user_id": "us_dana", "device_id": "dev_dana_desk", "webrtc": false }
sip_device fieldMeaning
auth_usernameThe SIP username.
realmThe account’s SIP domain (the digest realm).
ha1 / ha1bMD5(username:realm:password) and the @domain variant.

Because the realm is the account’s SIP domain, the same extension in two tenants (1002@acmeA vs 1002@acmeB) is two isolated credentials. WebRTC endpoints register over WSS and authenticate the same way.

The edge control plane’s own endpoints aren’t public; they’re for the SIP nodes and operator tooling:

SurfaceGate
SIP-facing (/auth, /route, /flow, /presence, /agent, /cac, /media, /calls)App-layer IP allowlist (node + operator IPs).
/media/*Restricted to media-node IPs (keeps object storage private).
/admin/* (key minting, console-user provisioning)x-admin-token shared secret.
Node pushA secure tunnel + per-node agent token.
Outbound PSTNMust originate from an active, account-owned device (toll-fraud gate).

The management (console.sip.io), realtime (realtime.sip.io), and public API (api.sip.io) services use the per-account API-key / session model above, not the internal x-admin-token.