Authorization Flow
Authorization Code with PKCE step by step — the only supported flow in Whatalo OAuth 2.1.
Whatalo implements the Authorization Code with PKCE flow in accordance with OAuth 2.1. PKCE is mandatory — there is no implicit flow or client credentials flow for user-delegated access.
Prerequisites
client_idobtained via dynamic registration- Redirect URI registered exactly as you will use it
Step 1 — Generate the PKCE pair
import { randomBytes, createHash } from "crypto";
// code_verifier: 43–128 URL-safe random characters
const codeVerifier = randomBytes(32).toString("base64url");
// code_challenge: SHA-256 of the verifier, encoded in base64url
const codeChallenge = createHash("sha256")
.update(codeVerifier)
.digest("base64url");Only code_challenge_method=S256 is accepted. The plain method is explicitly rejected per OAuth 2.1.
Step 2 — Redirect the user to the authorization endpoint
Build the URL and redirect:
GET https://app.whatalo.com/oauth/authorize?
response_type=code
&client_id=abc123def456ghi789jkl012
&redirect_uri=https%3A%2F%2Fmy-app.com%2Foauth%2Fcallback
&scope=read%3Aproducts%20read%3Aorders
&state=RANDOM_OPAQUE_VALUE
&code_challenge=THE_CHALLENGE_B64URL
&code_challenge_method=S256
&resource=https%3A%2F%2Fapi.whatalo.comRequest parameters
| Parameter | Required | Description |
|---|---|---|
response_type | Yes | Always code |
client_id | Yes | The client_id from your registration |
redirect_uri | Yes | Must match exactly one registered URI |
scope | Yes | Space-separated scopes. See Scopes |
state | Yes | Random opaque value. Validate on callback receipt to prevent CSRF |
code_challenge | Yes | SHA-256 of the code_verifier, in base64url |
code_challenge_method | Yes | Always S256 |
resource | No | RFC 8707. Identifies the target resource server. Single-value policy. |
What does the user see?
The user sees the Whatalo consent screen where they:
- Sign in (if not already)
- Select the store they want to connect
- Review the permissions your app is requesting
- Approve or decline
Store binding: the issued access_token is bound to the store the user selected. If your app needs access to multiple stores for the same user, start a separate authorization flow for each store.
Step 3 — Receive the authorization code
Whatalo redirects back to your redirect_uri:
GET https://my-app.com/oauth/callback?code=AUTH_CODE_HERE&state=RANDOM_OPAQUE_VALUEValidate that state matches the value you sent before continuing. If it does not match, discard the code — a CSRF attack may be in progress.
The authorization code:
- Is single-use
- Expires in 10 minutes
- Is bound to your
code_verifiervia PKCE
Step 4 — Exchange the code for tokens
Call the token endpoint with the code and the code_verifier:
POST https://app.whatalo.com/oauth/token
Content-Type: application/x-www-form-urlencoded
grant_type=authorization_code
&code=AUTH_CODE_HERE
&redirect_uri=https%3A%2F%2Fmy-app.com%2Foauth%2Fcallback
&client_id=abc123def456ghi789jkl012
&code_verifier=THE_ORIGINAL_CODE_VERIFIERYou will receive an access_token and a refresh_token. See the Token endpoint for full details.
Redirect URI requirements
| Case | Allowed |
|---|---|
https:// in production | Yes |
http://localhost or http://127.0.0.1 | Yes (development only) |
http:// on public domains | No |
| Substring of a registered URI | No — must match exactly |
| Multiple registered URIs | Yes, up to 10 per client |
Next step
With the obtained tokens, use them to call the Whatalo API with Authorization: Bearer <access_token>. When the access token expires, use the token endpoint with grant_type=refresh_token.