Z Zise Developers 简体中文

Required KYC levels by business line

GET /v1/kyc/requirements scope: kyc:read
Merchant account

Returns the KYC level required by each business line. Do not hardcode a table on your side; requirements may change.

Parameters

This endpoint takes no parameters: no path parameters, query parameters or request body. For the authentication header (x-auth-token) and on-behalf-of header (x-on-behalf-of), see Authentication and Signing.

Response

200OK
{
  "requirements": [
    {
      "business": "remittance.express",
      "required_level": 1
    },
    {
      "business": "remittance.pobo",
      "required_level": 2
    },
    {
      "business": "card",
      "required_level": 1
    },
    {
      "business": "exchange",
      "required_level": 0
    },
    {
      "business": "earn",
      "required_level": 0
    }
  ]
}
403insufficient_scope: missing kyc:read.

Additional Details

Covered lines (completed on 2026-08-13)

remittance.express · remittance.pobo · card · exchange · earn · withdraw · transfer.send · transfer.receive · qrpay

⚠ The last four were previously missing from this table, despite having KYC gates. Merchants following the instruction to use this endpoint found no entries and assumed 0, skipped prechecks, and let users complete the whole flow only to be rejected at the last step.

⚠ Sending and receiving transfers are separate rows (transfer.send / transfer.receive). Combining them using the stricter requirement would incorrectly reject a member who only receives transfers.

⚠ card uses the minimum across card products visible to you, not a constant 1. Card products may require L2.

⚠ QR payments have required_level 0; that is not unconditional permission

The gate is a cumulative trigger, not a fixed level. Members without L1 may continue paying until their cumulative spending exceeds kyc_trigger_amount, at which point L1 is required.

This entry therefore includes two additional fields:

  • kyc_trigger_amount: integer string in the smallest unit; omitted when there is no trigger.
  • kyc_trigger_level: the required level after crossing the trigger, 1.

Using required_level: 1 overstates the requirement, rejecting users currently allowed to pay. Reading only required_level: 0 misses the trigger, causing an unexpected rejection on a later payment. Use both figures.

This does not indicate whether a business line is available

This endpoint answers only which level is required. Availability, including whether a line is enabled or halted, comes from GET /v1/merchant/lines. Even with no configuration row, this endpoint still returns 0, which does not mean the line is enabled. Call as the merchant itself, without x-on-behalf-of. The response describes the minimum KYC level for each business line under your configuration. Prechecking before order creation is better than letting members hit kyc_required and then go back to supply documents.

Five entries always appear: remittance.express (1), remittance.pobo (2), card (1), exchange (from your exchange configuration), and earn (the lowest requirement among wealth products on sale and visible to you). The last answers the minimum level needed to start buying, not the level needed to buy every product.

⚠ The top-level key is requirements, not data, for legacy reasons.

These are risk-control eligibility rules and are read-only to you. Values change with administrative configuration; do not hardcode them.

Request
curl -X GET 'https://api.zinfra.vip/v1/kyc/requirements' \
  -H 'x-auth-token: Bearer $TOKEN'
const res = await fetch("https://api.zinfra.vip/v1/kyc/requirements", {
  method: "GET",
  headers: {
    "x-auth-token": "Bearer $TOKEN",
  },
});
// Keep monetary amounts as strings, never numbers.
const data = await res.json();
import requests

res = requests.get(
    "https://api.zinfra.vip/v1/kyc/requirements",
    headers={
        "x-auth-token": "Bearer $TOKEN",
    },
)
# Use Decimal(str(...)) for amounts, not float.
data = res.json()
req, _ := http.NewRequest("GET", "https://api.zinfra.vip/v1/kyc/requirements",
    nil)
req.Header.Set("x-auth-token", "Bearer $TOKEN")
res, err := http.DefaultClient.Do(req)
// Decode amount fields as string, not float64.
HttpRequest req = HttpRequest.newBuilder()
    .uri(URI.create("https://api.zinfra.vip/v1/kyc/requirements"))
    .header("x-auth-token", "Bearer $TOKEN")
    .method("GET", HttpRequest.BodyPublishers.noBody())
    .build();
// Use String / BigDecimal for amounts, not double.
$ch = curl_init('https://api.zinfra.vip/v1/kyc/requirements');
curl_setopt_array($ch, [
  CURLOPT_CUSTOMREQUEST => 'GET',
  CURLOPT_RETURNTRANSFER => true,
  CURLOPT_HTTPHEADER => [
    'x-auth-token: Bearer $TOKEN',
  ],
]);
$res = curl_exec($ch);
// Use bcmath / strings for amounts, not floatval.
200
{
  "requirements": [
    {
      "business": "remittance.express",
      "required_level": 1
    },
    {
      "business": "remittance.pobo",
      "required_level": 2
    },
    {
      "business": "card",
      "required_level": 1
    },
    {
      "business": "exchange",
      "required_level": 0
    },
    {
      "business": "earn",
      "required_level": 0
    }
  ]
}