Overview

Passkey login (Face ID, Touch ID, Android biometrics) plus WhatsApp one-time codes, for any website. No passwords, no email flows, no auth code to maintain.

What your site gets

You get How
Biometric sign-in WebAuthn passkeys — the same standard behind Face ID, Touch ID, and Android biometrics
Guaranteed fallback 6-digit codes delivered over WhatsApp, for first-time enrollment and device loss
Zero password storage Okia hosts the auth pages; your site only exchanges an OAuth code for tokens
Privacy by construction Each site receives a pairwise subject ID (pw_…). Two sites can never correlate the same user
Standard protocol OAuth2 authorization code + PKCE (S256 only); OIDC-shaped ES256 JWTs verified against a public JWKS
Step-up signal amr claim tells you whether login was passkey or OTP (["otp"]), so you can require step-up

The five-minute pitch

  1. Enroll — a user hits your login button, enters their phone on the hosted Okia page, gets a WhatsApp code, verifies, and is offered a passkey. Under 60 seconds, once ever.
  2. Return — every later login on any connected site is one Face ID tap. Under 5 seconds, zero typing.
  3. Fallback — WhatsApp code is always one tap away; nobody gets locked out by a lost phone upgrade.
  4. Your side — you exchange a short-lived code at POST /oauth/token, verify the ID token, and mint your own session. One endpoint, any language.

Users have no email in Okia. You identify them by the pairwise sub; the phone number is available only via the consented phone scope (double opt-in).

Protocol facts

All endpoints live on the auth domain.

Endpoint Method
/authorize GET
/oauth/token POST
/oauth/revoke POST
/userinfo GET
/logout GET
/.well-known/jwks.json GET
/.well-known/openid-configuration GET
Artifact Format Lifetime aud Notes
Auth code opaque 60 s single-use
ID token ES256 JWT 15 min your client_id token_use: "id", nonce, amr, auth_time
Access token ES256 JWT 15 min https://auth.okia.io token_use: "access"
Refresh token opaque 30 d rolling idle, 90 d absolute rotates on every use

Always check token_use when verifying: an access token is never an ID token.

Pick your connector

Connector Fits Quickstart Target
Universal JS snippet Any page that can add a <script> tag — static HTML, any CMS, any backend quickstart-js.md ~5 min
WordPress plugin WordPress and WooCommerce; pure redirect, zero JS, caching-plugin safe quickstart-wordpress.md ~6 min
@okia/react React SPAs and Next.js App Router quickstart-react.md ~8 min

Anything else (Laravel, Rails, Webflow, Framer, headless Shopify): it is a standard OAuth2 code + PKCE flow against the endpoints above — implement the redirect and the token exchange directly.

Overview · Okia docs