Z Zise Developers 简体中文

Submit advanced L2 verification as merchant-provided JSON

POST /v1/kyc/l2/applications scope: kyc:write
On behalf of a member · x-on-behalf-of required Requires x-idempotency-key

After primary L1 approval, submit parameters directly without creating a session or opening a hosted page. Upload supporting documents through POST /v1/kyc/files first; only existing files uploaded by the current member are accepted. POST requires a signature; the JSON body may be at most 128 KiB. Successful submission means only awaiting review. A member with an existing non-rejected application cannot create another. Quick KYC bindings do not satisfy the genuine L1 prerequisite. See the L2 integration guide for detailed field rules and a complete example.

FieldTypeRequiredDescription
x-on-behalf-of string Required
x-idempotency-key string Required

Request Body

FieldTypeRequiredDescription
profile object Required
profile.nickname string Required
profile.postal_code string Required
profile.tax_number string Optional
profile.employment_status string Required The value from the corresponding configuration option.
profile.industry string Required The value from the corresponding configuration option.
profile.job_title string Required The value from the corresponding configuration option.
profile.company_name string Required English letters, digits, spaces, and specified symbols.
profile.annual_income string Required Positive amount, annual income in US dollars.
profile.account_purpose string[] Required Array of values from the corresponding configuration options.
profile.other_purpose string Optional Required when purposes include OTHERS.
profile.banking_countries string[] Required
profile.banking_currencies string[] Required A value from configured currencies.
profile.internationally "0" | "1" Optional
profile.turnover_monthly string Required The value from the corresponding configuration option.
profile.turnover_monthly_currency string Required A value from configured currencies.
profile.proof_of_address string Required Proof-of-address file_url.
profile.source_of_funds string Required Source-of-funds proof file_url.
profile.income_proof string Optional Optional proof-of-income file_url.
profile.other_proof string Optional Optional additional-document file_url.
tos_acceptance object Required
tos_acceptance.accepted "true" Required
tos_acceptance.ip string Required The member's real IPv4 address; do not substitute the merchant server's address.
tos_acceptance.user_agent string Required The member's actual device information.
tos_acceptance.accepted_at string Required The member's confirmation time as UTC ISO text ending in Z, with at most three millisecond digits and no more than 5 minutes ahead of server time.

Response

201Submitted; awaiting review.
400invalid_fields / invalid_request / kyc_required / state_invalid
403insufficient_scope
404member_not_found
409idempotency_key_reused / idempotency_in_progress
Request
curl -X POST 'https://api.zinfra.vip/v1/kyc/l2/applications' \
  -H 'x-auth-token: Bearer $TOKEN' \
  -H 'x-on-behalf-of: $MEMBER_ID' \
  -H 'x-idempotency-key: $IDEMPOTENCY_KEY' \
  -H 'content-type: application/json' \
  -d '{
    "profile": "…",
    "tos_acceptance": "…"
  }'
const res = await fetch("https://api.zinfra.vip/v1/kyc/l2/applications", {
  method: "POST",
  headers: {
    "x-auth-token": "Bearer $TOKEN",
    "x-on-behalf-of": "$MEMBER_ID",
    "x-idempotency-key": "$IDEMPOTENCY_KEY",
    "content-type": "application/json",
  },
  body: JSON.stringify({
    "profile": "…",
    "tos_acceptance": "…"
  }),
});
// Keep monetary amounts as strings, never numbers.
const data = await res.json();
import requests

res = requests.post(
    "https://api.zinfra.vip/v1/kyc/l2/applications",
    headers={
        "x-auth-token": "Bearer $TOKEN",
        "x-on-behalf-of": "$MEMBER_ID",
        "x-idempotency-key": "$IDEMPOTENCY_KEY",
        "content-type": "application/json",
    },
    json={
      "profile": "…",
      "tos_acceptance": "…"
    },
)
# Use Decimal(str(...)) for amounts, not float.
data = res.json()
req, _ := http.NewRequest("POST", "https://api.zinfra.vip/v1/kyc/l2/applications",
    strings.NewReader(`{
  "profile": "…",
  "tos_acceptance": "…"
}`))
req.Header.Set("x-auth-token", "Bearer $TOKEN")
req.Header.Set("x-on-behalf-of", "$MEMBER_ID")
req.Header.Set("x-idempotency-key", "$IDEMPOTENCY_KEY")
req.Header.Set("content-type", "application/json")
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/l2/applications"))
    .header("x-auth-token", "Bearer $TOKEN")
    .header("x-on-behalf-of", "$MEMBER_ID")
    .header("x-idempotency-key", "$IDEMPOTENCY_KEY")
    .header("content-type", "application/json")
    .method("POST", HttpRequest.BodyPublishers.ofString("""
{
  "profile": "…",
  "tos_acceptance": "…"
}
"""))
    .build();
// Use String / BigDecimal for amounts, not double.
$ch = curl_init('https://api.zinfra.vip/v1/kyc/l2/applications');
curl_setopt_array($ch, [
  CURLOPT_CUSTOMREQUEST => 'POST',
  CURLOPT_RETURNTRANSFER => true,
  CURLOPT_HTTPHEADER => [
    'x-auth-token: Bearer $TOKEN',
    'x-on-behalf-of: $MEMBER_ID',
    'x-idempotency-key: $IDEMPOTENCY_KEY',
    'content-type: application/json',
  ],
  CURLOPT_POSTFIELDS => <<<'JSON'
{
  "profile": "…",
  "tos_acceptance": "…"
}
JSON,
]);
$res = curl_exec($ch);
// Use bcmath / strings for amounts, not floatval.
201
// No response example is declared in the specification for this operation.