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

# Verify OTP

Verify a one-time password (OTP) sent to a user's phone number for secure authentication and validation.

This endpoint is used to confirm OTPs during login, signup, multi-factor authentication (MFA), and transaction verification flows. It ensures that the OTP entered by the user matches the one issued and is still valid.

Authentication is handled via secure headers, ensuring your credentials remain protected and are never exposed in the request body.

<CodeGroup>
  ```bash cURL theme={null}
  curl --request POST \
    --url https://ses.antryk.com/api/v1/sms/verify-otp \
    --header "Content-Type: application/json" \
    --header "x-access-key: YOUR_ACCESS_KEY" \
    --header "x-secret-key: YOUR_SECRET_KEY" \
    --data '{
      "to": "+1XXXXXXXXXX",
      "serviceId": "YOUR_SERVICE_ID",
      "otp": "USER_OTP"
    }'
  ```

  ```javascript JavaScript theme={null}
  fetch("https://ses.antryk.com/api/v1/sms/verify-otp", {
    method: "POST",
    headers: {
      "Content-Type": "application/json",
      "x-access-key": "YOUR_ACCESS_KEY",
      "x-secret-key": "YOUR_SECRET_KEY",
    },
    body: JSON.stringify({
      to: "+1XXXXXXXXXX",
      serviceId: "YOUR_SERVICE_ID",
      otp: "USER_OTP",
    }),
  });
  ```

  ```javascript NodeJs theme={null}
  // npm i @antryk/sdk
  import { AntrykClient } from "@antryk/sdk";

  const client = new AntrykClient({
    accessKey: process.env.ANTRYK_ACCESS_KEY,
    secretKey: process.env.ANTRYK_SECRET_KEY,
  });

  async function verifyOtp() {
    const result = await client.sms.verifyOtp({
      to: "+1XXXXXXXXXX",
      serviceId: "YOUR_SERVICE_ID",
      otp: "USER_OTP",
    });

    console.log(result.data);
  }

  verifyOtp();
  ```

  ```python Python theme={null}
  # pip install requests
  import requests

  url = "https://ses.antryk.com/api/v1/sms/verify-otp"

  headers = {
      "Content-Type": "application/json",
      "x-access-key": "YOUR_ACCESS_KEY",
      "x-secret-key": "YOUR_SECRET_KEY"
  }

  data = {
      "to": "+1XXXXXXXXXX",
      "serviceId": "YOUR_SERVICE_ID",
      "otp": "USER_OTP"
  }

  response = requests.post(url, headers=headers, json=data)

  print(response.status_code)
  print(response.json())
  ```
</CodeGroup>

<Note>
  {" "}

  For Node.js applications, it is recommended to use the official
  [`@antryk/sdk`](https://www.npmjs.com/package/@antryk/sdk). The SDK simplifies
  OTP verification by handling authentication, validation, and error handling
  internally.{" "}
</Note>

<Note>
  {" "}

  Authentication is handled via headers (`x-access-key`, `x-secret-key`). The
  request body should only include OTP verification data such as phone number,
  service ID, and the OTP code.{" "}
</Note>

### New OTP Verification Approach (Recommended)

This is the recommended and modern approach for verifying OTPs:

* Authentication is passed via headers instead of request body.
* Request body contains only verification-related fields.
* Improved security and cleaner API design.
* Easier integration across backend services.

<Note>
  {" "}

  ⚠️ The older approach (sending `accessKey` and `secretKey` in the request
  body) may still work for backward compatibility, but it is **strongly
  recommended to migrate to header-based authentication**.{" "}
</Note>

## Request Parameters

<ParamField header="x-access-key" type="string" required>
  {" "}

  Your Antryk access key used for authentication.{" "}
</ParamField>

<ParamField header="x-secret-key" type="string" required>
  {" "}

  Your Antryk secret key used to authorize the request securely.{" "}
</ParamField>

<ParamField body="to" type="string" required>
  {" "}

  The phone number (in E.164 format, e.g. `+919876543210`) that received the
  OTP.{" "}
</ParamField>

<ParamField body="serviceId" type="string" required>
  {" "}

  UUID v4 identifier of your configured SMS verification service.{" "}
</ParamField>

<ParamField body="otp" type="string" required>
  {" "}

  The OTP code entered by the user. Must be a 4–10 digit numeric value.{" "}
</ParamField>

<Tip>
  {" "}

  Always validate OTP input on the client side (length and numeric format)
  before sending the request to reduce unnecessary API calls.{" "}
</Tip>

<Warning>
  {" "}

  OTPs are time-sensitive. Expired or incorrect OTPs will result in validation
  failure. Limit retry attempts to prevent abuse or brute-force attacks.{" "}
</Warning>

## Examples

<ParamField header="x-access-key" type="string" required>
  {" "}

  Example: YOUR\_ACCESS\_KEY{" "}
</ParamField>

<ParamField header="x-secret-key" type="string" required>
  {" "}

  Example: YOUR\_SECRET\_KEY{" "}
</ParamField>

<ParamField body="to" type="string" required>
  {" "}

  Example: +919876543210{" "}
</ParamField>

<ParamField body="serviceId" type="string" required>
  {" "}

  Example: xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx{" "}
</ParamField>

<ParamField body="otp" type="string" required>
  {" "}

  Example: 482193{" "}
</ParamField>

<Note>
  {" "}

  ### Additional Notes

  * OTP verification is a critical step in authentication workflows.
  * Ensure that verification is performed securely on the backend.
  * Avoid exposing sensitive validation logic on the frontend.
  * Use retry limits and session-based controls to enhance security.
  * SDK usage is recommended for simplified integration and consistent error handling.
</Note>

## Response

Returns a JSON object indicating whether the OTP is valid and verified

```json theme={null}
{
  "success": true,
  "message": "Otp Verified Successfully!",
  "data": {
    "valid": true,
    "to": "+1XXXXXXXXXX",
    "status": "verified"
  }
}
```

## Error Scenarios

* **400 otp\_invalid** – Incorrect or invalid OTP entered
* **404 otp\_not\_found** – No pending OTP found for the given number and service
* **401 invalid\_credentials** – Invalid x-access-key or x-secret-key
* **410 otp\_expired** – OTP exists but has expired
* **429 rate\_limited** – Too many verification attempts in a short time

## Invalid OTP example

```json theme={null}
{
  "success": true,
  "message": null,
  "data": {
    "valid": false,
    "status": "pending",
    "to": "+1XXXXXXXXXX"
  }
}
```

<Warning>
  Limit verification retries per user session to prevent brute-force attempts.
  Lock the service after repeated `otp_invalid` responses.
</Warning>
