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

# Verify the OTP

> Checks the code the user typed in the chat and opens their session. The code allows 3 attempts and lasts 5 minutes. Opening a session closes any previous channel session of the same number.

#### Authentication

`Authorization: Bearer <channel token>`, from `POST /api/v1/channel/token`. The user token is not accepted here.

#### Production

Available in test today. In production these calls go to `https://partners-api.kravata.co` with your mTLS client certificate; ask your Kravata point of contact before going live.

See the [WhatsApp channel guide](/stack/whatsapp-channel) for the full flow.

#### Errors

| Status | Code | Meaning |
| --- | --- | --- |
| 401 | `OTP_INVALID` | Wrong code; the message says how many attempts are left. |
| 401 | `OTP_EXPIRED` | The code expired: request a new one. |
| 403 | `USER_DISABLED` | The user is disabled. |
| 404 | `CHALLENGE_NOT_FOUND` | Unknown or already used `challengeId`. |
| 429 | `OTP_LOCKED` | Too many wrong codes: request a new one. |



## OpenAPI

````yaml /stack/openapi.json post /api/v1/channel/whatsapp/session/verify
openapi: 3.1.0
info:
  title: Kravata Stack API
  version: '2.0'
  description: >-
    Kravata Stack API: users, accounts, custody wallets, liquidity ramps and
    fiat payments.
servers:
  - url: https://test-api-kore.kravata.co
    description: Test
  - url: https://partners-api.kravata.co
    description: Production (mTLS + IP allowlist)
security:
  - bearerAuth: []
tags:
  - name: Authentication
  - name: Users
  - name: Accounts
  - name: Earn
  - name: Custody
  - name: Liquidity Ramps
  - name: Payments
  - name: Webhooks
  - name: Request Logs
  - name: WhatsApp Channel
    description: >-
      Endpoints for a company's own WhatsApp bot acting for one end user at a
      time. See the WhatsApp channel guide.
paths:
  /api/v1/channel/whatsapp/session/verify:
    post:
      tags:
        - WhatsApp Channel
      summary: Verify the OTP
      description: >-
        Checks the code the user typed in the chat and opens their session. The
        code allows 3 attempts and lasts 5 minutes. Opening a session closes any
        previous channel session of the same number.


        #### Authentication


        `Authorization: Bearer <channel token>`, from `POST
        /api/v1/channel/token`. The user token is not accepted here.


        #### Production


        Available in test today. In production these calls go to
        `https://partners-api.kravata.co` with your mTLS client certificate; ask
        your Kravata point of contact before going live.


        See the [WhatsApp channel guide](/stack/whatsapp-channel) for the full
        flow.


        #### Errors


        | Status | Code | Meaning |

        | --- | --- | --- |

        | 401 | `OTP_INVALID` | Wrong code; the message says how many attempts
        are left. |

        | 401 | `OTP_EXPIRED` | The code expired: request a new one. |

        | 403 | `USER_DISABLED` | The user is disabled. |

        | 404 | `CHALLENGE_NOT_FOUND` | Unknown or already used `challengeId`. |

        | 429 | `OTP_LOCKED` | Too many wrong codes: request a new one. |
      operationId: channel-session-verify
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              required:
                - waId
                - challengeId
                - otpCode
              properties:
                waId:
                  type: string
                  description: >-
                    The user's WhatsApp number as WhatsApp sends it: country
                    code, no `+`.
                  example: '573001234567'
                challengeId:
                  type: string
                  description: From *Request the OTP*.
                otpCode:
                  type: string
                  description: Code the user typed.
                  example: '482915'
      responses:
        '200':
          description: Successful response
          content:
            application/json:
              schema:
                type: object
                required:
                  - accessToken
                  - userId
                properties:
                  accessToken:
                    type: string
                    description: >-
                      User token. Use it for every user call (PIN, deposit,
                      accounts, withdrawal).
                  refreshToken:
                    type: string
                    description: Use it with *Refresh the session*.
                  expiresIn:
                    type: integer
                    description: Validity of `accessToken`, in seconds.
                    example: 300
                  refreshExpiresIn:
                    type: integer
                    description: Validity of `refreshToken`, in seconds.
                  userId:
                    type: string
                    description: Kravata user id.
      security:
        - bearerAuth: []
components:
  securitySchemes:
    bearerAuth:
      type: http
      scheme: bearer
      description: Access token from POST /api/v1/client/token.

````

This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.