Reference
Endpoints
| issuer | https://accounts.u.cash |
| authorization | https://accounts.u.cash/oauth2?op=authorize |
| token | https://accounts.u.cash/oauth2?op=token |
| userinfo | https://accounts.u.cash/oauth2?op=userinfo (Bearer) |
| revocation | https://accounts.u.cash/oauth2?op=revoke (RFC 7009) |
| end session | https://accounts.u.cash/oauth2?op=end_session |
| jwks | https://accounts.u.cash/.well-known/jwks.json |
| discovery | https://accounts.u.cash/.well-known/openid-configuration |
Authorization request
GET /oauth2?op=authorize response_type=code (required, only "code") client_id (required) redirect_uri (required, exact match against registered URIs) scope (openid email profile - requested scopes are filtered) state (required, min 16 chars, echoed back) code_challenge + code_challenge_method=S256 (required for public clients and every non-first-party client) nonce (optional, embedded in the id_token) prompt (optional: none / login / consent) max_age (optional seconds, forces re-authentication when exceeded)
The first time a user signs in to your app they see a consent screen showing your app name, your verified domain, and exactly what is shared. Grants are remembered and only re-asked when you request a new scope. Users can revoke any app from their U account at any time.
Token exchange
POST /oauth2?op=token (application/x-www-form-urlencoded) grant_type=authorization_code code, redirect_uri, client_id client_secret (confidential clients) code_verifier (PKCE - required for public + non-first-party clients)
Response: access_token (opaque Bearer, 1 hour), id_token (RS256, 10 min), scope. Codes are single use and expire in 120 seconds. There are no refresh tokens: use prompt=none silent re-authorization through the persistent U session instead.
Scopes and claims
| openid | sub (plus iss, aud, exp, iat, azp, nonce) |
email, email_verified | |
| profile | name, preferred_username, picture, locale |
Claims ship only for granted scopes, in both the id_token and userinfo.
Errors and limits
Authorization errors redirect to your redirect_uri with error + state (login_required, consent_required, access_denied, invalid_scope). Token errors are RFC-shaped JSON (invalid_grant, invalid_client, pkce_failed, pkce_required). Endpoints are rate limited per IP and per client with HTTP 429 + Retry-After - they never lock.
Domain verification
Redirect URIs go live when their host (or a parent) is a domain you verified in the portal: add the shown TXT record _u-signin.yourdomain and click Verify. Loopback http URIs (127.0.0.1) are allowed for public development apps without verification. Re-checked daily: if the TXT record disappears, the domain's URIs stop being active.