apikey header — the Anon Key is what makes the auth endpoints reachable from public clients. After sign-in, you’ll send the user’s access token as the Authorization: Bearer <token> header on subsequent API calls (and keep the Anon Key in apikey).
For the conceptual underpinning, see Auth model. For the full endpoint surface, see Auth Reference. For OAuth flows specifically, see OAuth providers.
Headers used throughout
Every request below uses these two headers (the auth API doesn’t need its own access token — that’s what you’re trying to get):Authorization value with the user’s access_token. Keep apikey as the Anon Key — PostgREST and GoTrue both check it for upstream routing.
Email + password — signup
POST /auth/v1/signup creates a new user with email + password and, on default settings (autoConfirm: true), returns a session immediately. On projects where you’ve enabled email confirmation, the response is just { user } and the user has to click the email link before they can sign in.
data: { ... }— populatesuser_metadata. Use for display name, signup source, marketing consent, etc.phone: "+1..."— phone-based signup (requiresGOTRUE_EXTERNAL_PHONE_ENABLED=true+ Twilio configured).gotrue_meta_security: { captcha_token: "..." }— required if CAPTCHA is enabled on the project.
Email + password — signin
POST /auth/v1/token?grant_type=password exchanges credentials for an access token + refresh token.
400 invalid_grant— wrong email/password combination, or the user doesn’t exist.400 email_not_confirmed— autoConfirm is off and the user hasn’t clicked the verification email yet.400 over_email_send_rate_limit— too many recent failed signin attempts from this IP (30/hour by default).
Magic link (passwordless email)
POST /auth/v1/otp sends an email containing a magic link. The user clicks it, GoTrue verifies the token in the link, redirects to your app with a code in the URL, and your app calls POST /auth/v1/token?grant_type=pkce to exchange that code for the session.
The link flow takes two steps in your app: (1) request the magic link, (2) handle the redirect callback.
create_user: falselets you implement “magic link only for existing users” (returns 400 if no user with that email).- Your redirect URL must be in the project’s URI allow list (
gotrue.uriAllowListin Helm overrides, or the auth settings in the Studio). GoTrue won’t redirect to arbitrary URLs.
Password recovery
The recovery flow looks just like magic link — request a recovery email, user clicks it, your callback grabs tokens from the URL fragment.POST /auth/v1/recover always returns 200, even for emails that don’t exist — this is intentional, so an attacker can’t enumerate user accounts via the recovery endpoint.
Refreshing the access token
Access tokens last 1 hour. Before yours expires, exchange the refresh token for a new pair:expires_at - 60s. If you wait for expiry, you’ll get 401s on in-flight requests.
Sign out
POST /auth/v1/logout (with the user’s access token) invalidates the refresh token server-side and emits a session-revocation event. Always clear client-side storage too — server-side invalidation alone won’t log the user out if the access token is still in localStorage.
scope query parameter can be global (default — revoke refresh tokens on all devices), local (just this session), or others (everywhere except this device).
Storing tokens
A short detour because this trips people up. The right place to store the tokens depends on your environment:- Browser SPA —
localStorageis fine for most apps. The Anon Key is already public; the access token is short-lived; the refresh token’s single-use rotation limits damage from XSS-stolen tokens. If XSS is a serious concern, use an httpOnly cookie set by your backend proxy. - Server-side rendering (Next.js, Remix, etc.) — use httpOnly cookies set by the server. The client never sees the tokens; your server attaches them on outbound API calls.
- Mobile (iOS, Android) — the OS-native secure storage (Keychain on iOS, EncryptedSharedPreferences on Android). Don’t put refresh tokens in regular preferences.
- CLI / desktop apps — write to a
~/.config/your-app/credentials.jsonwith 0600 perms.
Next steps
OAuth providers
Google, GitHub, and 20 more OAuth providers with PKCE.
Auth model
What’s inside the JWTs and how rotation works under the hood.
Auth Reference
Full /auth/v1/* endpoint surface.
RLS Cookbook
The policy patterns that gate what signed-in users can see.