# POST /auth/otp/send

> Send a one-time code to email or phone

Send a one-time code for **passwordless sign-in** — no password field. User enters email or phone, receives a code, then verifies with [POST /auth/otp/verify](/reference/authentication/otp-verify) to get a token.

**Email OTP** delivers the code via email; **Phone OTP** delivers via SMS. Which method is available depends on your project's Auth settings (**Sign-in method**: Email OTP only, Phone OTP only, or Both).

When **Auto-create user on first OTP** is enabled, a new account is created if the identifier (email or phone) doesn't exist yet.

  **Passwordless:** This flow needs no password. For traditional sign up (email + password), use [POST /auth/register](/reference/authentication/register) instead.

  **Rate limiting:** OTP send is rate-limited per identifier and per IP to prevent abuse.

## Endpoint

```http
POST /v1/public/projects/:projectSlug/auth/otp/send
```

## Request Body

Send **either** `email` **or** `phone`—one is required. Which is accepted depends on your project's `otp_channels` (Email OTP only, Phone OTP only, or Both).

| Field | Type | Required | Description |
|-------|------|----------|-------------|
| `email` | string | One of email/phone | Email address (valid format) |
| `phone` | string | One of email/phone | Phone in E.164 format (e.g. `+919876543210`) |

### Example: Email OTP

```json
{
  "email": "user@example.com"
}
```

### Example: Phone OTP

```json
{
  "phone": "+919876543210"
}
```

## Response

### Success (200 OK)

```json
{
  "message": "OTP sent successfully",
  "accountExists": true
}
```

| Field | Type | Description |
|-------|------|-------------|
| `message` | string | Success message |
| `accountExists` | boolean | `true` if the user already had an account; `false` if a new user was created (when auto-create is enabled) |

### Error Responses

| Status Code | Description |
|-------------|-------------|
| 400 | Invalid request: missing/ invalid email or phone; or "Phone OTP is not enabled for this project" / "Email OTP is not enabled for this project" when using an identifier your project doesn't support |
| 400 | "No account found. Please sign up first." when identifier is unknown and auto-create is disabled |
| 429 | Too many OTP requests (rate limited) |

## Related Endpoints

- [POST /auth/otp/verify](/reference/authentication/otp-verify) - Verify the code and get a JWT
- [POST /auth/login](/reference/authentication/login) - Password-based login
