If you just need a single server-to-server credential for your own workspace, an API key is simpler. Use OAuth when another Flow9 user needs to authorize your app against their workspace.
The endpoints
Everything is discoverable from the authorization-server metadata:
All requests carry the project’s public
apikey header (the anon key), exactly
as the REST guide describes.
Step 1 — Register your app (once)
Register with Dynamic Client Registration to get aclient_id. Public clients
(desktop / CLI / native apps that can’t keep a secret) use PKCE and get no secret.
client_id. Your redirect_uris must exactly match what you
send in Step 2.
Step 2 — Send the user to authorize (with PKCE)
Generate a PKCEcode_verifier (random) and its code_challenge
(base64url(sha256(verifier))), then open the authorize URL in the user’s
browser:
- Request the standard OIDC scopes (
openid profile email). You do not request Flow9 data permissions here — those are chosen by the workspace owner on the consent screen (Step 3). - Add
&prompt=consentif you want to force the consent screen even for a returning user (otherwise a user who already approved is sent straight through).
Step 3 — The user consents
Flow9 shows the user a consent screen listing your app and four permission groups. The user ticks what your app may do:
Spend-capable (Messaging) and sensitive (Admin) groups are off by default, so
a careless “Allow” never hands out paid or administrative actions. Your app
receives whatever the user approves — request only what you need and degrade
gracefully if a scope wasn’t granted (you’ll get
403 FORBIDDEN_SCOPE).
On approval the browser is redirected to your redirect_uri with ?code=…&state=….
Verify state matches what you sent.
Step 4 — Exchange the code for a token
access_token (a signed ES256 JWT) and a refresh_token. The
access token is short-lived; use the refresh token to get a new one when it
expires.
Step 5 — Call the Flow9 API
Send the access token as a Bearer credential (see auth.md):403 FORBIDDEN_SCOPE
listing what was required.
Revocation
The workspace owner can revoke your app at any time from Settings → Connected Apps. Revocation is immediate: existing tokens stop authorizing straight away, and the next call returns403. If the user reconnects later, they’ll be asked to
consent again — so re-request access through Step 2 rather than reusing an old
token.
Errors you should handle
Treat
401 as “refresh or re-authorize” and 403 as “you weren’t granted this —
ask the user for that permission group.”