Skip to content

Authentication

SIPSTACK has two authentication mechanisms:

MechanismHeaderUsed by
Session token (JWT from login)Authorization: Bearer <token> or the portal_token cookiePortal API (/v2/portal/...) and key/webhook management (/api/api-keys, /api/webhooks)
API keyx-api-key: sk_live_...Developer API (/api/v2/...)

They are not interchangeable — an API key will not authenticate portal endpoints, and vice versa.

POST /v2/portal/auth/login
Content-Type: application/json
{
"email": "user@example.com",
"password": "yourpassword"
}

Response:

{
"success": true,
"data": {
"token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
"user": { "...": "..." },
"availableOrganizations": [],
"requiresOrgSelection": false,
"requirePasswordChange": false
}
}

The token is also set as an httpOnly portal_token cookie — browser clients (like Switchboard) authenticate via the cookie automatically, while server-side clients can send the same JWT as a Bearer header:

Authorization: Bearer <token>

Notes:

  • If your account belongs to multiple organizations, requiresOrgSelection is true and availableOrganizations lists them — call POST /v2/portal/auth/switch-organization with { "organizationId": "<uuid>" } to re-scope the session (the response includes a new token, and the cookie is updated).
  • Tokens last 8 hours (or 7 days when the login request sets remember).
  • When the token expires you receive 401 with code TOKEN_EXPIRED. You can either log in again, or call POST /v2/portal/auth/token/refresh with the expired token (cookie or Bearer header) — if the underlying server-side session is still active, it returns a fresh token (data.accessToken) with the same lifetime window. If the refresh also returns 401, the session is gone: log in again. (This is what Switchboard itself does.)

If the account has 2FA enabled, login does not return a session. Instead you receive a challenge with a temporary token; complete it with the 6-digit TOTP code:

POST /v2/portal/auth/2fa/login-verify
Content-Type: application/json
{
"tempToken": "<from the login response>",
"code": "123456"
}

On success this returns the standard session response. See Two-Factor Authentication for the user-facing setup.

POST /v2/portal/auth/logout

Invalidates the session and clears the cookie.

Login is brute-force protected: repeated failed attempts for the same email (3 in 30 minutes) or from the same IP temporarily block further attempts. Password reset and 2FA verification have similar per-IP limits. See Rate Limits.

API keys are long-lived credentials for the Developer API. They are sent in the x-api-key header — not as a Bearer token:

Terminal window
curl -s -X POST https://api.sipstack.com/api/v2/messages/send \
-H "x-api-key: sk_live_your_api_key" \
-H "Content-Type: application/json" \
-d '{ "to": "+14165550100", "message": "Hello" }'

Key facts:

  • Keys are prefixed sk_live_ (production) or sk_test_ — test keys are rejected in production.
  • Keys are stored hashed (SHA-256); the full key is only visible when issued.
  • Keys belong to your organization and can be given an optional expiry — 30, 60, 90, or 365 days, or set to never expire — and can be revoked at any time.
  • Each key carries a set of capability scopes (fail-closed — a key with no scopes can call nothing). Grant only what an integration needs. See Scopes.
  • API access is plan-gated — on plans without API access, requests return 403.

See API Keys for provisioning and security practices.

HTTPcodeMeaningAction
401AUTH_REQUIREDNo token/cookie providedAuthenticate first
401TOKEN_EXPIREDSession JWT past expiryRefresh the token (POST /v2/portal/auth/token/refresh) or log in again
401TOKEN_INVALID / TOKEN_REVOKEDMalformed or revoked tokenLog in again
401— (success: false)Missing/invalid API key on the messaging APICheck the x-api-key header and key status
403FORBIDDENAuthenticated but not permittedCheck the user’s role/permissions
  • Never commit tokens or API keys to version control — load them from environment variables or a secrets manager.
  • Never expose API keys in client-side code; proxy through your own server.
  • Treat session JWTs as secrets: don’t log them, don’t put them in URLs.
  • Revoke API keys immediately if you suspect compromise.