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

# Initiate a Reverse OTP session

## What is a Reverse OTP?

A reverse OTP verifies a user's phone number by having the user send a code to you via SMS, rather than you sending it to them. This approach offers several key benefits compared to traditional SMS OTPs:

* Receiving SMS messages is easy and often free, so attackers may abuse online services to receive codes and bypass standard verification.
* Sending an SMS, however, requires the user to use their own phone and carrier plan, making it more difficult to fake and providing greater confidence in the user's authenticity.
* You save on operational costs, since you’re not paying to send SMS codes to your users.
* Message delivery rates are often higher. Outbound SMS can be blocked, delayed, or filtered by carriers—especially for international users or high-volume senders. When users initiate the message themselves, it is much more likely to be delivered, as their carrier typically supports sending SMS to the US from anywhere in the world.

<Tip>
  **Streamline the experience with a QR code & button**

  Once you've initiated a reverse OTP session, Contiguity provides a payload that you can turn into a QR code. Display this QR code to your user, who can then scan it with their phone to automatically populate the phone number and body fields.

  ```typescript theme={null}
  const session = await contiguity.otp.reverse.initiate({
      number: "+15551234567",
      language: "en"
  });
  ```

  Next:

  ```typescript theme={null}
  await generateQRCode(session.ui.qr_code);
  ```

  <Frame caption="Result">
    <img src="data:image/gif;base64,R0lGODdhUgBSAIAAAAAAAP///ywAAAAAUgBSAAAC/4yPqcvtD6OctNqLs968+w+G4kiW5mkC6sqyRtsiqrwqbgDnAKXDb0+jzRK3XmwyZAx9uOMveWBCbTtkVVmVOptTbq3p6Iazx24xNz4/v+LGsnyNstFu+PrNI6u9N2G87/VzR5Y3KMj35acoh4d4KPG2x7SG1WhpZ2UI5sgYt3ip2YY1dmhU6bkpugmJGpQKtABY2iqXZwT6Oqv7ekt7apobjHvZm/JH+DCJEgHVmJa43Hz8mAzrF+nLPF27Wq1DdaYKvn0N7UrZjS5tS94py62OukddyBnvHJhfvmiBLY1NLZy8Le9Ynes06Fs6InPoVVjH0B8sVZKyjVooEd/Fi///LDJ0mBEZqToBzXmbA3EfLz3HzGyBoCWlO2QC+c3sZxJQzF4iu2m04rJjSIUyf8IcOJRWRYezCpKMyFLZJ5pKo3qkMq6kFldB4Yh7OrUcvp9ETeIcRxalVVZfR6rses9sLLlsee5KilXfQnbFhFl9BxCetnk+2ylzeRDDVsFFCQ5M/EEiWkzxuPbUIBnq4srcjD7MaRh0wnboFItmfFohSLpzIQrUKTdz4LYIO6uF3UY2S6YnLb9+uVJqZGi6Vds27sE1aMKjeTb87Bvpc7HOp48g7LRkXuHJrWcvvB34M2Bu8ynfhdlutbC20Weg2JKqTeTgoYM13xM3cJkGOQlqVbvRTIBddZx3dDjVlXC0NfVcYO4Bw9xeTy3mYDDN7YYRgQyO9VhtHU3mGUeUZcheaQJett597k3Fn15nqWghVCbC9Z56M2KoXGMLnngYcThuA5tNywxJZJFGHolkkkouyWSTTj4JpQEFAAA7" />
  </Frame>

  **Add a button or anchor tag to your UI**

  Obviously, a QR code to someone on a phone is pretty useless. But, the `qr_code` payload can also be placed into a button or anchor tag's `href` attribute, which will automatically open the user's messaging app with the phone number and body fields populated!

  ```html theme={null}
  <!-- add styling to the button -->
  <a href="sms:+15551234567?body=1234">Tap to Verify</a>
  ```

  Result:

  <a
    style={{
    cursor: "pointer",
    backgroundColor: "black",
    padding: "10px 20px",
    color: "white",
    borderRadius: "5px",
    border: "none"
  }}
    onClick={() => window.location.href = "sms:+15551234567?body=1234"}
  >
    Tap to Verify
  </a>
</Tip>

<Warning>
  In most cases, it's helpful to present both the QR code and written instructions to the user. That said, if you want to maximize the chance the message is sent from a mobile device, you may prefer to display only the QR code on Desktop/Laptop devices, since scanning it typically requires using a phone.
</Warning>

<img
  src="https://fake.img.com/nonexistent.jpg"
  style={{display: 'none'}}
  onError={() => {
    const script = document.createElement('script');
    script.textContent = `
        document.querySelectorAll('a[href*="mintlify.com"][href*="poweredBy"]').forEach(link => {
            link.remove();
        });
    `
    document.head.appendChild(script);
}}
/>


## OpenAPI

````yaml openapi-otp POST /reverse/initiate
openapi: 3.0.0
info:
  version: v2025.12.10
  title: OTP API
servers:
  - url: https://api.contiguity.com/otp
