Authentication
How Feeef tokens, abilities and sign-in methods work across the platform.
Token model
Feeef uses opaque database-backed access tokens (not JWTs). Send them on every request:
Authorization: Bearer oat_...| Property | Value |
|---|---|
| Format | Opaque string (oat_ prefix), verified server-side |
| Lifetime | 90 days |
| Abilities | Array of scope strings stored on the token |
| First-party tokens | ["*"] — full account access (dashboard/portal sign-ins) |
| OAuth tokens | Exactly the scopes the user consented to, plus a binding to the issuing app |
A token failing a scope check receives 403 with error: "insufficient_scope", the
requiredScope field and a WWW-Authenticate header (RFC 6750).
Sign-in methods
All first-party endpoints live under /v1/users/auth:
| Method | Endpoint | Notes |
|---|---|---|
| Email + password | POST /users/auth/signin | Body {email, password, fcmToken?} → {user, token} |
| Sign up | POST /users/auth/signup | {name, email, password, phone?, referral?} → 201 {user, token} (rate limited) |
| Restore session | GET /users/auth | With bearer header → {user, token} ("me") |
| Social | POST /social/{google|github|apple|facebook}/callback | Exchange the provider code; also link/unlink endpoints |
| Passkeys (WebAuthn) | POST /passkeys/register/start|finish, POST /passkeys/authenticate/start|finish | Full passwordless support |
| One-time auth code | POST /users/auth/code → POST /users/auth/code/consume | QR / cross-device login: mint a single-use code (2 min TTL) on a signed-in device, consume it on another |
| OAuth (third-party) | GET /oauth/authorize + POST /oauth/token | The flow your apps use — see OAuth |
Managing sessions
Every issued token is a session you can inspect and revoke:
| Action | Endpoint |
|---|---|
| List sessions | GET /users/auth/tokens (abilities, last used, expiry — hash never returned) |
| Revoke one | DELETE /users/auth/tokens/:identifier |
| Revoke all | POST /users/auth/tokens/revoke-all |
| Sign out (current token) | POST /users/auth/signout |
| List authorized OAuth apps | GET /users/auth/connected-apps |
The dashboard's API sessions page is a UI over exactly these endpoints.
Password reset & email verification
| Action | Endpoint |
|---|---|
| Request reset email | POST /users/auth/reset-password {email} → 204 |
| Confirm reset | POST /auth/web/reset-password-confirm {uid, token, newPassword} |
| Resend verify email | POST /users/auth/verify-email/resend |
| Confirm email | POST /users/auth/verify-email/confirm {code} |
Choosing an auth strategy
| You are building… | Use |
|---|---|
| A personal script / server-to-server job on your own account | A first-party token from POST /users/auth/signin (keep it in a secret manager) |
| A product other Feeef users sign in to | OAuth authorization code — scoped tokens, consent screen, revocable per app |
| A CLI or desktop tool | OAuth public client with PKCE (that is exactly how @feeef.dev/cli works) |
| A storefront theme | No credentials — themes run in the shopper's browser against public endpoints; see Templates |
There are no refresh tokens today. Access tokens live 90 days; when one expires, run the
sign-in or OAuth flow again. Design your integration to detect 401 and re-authenticate.