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

# Submit customer for verification

> Trigger KYC (individual) or KYB (business) verification for a customer.
The response indicates whether all required information has been provided.
If data is missing, the `errors` array describes exactly what needs to be
supplied before verification can proceed.

Call this endpoint again after resolving errors to re-submit.

### What to collect for KYB

Before submitting a `BUSINESS` customer, collect the following via
`POST /customers`, `POST /beneficial-owners`, and `POST /documents`:

**Business identifying information**
- Entity full legal name
- Doing Business As (DBA) name, if applicable
- Physical address — principal place of business
- Countries of operation
- Identification number — U.S. taxpayer identification number, or, for a
  foreign business without one, alternative government-issued documentation
  certifying the existence of the business

**Ownership and control structure** — collected for **one control person**
(an individual with significant responsibility to control, manage, or
direct the legal entity) **and all beneficial owners** (every individual
who owns 25% or more, directly or indirectly). For each, provide:
- Full name
- Date of birth
- Address
- Identification number:
  - U.S. persons — SSN or ITIN
  - Non-U.S. persons — one or more of: ITIN, passport (with country of
    issuance), alien identification card, or another government-issued
    photo ID evidencing nationality or residence

**Required documents**
- Company formation and existence documents (certificate of incorporation,
  articles of association, etc.)
- Proof of ownership and control structure (organization and ownership
  chart, shareholder agreements, operating agreements, register of members,
  or certification of controlling person and beneficial owners)
- Proof of address dated within the last 3 months (utility bill, bank
  statement, lease agreement, or official correspondence)
- Tax ID or equivalent identifying-number documents
- For non-U.S. beneficial owners — passport plus one additional
  government-issued ID




## OpenAPI

````yaml https://app.stainless.com/api/spec/documented/grid/openapi.documented.yml post /verifications
openapi: 3.1.0
info:
  title: Grid API
  description: >
    API for managing global payments on the open Money Grid. Built by
    Lightspark. See the full documentation at https://docs.lightspark.com/.
  version: '2025-10-13'
  contact:
    name: Lightspark Support
    email: support@lightspark.com
  license:
    name: Proprietary
    url: https://lightspark.com/terms
servers:
  - url: https://api.lightspark.com/grid/2025-10-13
    description: Production server
security:
  - BasicAuth: []
  - AgentAuth: []
tags:
  - name: Platform Configuration
    description: >-
      Platform configuration endpoints for managing global settings. You can
      also configure these settings in the Grid dashboard.
  - name: Customers
    description: >-
      Customer management endpoints for creating and updating customer
      information
  - name: KYC/KYB Verifications
    description: >-
      Endpoints for Know Your Customer (KYC) and Know Your Business (KYB)
      verification, including managing beneficial owners and triggering
      verification for customers.
  - name: Documents
    description: >-
      Endpoints for uploading and managing verification documents for customers
      and beneficial owners. Supports KYC and KYB document requirements.
  - name: Internal Accounts
    description: >-
      Internal account management endpoints for creating and managing internal
      accounts
  - name: External Accounts
    description: >-
      External account management endpoints for creating and managing external
      bank accounts
  - name: Same-Currency Transfers
    description: >-
      Endpoints for transferring funds between internal and external accounts
      with the same currency
  - name: Cross-Currency Transfers
    description: Endpoints for creating and confirming quotes for cross-currency transfers
  - name: Transactions
    description: Endpoints for retrieving transaction information
  - name: Webhooks
    description: Webhook endpoints and configuration for receiving notifications
  - name: Invitations
    description: Endpoints for creating, claiming and managing UMA invitations
  - name: Sandbox
    description: Endpoints to trigger test cases in sandbox
  - name: API Tokens
    description: Endpoints to programmatically manage API tokens
  - name: Exchange Rates
    description: >-
      Endpoints for retrieving cached foreign exchange rates. Rates are cached
      for approximately 5 minutes and include platform-specific fees.
  - name: Discoveries
    description: >-
      Endpoints for discovering available payment rails, banks, and providers
      for a given country and currency corridor.
  - name: Embedded Wallet Auth
    description: >-
      Endpoints for registering and verifying end-user authentication
      credentials (email OTP, OAuth, passkey) used to sign Embedded Wallet
      actions.
  - name: Agent Management
    description: >-
      Endpoints for creating and managing agents (experimental), called by the
      partner's backend using platform credentials. Covers the full agent
      lifecycle: creation, policy configuration, pausing, deletion, the device
      code installation flow, and approving or rejecting transactions initiated
      by agents.
  - name: Agent Operations
    description: >-
      Endpoints called by the agent itself using its own credentials (obtained
      via device code redemption). Scoped to the agent's associated customer —
      all requests automatically operate on behalf of that customer and are
      subject to the agent's policy. When an action requires approval, the
      resulting transaction enters a pending state and must be approved by the
      platform via `POST /transactions/{transactionId}/approve`.
  - name: Cards
    description: >-
      Card management endpoints. Issue debit cards against an internal account,
      freeze / unfreeze, close, manage card funding sources, and list card
      transactions.
