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

# Change Your Account Phone Number — OTP Verification

> Update your phone number with an OTP verification. Submit your new E.164 phone number and current password, then confirm the 6-digit code sent via SMS.

Updating your phone number follows the same protect-then-verify pattern used across the account settings. You provide the new number in E.164 format together with your current password, and the API dispatches a one-time passcode (OTP) via SMS. Enter that 6-digit code in the second step to confirm ownership of the new number and complete the update.

<Note>
  The OTP sent to your new phone number expires after **10 minutes**. If it expires before you confirm it, restart the flow by calling `POST /users/me/phone-number` again to receive a fresh code.
</Note>

## Phone Number Change Flow

<Steps>
  <Step title="Initiate the Phone Number Change">
    Call `POST /users/me/phone-number` with your new phone number (in E.164 format) and your current account password. The API validates the number, checks it is not already in use, and sends a 6-digit OTP via SMS.

    **`POST /users/me/phone-number`**

    Obtain a CSRF token from `GET /auth/csrf-token` before sending this request, and pass it in the `x-csrf-token` header.

    <Info>
      E.164 format requires a leading `+`, the country code, and the subscriber number with no spaces or dashes. For example, a US number looks like `+14155552671`.
    </Info>

    **Request Body**

    <ParamField body="new_phone_number" type="string" required>
      The phone number you want to register, in E.164 format. Pattern: `^\+[1-9]\d{1,14}$`. Example: `+14155552671`.
    </ParamField>

    <ParamField body="password" type="string" required>
      Your current account password, used to re-authenticate the request.
    </ParamField>

    <CodeGroup>
      ```bash cURL theme={null}
      # Step 1a — get CSRF token
      CSRF=$(curl -s -X GET https://api.example.com/api/v1/auth/csrf-token \
        --cookie "session=<your-session-cookie>" | jq -r '.data.csrf_token')

      # Step 1b — request phone number change
      curl -X POST https://api.example.com/api/v1/users/me/phone-number \
        --cookie "session=<your-session-cookie>" \
        -H "x-csrf-token: $CSRF" \
        -H "Content-Type: application/json" \
        -d '{
          "new_phone_number": "+14155552672",
          "password": "S3cure!Pass"
        }'
      ```

      ```javascript JavaScript theme={null}
      // Step 1a — get CSRF token
      const { data: csrfData } = await fetch(
        "https://api.example.com/api/v1/auth/csrf-token",
        { credentials: "include" }
      ).then((r) => r.json());

      // Step 1b — request phone number change
      const response = await fetch(
        "https://api.example.com/api/v1/users/me/phone-number",
        {
          method: "POST",
          credentials: "include",
          headers: {
            "Content-Type": "application/json",
            "x-csrf-token": csrfData.csrf_token,
          },
          body: JSON.stringify({
            new_phone_number: "+14155552672",
            password: "S3cure!Pass",
          }),
        }
      );
      // 202 Accepted — OTP dispatched via SMS
      ```

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

      s = requests.Session()
      s.cookies.set("session", "<your-session-cookie>")

      csrf = s.get(
          "https://api.example.com/api/v1/auth/csrf-token"
      ).json()["data"]["csrf_token"]

      resp = s.post(
          "https://api.example.com/api/v1/users/me/phone-number",
          headers={"x-csrf-token": csrf},
          json={
              "new_phone_number": "+14155552672",
              "password": "S3cure!Pass",
          },
      )
      # 202 Accepted
      ```
    </CodeGroup>

    **Response — 202 Accepted**

    No response body is returned. An OTP has been sent to the new phone number via SMS.

    **Error Responses**

    | Status | Meaning                                                          |
    | ------ | ---------------------------------------------------------------- |
    | `400`  | Missing field or `new_phone_number` does not match E.164 format. |
    | `401`  | Wrong password or missing/expired session cookie.                |
    | `409`  | The new phone number is already registered to another account.   |
    | `429`  | Rate limit exceeded — check the `Retry-After` header.            |
  </Step>

  <Step title="Confirm with the OTP">
    Retrieve the 6-digit OTP from your SMS inbox and call `POST /users/me/phone-number/verify` while still authenticated. The code is single-use and must be submitted within 10 minutes of dispatch.

    **`POST /users/me/phone-number/verify`**

    Obtain a fresh CSRF token before this call.

    **Request Body**

    <ParamField body="otp" type="string" required>
      The 6-digit one-time passcode received via SMS. Pattern: `^\d{6}$`. Example: `123456`.
    </ParamField>

    <CodeGroup>
      ```bash cURL theme={null}
      # Step 2a — get CSRF token
      CSRF=$(curl -s -X GET https://api.example.com/api/v1/auth/csrf-token \
        --cookie "session=<your-session-cookie>" | jq -r '.data.csrf_token')

      # Step 2b — verify OTP
      curl -X POST https://api.example.com/api/v1/users/me/phone-number/verify \
        --cookie "session=<your-session-cookie>" \
        -H "x-csrf-token: $CSRF" \
        -H "Content-Type: application/json" \
        -d '{"otp": "123456"}'
      ```

      ```javascript JavaScript theme={null}
      const { data: csrfData } = await fetch(
        "https://api.example.com/api/v1/auth/csrf-token",
        { credentials: "include" }
      ).then((r) => r.json());

      const response = await fetch(
        "https://api.example.com/api/v1/users/me/phone-number/verify",
        {
          method: "POST",
          credentials: "include",
          headers: {
            "Content-Type": "application/json",
            "x-csrf-token": csrfData.csrf_token,
          },
          body: JSON.stringify({ otp: "123456" }),
        }
      );
      const result = await response.json();
      ```

      ```python Python theme={null}
      csrf = s.get(
          "https://api.example.com/api/v1/auth/csrf-token"
      ).json()["data"]["csrf_token"]

      resp = s.post(
          "https://api.example.com/api/v1/users/me/phone-number/verify",
          headers={"x-csrf-token": csrf},
          json={"otp": "123456"},
      )
      print(resp.json())
      ```
    </CodeGroup>

    **Response — 200 OK**

    ```json theme={null}
    {
      "success": true,
      "data": {}
    }
    ```

    Your account phone number is now updated. The new number will appear in your profile and will be used for future SMS communications.

    **Error Responses**

    | Status | Meaning                                                                        |
    | ------ | ------------------------------------------------------------------------------ |
    | `400`  | `otp` field is missing or does not match the 6-digit pattern.                  |
    | `401`  | Session is missing or expired.                                                 |
    | `410`  | OTP has expired (older than 10 minutes) or was already used. Restart the flow. |
    | `429`  | Rate limit exceeded — check the `Retry-After` header.                          |
  </Step>
</Steps>
