Skip to main content
The API accepts two bearer credentials interchangeably: long-lived API keys (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:
Scope rules, error shapes, and rate limits are identical to API-key requests. Tokens expire after one hour — fetch a new one when you receive 401, and don’t cache tokens past expires_in.

Revocation

  • POST /oauth/revoke with token=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.
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.
  1. 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.
  2. Receive the code. The browser returns to your redirect_uri with ?code=ck_ac_…&state=…. Codes are single-use and expire in 5 minutes.
  3. 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.
  4. 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 answers invalid_grant.
Tokens from this flow act as the consenting user: requests are attributed to them, and the token’s scopes are clamped to their current role on every call — if they leave the business, the grant stops working. POST /oauth/revoke accepts ck_rt_… refresh tokens as well as access tokens.

Token endpoint errors