Authentication
Authentication
Section titled “Authentication”SIPSTACK has two authentication mechanisms:
| Mechanism | Header | Used by |
|---|---|---|
| Session token (JWT from login) | Authorization: Bearer <token> or the portal_token cookie | Portal API (/v2/portal/...) and key/webhook management (/api/api-keys, /api/webhooks) |
| API key | x-api-key: sk_live_... | Developer API (/api/v2/...) |
They are not interchangeable — an API key will not authenticate portal endpoints, and vice versa.
Session Tokens (Portal Login Flow)
Section titled “Session Tokens (Portal Login Flow)”POST /v2/portal/auth/loginContent-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,
requiresOrgSelectionistrueandavailableOrganizationslists them — callPOST /v2/portal/auth/switch-organizationwith{ "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
401with codeTOKEN_EXPIRED. You can either log in again, or callPOST /v2/portal/auth/token/refreshwith 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 returns401, the session is gone: log in again. (This is what Switchboard itself does.)
Two-Factor Authentication
Section titled “Two-Factor Authentication”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-verifyContent-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.
Logout
Section titled “Logout”POST /v2/portal/auth/logoutInvalidates the session and clears the cookie.
Login rate limits
Section titled “Login rate limits”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 (Server-to-Server)
Section titled “API Keys (Server-to-Server)”API keys are long-lived credentials for the Developer API. They are sent in the x-api-key header — not as a Bearer token:
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) orsk_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.
Handling Authentication Errors
Section titled “Handling Authentication Errors”| HTTP | code | Meaning | Action |
|---|---|---|---|
| 401 | AUTH_REQUIRED | No token/cookie provided | Authenticate first |
| 401 | TOKEN_EXPIRED | Session JWT past expiry | Refresh the token (POST /v2/portal/auth/token/refresh) or log in again |
| 401 | TOKEN_INVALID / TOKEN_REVOKED | Malformed or revoked token | Log in again |
| 401 | — (success: false) | Missing/invalid API key on the messaging API | Check the x-api-key header and key status |
| 403 | FORBIDDEN | Authenticated but not permitted | Check the user’s role/permissions |
Token Security Best Practices
Section titled “Token Security Best Practices”- 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.