Z Zise Developers 简体中文

Update a member's KYC profile directly (partial update)

PATCH /v1/kyc scope: kyc:write
Merchant account Requires x-idempotency-key

The merchant server submits JSON directly to update the member's primary KYC profile, without a hosted page. Editable data includes name, sex, date of birth, email, phone, document type and expiry, photos, residence type, and address. identity_number (document number), nationality (nationality), identity_issue_country (document-issuing country), and address_country (country of residence) cannot be changed. Supplying them returns invalid_fields and none of the update is applied. Send only fields to change within profile; omitted data and document photos retain their existing values. An empty string or empty array is an explicit change and remains subject to validation; null does not mean keep unchanged. identity_photos merges subfields, while residence_permit_urls replaces the whole array. An empty profile, unknown fields, invalid phone numbers, or incorrect field types are rejected.

A successful update returns pending and level: 0, sending the profile for review again; KYC records for individual card products also return to pending review. Business requiring a verified KYC level is blocked until approval. This endpoint does not directly update existing cards or upstream cardholder contact details, nor automatically retry failed applications. If issuance failed because the phone number was already in use, change it to the user's real available number, obtain approval, then submit a new card application with a new idempotency key. Reusing the old key returns the original failure.

Review status, KYC level, member ownership, and the quick KYC profile pool cannot be changed. Changing profile.email does not change the account login email. The new contact email must match the account email or be accompanied by a matching email_verify_key. If no profile exists, returns not_found without creating one. Concurrent modifications return state_invalid; resubmit with a new idempotency key.

FieldTypeRequiredDescription
x-on-behalf-of string Required The member's external_member_id or mem_<uuid>, not a card application ID.
x-idempotency-key string Required

Request Body

FieldTypeRequiredDescription
email_verify_key string Optional Email verification credential used when changing to a new contact email.
profile object Required
profile.first_name string Optional
profile.last_name string Optional
profile.email string Optional
profile.phone string Optional
profile.phone_zone_number string Optional
profile.identity_type string Optional
profile.identity_expiry_date string Optional
profile.cardholder_residence string Optional
profile.residence_permit_type string Optional
profile.sex string Optional
profile.occupation string Optional
profile.birth_date string Optional
profile.address_province string Optional
profile.address_city string Optional
profile.address_district string Optional
profile.address string Optional
profile.street_number string Optional
profile.postal_code string Optional
profile.identity_photos object Optional
profile.residence_permit_urls string[] Optional

Response

200Updated and pending review; the response does not echo identity data or images.
{
  "kyc_id": "48",
  "status": "pending",
  "review_status": "UNREVIEWED",
  "level": 0
}
400invalid_request · invalid_fields · member_context_required · state_invalid · request_rejected · idempotency_key_required
401invalid_token · invalid_signature · signature_required
403insufficient_scope
404member_not_found · not_found
409idempotency_key_reused
Request
curl -X PATCH 'https://api.zinfra.vip/v1/kyc' \
  -H 'x-auth-token: Bearer $TOKEN' \
  -H 'x-idempotency-key: $IDEMPOTENCY_KEY' \
  -H 'content-type: application/json' \
  -d '{
    "profile": {
      "first_name": "Alex",
      "occupation": "designer",
      "address": "25 Main Street",
      "phone_zone_number": "1",
      "phone": "2025550123"
    }
  }'
const res = await fetch("https://api.zinfra.vip/v1/kyc", {
  method: "PATCH",
  headers: {
    "x-auth-token": "Bearer $TOKEN",
    "x-idempotency-key": "$IDEMPOTENCY_KEY",
    "content-type": "application/json",
  },
  body: JSON.stringify({
    "profile": {
      "first_name": "Alex",
      "occupation": "designer",
      "address": "25 Main Street",
      "phone_zone_number": "1",
      "phone": "2025550123"
    }
  }),
});
// Keep monetary amounts as strings, never numbers.
const data = await res.json();
import requests

res = requests.patch(
    "https://api.zinfra.vip/v1/kyc",
    headers={
        "x-auth-token": "Bearer $TOKEN",
        "x-idempotency-key": "$IDEMPOTENCY_KEY",
        "content-type": "application/json",
    },
    json={
      "profile": {
        "first_name": "Alex",
        "occupation": "designer",
        "address": "25 Main Street",
        "phone_zone_number": "1",
        "phone": "2025550123"
      }
    },
)
# Use Decimal(str(...)) for amounts, not float.
data = res.json()
req, _ := http.NewRequest("PATCH", "https://api.zinfra.vip/v1/kyc",
    strings.NewReader(`{
  "profile": {
    "first_name": "Alex",
    "occupation": "designer",
    "address": "25 Main Street",
    "phone_zone_number": "1",
    "phone": "2025550123"
  }
}`))
req.Header.Set("x-auth-token", "Bearer $TOKEN")
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"))
    .header("x-auth-token", "Bearer $TOKEN")
    .header("x-idempotency-key", "$IDEMPOTENCY_KEY")
    .header("content-type", "application/json")
    .method("PATCH", HttpRequest.BodyPublishers.ofString("""
{
  "profile": {
    "first_name": "Alex",
    "occupation": "designer",
    "address": "25 Main Street",
    "phone_zone_number": "1",
    "phone": "2025550123"
  }
}
"""))
    .build();
// Use String / BigDecimal for amounts, not double.
$ch = curl_init('https://api.zinfra.vip/v1/kyc');
curl_setopt_array($ch, [
  CURLOPT_CUSTOMREQUEST => 'PATCH',
  CURLOPT_RETURNTRANSFER => true,
  CURLOPT_HTTPHEADER => [
    'x-auth-token: Bearer $TOKEN',
    'x-idempotency-key: $IDEMPOTENCY_KEY',
    'content-type: application/json',
  ],
  CURLOPT_POSTFIELDS => <<<'JSON'
{
  "profile": {
    "first_name": "Alex",
    "occupation": "designer",
    "address": "25 Main Street",
    "phone_zone_number": "1",
    "phone": "2025550123"
  }
}
JSON,
]);
$res = curl_exec($ch);
// Use bcmath / strings for amounts, not floatval.
200
{
  "kyc_id": "48",
  "status": "pending",
  "review_status": "UNREVIEWED",
  "level": 0
}