Skip to content

Accounts and sign-in

Authentication is Better Auth, configured in packages/core/src/lib/auth.ts and served at /api/auth/* — proxied to apps/api when API_INTERNAL_URL is set, local otherwise. The browser only ever talks to the web origin, so cookies behave the same either way.

Route Purpose
/auth/login Email OTP and social sign-in
/auth/sign-up Account creation
/membership Marketing page for the free account, with an inline join form
  • When APP_VARIANT is not production, the OTP is hardcoded 666666. That is what lets beta and local testing run without a mailbox.
  • In production a random OTP is generated and the real email is sent. There is no bypass.

The mobile app authenticates against /v1/auth/* and receives a Better Auth session token (also returned in the set-auth-token response header), which it sends as Authorization: Bearer <token>. Credentialed requests must carry an Origin header matching the API origin. See REST /v1.

BETTER_AUTH_TRUSTED_ORIGINS is comma-separated. A new preview or custom domain that cannot sign in is usually missing from that list.