The Prisme.ai API uses a robust authentication system to secure access to resources. This guide explains how authentication works and how to implement it in your API requests.Authentication is part of what makes the platform governed by design: the same identity model spans SSO, service accounts, and per-organization scoping across the unified foundation.
JSON Web Tokens (JWTs) are the primary authentication method for web clients and interactive sessions.
1
Obtain a JWT
JWTs are issued in two scenarios:
OpenID Connect (OIDC) authentication: After authenticating with the OIDC server (the api-gateway), clients receive an authorization code that can be exchanged for a JWT. Find your current JWT in the access-token cookie sent to the https://api.studio.prisme.ai/v2/me API after opening any Prisme.ai page
Anonymous authentication: The /v2/login/anonymous endpoint initiates unauthenticated sessions and returns a JWT.
# Example of anonymous logincurl -X POST "https://api.studio.prisme.ai/v2/login/anonymous" \ -H "Content-Type: application/json"
JWTs have an expiration time defined by the ACCESS_TOKENS_MAX_AGE setting (default is 30 days). Your application should handle token refreshing or re-authentication when tokens expire.
Access tokens are opaque tokens generated for longer-term programmatic access. They are ideal for scripts, integrations, and backend applications.
1
Generate an Access Token
Authenticated users can generate access tokens using the /v2/user/accessTokens endpoint:
Access tokens cannot be recovered if lost. Store them securely and never expose them in client-side code.
Workspace API keys are scoped to a single workspace. They let an integration read, update, or execute that specific workspace with elevated privileges, using the CASL rules granted at creation. Use them for workspace-local integrations; for organization-wide programmatic access, use Organization API Keys (see the next tab) instead.
1
Create an API Key
Workspace administrators can create API keys with specific permissions:
API keys follow the principle of least privilege. They only have the permissions explicitly granted during creation.
Organization API keys are scoped to an organization (not a single workspace) and enable programmatic access from external systems. Unlike workspace API keys, they carry organization-level permissions (product:resource:action) and optional resource scopes, and are resolved natively by the runtime.Crucially, and unlike workspace API keys, they let you call the Prisme.ai product APIs — such as AI Knowledge, Agent Factory, or the LLM Gateway — rather than only reading/updating/executing a single workspace.They use the format iak_{orgSlug}_{uuid}; the embedded orgSlug lets the auth middleware resolve the organization without a database lookup. Keys are stored hashed and the plaintext key is shown only once at creation.
1
Create an Organization API Key
Create keys from the API Keys section of the organization, selecting permissions (and optionally scopes and an expiration date). Keys are managed under /v2/orgs/:orgSlug/api-keys.
Token exchange lets a client that has already authenticated against an external identity provider (OIDC) trade that provider’s id_token for a nominative Prisme.ai JWT, with no browser redirect. It is the headless counterpart of the browser SSO callback and follows the spirit of RFC 8693.Use it for any client that already holds an external IdP token and cannot (or should not) run the interactive browser flow: native and mobile apps, desktop clients, CLIs, and backend / server-to-server integrations.
1
Enable the provider for token exchange
The target OIDC provider must opt in with allowTokenExchange: true in its configuration. See Enterprise Authentication for how to configure providers.
2
Exchange the external id_token
Send the provider’s id_token to the token-exchange endpoint:
Optionally pass expiresAfter (seconds) to control the session lifetime. subject_token_type and grant_type are accepted for RFC 8693 compatibility but are optional.
3
Use the JWT
Send the returned token as a Bearer token, exactly like a JWT obtained from any other flow:
curl -X GET "https://api.studio.prisme.ai/v2/me" \ -H "Authorization: Bearer eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVC..."
The user is matched or provisioned exactly like the browser SSO callback (same identity mapping), organization resolution included: the exchange claims pending invitations, auto-joins the provider’s organization and syncs the user’s orgSlugs, exactly as the browser callback does. The first exchange for an unknown user creates the Prisme.ai account, with its membership.
The subject_token is verified against the provider’s published keys (jwks_uri), and its aud claim must match the provider’s client_id (and iss the configured issuer). A token minted for a different application is rejected. The endpoint only works for providers that explicitly set allowTokenExchange: true.
A provider tied to an organization must resolve to that organization for the login to succeed. A token that authenticates but resolves no organization is refused rather than producing a member-less account, which used to yield an account that held no permission and answered 403 on every organization-scoped resource, with no way to repair it afterwards.
The endpoint is rate-limited per source IP (default 60 exchanges/min, configurable via RATE_LIMIT_TOKEN_EXCHANGE). When brokering exchanges server-side, all users share one IP; exceeding the limit returns 429 Too Many Requests. Self-hosters can raise it; see Environment Variables.
A native client authenticates with a bearer token, and that token must never reach a browser: there is no API to seed a cookie inside a system web view, and putting the token in a URL would leak it through the Referer header, proxy logs and history. Flows that need a real web session, connector OAuth in particular, were therefore unreachable from a mobile app.The web session ticket solves this the way RFC 9126 treats request_uri: the app states its intent through an authenticated back channel and receives an opaque single-use reference, and that reference is the only thing that ever travels through the browser.
1
Mint a ticket
Call the endpoint with the API token the app already holds:
The ticket carries 256 bits of randomness and no information of its own. It is bound to the caller and to its session, lives 60 seconds by default and 300 at most (WEB_SESSION_TICKET_TTL and WEB_SESSION_TICKET_MAX_TTL), and is forbidden to access tokens and service accounts.
2
Open the returned URL in the system browser
GET /v2/user/webSession burns the ticket, sets the access-token cookie under Referrer-Policy: no-referrer and Cache-Control: no-store, then redirects to your redirect target. The window now holds an ordinary Prisme.ai session, so anything that works on web, connector OAuth included, works from there.
redirect must point at this platform (its API, consoles or workspace pages), or be a root-relative path. It is validated when the ticket is minted and again when it is exchanged. Self-hosters can allow extra hostnames with WEB_SESSION_ALLOWED_REDIRECT_HOSTS.
The cookie reuses the caller’s prismeaiSessionId, so the app and the browser share one session: same MFA state, same lifetime, and nothing extra to revoke. The exchange endpoint is rate-limited per source IP (default 30/min, RATE_LIMIT_WEB_SESSION). Never log a ticket. The SDK exposes the first call as api.webSessionTicket().
Client Authentication: The client authenticates via OIDC or anonymous login to obtain a JWT
API Gateway Validation: Requests are sent to the api-gateway with the JWT or access token
Header Transformation: The api-gateway validates the token and adds an x-prismeai-user-id header
Internal Routing: The request is forwarded to the appropriate microservice with the user context
Authorization Check: The target microservice checks if the authenticated user has the required permissions
Backend microservices rely on the x-prismeai-user-id header for identification. This header should not be directly set in client requests, as it will be overwritten by the api-gateway.
const axios = require('axios');async function getPrismeData() { // Get or refresh your token using your authentication method const token = 'YOUR_ACCESS_TOKEN'; try { const response = await axios.get('https://api.studio.prisme.ai/v2/workspaces', { headers: { 'Content-Type': 'application/json', 'Authorization': `Bearer ${token}` } }); return response.data; } catch (error) { if (error.response && error.response.status === 401) { // Handle authentication error, potentially refresh token console.error('Authentication failed, token may be expired'); } else { console.error('API request failed:', error.message); } throw error; }}
import requestsdef get_prisme_data(): # Get or refresh your token using your authentication method token = 'YOUR_ACCESS_TOKEN' headers = { 'Content-Type': 'application/json', 'Authorization': f'Bearer {token}' } try: response = requests.get('https://api.studio.prisme.ai/v2/workspaces', headers=headers) response.raise_for_status() # Raise exception for HTTP errors return response.json() except requests.exceptions.HTTPError as err: if err.response.status_code == 401: # Handle authentication error, potentially refresh token print('Authentication failed, token may be expired') else: print(f'API request failed: {err}') raise
# Set your token as a variableTOKEN="YOUR_ACCESS_TOKEN"# Make API requestcurl -X GET "https://api.studio.prisme.ai/v2/workspaces" \ -H "Content-Type: application/json" \ -H "Authorization: Bearer $TOKEN"