Skip to main content
Some card products (BINs) require cardholders to complete Enhanced KYC — identity verification through a third-party provider — before a card can be issued. This guide walks through the full flow from checking product requirements to issuing a card.
If your card product only requires basic fields (Simplified KYC), the existing cardholder creation flow works as before — no changes needed. Use List Products to check what your product requires.

Overview

Prerequisites

Before making API calls, obtain an access token:
curl -X POST "https://api-sandbox.uqpaytech.com/api/v1/connect/token" \
  -H "Content-Type: application/json" \
  -H "x-api-key: {your_api_key}" \
  -H "x-client-id: {your_client_id}"
{
  "auth_token": "eyJhbGciOiJIUzI1NiIs...",
  "expired_at": 1775210493
}
Use the returned auth_token in all subsequent requests via the x-auth-token header.

Step 1: Check Product Requirements

Call List Products to identify which fields your target product requires.
curl -X GET "https://api-sandbox.uqpaytech.com/api/v1/issuing/products?page_size=10&page_number=1" \
  -H "Content-Type: application/json" \
  -H "x-auth-token: {your_auth_token}"
In the response, look at the required_fields array. An Enhanced KYC product will include identity, residential_address, and kyc_verification as required fields. Here is an example of an Enhanced product (BIN 46651711):
{
  "product_id": "0d8f10de-c888-4107-ab65-1cc9deb31b3b",
  "card_bin": "46651711",
  "card_scheme": "VISA",
  "card_form": ["VIR"],
  "card_currency": ["USD", "SGD", "HKD"],
  "mode_type": "SHARE",
  "kyc_level": "ENHANCED",
  "max_card_quota": 3001,
  "product_status": "ENABLED",
  "required_fields": [
    { "name": "first_name", "type": "string", "required": true },
    { "name": "last_name", "type": "string", "required": true },
    { "name": "email", "type": "string", "required": true },
    { "name": "country_code", "type": "string", "required": true },
    { "name": "date_of_birth", "type": "string", "required": true },
    { "name": "phone_number", "type": "string", "required": true },
    { "name": "nationality", "type": "string", "required": true },
    {
      "name": "identity",
      "type": "object",
      "required": true,
      "fields": [
        { "name": "type", "type": "string", "required": true },
        { "name": "number", "type": "string", "required": true },
        { "name": "front_file", "type": "string", "required": true },
        { "name": "back_file", "type": "string", "required": false },
        { "name": "hand_file", "type": "string", "required": false }
      ]
    },
    {
      "name": "residential_address",
      "type": "object",
      "required": true,
      "fields": [
        { "name": "country", "type": "string", "required": true },
        { "name": "state", "type": "string", "required": true },
        { "name": "city", "type": "string", "required": true },
        { "name": "district", "type": "string", "required": false },
        { "name": "line1", "type": "string", "required": true },
        { "name": "line2", "type": "string", "required": false },
        { "name": "line_en", "type": "string", "required": true },
        { "name": "postal_code", "type": "string", "required": true }
      ]
    },
    {
      "name": "kyc_verification",
      "type": "object",
      "required": true,
      "fields": [
        { "name": "method", "type": "string", "required": true },
        {
          "name": "kyc_proof",
          "type": "object",
          "required": false,
          "fields": [
            { "name": "provider", "type": "string", "required": false },
            { "name": "reference_id", "type": "string", "required": false }
          ]
        }
      ]
    }
  ]
}
The required_fields tell you exactly what information is needed. Only fields marked "required": true are mandatory — optional fields can be omitted.

Step 2: Create Cardholder with Enhanced KYC

Call Create Cardholder with the full set of required fields plus kyc_verification.
The residential_address.country and nationality fields are subject to region restrictions. See Cardholder Region Restrictions for the full list of supported countries and sanctioned nationalities.
There are two verification methods — choose the one that fits your use case:
MethodWhen to useResult
SUMSUB_REDIRECTYou want UQPAY to handle IDV via SumsubReturns an IDV URL for the cardholder to complete verification
THIRD_PARTYYou have already verified the cardholder through your own KYC providerCardholder is verified immediately

Option A: SUMSUB_REDIRECT

Use this if you want UQPAY to handle identity verification via Sumsub. You will receive an IDV URL to redirect your cardholder to.
curl -X POST "https://api-sandbox.uqpaytech.com/api/v1/issuing/cardholders" \
  -H "Content-Type: application/json" \
  -H "x-auth-token: {your_auth_token}" \
  -H "x-idempotency-key: cc58fa96-7a49-4be1-a70b-85075c1b4957" \
  -d '{
    "first_name": "Sarah",
    "last_name": "Chen",
    "email": "sarah.chen@example.com",
    "country_code": "SG",
    "phone_number": "90755646",
    "date_of_birth": "1992-06-15",
    "nationality": "SG",
    "identity": {
      "type": "PASSPORT",
      "number": "E98765432",
      "front_file": "<base64_encoded_image>",
      "back_file": "<base64_encoded_image>",
      "hand_file": "<base64_encoded_image>"
    },
    "residential_address": {
      "country": "SG",
      "state": "Singapore",
      "city": "Singapore",
      "district": "Buona Vista",
      "line1": "9 N Buona Vista Dr",
      "line2": "THE METROPOLIS",
      "line_en": "9 N Buona Vista Dr, THE METROPOLIS",
      "postal_code": "138666"
    },
    "kyc_verification": {
      "method": "SUMSUB_REDIRECT"
    }
  }'
