Reference

Endpoints

issuerhttps://accounts.u.cash
authorizationhttps://accounts.u.cash/oauth2?op=authorize
tokenhttps://accounts.u.cash/oauth2?op=token
userinfohttps://accounts.u.cash/oauth2?op=userinfo (Bearer)
revocationhttps://accounts.u.cash/oauth2?op=revoke (RFC 7009)
end sessionhttps://accounts.u.cash/oauth2?op=end_session
jwkshttps://accounts.u.cash/.well-known/jwks.json
discoveryhttps://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

openidsub (plus iss, aud, exp, iat, azp, nonce)
emailemail, email_verified
profilename, 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.