OAuth 2.1

For apps acting on behalf of a user (Zapier, n8n, chat connectors): authorization code with PKCE, refresh tokens, consent with organization choice. For server-to-server the API key remains the simpler way.

When OAuth, when keys

API keys (capi_…) belong to an organization and suit scripts and servers. OAuth tokens belong to a user who grants one organization in the consent screen — so end users connect their own claritos organization to a third-party app without copying keys. Both ways use the same scopes and endpoints.

Authorization code + PKCE

The client sends the user to authorize (PKCE is mandatory, S256), receives a code at its redirect URI after consent and exchanges it at the token endpoint for an access token (1 hour) and a refresh token (30 days). Confidential clients send their client_secret; public clients only the code_verifier.

http
GET https://www.claritos.io/api/auth/oauth2/authorize
  ?response_type=code
  &client_id=CLIENT_ID
  &redirect_uri=https://app.example.com/callback
  &scope=openid%20offline_access%20contacts:read%20invoices:write
  &state=RANDOM
  &code_challenge=BASE64URL(SHA256(code_verifier))
  &code_challenge_method=S256
curl
curl -X POST https://www.claritos.io/api/auth/oauth2/token \
  -d grant_type=authorization_code \
  -d code=CODE_FROM_CALLBACK \
  -d redirect_uri=https://app.example.com/callback \
  -d client_id=CLIENT_ID -d client_secret=CLIENT_SECRET \
  -d code_verifier=CODE_VERIFIER
json
{
  "access_token": "…",
  "token_type": "Bearer",
  "expires_in": 3600,
  "refresh_token": "…",
  "scope": "openid offline_access contacts:read invoices:write"
}

Consent with organization choice

The user sees the client and the requested permissions and chooses the organization the access applies to. Exactly one per connection; permissions apply only as far as the user’s role in the organization allows (membership is checked on every call). Clients-data scopes additionally need the organization’s enablement. Since 1.26.0 the user can deselect individual permissions in the consent; access applies only to the selected scopes, clients-data scopes are deselected by default. Users see their grants in the profile under “Connected apps” and can revoke them there at any time.

Calling the API

The access token is sent like a key as a Bearer token. GET /me shows organization, scopes and limits of the token.

curl
curl https://www.claritos.io/api/v1/me -H "Authorization: Bearer ACCESS_TOKEN"

Refreshing tokens

When the access token expires, the token endpoint returns a new pair with grant_type=refresh_token. Refresh tokens are rotated.

curl
curl -X POST https://www.claritos.io/api/auth/oauth2/token \
  -d grant_type=refresh_token -d refresh_token=REFRESH_TOKEN \
  -d client_id=CLIENT_ID -d client_secret=CLIENT_SECRET

Discovery

Metadata per RFC 8414 (authorization server) and RFC 9728 (protected resource) live at the root; the OpenID configuration additionally under the auth path. Clients supporting discovery (MCP connectors) only need the base URL.

http
GET https://www.claritos.io/.well-known/oauth-authorization-server
GET https://www.claritos.io/.well-known/oauth-protected-resource
GET https://www.claritos.io/api/auth/.well-known/openid-configuration

Dynamic client registration

Clients can register themselves (RFC 7591) — this is how claude.ai, ChatGPT and other MCP clients connect without manual setup. Registered clients appear in the system area and can be disabled there.

curl
curl -X POST https://www.claritos.io/api/auth/oauth2/register \
  -H "Content-Type: application/json" \
  -d '{ "client_name": "My MCP client", "redirect_uris": ["https://client.example.com/cb"], "token_endpoint_auth_method": "none", "grant_types": ["authorization_code","refresh_token"] }'

Zapier, n8n, Make

Create a client in the system area (enter the platform’s redirect URI), store client_id/client_secret there, authorization URL /api/auth/oauth2/authorize, token URL /api/auth/oauth2/token, scopes as needed (e.g. contacts:write invoices:read). Enable PKCE if the platform offers it. Per-platform setup see the “Webhooks” guide → Platforms.