Endpoints
Scopes and claims
The ID token also carries
iss, aud (your client ID), azp, iat, exp, auth_time, nonce and
amr (["otp"] for a fresh code, ["session"] for Continue as).
The flow
1
Send the browser to the authorization endpoint
S256) is required for every client, including websites with a server.
Optional: prompt=login always asks for a fresh code; login_hint=+919876543210 (E.164) pre-fills
the number if its country is allowed for your website.2
Handle the callback
The customer returns to your
redirect_uri with ?code=…&state=…. Check state matches what you sent.
On failure you get ?error=…&error_description=…&state=… instead (see Errors).3
Exchange the code (within 60 seconds)
client_secret (in the body or as HTTP Basic). Browser and
mobile apps send only client_id — PKCE proves it’s them. Codes work once and expire after 60 seconds.4
Verify the ID token
Check the RS256 signature against the JWKS, and that
iss is https://auth.storetalk.app, aud is
your client ID, exp is in the future and nonce matches. Then sign the customer in to your own
session.
There are no refresh tokens: sign-ins are quick, and customers who come back get Continue as … without a code.
Using the StoreTalk SDK
The@citymapia-llc/storetalk-app-sdk package (version 1.19.0+) includes a ready-made button and
helpers that handle PKCE, state, nonce and token verification. They run in browsers, Node 18+ and edge
runtimes.
The SDK is published to GitHub Packages. Add
@citymapia-llc:registry=https://npm.pkg.github.com to your
.npmrc with a GitHub token that can read packages. You don’t need the SDK — any OIDC library works.1. The button (React)
loginHint="+919876543210" to pre-fill the number, or forceLogin to always ask for a fresh code.
locale sets the label (Continue with WhatsApp in English, Hindi, Malayalam or Tamil); variant="outline"
gives a white button that sits well next to Google/Apple buttons. Not using React? Call
startWhatsAppLogin({ clientId, redirectUri }) and send the browser to the returned url.
2. The callback page (browser)
completeWhatsAppLogin throws a WhatsAppLoginError if the customer cancelled (access_denied) or the
sign-in can’t be matched. Each sign-in can be completed only once.
3. Your server
verifyWhatsAppIdToken checks the signature (caching the JWKS for an hour and refetching when keys
rotate), issuer, audience, expiry and nonce. getWhatsAppUserInfo(accessToken) calls the UserInfo endpoint.
Auth.js / NextAuth
https://your-site.com/api/auth/callback/whatsapp as the redirect URI in Settings.
Other platforms
- WordPress — use an OpenID Connect client plugin. Enter the client ID and secret, scope
openid phone profile, and the endpoints above (or the discovery URL if the plugin supports it). Enable PKCE. - Any server language — use your language’s OIDC client with the discovery URL. Choose the authorization code flow with PKCE (S256).
Mobile apps
Register a Browser or mobile app client (no secret).- Open the sign-in page in the system browser sheet —
ASWebAuthenticationSessionon iOS, Custom Tabs on Android. Don’t use an embedded WebView: the Continue as session isn’t shared, and sign-in pages inside WebViews are a common phishing pattern. - Prefer a verified app link as the redirect URI (
https://example.com/auth/callback, verified withapple-app-site-association/assetlinks.json). A custom scheme such ascom.example.app:/oauthalso works, but another app could claim it. - AppAuth for iOS and Android works out of the box with the discovery URL.
Apple requires iOS apps that offer third-party sign-in (Google, WhatsApp…) to also offer Sign in with
Apple or an equivalent privacy-focused option (App Store guideline 4.8).
Browser apps (no server)
Browser apps can exchange the code directly from the page: add your site under Allowed origins and call the token endpoint with a form POST (noclient_secret). Call the UserInfo endpoint from a server, not
the browser — or simply read the claims from the verified ID token.
Signing out
Your website ends its own session as usual. To also end the Continue as session on that browser, send it to:post_logout_redirect_uri (with your state) only if it’s one of the
Sign-out return addresses registered in Settings; otherwise they see a StoreTalk confirmation.
To revoke an access token, POST token, client_id (and client_secret for websites with a server) to
the revocation endpoint. It always returns 200.
Errors
Errors on your redirect URI (?error=…):
If the client ID or redirect URI is wrong, the customer sees an error on the StoreTalk page and is not
redirected — so a mistyped redirect URI can’t send customers elsewhere.
Token endpoint errors (JSON, RFC 6749):
Testing
- Add
http://localhost:3000/…as a redirect URI while developing. - The Codes per day limit and allowed countries apply during testing too.
- Each code you request is a real WhatsApp message charged to the business’s WhatsApp account.