Skip to content

Authentication

Every Layer REST API request must be authenticated with a bearer token in the Authorization header:

Terminal window
curl https://api.app.layer.ai/api/v2/workspaces \
-H "Authorization: Bearer $LAYER_TOKEN"

The API base URL is https://api.app.layer.ai/api, and every endpoint is versioned — v2 is current, v1 is still live — so full paths look like https://api.app.layer.ai/api/v2/workspaces/{workspace_id}/.... See Versioning.

A Personal Access Token (PAT) is the recommended way to authenticate a server-side integration. Tokens are prefixed with pat_.

  1. Log in to app.layer.ai.
  2. Go to Settings → Personal Access Tokens.
  3. Click Create Token, give it a name (and an optional expiry), and copy the value.

A PAT is created and managed only in the app UI — there is no REST endpoint to mint, list, or revoke tokens. Creating one is free and needs no approval; see self-serve access.

A PAT inherits all of the permissions of the user who created it — there are no per-token scopes. Treat a PAT as equivalent to that user’s access, and provision integration users with only the workspace access they need. See Permissions for the full model.

If you set an expiry when creating the token, requests made after that time fail with 401 UNAUTHENTICATED. Rotate tokens before they expire.

Layer runs an OAuth 2.0 authorization server at https://auth.app.layer.ai. It is what MCP clients connect through, and the access token it issues is accepted by the REST API as a bearer token too.

  1. Discover the endpoints from the authorization server metadata (RFC 8414).
  2. Register your client dynamically at the registration_endpoint — there is no pre-shared client id to request.
  3. Run the authorization code flow with PKCE (S256 required).
Issuer https://auth.app.layer.ai/
Metadata /.well-known/oauth-authorization-server
Grants authorization_code, refresh_token
Scopes issued openid, profile, email, offline_access
PKCE Required (S256)
Dynamic client registration Supported

layer.ai/.well-known/oauth-authorization-server redirects to the document above — the metadata has to be served by the issuer itself, so the marketing domain points at it rather than mirroring it.

The scopes above are OpenID Connect scopes: they govern what the token tells Layer about who you are, not what you may do with the API. Layer does not define read:* / write:* API scopes — see Permissions.

There is no client credentials grant. Every token acts as a Layer user; for an unattended integration, create a Layer user for it and issue that user a PAT.

Layer authorizes each request from the calling user, not from the credential. Access is evaluated against that user’s role in the target workspace (VIEWER, MEMBER, ADMIN, OWNER) and, for project-scoped resources, their project membership. A request the user may not perform returns 403 FORBIDDEN.

Two consequences worth designing around:

  • A credential cannot be narrowed below its owner. A PAT inherits all of its creating user’s permissions, and an OAuth access token acts as the user who authorized it.
  • Least privilege means a least-privileged user. To restrict an integration, provision a dedicated Layer user with only the workspace role and project membership it needs, then create the credential as that user.

As a rule: GET operations need VIEWER; anything that creates, changes, or deletes state — or starts a run, and so spends Creative Units — needs at least MEMBER; workspace and member administration needs ADMIN or OWNER. The same rule is published machine-readably at /api/index.json under interfaces.rest.permissions.

  • Never embed a PAT in client-side code or a public repository — the API is server-to-server only.
  • Scope integration users to the minimum workspace access required.
  • Rotate tokens periodically and on suspected exposure.