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

# Check a code

> Checks the code your user entered. A correct code approves the verification. Each wrong code uses one of `checks_left`; the last wrong code fails the verification. A wrong code still returns `200` with `valid: false`.



## OpenAPI

````yaml api-reference/openapi.yaml POST /verifications/{sid}/check
openapi: 3.1.0
info:
  title: OTPBay API
  version: 1.0.0
  description: >-
    Send one-time passwords over Telegram and SMS, verify the codes your users
    enter, and send transactional SMS from your own sender ID.
  contact:
    name: OTPBay support
    email: hello@otpbay.com
servers:
  - url: https://api.otpbay.com/v1
    description: Production
security:
  - bearerAuth: []
tags:
  - name: Project
    description: The project that owns the API key.
  - name: Verify
    description: >-
      Send a code and check it. OTPBay generates the code and falls back from
      Telegram to SMS.
  - name: SMS
    description: Send any text message from one of your approved sender IDs.
  - name: Telegram
    description: Send a one-time code to a Telegram account through the Telegram Gateway.
paths:
  /verifications/{sid}/check:
    post:
      tags:
        - Verify
      summary: Check a code
      description: >-
        Checks the code your user entered. A correct code approves the
        verification. Each wrong code uses one of `checks_left`; the last wrong
        code fails the verification. A wrong code still returns `200` with
        `valid: false`.
      operationId: checkVerification
      parameters:
        - $ref: '#/components/parameters/VerificationSid'
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/CheckCodeRequest'
            example:
              code: '482913'
      responses:
        '200':
          description: The code was checked. Read `valid` to see whether it matched.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/VerificationCheckResult'
              examples:
                valid:
                  summary: Correct code
                  value:
                    valid: true
                    sid: VE6650c3a1b2c3d4e5f6a7b8c9
                    status: approved
                    to: '+14155552671'
                    channel: telegram
                    fallback_reason: null
                    attempts:
                      - channel: telegram
                        sid: TG6650c3a1b2c3d4e5f6a7b8d0
                        status: read
                        cost: '0.02'
                        date_created: '2026-09-26T10:15:02.114Z'
                    checks_left: 4
                    fee: '0.02'
                    cost: '0.04'
                    date_created: '2026-09-26T10:15:01.873Z'
                    expires_at: '2026-09-26T10:25:01.873Z'
                    approved_at: '2026-09-26T10:15:40.518Z'
                    metadata:
                      user_id: usr_1042
                invalid:
                  summary: Wrong code
                  value:
                    valid: false
                    sid: VE6650c3a1b2c3d4e5f6a7b8c9
                    status: pending
                    to: '+14155552671'
                    channel: telegram
                    fallback_reason: null
                    attempts:
                      - channel: telegram
                        sid: TG6650c3a1b2c3d4e5f6a7b8d0
                        status: read
                        cost: '0.02'
                        date_created: '2026-09-26T10:15:02.114Z'
                    checks_left: 4
                    fee: '0.02'
                    cost: '0.04'
                    date_created: '2026-09-26T10:15:01.873Z'
                    expires_at: '2026-09-26T10:25:01.873Z'
                    approved_at: null
                    metadata:
                      user_id: usr_1042
        '400':
          $ref: '#/components/responses/InvalidSid'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/IpNotAllowed'
        '404':
          description: >-
            `VERIFICATION_NOT_FOUND` — no verification with this `sid` in your
            project.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
              example:
                error:
                  code: VERIFICATION_NOT_FOUND
                  message: Verification was not found for this account.
        '409':
          description: >-
            `VERIFICATION_NOT_PENDING` — the verification is already `approved`,
            `expired` or `failed`. Start a new one.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
              example:
                error:
                  code: VERIFICATION_NOT_PENDING
                  message: This verification is expired; start a new one.
        '422':
          $ref: '#/components/responses/InvalidBody'
