OAuth 2.1 — Overview
How OAuth enables third-party applications to act on behalf of merchants in Whatalo.
OAuth 2.1 is the correct mechanism when your application needs to access the Whatalo API on behalf of a merchant. Unlike an API Key that identifies a single integration, an OAuth token is bound to a user who authorized your app and to the specific store they chose at the moment of consent.
When to use OAuth vs. API Keys
| Criteria | API Key | OAuth 2.1 |
|---|---|---|
| Who authorized access | The merchant themselves, manually | The merchant via a consent flow |
| Bound to | One store (manual setup) | The store the user selects during authorization |
| Multi-tenant support | No (one key per store) | Yes (one app for many stores) |
| Delegated access | No | Yes |
| Best for | Internal scripts, server-to-server | Third-party apps, MCP clients, SaaS integrations |
| Revocation | Manual from dashboard | By the user from settings, on token expiry, or for DCR clients on client expiry (default 90 days) |
High-level flow
Your app Whatalo AS Merchant's store
│ │ │
│── POST /oauth/register ─────►│ │
│◄── client_id ───────────────│ │
│ │ │
│── GET /oauth/authorize ─────►│ │
│ │◄── user selects store ────────│
│◄── ?code=AUTH_CODE ─────────│ │
│ │ │
│── POST /oauth/token ────────►│ │
│◄── access_token + refresh ──│ │
│ │ │
│── Authorization: Bearer ────►│ (API v1) │RFC standards compliance
Whatalo implements the following standards as an Authorization Server:
| RFC | Name | Support |
|---|---|---|
| OAuth 2.1 (draft) | Updated base framework | Full |
| RFC 7591 | Dynamic Client Registration | Full |
| RFC 7662 | Token Introspection | Full |
| RFC 7009 | Token Revocation | Full |
| RFC 8414 | Authorization Server Metadata | Full |
| RFC 8707 | Resource Indicators | Partial — single-value policy |
| RFC 6749 §4.1 | Authorization Code Flow | Full (mandatory PKCE) |
Authorization Server base URL
https://app.whatalo.comAll OAuth endpoints are served from this base. Never hardcode endpoint URLs — use the Discovery endpoint to resolve them at runtime.
access_token format
Whatalo issues opaque tokens (not JWT). This architectural decision directly affects how your Resource Server validates tokens:
- The
access_tokenis a 32-byte random string encoded in base64url. It contains no client-side decodable information. - It is not signed with public keys, so the Discovery endpoint does not expose
jwks_uri. - To validate a token, your Resource Server must call the Introspection endpoint on each request (with optional caching, TTL ≤ 60 s).
Implications for your Resource Server
| Topic | Opaque tokens (Whatalo) | Signed JWT tokens |
|---|---|---|
| Validation | Round-trip to /oauth/introspect | Local verification with JWKS |
| Added latency | ~50–100 ms (mitigable with caching) | Zero |
| Instant revocation | Yes — effective when cache expires | Difficult — requires a denylist |
| Token privacy | Zero exposed metadata | Claims visible if decoded |
This is a deliberate decision. Opaque tokens enable immediate revocation when a merchant revokes an app's access from their settings — all active tokens are invalidated instantly. With signed JWTs, this use case would require an additional distributed denylist.
Recommended caching
Cache active: true Introspection responses with a TTL of at most 60 seconds per token. Do not cache active: false responses — a token can be revoked at any time by the user, and aggressive caching would delay effective revocation.
Reference pages
| Page | Description |
|---|---|
| Discovery | Authorization Server metadata (RFC 8414) |
| Client registration | Dynamic registration of your app (RFC 7591) |
| Authorization flow | Authorization Code + PKCE step by step |
| Token endpoint | Code exchange and token renewal |
| Introspection | Bearer token validation (RFC 7662) |
| Revocation | Revoke active tokens (RFC 7009) |
| Scopes | Complete table of the 15 available scopes |
| OAuth errors | Error codes and how to handle them |