Skip to main content
Delegate tokens are short-lived JWTs (default 5-minute expiry) that represent a specific logged-in Aptly user. An embedded app or agent receives the token and uses it directly for API calls. Tokens are scoped — they only grant access to the resources you declare at issue time. If you’re building a Replit app or iframe widget, the Aptly SDK handles all of this automatically. Come here if you need the raw token exchange API for a server-side integration, a custom auth flow, or an AI agent.

The flow


Issue a delegate token

POST /api/platform/user-token Call this from your server. Requires the logged-in user’s session JWT in the access_token header. Option A — explicit scopes (no marketplace app registration needed):
Option B — registered marketplace app (scopes come from the marketplace item):
Optional: custom expiry Both options accept expirationSeconds to override the default 5-minute TTL. Maximum is 7 days (604800).
Response:

Verify the token

Use this to confirm who the token belongs to before trusting an incoming request.

Option A — keyless verify

POST /api/app/verify No API key needed. Works for two token types:
  • Marketplace tokens — issued with appClientId. Returns user identity plus appClientId and appTitle.
  • Scoped dev tokens — issued by a GA admin via the Dev Tokens panel, without an appClientId. Returns user identity with appClientId: null. Revoked tokens return 401.
Response:

Option B — verify with board API key

POST /api/board/verify-user Works for any delegate token. Requires a board API key from the same company.
Response:

Call the API with a delegate token

Pass the token as Authorization: DelegateToken <token> on any supported route. The token’s scopes must cover the resource.
Always use DelegateToken as the Authorization scheme — not Bearer.

Scopes

Scopes follow the format resource:qualifier. readScopes — GET requests and read operations. writeScopes — POST/PUT/DELETE requests and write operations. A missing scope returns 403 Forbidden. No scopes are granted by default — omitted scopes are denied.

Marketplace vs explicit scopes


Server-side example


Iframe embed pattern (without the SDK)

If you can’t use the Aptly SDK script tag, you can implement the postMessage handshake manually. The parent Aptly window responds to { type: 'aptly-token-request' } with a token and context object.
Register the listener before calling postMessage — the parent may respond synchronously. The listener removes itself after the first matching message to avoid leaks. Retry once, not in a loop — a second 401 after a fresh token means the session is actually expired or the scope is wrong. One retry distinguishes stale tokens from real auth failures.

For AI agents

When Aptly embeds a generated app or AI agent into an iframe context, the system prompt will include a block declaring what scopes are available:
If you see this block, use requestToken() from the iframe embed pattern above to receive the token, then use apiFetch for all API calls. The scope list is authoritative — calling a route outside those scopes returns 403 Forbidden. Check whether a scope appears under read or write access before attempting mutations.

Error reference