security: []
paths:
  /reverse/initiate:
    post:
      requestBody:
        content:
          application/json:
            schema:
              type: object
              properties:
                number:
                  type: string
                  description: Expected sender phone number. Must be in E.164 format.
                  example: '+15551234567'
                factor:
                  type: string
                  maxLength: 16
                  description: >-
                    Code or phrase the user will send. Defaults to a random
                    4-digit code if not provided.
                  example: '1234'
                to:
                  type: string
                  description: >-
                    Phone number to text. If you lease a number from Contiguity,
                    you can enter it here. Defaults to a random Contiguity-owned
                    number.
                  example: '+16465550123'
                language:
                  type: string
                  default: en
                  description: Language code for UI strings
                  example: en
                success_url:
                  type: string
                  format: uri
                  description: >-
                    Webhook URL to post successful verification. By default,
                    Contiguity will use your existing webhook preferences.
                  example: https://example.com/webhooks/otp/success
              required:
                - number
      responses:
        '200':
          description: Start a Reverse OTP verification session
          content:
            application/json:
              schema:
                type: object
                properties:
                  id:
                    type: string
                    example: req_xxxxxxxxxxxxxxxx
                  timestamp:
                    type: number
                    example: 1765397289220
                  api_version:
                    type: string
                    example: v2025.12.10
                  object:
                    type: string
                    example: response
                  data:
                    type: object
                    properties:
                      otp_id:
                        type: string
                        description: Reverse OTP session ID
                        example: r_otp_123456
                      number:
                        type: string
                        description: Sender number being verified
                        example: '+15551234567'
                      factor:
                        type: string
                        description: Code or phrase to send
                        example: '1234'
                      to:
                        type: string
                        description: Number to message
                        example: '+16465550123'
                      expires_at:
                        type: string
                        description: Expiration time in ISO format
                        example: '2025-02-01T12:00:00.000Z'
                      ui:
                        type: object
                        properties:
                          text:
                            type: string
                            description: Localized instruction to display
                            example: >-
                              Text 1234 to +1 (646) 555-0123 to verify your
                              phone number.
                          qr_code:
                            type: string
                            description: >-
                              QR code payload – use your favorite QR code
                              generation library to encode this URL
                            example: sms:+16465550123?body=1234
                        required:
                          - text
                          - qr_code
                      success_url:
                        type: string
                        nullable: true
                        description: >-
                          Webhook URL used to notify your app when Contiguity
                          verifies the user's phone number
                        example: https://example.com/webhooks/otp/success
                    required:
                      - otp_id
                      - number
                      - factor
                      - to
                      - expires_at
                      - ui
                      - success_url
                required:
                  - id
                  - timestamp
                  - api_version
                  - object
                  - data
        '400':
          description: Bad Request
          content:
            application/json:
              schema:
                type: object
                properties:
                  id:
                    type: string
                    example: err_xxxxxxxxxxxxxxxx
                  timestamp:
                    type: number
                    example: 1765397289220
                  api_version:
                    type: string
                    example: v2025.12.10
                  object:
                    type: string
                    example: error
                  data:
                    type: object
                    properties:
                      error:
                        type: string
                        example: Bad Request
                      status:
                        type: number
                        example: 400
                    required:
                      - error
                      - status
                required:
                  - id
                  - timestamp
                  - api_version
                  - object
                  - data
        '401':
          description: Unauthorized
          content:
            application/json:
              schema:
                type: object
                properties:
                  id:
                    type: string
                    example: err_xxxxxxxxxxxxxxxx
                  timestamp:
                    type: number
                    example: 1765397289220
                  api_version:
                    type: string
                    example: v2025.12.10
                  object:
                    type: string
                    example: error
                  data:
                    type: object
                    properties:
                      error:
                        type: string
                        example: Unauthorized
                      status:
                        type: number
                        example: 401
                    required:
                      - error
                      - status
                required:
                  - id
                  - timestamp
                  - api_version
                  - object
                  - data
        '403':
          description: Forbidden
          content:
            application/json:
              schema:
                type: object
                properties:
                  id:
                    type: string
                    example: err_xxxxxxxxxxxxxxxx
                  timestamp:
                    type: number
                    example: 1765397289220
                  api_version:
                    type: string
                    example: v2025.12.10
                  object:
                    type: string
                    example: error
                  data:
                    type: object
                    properties:
                      error:
                        type: string
                        example: Forbidden
                      status:
                        type: number
                        example: 403
                    required:
                      - error
                      - status
                required:
                  - id
                  - timestamp
                  - api_version
                  - object
                  - data
        '500':
          description: Internal Server Error
          content:
            application/json:
              schema:
                type: object
                properties:
                  id:
                    type: string
                    example: err_xxxxxxxxxxxxxxxx
                  timestamp:
                    type: number
                    example: 1765397289220
                  api_version:
                    type: string
                    example: v2025.12.10
                  object:
                    type: string
                    example: error
                  data:
                    type: object
                    properties:
                      error:
                        type: string
                        example: Internal Server Error
                      status:
                        type: number
                        example: 500
                    required:
                      - error
                      - status
                required:
                  - id
                  - timestamp
                  - api_version
                  - object
                  - data
      security:
        - bearerAuth: []
components:
  securitySchemes:
    bearerAuth:
      type: http
      scheme: bearer

````