Registering a user-authorized app
- Status
- Current
- Updated
- 2026-08-13
- Scope
- API Platform user-authorized application onboarding
When to use one
A user-authorized application suits a desktop agent, CLI, mobile app, or a web application with a backend: each end user signs in with their own ZaunEkko Account and explicitly authorizes the app, which can then call the API Platform for that user.
Calls still belong to the end user. Their quota, points, usage and receipts remain under their own account. The application does not gain a single identity that pays for everyone.
If the application must run unattended and pay with its own points, use a self-paid app identity instead.
Application process
Open Console → User-authorized apps in the API Marketplace:
- enter a display name;
- choose a client type;
- enter one exact redirect URI;
- save the draft and submit it for review;
- once approved, activate the client yourself.
Review may approve the application or return it to draft with a note. Approval does not automatically issue a Secret and does not authorize the app for any end user.
Two client types
Web confidential
For a web application with a trusted backend. Activation returns a Client ID and Client Secret. The plaintext Secret appears once, so put it into a server-side secret manager immediately and never send it to browser code.
Use an exact HTTPS redirect URI. Loopback HTTP is allowed for local development.
Native public
For a desktop agent, CLI, or mobile application. It deliberately has no Client Secret — distributed software cannot keep one shared Secret confidential.
Use loopback HTTP or a reverse-domain private URI scheme. After activation you only store the Client ID.
Fixed authorization scope
A user-authorized app receives only:
openid profile account.read ekko-api.invoke
It cannot request Provider, Reviewer, Operator, self-paid application, or platform-internal scopes. The app receives an authorization code only after the end user sees and accepts these permissions.
Authorization Code + PKCE
Every user-authorized app must use authorization code + PKCE with code_challenge_method=S256.
An authorization request looks like:
GET https://account.zaunekko.com/oauth2/authorize
?response_type=code
&client_id={client_id}
&redirect_uri={exact_redirect_uri}
&scope=openid%20profile%20account.read%20ekko-api.invoke
&code_challenge={base64url_sha256_code_verifier}
&code_challenge_method=S256
&state={unpredictable_state}
At the callback, verify state, then exchange the code using the same exact redirect URI and the original code_verifier. A web confidential client also authenticates at the token endpoint from its backend; a native public client sends no Secret.
Never put access tokens, refresh tokens, authorization codes, code verifiers, or Client Secrets in URLs, logs, browser storage, or public source code.
Tokens and revocation
Access tokens are short-lived. Refresh tokens rotate on every use: after a successful refresh, atomically persist the new refresh token before discarding the old one, and serialize concurrent refresh attempts.
The owner can revoke the client in the Marketplace. Revocation blocks new authorization and refresh, but does not delete past calls, point ledger entries, or receipts. End users can also withdraw their grant to the application.
Redirect URI rules
- It must exactly match the URI in the application record.
- Wildcards, query strings, and fragments are not supported.
- Web clients use HTTPS; only loopback HTTP is allowed for local development.
- Native clients may use loopback HTTP or a reverse-domain private scheme.
- A redirect URI, client type, or ownership change should go through review again; runtime parameters cannot expand the callback surface.