For the complete documentation index, see llms.txt. This page is also available as Markdown.

KYC flow

Most flows require validating a user’s Know Your Customer (KYC) level before creating an order. The high-level steps are:

  1. Call Get user KYC state with a user's email and a country.

  2. If requiredKycType is non-null and higher than passedKycType, the user has already crossed an aggregate threshold and must upgrade KYC before further orders. Skip to step 5.

  3. Otherwise, inspect kycSettings to determine whether the order you're about to create triggers a per-order rule:

    • Match settings where operationType and currencyType align with the order side you care about.

    • For per-order entries (min/max set), check whether the order's USD value falls in [min, max).

    • Take the highest type among all matching entries.

  4. If passedKycType is already at or above the required tier, proceed to quoting and order creation.

  5. Otherwise, pick the document from kycDocuments whose type matches the required tier, collect requiredFields from the user, and submit via Submit user KYC. The response is the same shape as Get user KYC state.

  6. Poll Get user KYC state until currentKycStatus === "approved" and passedKycType reaches the required tier. (For Nigerian advanced KYC, currentKycPhase transitions from bvn_check to images_check internally — no extra action needed.)

Note on amount-based pre-checks: requiredKycType reflects only the user's lifetime successful order history (aggregate rules). It does not account for the size of the next order. To pre-check whether a specific upcoming order will trip a per-order rule, evaluate kycSettings yourself as described in step 3.

Tip: In the sample below, a per-order rule requires advanced KYC for any single crypto payout of $100 or more, and an aggregate rule requires advanced once the user's lifetime successful crypto payouts exceed $1,000.

Response fields

  • passedKycType ("basic" | "advanced" | null) — the highest KYC tier the user has already passed.

  • reachedKycLimit (boolean) — true when the user has too many pending KYC submissions and cannot initiate another until existing ones resolve.

  • requiredKycType ("basic" | "advanced" | null) — server-computed required tier based on the user's lifetime successful order history (aggregate rules only). If non-null and higher than passedKycType, the user must upgrade KYC. null means no aggregate rule is forcing an upgrade — a per-order rule in kycSettings may still apply to the next order.

  • currentKycType ("basic" | "advanced" | undefined) — the tier of the user's latest in-flight KYC submission.

  • currentKycStatus ("initiated" | "approved" | "rejected" | "invalid" | null) — status of the latest KYC submission.

  • currentKycStatusDescription (string | null) — human-readable reason for the current status.

  • currentKycPhase ("bvn_check" | "images_check" | undefined) — set only for Nigerian advanced KYC. Internal sub-step of an advanced verification. Merchants submit all fields (including images) in a single call; phases progress internally. Use only for progress UI.

  • kycDocuments — list of documents available for the country, each with _id, type, title, value, and a requiredFields array.

  • kycSettings — list of KYC rules for the country. Two variants coexist:

    • Per-ordermin and max are set. The rule fires when the order's USD value on the matching operationType + currencyType side is in [min, max). max may be "Infinity".

    • AggregatemaxOrdersCount and/or maxAmountUsd are set. The rule fires once the user's lifetime successful order count or USD volume in that (operationType, currencyType) bucket reaches the threshold. This is what requiredKycType reflects.

    • All settings carry operationType, currencyType, and type (required KYC tier). When multiple fire, the highest type wins.

Sample Get user KYC state response

The "advanced" KYC document requires images. Submit them as an array of objects with image_type_id and image URL. Image URLs must be publicly accessible or contain the image data as a base64-encoded string. The "image_type_id" can accept the following values:

  • 0: Selfie

  • 1: Document front

  • 5: Document back

Sample Submit user KYC request

The Submit response has the same shape as Get user KYC state. Continue polling Get user KYC state until currentKycStatus becomes approved and passedKycType reaches the required tier, then proceed with quoting and order creation.

Last updated