# Get KYC status (/docs/api-reference/reseller-verification/getResellerKycStatus)

> Get the identity verification status of a client for every carrier it can verify on. Use next_step to know which step to call next, so you drive the whole flow off one poll instead of hardcoding the sequence.

> **Reseller accounts only.** [Request access](https://omnidim.io/contact-us?reason=reseller_api&lock=1).

`next_step` is the field to drive your integration from: read it once here to get the first step,
then chain from each step's response until the status is `completed`.

There is one entry per carrier, not per region. Match on `carrier`, and pass that same name to the
steps and to the purchase.

`can_purchase` is the exact gate a purchase enforces, so this answer and a purchase attempt cannot
disagree. When it is false while `next_step` is `null`, the client has finished every step and the
carrier is still reviewing: `review_status` says `pending_review`.

The full loop, with the step tables, is on the [Verify a client](/docs/reseller/your-clients/verification)
guide.

**GET** `/reseller/kyc/status`

Get the identity verification status of a client for every carrier it
can verify on. Use `next_step` to know which step to call next, so
you drive the whole flow off one poll instead of hardcoding the
sequence.

Verification is per carrier, not per region: a client verified on one
carrier of a region still has to verify on the other before it can
buy there. A region with one carrier returns exactly one entry.

```yaml
operationId: getResellerKycStatus
parameters:
  - name: user_id
    in: query
    required: true
    description: ID of the child user to check.
    schema:
      type: integer
    example: 1234
responses:
  '200':
    description: KYC status per region.
    content:
      application/json:
        schema:
          type: object
          properties:
            success:
              type: boolean
            user_id:
              type: integer
            regions:
              type: array
              description: One entry per carrier, each with that carrier's verification state.
              items:
                type: object
                properties:
                  region:
                    type: string
                    enum:
                      - IN
                      - US
                  carrier:
                    type: string
                    description: >-
                      The carrier this entry is about. Pass it to the verification calls and to a
                      purchase.
                    example: carrier-1
                  carrier_label:
                    type: string
                    description: Display name of that carrier.
                    example: Carrier 1
                  kyc_required:
                    type: boolean
                    description: >-
                      Whether this client must complete verification before buying a number in this
                      region.
                  can_purchase:
                    type: boolean
                    description: >-
                      Whether this client can buy a number on this carrier right now. Always agrees
                      with what a purchase attempt would allow.
                  status:
                    type: string
                    description: |
                      Where this client has reached in verification.
                      `not_started` before anything is submitted,
                      `completed` once they are verified. Drive your
                      integration off `next_step`, not this value.
                  next_step:
                    type: string
                    nullable: true
                    description: |
                      The step to call next, or `null` when there is
                      nothing left for you to do.

                      Not a fixed list. Which steps exist depends on
                      the carrier, and carriers do not run the same
                      checks. Read the step list from
                      `GET /reseller/kyc/requirements` for that carrier
                      and follow this field; never hard-code the names.

                      `null` with `can_purchase: false` means the
                      carrier is still reviewing the submission. See
                      `review_status`.
                  review_status:
                    type: string
                    nullable: true
                    description: |
                      Set when the carrier is holding a finished
                      submission for its own review, which is why
                      `can_purchase` can still be false with no step
                      left to call. `null` otherwise.
        example:
          success: true
          user_id: 1234
          regions:
            - region: IN
              carrier: carrier-1
              carrier_label: Carrier 1
              kyc_required: true
              can_purchase: false
              status: pan_verified
              next_step: aadhaar-otp
              review_status: null
            - region: IN
              carrier: carrier-2-new
              carrier_label: Carrier 2 (new)
              kyc_required: true
              can_purchase: false
              status: not_started
              next_step: register
              review_status: null
  '401':
    description: Missing or invalid API key.
  '403':
    description: |
      A `user_id` was sent by a key that is not a reseller admin, or
      the named client's account is currently unavailable.
    content:
      application/json:
        schema:
          type: object
          properties:
            error:
              type: string
              description: Machine-readable error code.
            error_description:
              type: string
              description: Human-readable explanation.
            code:
              type: string
              description: |
                Stable, specific reason. Present on the newer endpoints (Voice
                cloning, WhatsApp); older endpoints return only `error`.
            request_id:
              type: string
              description: |
                Correlates this response with the server log. Present alongside
                `code`. Also sent as the `X-Request-Id` header.
        example:
          error: forbidden
          error_description: Access denied. Only reseller accounts can use this endpoint.
  '404':
    description: Child user not found under this reseller account.
    content:
      application/json:
        schema:
          type: object
          properties:
            error:
              type: string
              description: Machine-readable error code.
            error_description:
              type: string
              description: Human-readable explanation.
            code:
              type: string
              description: |
                Stable, specific reason. Present on the newer endpoints (Voice
                cloning, WhatsApp); older endpoints return only `error`.
            request_id:
              type: string
              description: |
                Correlates this response with the server log. Present alongside
                `code`. Also sent as the `X-Request-Id` header.
        example:
          error: not_found
          error_description: Child user not found.
  '500':
    description: Unexpected server error.
    content:
      application/json:
        schema:
          type: object
          properties:
            error:
              type: string
              description: Machine-readable error code.
            error_description:
              type: string
              description: Human-readable explanation.
            code:
              type: string
              description: |
                Stable, specific reason. Present on the newer endpoints (Voice
                cloning, WhatsApp); older endpoints return only `error`.
            request_id:
              type: string
              description: |
                Correlates this response with the server log. Present alongside
                `code`. Also sent as the `X-Request-Id` header.
            ref:
              type: string
              description: Reference to quote to support.
        example:
          error: server_error
          error_description: >-
            Something went wrong on our side. Please try again shortly, or contact support with
            reference a1b2c3d4e5f6.
          ref: a1b2c3d4e5f6
```

**Python SDK**

```python
from omnidimension import Client
client = Client(api_key)

status = client.reseller.kyc_status(user_id=1234)["json"]

# One entry per carrier, not per region: a client verified on one
# carrier still has to verify on the other before it can buy there.
for entry in status["regions"]:
    print(entry["carrier"], entry["next_step"], entry["can_purchase"])
```

**curl**

```bash
curl -X GET "https://backend.omnidim.io/api/v1/reseller/kyc/status?user_id=1234" \
  -H "Authorization: Bearer $OMNIDIM_API_KEY"
```