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

# Authentication Endpoints: Login, Register, and Tokens

> Reference for all Scrubbe authentication endpoints — registration, login, email verification, password reset, token refresh, and profile management.

The Scrubbe authentication API lives under `/api/v1/auth` and covers the full identity lifecycle: registering a new account, verifying an email address, logging in to receive tokens, refreshing those tokens, and managing your profile. Public endpoints require no credentials; protected endpoints require a valid Bearer token in the `Authorization` header.

## Public endpoints

These endpoints do not require authentication.

***

### POST /auth/login

Authenticate with email and password. Returns a short-lived access token and a long-lived refresh token.

<ParamField body="email" type="string" required>
  The registered email address.
</ParamField>

<ParamField body="password" type="string" required>
  The account password.
</ParamField>

<CodeGroup>
  ```bash cURL theme={null}
  curl --request POST \
    --url "https://your-api-domain.com/api/v1/auth/login" \
    --header "Content-Type: application/json" \
    --data '{
      "email": "user@example.com",
      "password": "s3cur3P@ssword"
    }'
  ```

  ```javascript Node.js theme={null}
  const response = await fetch('https://your-api-domain.com/api/v1/auth/login', {
    method: 'POST',
    headers: { 'Content-Type': 'application/json' },
    body: JSON.stringify({
      email: 'user@example.com',
      password: 's3cur3P@ssword'
    })
  });
  const { data } = await response.json();
  // data.accessToken, data.refreshToken
  ```

  ```python Python theme={null}
  import requests

  resp = requests.post(
      "https://your-api-domain.com/api/v1/auth/login",
      json={"email": "user@example.com", "password": "s3cur3P@ssword"}
  )
  data = resp.json()["data"]
  access_token = data["accessToken"]
  ```
</CodeGroup>

**200 response**

```json theme={null}
{
  "success": true,
  "message": "Login successful.",
  "data": {
    "accessToken": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
    "refreshToken": "dGhpcyBpcyBhIHJlZnJlc2ggdG9rZW4...",
    "user": {
      "id": "usr_01HX...",
      "email": "user@example.com",
      "firstName": "Ada",
      "lastName": "Lovelace",
      "role": "ENGINEER"
    }
  }
}
```

<ResponseField name="data.accessToken" type="string">
  JWT to include in the `Authorization: Bearer` header for protected requests. Short-lived.
</ResponseField>

<ResponseField name="data.refreshToken" type="string">
  Long-lived token used to obtain a new access token via `POST /auth/refresh-token`.
</ResponseField>

<ResponseField name="data.user" type="object">
  Basic profile information for the authenticated user.
</ResponseField>

***

### POST /auth/business/register

Register a new business account and workspace.

<ParamField body="businessName" type="string" required>
  Name of the organization.
</ParamField>

<ParamField body="email" type="string" required>
  Owner's email address.
</ParamField>

<ParamField body="password" type="string" required>
  Account password (minimum 8 characters).
</ParamField>

***

### POST /auth/dev/register

Register a new developer account.

<ParamField body="email" type="string" required>
  Developer email address.
</ParamField>

<ParamField body="password" type="string" required>
  Account password.
</ParamField>

***

### POST /auth/oauth/login

Authenticate or register via an OAuth provider (e.g., Google). Redirects to the provider's consent screen.

<ParamField body="provider" type="string" required>
  OAuth provider name. Example: `"google"`.
</ParamField>

***

### POST /auth/verify\_email

Verify an email address using the OTP sent after registration.

<ParamField body="email" type="string" required>
  The email address to verify.
</ParamField>

<ParamField body="otp" type="string" required>
  The one-time passcode delivered to the email address.
</ParamField>

***

### POST /auth/resend\_otp

Resend the email verification OTP. Subject to the email rate limit (3 requests per minute).

<ParamField body="email" type="string" required>
  The email address to resend the OTP to.
</ParamField>

<Warning>
  This endpoint is rate-limited to 3 requests per minute per email address. Repeated calls within the window return `429 Too Many Requests`.
</Warning>

***

### POST /auth/forgot-password

Initiate the password reset flow. Sends a reset link or token to the specified email.

<ParamField body="email" type="string" required>
  The email address associated with the account.
</ParamField>

***

### POST /auth/validate-reset-token

Validate that a password reset token is still active before presenting the reset form.

<ParamField body="token" type="string" required>
  The reset token received via email.
</ParamField>

***

### POST /auth/reset-password

Set a new password using a valid reset token.

<ParamField body="token" type="string" required>
  The reset token from the email.
</ParamField>

<ParamField body="password" type="string" required>
  The new password (minimum 8 characters).
</ParamField>

***

### POST /auth/refresh-token

Exchange a refresh token for a new access token. Does not require the `Authorization` header.

<ParamField body="refreshToken" type="string" required>
  A valid, unexpired refresh token.
</ParamField>

```json theme={null}
{
  "success": true,
  "message": "Token refreshed.",
  "data": {
    "accessToken": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..."
  }
}
```

***

## Protected endpoints

These endpoints require `Authorization: Bearer <accessToken>`.

***

### POST /auth/logout

Invalidate the current session. The access token is revoked server-side.

No request body required.

```json theme={null}
{
  "success": true,
  "message": "Logged out successfully.",
  "data": {}
}
```

***

### POST /auth/change-password

Change the authenticated user's password.

<ParamField body="currentPassword" type="string" required>
  The user's current password.
</ParamField>

<ParamField body="newPassword" type="string" required>
  The new password (minimum 8 characters, must differ from the current password).
</ParamField>

***

### GET /auth/me

Retrieve the profile of the currently authenticated user.

```json theme={null}
{
  "success": true,
  "message": "Profile retrieved.",
  "data": {
    "id": "usr_01HX...",
    "email": "user@example.com",
    "firstName": "Ada",
    "lastName": "Lovelace",
    "role": "ENGINEER",
    "businessId": "biz_01HX...",
    "createdAt": "2025-01-15T10:30:00Z"
  }
}
```

***

### PUT /auth/profile

Update the authenticated user's profile information.

<ParamField body="firstName" type="string">
  Updated first name.
</ParamField>

<ParamField body="lastName" type="string">
  Updated last name.
</ParamField>

<ParamField body="phone" type="string">
  Contact phone number.
</ParamField>

<Note>
  Email address cannot be changed through this endpoint. Contact support to update your login email.
</Note>