paths:
  /verifications:
    post:
      tags:
        - KYC/KYB Verifications
      summary: Submit customer for verification
      description: >
        Trigger KYC (individual) or KYB (business) verification for a customer.

        The response indicates whether all required information has been
        provided.

        If data is missing, the `errors` array describes exactly what needs to
        be

        supplied before verification can proceed.


        Call this endpoint again after resolving errors to re-submit.


        ### What to collect for KYB


        Before submitting a `BUSINESS` customer, collect the following via

        `POST /customers`, `POST /beneficial-owners`, and `POST /documents`:


        **Business identifying information**

        - Entity full legal name

        - Doing Business As (DBA) name, if applicable

        - Physical address — principal place of business

        - Countries of operation

        - Identification number — U.S. taxpayer identification number, or, for a
          foreign business without one, alternative government-issued documentation
          certifying the existence of the business

        **Ownership and control structure** — collected for **one control
        person**

        (an individual with significant responsibility to control, manage, or

        direct the legal entity) **and all beneficial owners** (every individual

        who owns 25% or more, directly or indirectly). For each, provide:

        - Full name

        - Date of birth

        - Address

        - Identification number:
          - U.S. persons — SSN or ITIN
          - Non-U.S. persons — one or more of: ITIN, passport (with country of
            issuance), alien identification card, or another government-issued
            photo ID evidencing nationality or residence

        **Required documents**

        - Company formation and existence documents (certificate of
        incorporation,
          articles of association, etc.)
        - Proof of ownership and control structure (organization and ownership
          chart, shareholder agreements, operating agreements, register of members,
          or certification of controlling person and beneficial owners)
        - Proof of address dated within the last 3 months (utility bill, bank
          statement, lease agreement, or official correspondence)
        - Tax ID or equivalent identifying-number documents

        - For non-U.S. beneficial owners — passport plus one additional
          government-issued ID
      operationId: createVerification
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/VerificationRequest'
      responses:
        '200':
          description: >
            Verification status returned. Check `verificationStatus` and
            `errors` to determine next steps.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Verification'
              examples:
                missingInfo:
                  summary: Verification blocked by missing data
                  value:
                    id: Verification:019542f5-b3e7-1d02-0000-000000000001
                    customerId: Customer:019542f5-b3e7-1d02-0000-000000000001
                    verificationStatus: RESOLVE_ERRORS
                    errors:
                      - resourceId: Customer:019542f5-b3e7-1d02-0000-000000000001
                        type: MISSING_FIELD
                        field: customer.address.line1
                        reason: Business address line 1 is required
                      - resourceId: Customer:019542f5-b3e7-1d02-0000-000000000001
                        type: MISSING_PROOF_OF_ADDRESS_DOCUMENT
                        acceptedDocumentTypes:
                          - PROOF_OF_ADDRESS
                        reason: Proof of address document is required
                      - resourceId: BeneficialOwner:019542f5-b3e7-1d02-0000-000000000002
                        type: MISSING_FIELD
                        field: personalInfo.birthDate
                        reason: Date of birth is required for beneficial owners
                    createdAt: '2025-10-03T12:00:00Z'
                submitted:
                  summary: Verification submitted successfully
                  value:
                    id: Verification:019542f5-b3e7-1d02-0000-000000000002
                    customerId: Customer:019542f5-b3e7-1d02-0000-000000000001
                    verificationStatus: IN_PROGRESS
                    errors: []
                    createdAt: '2025-10-03T12:00:00Z'
        '400':
          description: Bad request - Invalid parameters
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error400'
        '401':
          description: Unauthorized
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error401'
        '404':
          description: Customer not found
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error404'
        '500':
          description: Internal service error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error500'
      security:
        - BasicAuth: []
      x-codeSamples:
        - lang: JavaScript
          source: |-
            import LightsparkGrid from '@lightsparkdev/grid';

            const client = new LightsparkGrid({
              username: process.env['GRID_CLIENT_ID'], // This is the default and can be omitted
              password: process.env['GRID_CLIENT_SECRET'], // This is the default and can be omitted
            });

            const verification = await client.verifications.submit({
              customerId: 'Customer:019542f5-b3e7-1d02-0000-000000000001',
            });

            console.log(verification.id);
        - lang: Python
          source: |-
            import os
            from grid import LightsparkGrid

            client = LightsparkGrid(
                username=os.environ.get("GRID_CLIENT_ID"),  # This is the default and can be omitted
                password=os.environ.get("GRID_CLIENT_SECRET"),  # This is the default and can be omitted
            )
            verification = client.verifications.submit(
                customer_id="Customer:019542f5-b3e7-1d02-0000-000000000001",
            )
            print(verification.id)
        - lang: Go
          source: "package main\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\n\t\"github.com/stainless-sdks/grid-go\"\n\t\"github.com/stainless-sdks/grid-go/option\"\n)\n\nfunc main() {\n\tclient := grid.NewClient(\n\t\toption.WithUsername(\"My Username\"),\n\t\toption.WithPassword(\"My Password\"),\n\t)\n\tverification, err := client.Verifications.Submit(context.TODO(), grid.VerificationSubmitParams{\n\t\tVerificationRequest: grid.VerificationRequestParam{\n\t\t\tCustomerID: \"Customer:019542f5-b3e7-1d02-0000-000000000001\",\n\t\t},\n\t})\n\tif err != nil {\n\t\tpanic(err.Error())\n\t}\n\tfmt.Printf(\"%+v\\n\", verification.ID)\n}\n"
        - lang: Kotlin
          source: |-
            package com.lightspark.grid.example

            import com.lightspark.grid.client.LightsparkGridClient
            import com.lightspark.grid.client.okhttp.LightsparkGridOkHttpClient
            import com.lightspark.grid.models.verifications.Verification
            import com.lightspark.grid.models.verifications.VerificationRequest

            fun main() {
                val client: LightsparkGridClient = LightsparkGridOkHttpClient.fromEnv()

                val params: VerificationRequest = VerificationRequest.builder()
                    .customerId("Customer:019542f5-b3e7-1d02-0000-000000000001")
                    .build()
                val verification: Verification = client.verifications().submit(params)
            }
        - lang: Ruby
          source: >-
            require "grid"


            lightspark_grid = Grid::Client.new(username: "My Username",
            password: "My Password")


            verification = lightspark_grid.verifications.submit(customer_id:
            "Customer:019542f5-b3e7-1d02-0000-000000000001")


            puts(verification)
        - lang: PHP
          source: |-
            <?php

            require_once dirname(__DIR__) . '/vendor/autoload.php';

            use Grid\Client;
            use Grid\Core\Exceptions\APIException;

            $client = new Client(
              username: getenv('GRID_CLIENT_ID') ?: 'My Username',
              password: getenv('GRID_CLIENT_SECRET') ?: 'My Password',
            );

            try {
              $verification = $client->verifications->submit(
                customerID: 'Customer:019542f5-b3e7-1d02-0000-000000000001'
              );

              var_dump($verification);
            } catch (APIException $e) {
              echo $e->getMessage();
            }
        - lang: C#
          source: |-
            using System;
            using Grid;
            using Grid.Models.Verifications;

            LightsparkGridClient client = new();

            VerificationSubmitParams parameters = new()
            {
                CustomerID = "Customer:019542f5-b3e7-1d02-0000-000000000001"
            };

            var verification = await client.Verifications.Submit(parameters);

            Console.WriteLine(verification);
        - lang: CLI
          source: |-
            grid verifications submit \
              --username 'My Username' \
              --password 'My Password' \
              --customer-id Customer:019542f5-b3e7-1d02-0000-000000000001
