---
title: "Sign in with email"
description: "Registration, login, password reset, and email verification flows."
---

> Documentation Index
> Fetch the complete documentation index at: https://truememory-docs.mvstg.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Sign in with email

All requests go to the **Truememory Auth base URL** (see [Before you start](/authentication/overview/#before-you-start) for prerequisites: base URL, CORS whitelisting, OAuth client IDs).

## Registration (Email/Password)

Create a new user account. Password must be at least 6 characters.

```bash
POST https://your-auth-host/auth/register
Content-Type: application/json

{
  "email": "user@example.com",
  "password": "SecurePassword123!",
  "display_name": "Jane Doe",
  "app_name": "Vibrantly"
}
```

`app_name` is optional — it brands the verification email sent at signup (see [Email Verification](#email-verification)); omitted, the email uses Truememory branding.

**Response** (`201 Created`):

```json
{
  "id_token": "eyJhbGciOiJSUzI1NiIs...",
  "refresh_token": "AMf-xB...",
  "expires_in": "3600",
  "user": {
    "id": "4b822c30-1a07-40d6-8d59-321ef99037f6",
    "gip_uid": "5iexdslxx7hFwmKPIdlssLRkREA3",
    "email": "user@example.com",
    "email_verified": false,
    "username": null,
    "display_name": "Jane Doe",
    "photo_url": null,
    "phone_number": null,
    "disabled": false,
    "role": "user",
    "metadata": {},
    "created_at": "2026-03-25T10:00:00Z",
    "updated_at": "2026-03-25T10:00:00Z"
  }
}
```

All auth endpoints (`/register`, `/login`, `/oauth/token`) return this same response shape: an `id_token` for authenticating API calls, a `refresh_token` for getting new tokens when the current one expires, and a `user` object with the account details.

**Error responses:**

| Status | Code | When |
|--------|------|------|
| `409 Conflict` | `AUTH_EMAIL_EXISTS` | A user with this email is already registered |
| `400 Bad Request` | `AUTH_REGISTRATION_FAILED` | Other registration failures (e.g. provider error) |
| `422 Unprocessable Entity` | `VALIDATION_ERROR` | Invalid email format or password too short |

### User IDs

- `user.id` — Truememory's canonical user UUID. Deterministic — the same Firebase user always produces the same UUID, across all services, without a central registry or database lookup.
- `user.gip_uid` — The raw Firebase/GIP UID. Also appears as `sub` in the JWT.

:::tip[Store `user.id` in your database]
All Truememory services (memory, personas, agents) reference users by `user.id`. Use it as your primary key for seamless cross-service integration. Backend services also need this UUID when calling Truememory [on behalf of a user](/authentication/service-accounts/#service-acting-as-a-user).
:::

## Login (Email/Password)

```bash
POST https://your-auth-host/auth/login
Content-Type: application/json

{
  "email": "user@example.com",
  "password": "SecurePassword123!"
}
```

Returns the same `{ id_token, refresh_token, expires_in, user }` shape as registration.

## Password Reset

The reset flow is two steps: request the email, then confirm the new password using the code from the link.

### Step 1 — Request reset email

```bash
POST https://your-auth-host/auth/forgot-password
Content-Type: application/json

{ "email": "user@example.com", "app_name": "Vibrantly" }
```

| Field | Required | Description |
|-------|----------|-------------|
| `email` | Yes | The account's email address |
| `app_name` | No | Your app's display name. When set, the reset email **and** the hosted reset page use your app's branding; when omitted, both use Truememory branding. |

Always returns `{ "status": "ok" }` regardless of whether the email exists (prevents email enumeration). Firebase sends a password reset email if the account exists.

:::note[App branding must be registered first]
Per-app branding is managed by the Truememory team — notify them and provide your logo and branding details before using `app_name`, so the email and reset page render them. Unregistered names fall back to Truememory branding.
:::

### Step 2 — User completes the reset on the hosted page

The emailed link opens **Truememory's hosted reset page** (branded per `app_name`), where the user chooses a new password — your app doesn't need to build a reset screen or handle the link at all.

If you run a custom flow instead (e.g. a native in-app reset screen that intercepts the link), extract the `oobCode` parameter from the link and exchange it yourself — this is the same endpoint the hosted page uses:

```bash
POST https://your-auth-host/auth/reset-password
Content-Type: application/json

{
  "oob_code": "<code from the reset link>",
  "new_password": "NewSecurePassword123!"
}
```

**Response** (`200 OK`):

```json
{ "status": "ok" }
```

**Error responses:**

| Status | Code | When |
|--------|------|------|
| `400 Bad Request` | `AUTH_INVALID_OOB_CODE` | The code is invalid or has expired — ask the user to request a new reset email |
| `400 Bad Request` | `AUTH_PASSWORD_RESET_FAILED` | Other failure from Firebase |

:::tip[After a successful reset]
The user's existing sessions are not invalidated automatically. If you want to sign the user in immediately after the reset, call `POST /auth/login` with their email and new password to get fresh tokens.
:::

## Email Verification

When a user registers with email/password, their `email_verified` field starts as `false`. Truememory Auth automatically sends a verification email on registration — no extra API call needed.

The `user` object in all auth responses includes `email_verified`, so your app can check it and show a verification prompt when it's `false`.

### Re-send verification email

If the user did not receive the email or the link expired, they can request a new one. Pass `app_name` (optional) to use your app's branding on the email and the hosted verification page — same rules as [password reset](#password-reset), including the branding registration requirement:

```bash
POST https://your-auth-host/auth/send-verification-email
Authorization: Bearer <id_token>
Content-Type: application/json

{ "email": "user@example.com", "app_name": "Vibrantly" }
```

**Response** (`200 OK`):

```json
{ "status": "ok" }
```

Returns `400` with code `AUTH_VERIFICATION_FAILED` if the email is already verified.

### Checking verification status after the user clicks the link

When the user clicks the verification link, Google Identity Platform marks their email as verified on Google's side. Your app's token still carries the old `email_verified: false` until you refresh it.

:::note[This is Google's recommended approach]
Google Identity Platform does not push a real-time event when a user verifies their email. The standard pattern — recommended by Google — is for the client to refresh the token after the user returns from the verification link. The fresh token carries the updated `email_verified: true` claim.
:::

**The client-side flow:**

```mermaid
sequenceDiagram
accTitle: Email Verification Refresh Flow
accDescr: Shows how a client detects email verification after the user clicks the link

    participant User
    participant App as Your App
    participant Truememory as Truememory Auth
    participant GIP as Google Identity Platform

    App->>App: Show "Verify your email" banner
    User->>User: Open email, click verification link
    User->>GIP: Browser opens verification URL
    GIP->>GIP: Mark email as verified
    User->>App: Return to app
    App->>Truememory: POST /auth/refresh { refresh_token }
    Truememory-->>App: New id_token (email_verified: true)
    App->>Truememory: GET /auth/me
    Truememory-->>App: user.email_verified = true
    App->>App: Hide verification banner
```

**When to trigger the refresh** — the client should call `POST /auth/refresh` when it detects the user has returned to the app after clicking the verification link:

### Why OAuth users skip verification

Users who sign in with Google or Apple already have a verified email — the provider confirms it during sign-in. Their `email_verified` is `true` from the first login, so no verification email is sent.

Source: https://truememory-docs.mvstg.com/authentication/email-password/index.mdx