components:
  parameters:
    VerificationSid:
      name: sid
      in: path
      required: true
      description: The verification `sid` returned by Start a verification.
      schema:
        type: string
        pattern: ^VE[a-fA-F0-9]{24}$
        example: VE6650c3a1b2c3d4e5f6a7b8c9
  schemas:
    CheckCodeRequest:
      type: object
      required:
        - code
      additionalProperties: false
      properties:
        code:
          type: string
          pattern: ^\d{4,8}$
          description: The code your user entered, 4–8 digits.
          example: '482913'
    VerificationCheckResult:
      allOf:
        - type: object
          required:
            - valid
          properties:
            valid:
              type: boolean
              description: >-
                `true` when the code matched and the verification is now
                `approved`.
        - $ref: '#/components/schemas/Verification'
    Error:
      type: object
      required:
        - error
      properties:
        error:
          type: object
          required:
            - code
            - message
          properties:
            code:
              type: string
              description: >-
                Stable, machine-readable error code. Branch on this, not on
                `message`.
              example: INSUFFICIENT_BALANCE
            message:
              type: string
              description: Human-readable explanation. The wording can change.
              example: Insufficient balance for this verification.
    Verification:
      type: object
      required:
        - sid
        - status
        - to
        - channel
        - fallback_reason
        - attempts
        - checks_left
        - fee
        - cost
        - date_created
        - expires_at
        - approved_at
        - metadata
      properties:
        sid:
          type: string
          pattern: ^VE[a-f0-9]{24}$
          description: Unique verification ID.
          example: VE6650c3a1b2c3d4e5f6a7b8c9
        status:
          type: string
          enum:
            - pending
            - approved
            - expired
            - failed
          description: >-
            `pending` until the user enters the right code (`approved`), the
            code expires (`expired`), or the code can't be sent or too many
            wrong codes are entered (`failed`).
        to:
          $ref: '#/components/schemas/PhoneNumber'
        channel:
          type: string
          enum:
            - telegram
            - sms
          description: Channel the code was last sent on.
        fallback_reason:
          type:
            - string
            - 'null'
          enum:
            - telegram_failed
            - timeout
            - null
          description: Why the code was re-sent by SMS, or `null` if it wasn't.
        attempts:
          type: array
          description: Every send of the code, oldest first.
          items:
            $ref: '#/components/schemas/VerificationAttempt'
        checks_left:
          type: integer
          description: Wrong codes the user can still enter before the verification fails.
          example: 5
        fee:
          $ref: '#/components/schemas/Money'
        cost:
          allOf:
            - $ref: '#/components/schemas/Money'
          description: >-
            Verify fee plus what the channel sends currently cost. Refunded
            sends count as `0.00`.
          example: '0.04'
        date_created:
          type: string
          format: date-time
        expires_at:
          type: string
          format: date-time
          description: When the code stops being accepted.
        approved_at:
          type:
            - string
            - 'null'
          format: date-time
          description: When the right code was entered.
        metadata:
          $ref: '#/components/schemas/Metadata'
        last_error:
          type: string
          description: Why the verification failed. Only present when `status` is `failed`.
          example: Too many wrong codes.
    PhoneNumber:
      type: string
      description: >-
        Destination phone number in international format. OTPBay normalizes it
        to E.164, so `+1 (415) 555-2671` becomes `+14155552671`.
      example: '+14155552671'
    VerificationAttempt:
      type: object
      description: One send of the code.
      required:
        - channel
        - sid
        - status
        - cost
        - date_created
      properties:
        channel:
          type: string
          enum:
            - telegram
            - sms
          description: Channel this attempt was sent on.
        sid:
          type: string
          description: '`sid` of the underlying message: `TG…` for Telegram, `SM…` for SMS.'
          example: TG6650c3a1b2c3d4e5f6a7b8d0
        status:
          type: string
          description: >-
            Delivery status of the message. Telegram: `sending`, `sent`,
            `delivered`, `read`, `expired`, `revoked`, `failed`. SMS: `queued`,
            `processing`, `sent`, `failed`, `enqueue_failed`.
          example: sent
        cost:
          $ref: '#/components/schemas/Money'
        date_created:
          type: string
          format: date-time
    Money:
      type: string
      pattern: ^\d+\.\d{2}$
      description: Amount in US dollars as a decimal string.
      example: '0.02'
    Metadata:
      type: object
      description: >-
        Your own key-value data, returned in responses and webhooks. At most 32
        keys of 1–64 characters. Values are strings (up to 512 characters),
        numbers or booleans.
      maxProperties: 32
      additionalProperties:
        oneOf:
          - type: string
            maxLength: 512
          - type: number
          - type: boolean
      example:
        user_id: usr_1042
  responses:
    InvalidSid:
      description: >-
        `INVALID_MESSAGE_SID` — the `sid` doesn't have the right prefix and 24
        hex characters.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error'
          example:
            error:
              code: INVALID_MESSAGE_SID
              message: '`sid` must match VExxxxxxxxxxxxxxxxxxxxxxxx (ObjectId hex).'
    Unauthorized:
      description: '`MISSING_API_KEY` or `INVALID_API_KEY`.'
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error'
          example:
            error:
              code: INVALID_API_KEY
              message: Invalid API key.
    IpNotAllowed:
      description: >-
        `IP_NOT_ALLOWED` — the project's IP allowlist is on and your address
        isn't in it.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error'
          example:
            error:
              code: IP_NOT_ALLOWED
              message: This IP address is not allowed for this project.
    InvalidBody:
      description: >-
        `INVALID_REQUEST_BODY` — a field is missing or invalid. `message` names
        each field.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error'
          example:
            error:
              code: INVALID_REQUEST_BODY
              message: 'code: Code must be 4–8 digits'
  securitySchemes:
    bearerAuth:
      type: http
      scheme: bearer
      description: >-
        Your project API key, sent as `Authorization: Bearer otp_live_...`.
        Create keys on the **API Keys** page of the dashboard.

````