Authentication
Bearer token (Supabase JWT)
Section titled “Bearer token (Supabase JWT)”Every authenticated request carries a Supabase JWT as a bearer token:
Authorization: Bearer <supabase-jwt>The token is validated as HS256 with audience authenticated, signed by the shared
Supabase auth secret. Failures return 401 Unauthorized with a WWW-Authenticate: Bearer
header.
Org context (X-Org-Id)
Section titled “Org context (X-Org-Id)”After the user is resolved, the request resolves an acting org. To act inside a specific subaccount, send its UUID:
X-Org-Id: <org-uuid>- Member → the request acts inside that org.
- Not a member →
403 Forbidden(existence is never leaked). - Malformed UUID →
400. - Omitted → falls back to your earliest-joined org.
The acting org is also bound to the database session for Row-Level Security, so the database itself enforces tenant isolation. See Multi-Tenant & RLS.
“View as client” impersonation
Section titled ““View as client” impersonation”An agency admin can mint a time-boxed token to act inside one of their own subaccounts.
POST /api/v1/impersonateContent-Type: application/json
{ "org_id": "<target-subaccount-uuid>" }Rules:
- The caller must be an admin/owner of their current org.
- The target must be the caller’s own org or one of its direct subaccounts (the
parent_org_idchain) — never a sibling, the parent, or another agency’s client. A violation returns403. - An unknown target returns
404. - The audit row records the real admin’s identity, not the impersonated user — this closes GoHighLevel’s “login as” attribution gap.
The minted token is then passed on subsequent requests via the X-Impersonate-Token header.
Service-to-service authentication
Section titled “Service-to-service authentication”Trusted internal callers (the telephony engine, inbound webhooks, the Instantly bridge) do not carry a user JWT. They authenticate with a shared secret header:
X-Iron-CRM-Secret: <shared-secret>and pass the org explicitly in the request body. These seams are documented under Webhooks. Do not use the shared secret for user-facing calls — use a JWT.