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

# Dashboard authentication

> Sign in, sign up, Google OAuth, and email verification flows for the MsgFlash console.

## Scope

This page documents authentication for the web console:

* [app.msgflash.com/login](https://app.msgflash.com/login)
* [app.msgflash.com/signup](https://app.msgflash.com/signup)

It does not apply to the public API `x-api-key` flow.

***

## Team workspace header (optional)

After login, **`Authorization: Bearer <jwt>`** identifies the user. For **resource** routes under **`/api/*`** (for example `/api/messages`, `/api/contacts`, `/api/campaigns`, `/api/instances`, `/api/templates`, `/api/webhooks`, `/api/statuses`, `/api/media`, `/api/number-lookups`), you may add:

```http theme={null}
X-Team-Id: <team uuid>
```

* **With** `X-Team-Id`: requests run in that team’s shared workspace (you must be an active member).
* **Without** it: requests use your **personal** workspace.

Auth-only routes under **`/api/auth/*`** ignore this header. Team admin routes under **`/api/teams`** are separate; see [Teams & workspaces](/guides/teams-workspaces) and [Team context](/api-reference/teams/team-context).

***

## Endpoints used by the console

| Method | Endpoint                                      | Usage                         |
| ------ | --------------------------------------------- | ----------------------------- |
| `POST` | `/api/auth/signup`                            | Create an account             |
| `POST` | `/api/auth/login`                             | Open a session                |
| `GET`  | `/api/auth/google`                            | Start Google OAuth            |
| `POST` | `/api/auth/resend-verification`               | Resend the verification email |
| `GET`  | `/api/auth/verify-email/validate?token=...`   | Check a verification token    |
| `POST` | `/api/auth/verify-email`                      | Confirm email verification    |
| `POST` | `/api/auth/forgot-password`                   | Request a reset link          |
| `GET`  | `/api/auth/reset-password/validate?token=...` | Validate a reset token        |
| `POST` | `/api/auth/reset-password`                    | Set a new password            |

***

## Email signup

`POST /api/auth/signup` no longer signs the user in automatically.

Expected response:

```json theme={null}
{
  "data": {
    "success": true,
    "verificationRequired": true,
    "email": "jean@example.com"
  }
}
```

Expected UX:

* account created
* “Check your email” screen
* resend link available
* return to the login page

***

## Email login

`POST /api/auth/login` always returns a JWT if login succeeds.

Important business cases:

| Code                 | UI meaning                                         |
| -------------------- | -------------------------------------------------- |
| `UNAUTHORIZED`       | wrong email or password                            |
| `EMAIL_NOT_VERIFIED` | show a clear message and offer to resend the email |

Example `EMAIL_NOT_VERIFIED`:

```json theme={null}
{
  "error": {
    "code": "EMAIL_NOT_VERIFIED",
    "message": "Email not verified"
  }
}
```

***

## Google OAuth

Flow:

1. the console opens `GET /api/auth/google`
2. the backend redirects to Google
3. Google returns to `https://app.msgflash.com/auth/callback`
4. the JWT is read from `?token=...`
5. the console stores the JWT and redirects to `/dashboard`

If the callback contains `?error=oauth_failed`, the console sends the user back to `/login?error=oauth_failed`.

***

## Email verification

Relevant page:

```txt theme={null}
/verify-email?token=...
```

Recommended flow:

1. read the token
2. call `GET /api/auth/verify-email/validate?token=...`
3. if valid, call `POST /api/auth/verify-email`
4. show the result without auto-login

States to handle:

* `valid`
* `expired`
* `used`
* `invalid`
* `already_verified`

The account is not auto-logged-in after verification. The user returns to `/login`.

***

## Forgot password

Flow:

1. `/forgot-password` form
2. `POST /api/auth/forgot-password`
3. email with reset link
4. `/reset-password?token=...`
5. validate token
6. `POST /api/auth/reset-password`
7. return to `/login`

***

## Important UX notes

* Classic signup does not open a session automatically.
* Email verification is mandatory before login.
* The “Resend verification email” button should stay available on:
  * the screen shown after signup
  * the login screen when `EMAIL_NOT_VERIFIED` is returned
  * the `/verify-email` page when the token is expired or invalid