Response — the cardholder enters INCOMPLETE status with an IDV link:
{
  "cardholder_id": "9d6017b2-0c2f-4b2e-876b-992b0db9597d",
  "cardholder_status": "INCOMPLETE",
  "idv_verification_url": "https://in.sumsub.com/websdk/p/sbx_MVSJTHTZj77PZggH",
  "idv_url_expires_at": "2026-04-04T17:32:50+08:00"
}
Redirect your cardholder to idv_verification_url to complete identity verification, then wait for the webhook notification (Step 3).

Option B: THIRD_PARTY

Use this if you have already completed identity verification through your own KYC provider and have a proof reference.
curl -X POST "https://api-sandbox.uqpaytech.com/api/v1/issuing/cardholders" \
  -H "Content-Type: application/json" \
  -H "x-auth-token: {your_auth_token}" \
  -H "x-idempotency-key: {unique_uuid}" \
  -d '{
    "first_name": "Sarah",
    "last_name": "Chen",
    "email": "sarah.chen@example.com",
    "country_code": "SG",
    "phone_number": "90755646",
    "date_of_birth": "1992-06-15",
    "nationality": "SG",
    "identity": {
      "type": "PASSPORT",
      "number": "E98765432",
      "front_file": "<base64_encoded_image>",
      "back_file": "<base64_encoded_image>",
      "hand_file": "<base64_encoded_image>"
    },
    "residential_address": {
      "country": "SG",
      "state": "Singapore",
      "city": "Singapore",
      "district": "Buona Vista",
      "line1": "9 N Buona Vista Dr",
      "line2": "THE METROPOLIS",
      "line_en": "9 N Buona Vista Dr, THE METROPOLIS",
      "postal_code": "138666"
    },
    "kyc_verification": {
      "method": "THIRD_PARTY",
      "kyc_proof": {
        "provider": "YOUR_PROVIDER",
        "reference_id": "your_provider_ref_1234567890"
      }
    }
  }'
kyc_proof.reference_id must be at least 10 characters and globally unique.
Response — the cardholder is verified immediately:
{
  "cardholder_id": "9d6017b2-0c2f-4b2e-876b-992b0db9597d",
  "cardholder_status": "SUCCESS"
}
You can proceed directly to Step 4: Create Card.

Step 3: Wait for KYC Approval (SUMSUB_REDIRECT only)

If you used SUMSUB_REDIRECT, subscribe to the cardholder.kyc.status_changed webhook to receive real-time KYC status updates. Webhook payload example (KYC approved):
{
  "version": "V1.6.0",
  "event_name": "ISSUING",
  "event_type": "cardholder.kyc.status_changed",
  "event_id": "d92ab1ec-1737-4b3c-bedb-7500a3c02677",
  "source_id": "9d6017b2-0c2f-4b2e-876b-992b0db9597d",
  "data": {
    "cardholder_id": "9d6017b2-0c2f-4b2e-876b-992b0db9597d",
    "cardholder_status": "SUCCESS",
    "country_code": "SG",
    "create_time": "2026-04-03T17:32:50+08:00",
    "date_of_birth": "1992-06-15",
    "email": "sarah.chen@example.com",
    "first_name": "Sarah",
    "idv_provider": "SUMSUB",
    "idv_status": "PASSED",
    "last_name": "Chen",
    "nationality": "SG",
    "phone_number": "90755646",
    "update_time": "2026-04-03T17:34:49+08:00"
  }
}
When cardholder_status becomes SUCCESS, the cardholder is ready for card issuance.
Cards cannot be issued while the cardholder is in PENDING status. Wait for KYC approval before proceeding.

Step 4: Create Card

Once cardholder_status is SUCCESS, call Create Card:
curl -X POST "https://api-sandbox.uqpaytech.com/api/v1/issuing/cards" \
  -H "Content-Type: application/json" \
  -H "x-auth-token: {your_auth_token}" \
  -H "x-idempotency-key: bf705cbd-27f0-48d1-a60b-212134a89ad7" \
  -d '{
    "cardholder_id": "9d6017b2-0c2f-4b2e-876b-992b0db9597d",
    "card_product_id": "0d8f10de-c888-4107-ab65-1cc9deb31b3b",
    "card_currency": "USD",
    "card_limit": 1000
  }'
Response:
{
  "card_id": "d26f2287-434b-41a4-af47-f06dbf6f9e71",
  "card_order_id": "c004375c-8137-4b94-b948-4282bff33625",
  "card_status": "PENDING",
  "order_status": "PROCESSING",
  "create_time": "2026-04-03T17:35:55+08:00",
  "risk_controls": {}
}

Error Handling

KYC insufficient at card creation

If you attempt to create a card but the cardholder hasn’t met the product’s KYC requirements, you will receive an error with missing_fields indicating which fields are still needed:
{
  "code": "kyc_insufficient",
  "message": "Cardholder KYC information is insufficient for this product.",
  "missing_fields": ["identity", "residential_address"]
}
You can either:
  1. Update the cardholder first via Update Cardholder, then retry card creation.
  2. Supply the missing fields inline by passing cardholder_required_fields in the Create Card request.

Cardholder in PENDING status

Creating a card while the cardholder’s cardholder_status is PENDING will be rejected. Wait for the KYC review to complete before retrying.