Skip to main content

Authentication

The portal API (/portal/* endpoints) authenticates with your signed-in portal session. There is no OptoLink-issued credential to configure: the account you create when you sign up at the portal is your API identity, and your organization role (viewer → owner) rides along inside every request.

How portal requests are authenticated​

The portal signs you in with Clerk (email + password or Google). Behind the scenes, every API call the portal makes carries a short-lived session token (~60 seconds) in the header:

Authorization: Bearer <session-token>
  • The token is minted and refreshed automatically while you're signed in. Sessions last up to 7 days, and an expired token is silently replaced with a fresh one; you never handle it.
  • Your organization and role are part of the token, so each request is authorized against the org you're acting in. Changing a member's role takes effect within about a minute.
  • There is deliberately no long-lived token and no API key for portal endpoints. Machine-to-machine access (your backend calling OptoLink to create links, resolve deep links, send events) uses API keys on the SDK endpoints instead, a separate credential for a separate actor. API keys do not work on /portal/* routes, and session tokens are not a supported way to call the SDK routes.

How API-key requests are authenticated​

Machine access — your backend and the mobile SDK — uses one of your org's two fixed API keys in the same header:

Authorization: Bearer opl_api_…

Each key works only on the routes meant for its tier. A valid key used on the other tier's routes gets 403 Forbidden:

KeyPrefixRoutes it authenticates
Server API Keyopl_api_…Link management: the /links CRUD routes — what the Node SDK sends
Mobile SDK Integration Keyopl_sdk_…SDK routes: /sdk/session, /sdk/identity, /sdk/identity/clear

/match needs no key; it accepts an X-API-Key header as optional attribution. Keys never authenticate /portal/* routes, and session tokens never authenticate the routes in the table above.

Statuses on key-authenticated routes:

  • 401 — missing or invalid key, or your organization is suspended ("Organization is suspended").
  • 403 — valid key, wrong tier for the route (for example the SDK key on /links).

Rotation changes behavior at a known moment: once you regenerate the server key, the old one stops working immediately; once you regenerate the SDK key, the old one keeps authenticating for up to 24 hours, so app versions already shipped keep working. Both keys are managed on the portal's API keys page — see API keys.

When you'll get a 401​

If a portal request arrives without a valid session token, the API answers with a JSON error (never an HTML page):

{
"statusCode": 401,
"error": "Unauthorized",
"message": "Missing or invalid Authorization header",
"timestamp": "2026-09-17T12:00:00.000Z",
"path": "/portal/links",
"requestId": "a1b2c3…"
}
  • 401 — the request had no token, or the token was expired or invalid. In the portal UI this never surfaces (the session refreshes transparently); if you're calling the API directly, sign in again for a fresh token.
  • 403 — the token was fine, but the signed-in user's role or organization doesn't permit the action (e.g. a viewer attempting a write, or acting outside their organization). Distinguish auth errors from plan/quota limits on Rate limits & errors.