Skip to main content
Different API endpoints use different authentication methods depending on the caller.

SDK / Mobile app

The iOS SDK identifies your app with Bundle ID + Team ID headers:
These headers are sent automatically by the SDK — but they only identify the tenant, they are not authentication. Bundle IDs and Team IDs are discoverable from the App Store, so they are not secrets. Attestation endpoints (/challenge, /validate, /refresh) need only these headers — the attestation object itself is the proof. All other SDK endpoints — feature flags, the flag SSE stream, heartbeat, feedback, and support — additionally require one of:
  • A Grantiva JWT issued by attestation, sent as Authorization: Bearer <jwt> (this is what the SDK does automatically after validateAttestation()), or
  • An API key (simulator/development mode, or server-side callers), sent as Authorization: Bearer <key>.
Requests with only the identity headers receive 401 Unauthorized with WWW-Authenticate: Bearer realm="grantiva". If you send an API key and omit the identity headers, the request resolves to your organization but not to a specific app — feedback and flag responses then cover the whole organization rather than one app. Personal keys (gpat_) are the exception: feedback listings reject them without X-Bundle-ID and X-Team-ID (400 Bad Request).
In practice the SDK handles this for you: run validateAttestation() once before using flags, feedback, or support. In the iOS Simulator (no App Attest), initialize the SDK with an API key instead — see Simulator Setup.

Server-to-server

For backend integrations (analytics, VRT), use an API key:
API keys are created in the dashboard under Settings, or with POST /api/v1/org/api-keys.
X-API-Key is accepted only on the analytics and VRT endpoints. The SDK endpoints and the /api/v1/org/* console endpoints read keys from Authorization: Bearer only.

Console API (/api/v1/org/*)

The /api/v1/org/* endpoints back both the dashboard and the grantiva CLI, so they accept either a dashboard session cookie or an API key:
  • API keyAuthorization: Bearer gpat_… / aat_…. The key’s scopes decide what it may do; org roles do not apply.
  • Session cookie — the dashboard path. Scopes do not apply; your org role does (viewer+ for reads, member+ or admin+ for writes, per endpoint).
Key-authenticated console requests also count against the apikey rate-limit bucket. See API Conventions.

Scopes

Each endpoint page lists the scopes it needs. The api:all scope satisfies every check, and legacy organization keys created before scopes existed are treated as full access. A request whose key lacks the required scope returns 403 Forbidden with the required scope names in the message.

JWT token

After successful attestation, the SDK receives a JWT. Protected SDK endpoints accept it as a bearer token:
Verify these tokens on your own backend with the public keys from JWKS.

Summary