Skip to main content

Authentication

The Turris Public API supports two authentication methods. Which are available to you depends on what kind of organization you are.

Authentication Methods

Both methods reach the same endpoints. OAuth is recommended wherever the calling system has a backend: its tokens expire after 60 minutes and rotate, whereas a Restricted Access Token never expires and stays valid until you delete it.

Carrier and agency credentials

A credential belongs to one organization, and that organization’s kind decides which endpoints it can reach. There is no credential that reaches both.

Carrier (upstream entity)

Reaches /v1/* and /v2/upstream/*. Both authentication methods are available.Mint from Settings → API in the carrier application. Requires the Public API product feature, and each area needs the feature of its matching screen; see Getting Started.

Agency (downstream entity)

Reaches /v2/downstream/*. Both authentication methods are available.Mint from Settings → API in the agency application. Requires the Public API product feature, and each area needs the feature of its matching screen; see Getting Started for Agencies.
Using a credential on the other surface returns 403 with errorType invalid_organization_category. That is the intended answer rather than a configuration problem: the two surfaces answer different questions, and an agency reading carrier endpoints would be reading other organizations’ data. Entitlement is verified on every request, on both versions. A credential does not expire, so an organization that stops being a Turris customer, or has a product feature switched off, receives 403 with product_feature_subscription_required rather than continuing to work. See Error Handling.
The agency surface is v2 only. There is no v1 agency surface and there will not be one — v1 predates the persona split and is upstream-only by construction.
OAuth uses Machine-to-Machine (M2M) JWT tokens for authentication. This is the preferred method for production integrations.

Step 1: Create API Client

  1. Open Settings → API in your own Turris application. Carriers use the carrier app; agencies use the agency app. The application you mint from decides which surface the credential reaches.
  2. Click Create API Client
  3. Store your client_id and client_secret securely
Never expose your client secret in frontend code. Store credentials securely in environment variables or a secrets manager.

Step 2: Get Access Token

Exchange your credentials for a JWT. The token endpoint carries no persona segment, so the same call issues a carrier token or an agency token depending on the credential you send:
Response:
On v1 the same call is POST /v1/auth/jwt. It stays available for carriers already on v1; there is no v1 agency equivalent, so an agency credential only has the v2 path.

Step 3: Use the Token

Include the token in the Authorization header. GET /v2/heartbeat is one of the four paths with no persona segment, so it answers for a carrier credential and an agency credential alike:
After that the paths diverge: a carrier calls /v1/* or /v2/upstream/*, an agency calls /v2/downstream/*. See Which API is mine?.

Token Lifecycle

Implement token caching in your application. Request a new token only when the current one is about to expire (e.g., 5 minutes before expiry).

Test Your Token

GET /v2/auth/test-oauth confirms the token is valid and reports which surface it is for:
Success Response:
orgCategory is upstreamEntity (carrier, MGA or wholesaler) or downstreamEntity (agency, brokerage or branch). It is a four-value enum: enterpriseUpstreamEntity and enterpriseDownstreamEntity also exist, for surfaces that are not routable yet, so match the value you expect rather than treating “not upstreamEntity” as an agency. Run this call first whenever a request comes back 403: it is the one request that tells you, without guessing, which paths the credential you just sent can reach. Full walkthrough in Which API is mine?. The v1 equivalent, GET /v1/auth/test-oauth, returns the message only and no orgCategory. Use the v2 path for this check even when the rest of your integration is on v1.

Restricted Access Token

Restricted Access Tokens provide a simpler authentication method with IP-based security.

Step 1: Create Token

  1. Open Settings → API in your own Turris application (carrier, agency)
  2. Choose Add New → Restricted Access Token
  3. Add the exact IP addresses your requests will originate from
  4. Store your token securely — it is shown once and only its hash is kept

Step 2: Use the Token

Include the token in the x-restricted-access-token header. The surface rule is the same as for OAuth. A carrier token reaches /v1/* and /v2/upstream/*; an agency token reaches /v2/downstream/*. Presenting one on the other surface returns 403, and there is no v1 agency surface. Carrier:
Agency:

Security Model

The Restricted Access Token guard performs three validations:
  1. Token Presence - Checks for the x-restricted-access-token header
  2. Token Validity - Validates the token against stored hashes
  3. IP Allowlist - Verifies the request originates from an allowed IP address
Requests from IP addresses not in your allowlist will be rejected with a 403 Forbidden error.The allowlist is matched exactly. CIDR ranges, wildcards and subnet masks are not supported, so every address must be listed individually. A token with an empty allowlist matches nothing and will reject every request.

Test Your Token

Verify your token and IP are configured correctly:
Success Response:
The same check exists on v1 as GET /v1/auth/test-restricted-access-token. Neither version reports orgCategory: that field is only on GET /v2/auth/test-oauth, which needs a JWT.

Fallback Behavior

When both authentication headers are provided, the API uses this priority:
  1. OAuth is attempted first
  2. If OAuth fails and a Restricted Access Token is present, token authentication is attempted
This allows for graceful migration between authentication methods.

Error Responses

401 Unauthorized

Missing or invalid credentials:
Expired JWT:

403 Forbidden

IP not in allowlist (Restricted Access Token only):

Best Practices

  • Use environment variables or a secrets manager
  • Never commit credentials to version control
  • Rotate credentials periodically
  • Cache OAuth tokens for their full TTL (60 minutes)
  • Refresh tokens proactively before expiry
  • Handle token refresh failures gracefully
  • Implement retry logic for transient failures
  • Log authentication errors for debugging
  • Alert on repeated authentication failures