OAuth 2.1

Snappy Agents is both the authorization server and the only resource server. Tokens are opaque, stored hashed, and revocable.

Endpoint Purpose
GET /.well-known/oauth-authorization-server Metadata (RFC 8414). Also served at /.well-known/openid-configuration for clients that look there.
GET /.well-known/oauth-protected-resource Resource metadata (RFC 9728); referenced from WWW-Authenticate on 401.
POST /oauth/register Dynamic client registration (RFC 7591).
GET /oauth/authorize Browser flow: sign-in (email code or Google) → consent (with read-only switch) → redirect with code.
POST /oauth/token authorization_code (PKCE S256 required) and refresh_token (rotating; reuse revokes the family).
POST /oauth/revoke Revoke a token and its family (RFC 7009).
POST /oauth/introspect Introspection for confidential clients (RFC 7662).

Scopes

Scope Grants Class
profile Email, name, saved addresses read / write (profile edits)
catalog:read Search, products, availability, collections, address tools read
orders:read Quotes, checkouts, orders, timelines, SSE read
orders:write Create quotes and checkouts, cancel, send receipts write / sensitive-write
offline_access Refresh token —

Read-only grants. On the consent screen the user can tick Limit to read-only; orders:write is dropped from the grant. Write endpoints then return 403 with code insufficient_scope and missingScopes, which the agent should turn into "you connected Snappy as read-only; reconnect to buy".

Token lifetimes

Token TTL Notes
Authorization code 5 min Single use; replay revokes every token issued from that grant
Access token 60 min Bearer header only
Refresh token 30 days Rotated on each refresh; reuse of an old one revokes the whole family

Redirect URIs

https only, except http://localhost / 127.0.0.1 for development and custom app schemes. No fragments. Exact match at authorize time.

Client authentication

Public clients use token_endpoint_auth_method: none and PKCE. Confidential clients get a client_secret once at registration and may send it as client_secret_post or HTTP Basic.

Errors

The token endpoint answers RFC 6749 bodies: { "error": "invalid_grant", "error_description": "…" }. The authorize endpoint redirects errors to the registered redirect_uri only after it has been validated; otherwise it renders an HTML error.

Snappy Agents · agents.snappy.com · support@snappy.com