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

# Send OTP

> Send a one-time password (OTP) to a customer email address for passwordless sign-in.

# Send OTP

Sends a one-time password to the provided email address for passwordless authentication. The customer enters the OTP in the portal to obtain a bearer token without needing their full password. This supports magic-link and OTP-based sign-in flows.

## Authentication

No authentication required. This is a public endpoint.

## Query Parameters

<ParamField query="email" type="string" required>
  The email address of the customer to send the OTP to. URL-encode this value.
</ParamField>

<ParamField query="businessId" type="number" required>
  The numeric identifier of the location. Ensures the OTP email uses the correct branding and is associated with the right space.
</ParamField>

## Response

Returns an `ActionConfirmation` envelope. As with the password-reset flow, the response does not reveal whether the email address is registered.

<ResponseField name="WasSuccessful" type="boolean">
  `true` when the OTP was dispatched (or when no account was found — intentionally the same to prevent enumeration).
</ResponseField>

<ResponseField name="Value" type="string | null">
  Usually `null`.
</ResponseField>

<ResponseField name="Status" type="number">
  HTTP-style status code mirrored in the body. `200` on success.
</ResponseField>

<ResponseField name="Message" type="string | null">
  Human-readable message. Usually `null` on success.
</ResponseField>

<ResponseField name="Errors" type="any">
  Validation errors. `null` on success.
</ResponseField>

## Example Response

```json theme={null}
{
  "WasSuccessful": true,
  "Value": null,
  "Status": 200,
  "Message": null,
  "Errors": null
}
```

## TypeScript Integration

```typescript theme={null}
import endpoints from '@/api/endpoints'

const url = endpoints.system.users.sendOtp(email, businessId)
// => '/api/sys/users/sendOtp?email=jane.doe%40example.com&businessId=7'

await httpClient.get(url)
```

## Usage in Portal

| Context                       | Source file              |
| ----------------------------- | ------------------------ |
| OTP / magic-link sign-in flow | `src/views/auth/SignIn/` |

## Error Responses

<ResponseField name="400 Bad Request" type="error">
  The `email` or `businessId` parameter is missing or malformed.
</ResponseField>

<ResponseField name="429 Too Many Requests" type="error">
  OTP requests are rate-limited. The customer must wait before requesting another code.
</ResponseField>

## Related Endpoints

| Method | Endpoint                            | Description                                       |
| ------ | ----------------------------------- | ------------------------------------------------- |
| `POST` | `/api/sys/users/startPasswordReset` | Trigger a full password-reset email               |
| `POST` | `/api/sys/users/exchange`           | Exchange a JWT (including OTP result) for a token |
| `POST` | `/api/token`                        | Standard credential-based sign-in                 |