components:
  schemas:
    VerificationRequest:
      type: object
      required:
        - customerId
      properties:
        customerId:
          type: string
          description: The ID of the customer to verify
          example: Customer:019542f5-b3e7-1d02-0000-000000000001
    Verification:
      type: object
      required:
        - id
        - customerId
        - verificationStatus
        - errors
        - createdAt
      properties:
        id:
          type: string
          description: Unique identifier for this verification
          example: Verification:019542f5-b3e7-1d02-0000-000000000001
        customerId:
          type: string
          description: The ID of the customer being verified
          example: Customer:019542f5-b3e7-1d02-0000-000000000001
        verificationStatus:
          $ref: '#/components/schemas/VerificationStatus'
        errors:
          type: array
          description: >-
            List of issues preventing verification from proceeding. Empty when
            verificationStatus is APPROVED or IN_PROGRESS.
          items:
            $ref: '#/components/schemas/VerificationError'
        createdAt:
          type: string
          format: date-time
          description: When this verification was created
          example: '2025-10-03T12:00:00Z'
        updatedAt:
          type: string
          format: date-time
          description: When this verification was last updated
          example: '2025-10-03T12:00:00Z'
    Error400:
      type: object
      required:
        - message
        - status
        - code
      properties:
        status:
          type: integer
          enum:
            - 400
          description: HTTP status code
        code:
          type: string
          description: >
            | Error Code | Description |

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

            | INVALID_INPUT | Invalid input provided |

            | MISSING_MANDATORY_USER_INFO | Required customer information is
            missing |

            | INVITATION_ALREADY_CLAIMED | Invitation has already been claimed |

            | INVITATIONS_NOT_CONFIGURED | Invitations are not configured |

            | INVALID_UMA_ADDRESS | UMA address format is invalid |

            | INVITATION_CANCELLED | Invitation has been cancelled |

            | QUOTE_REQUEST_FAILED | An issue occurred during the quote process;
            this is retryable |

            | INVALID_PAYREQ_RESPONSE | Counterparty Payreq response was invalid
            |

            | INVALID_RECEIVER | Receiver is invalid |

            | PARSE_PAYREQ_RESPONSE_ERROR | Error parsing receiver PayReq
            response |

            | CERT_CHAIN_INVALID | Counterparty certificate chain is invalid |

            | CERT_CHAIN_EXPIRED | Counterparty certificate chain has expired |

            | INVALID_PUBKEY_FORMAT | Counterparty Public key format is invalid
            |

            | MISSING_REQUIRED_UMA_PARAMETERS | Counterparty required UMA
            parameters are missing |

            | SENDER_NOT_ACCEPTED | Sender is not accepted |

            | AMOUNT_OUT_OF_RANGE | Amount is out of range |

            | INVALID_CURRENCY | Currency is invalid |

            | INVALID_TIMESTAMP | Timestamp is invalid |

            | INVALID_NONCE | Nonce is invalid |

            | INVALID_REQUEST_FORMAT | Request format is invalid |

            | INVALID_BANK_ACCOUNT | Bank account is invalid |

            | SELF_PAYMENT | Self payment not allowed |

            | LOOKUP_REQUEST_FAILED | Lookup request failed |

            | PARSE_LNURLP_RESPONSE_ERROR | Error parsing LNURLP response |

            | INVALID_AMOUNT | Amount is invalid |

            | WEBHOOK_ENDPOINT_NOT_SET | Webhook endpoint is not set |

            | WEBHOOK_DELIVERY_ERROR | Webhook delivery error |

            | LOW_QUALITY | Document quality too low to process |

            | DATA_MISMATCH | Document details don't match provided information
            |

            | EXPIRED | Document has expired |

            | SUSPECTED_FRAUD | Document suspected of being forged or edited |

            | UNSUITABLE_DOCUMENT | Document type is not accepted or not
            supported |

            | INCOMPLETE | Document is missing pages or sides |

            | EMAIL_OTP_CREDENTIAL_ALREADY_EXISTS | An EMAIL_OTP credential is
            already registered on the target internal account; only one email
            OTP credential is supported per internal account at this time |

            | PASSKEY_CREDENTIAL_ALREADY_EXISTS | A PASSKEY credential with the
            same WebAuthn credentialId is already registered on the target
            internal account |
          enum:
            - INVALID_INPUT
            - MISSING_MANDATORY_USER_INFO
            - INVITATION_ALREADY_CLAIMED
            - INVITATIONS_NOT_CONFIGURED
            - INVALID_UMA_ADDRESS
            - INVITATION_CANCELLED
            - QUOTE_REQUEST_FAILED
            - INVALID_PAYREQ_RESPONSE
            - INVALID_RECEIVER
            - PARSE_PAYREQ_RESPONSE_ERROR
            - CERT_CHAIN_INVALID
            - CERT_CHAIN_EXPIRED
            - INVALID_PUBKEY_FORMAT
            - MISSING_REQUIRED_UMA_PARAMETERS
            - SENDER_NOT_ACCEPTED
            - AMOUNT_OUT_OF_RANGE
            - INVALID_CURRENCY
            - INVALID_TIMESTAMP
            - INVALID_NONCE
            - INVALID_REQUEST_FORMAT
            - INVALID_BANK_ACCOUNT
            - SELF_PAYMENT
            - LOOKUP_REQUEST_FAILED
            - PARSE_LNURLP_RESPONSE_ERROR
            - INVALID_AMOUNT
            - WEBHOOK_ENDPOINT_NOT_SET
            - WEBHOOK_DELIVERY_ERROR
            - LOW_QUALITY
            - DATA_MISMATCH
            - EXPIRED
            - SUSPECTED_FRAUD
            - UNSUITABLE_DOCUMENT
            - INCOMPLETE
            - EMAIL_OTP_CREDENTIAL_ALREADY_EXISTS
            - PASSKEY_CREDENTIAL_ALREADY_EXISTS
        message:
          type: string
          description: Error message
        details:
          type: object
          description: Additional error details
          additionalProperties: true
    Error401:
      type: object
      required:
        - message
        - status
        - code
      properties:
        status:
          type: integer
          enum:
            - 401
          description: HTTP status code
        code:
          type: string
          description: >
            | Error Code | Description |

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

            | UNAUTHORIZED | Issue with API credentials |

            | INVALID_SIGNATURE | Signature header is invalid |

            | WALLET_SIGNATURE_MISSING | The `Grid-Wallet-Signature` header is
            required for this Embedded Wallet action but was not supplied |

            | WALLET_SIGNATURE_MALFORMED | The `Grid-Wallet-Signature` header
            could not be parsed (bad encoding, structure, or fields) |

            | WALLET_SIGNATURE_BODY_MISMATCH | The `Grid-Wallet-Signature` was
            computed over a different request body than the one received |

            | WALLET_SIGNATURE_INVALID | The `Grid-Wallet-Signature` failed
            cryptographic verification against the registered credential |

            | REQUEST_ID_MISSING | The `Request-Id` header is required on the
            signed retry but was not supplied (paired with
            `Grid-Wallet-Signature`) |
          enum:
            - UNAUTHORIZED
            - INVALID_SIGNATURE
            - WALLET_SIGNATURE_MISSING
            - WALLET_SIGNATURE_MALFORMED
            - WALLET_SIGNATURE_BODY_MISMATCH
            - WALLET_SIGNATURE_INVALID
            - REQUEST_ID_MISSING
        message:
          type: string
          description: Error message
        details:
          type: object
          description: Additional error details
          additionalProperties: true
    Error404:
      type: object
      required:
        - message
        - status
        - code
      properties:
        status:
          type: integer
          enum:
            - 404
          description: HTTP status code
        code:
          type: string
          description: >
            | Error Code | Description |

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

            | TRANSACTION_NOT_FOUND | Transaction not found |

            | INVITATION_NOT_FOUND | Invitation not found |

            | USER_NOT_FOUND | Customer not found |

            | QUOTE_NOT_FOUND | Quote not found |

            | LOOKUP_REQUEST_NOT_FOUND | Lookup request not found |

            | TOKEN_NOT_FOUND | Token not found |

            | BULK_UPLOAD_JOB_NOT_FOUND | Bulk upload job not found |

            | REFERENCE_NOT_FOUND | Reference not found |

            | UMA_NOT_FOUND | The UMA address is well-formed but no receiver
            exists at the counterparty VASP |
          enum:
            - TRANSACTION_NOT_FOUND
            - INVITATION_NOT_FOUND
            - USER_NOT_FOUND
            - QUOTE_NOT_FOUND
            - LOOKUP_REQUEST_NOT_FOUND
            - TOKEN_NOT_FOUND
            - BULK_UPLOAD_JOB_NOT_FOUND
            - REFERENCE_NOT_FOUND
            - UMA_NOT_FOUND
        message:
          type: string
          description: Error message
        details:
          type: object
          description: Additional error details
          additionalProperties: true
    Error500:
      type: object
      required:
        - message
        - status
        - code
      properties:
        status:
          type: integer
          enum:
            - 500
          description: HTTP status code
        code:
          type: string
          description: |
            | Error Code | Description |
            |------------|-------------|
            | GRID_SWITCH_ERROR | Grid switch error |
            | INTERNAL_ERROR | Internal server or UMA error |
          enum:
            - GRID_SWITCH_ERROR
            - INTERNAL_ERROR
        message:
          type: string
          description: Error message
        details:
          type: object
          description: Additional error details
          additionalProperties: true
    VerificationStatus:
      type: string
      enum:
        - RESOLVE_ERRORS
        - PENDING_MANUAL_REVIEW
        - IN_PROGRESS
        - APPROVED
        - REJECTED
        - READY_FOR_VERIFICATION
      description: Current status of the KYC/KYB verification
      example: RESOLVE_ERRORS
    VerificationError:
      type: object
      required:
        - resourceId
        - type
        - reason
      properties:
        resourceId:
          type: string
          description: >-
            ID of the resource with the issue (Customer, BeneficialOwner, or
            Document)
          example: Customer:019542f5-b3e7-1d02-0000-000000000001
        type:
          $ref: '#/components/schemas/VerificationErrorType'
        field:
          type: string
          description: >-
            Dot-notation path to the field with the issue. Present when type is
            MISSING_FIELD or INVALID_FIELD.
          example: customer.address.line1
        acceptedDocumentTypes:
          type: array
          items:
            $ref: '#/components/schemas/DocumentType'
          description: >-
            Document types that would satisfy this requirement. The integrator
            can upload any one of the listed types. Present when type is
            MISSING_LEGAL_PRESENCE_DOCUMENT, MISSING_CONTROL_STRUCTURE_DOCUMENT,
            MISSING_OWNERSHIP_STRUCTURE_DOCUMENT,
            MISSING_PROOF_OF_ADDRESS_DOCUMENT, MISSING_IDENTITY_DOCUMENT,
            INVALID_DOCUMENT, or EXPIRED_DOCUMENT.


            | Error Type | Accepted Document Types |

            |---|---|

            | MISSING_LEGAL_PRESENCE_DOCUMENT | CERTIFICATE_OF_INCORPORATION,
            ARTICLES_OF_INCORPORATION, ARTICLES_OF_ASSOCIATION,
            STATE_REGISTRY_EXCERPT |

            | MISSING_CONTROL_STRUCTURE_DOCUMENT | DIRECTOR_REGISTRY,
            TRUST_AGREEMENT, STATE_COMPANY_REGISTRY,
            PARTNERSHIP_CONTROL_AGREEMENT |

            | MISSING_OWNERSHIP_STRUCTURE_DOCUMENT | SHAREHOLDER_REGISTER,
            TRUST_AGREEMENT, PARTNERSHIP_AGREEMENT |

            | MISSING_PROOF_OF_ADDRESS_DOCUMENT | UTILITY_BILL,
            RENT_OR_LEASE_AGREEMENT, ELECTRICITY_BILL, BANK_STATEMENT,
            TAX_RETURN |

            | MISSING_IDENTITY_DOCUMENT | PASSPORT, DRIVERS_LICENSE, NATIONAL_ID
            |
        reason:
          type: string
          description: Human-readable description of the issue
          example: Business address line 1 is required
    VerificationErrorType:
      type: string
      enum:
        - MISSING_FIELD
        - INVALID_FIELD
        - MISSING_LEGAL_PRESENCE_DOCUMENT
        - MISSING_CONTROL_STRUCTURE_DOCUMENT
        - MISSING_OWNERSHIP_STRUCTURE_DOCUMENT
        - MISSING_PROOF_OF_ADDRESS_DOCUMENT
        - MISSING_IDENTITY_DOCUMENT
        - INVALID_DOCUMENT
        - EXPIRED_DOCUMENT
        - POOR_QUALITY_DOCUMENT
        - SUSPECTED_FRAUD_DOCUMENT
        - WRONG_DOCUMENT_TYPE
        - INCOMPLETE_DOCUMENT
        - UNREADABLE_DOCUMENT
        - DOCUMENT_VERIFICATION_FAILED
        - APPLICANT_SANCTIONED
        - APPLICANT_FRAUD
        - APPLICANT_CRIMINAL_RECORD
        - APPLICANT_REJECTED
        - MISSING_BENEFICIAL_OWNER
      description: >-
        Type of verification error. The category-specific MISSING_*_DOCUMENT
        types indicate which document category is needed. Document quality types
        (POOR_QUALITY_DOCUMENT, SUSPECTED_FRAUD_DOCUMENT, etc.) indicate
        specific issues with uploaded documents. APPLICANT_* types indicate
        issues with the applicant themselves (sanctions, fraud, criminal
        records).
      example: MISSING_FIELD
    DocumentType:
      type: string
      enum:
        - PASSPORT
        - DRIVERS_LICENSE
        - NATIONAL_ID
        - PROOF_OF_ADDRESS
        - BANK_STATEMENT
        - TAX_RETURN
        - CERTIFICATE_OF_INCORPORATION
        - ARTICLES_OF_INCORPORATION
        - ARTICLES_OF_ASSOCIATION
        - STATE_REGISTRY_EXCERPT
        - GOOD_STANDING_CERTIFICATE
        - INFORMATION_STATEMENT
        - INCUMBENCY_CERTIFICATE
        - BUSINESS_LICENSE
        - SHAREHOLDER_REGISTER
        - POWER_OF_ATTORNEY
        - UTILITY_BILL
        - ELECTRICITY_BILL
        - RENT_OR_LEASE_AGREEMENT
        - DIRECTOR_REGISTRY
        - TRUST_AGREEMENT
        - STATE_COMPANY_REGISTRY
        - PARTNERSHIP_CONTROL_AGREEMENT
        - PARTNERSHIP_AGREEMENT
        - SELFIE
        - OTHER
      description: >-
        Type of identity or business verification document. Document types are
        grouped by verification category:

        **Identity** — PASSPORT, DRIVERS_LICENSE, NATIONAL_ID

        **Business — Legal presence** — CERTIFICATE_OF_INCORPORATION,
        ARTICLES_OF_INCORPORATION, ARTICLES_OF_ASSOCIATION,
        STATE_REGISTRY_EXCERPT

        **Business — Control structure** — DIRECTOR_REGISTRY, TRUST_AGREEMENT,
        STATE_COMPANY_REGISTRY, PARTNERSHIP_CONTROL_AGREEMENT

        **Business — Ownership structure** — SHAREHOLDER_REGISTER,
        TRUST_AGREEMENT, PARTNERSHIP_AGREEMENT

        **Proof of address** — UTILITY_BILL, RENT_OR_LEASE_AGREEMENT,
        ELECTRICITY_BILL, BANK_STATEMENT, TAX_RETURN
      example: PASSPORT
  securitySchemes:
    BasicAuth:
      type: http
      scheme: basic
      description: >-
        API token authentication using format `<api token id>:<api client
        secret>`
    AgentAuth:
      type: http
      scheme: bearer
      description: >-
        Bearer token authentication for agent-scoped endpoints. The token is the
        `accessToken` returned when redeeming a device code via `POST
        /agents/device-codes/{code}/redeem`. Agent credentials are user-scoped:
        all requests are automatically bound to the agent's associated customer
        and subject to the agent's policy.

````