Authentication — read this first
Sign up or log in once to get a token string back. On every following request, send it as Authorization: Bearer <token>. Tokens are opaque, DB‑backed session IDs (not JWTs) — they last 14 days and can be revoked early by calling Log out.
For the iOS app: store the token field from the signup/login response (e.g. in the Keychain) and send it as a Bearer header on every request. The dc_session cookie the API also sets is a convenience for browser/cURL testing — native clients don't need it.
Every endpoint below marked 🔒 auth requires this header; a missing or expired token gets a 401 with {"error":"Sign in required."}.
Every route also works with an /api prefix (e.g. /api/v1/auth/login) if that's easier for your client config — both resolve identically.
Note: POST /v1/auth/forgot-password is currently a stub — it always returns success without actually sending an email yet.