ck_live_…, see Authentication) and short-lived OAuth
access tokens (ck_oat_…). OAuth is the better fit when your platform already
manages OAuth credentials, or when you want tokens that expire on their own
instead of a key that lives until revoked.
The server implements the standard client credentials grant
(RFC 6749 §4.4),
token revocation (RFC 7009),
and discovery metadata at /.well-known/oauth-authorization-server
(RFC 8414).
1. Register a client
An owner or admin registers an OAuth client for the business (same policy as API keys — see who can create keys). Registration returns:
Like an API key, a client is pinned to one business and owned by the member who
created it. Its effective scopes are clamped to that member’s current role on
every request.
2. Exchange for a token
POST /oauth/token at the API root (not under /v1). Authenticate with HTTP
Basic (recommended) or client_id/client_secret form parameters:
scope is optional and space-delimited; omit it to receive every scope the
client holds. Requesting a scope the client wasn’t granted returns
invalid_scope — never a silent narrowing.
3. Call the API
Send the token exactly like an API key, on any/v1 endpoint or the MCP
server:
401, and
don’t cache tokens past expires_in.
Revocation
POST /oauth/revokewithtoken=ck_oat_…(client-authenticated, RFC 7009) kills one token immediately. A client can only revoke its own tokens.- Revoking the client in Cherry kills every outstanding token instantly and stops future issuance.
Authorization code + PKCE (per-user consent)
Use this flow when your product’s users connect their own Cherry business — a “Connect Cherry” button instead of copy-pasted credentials. It requires redirect URIs registered on the client (exact-match,https only except
localhost/127.0.0.1), and PKCE with S256 is mandatory.
-
Send the user to the consent page on the Cherry web app:
The user signs in, sees your client’s name, the requested scopes, and which business the grant binds, and approves. The scopes a user can approve are capped by their own role — a read-only member cannot grant
write. -
Receive the code. The browser returns to your
redirect_uriwith?code=ck_ac_…&state=…. Codes are single-use and expire in 5 minutes. -
Exchange it (server-side, with your client secret and the PKCE
verifier):
The response includes a
refresh_token(ck_rt_…) alongside the usual access token. -
Refresh. Refresh tokens rotate on every use — each refresh response
carries a new
refresh_token, and the old one dies. Presenting a retired refresh token is treated as theft and answersinvalid_grant.
POST /oauth/revoke accepts ck_rt_… refresh tokens as well as access
tokens.