# KYC China

KYC verification for mainland China citizens — identity, mobile, risk, and bank checks against Ministry of Public Security, telecom carrier, and banking records.

### Single endpoint, smart fan-out

You send one request to `POST /kyc/cn/request` with whatever fields you have, then either receive the result via a webhook (pass `callbackUrl` in the request) or poll `POST /kyc/cn/poll` until the result is ready. The service inspects the request, picks the strongest verification variant on each axis (e.g. four-factor instead of two-factor when ID dates are present), and runs every eligible sub-check in parallel against the upstream sources.

The merged response tells you, per category, whether the person matched, plus an execution `summary` so you can tell at a glance which checks ran, which matched, which came back empty, and which errored.

### What can be verified

| Category                     | Verifies                                                                                                           | Required upstream fields                                   |
| ---------------------------- | ------------------------------------------------------------------------------------------------------------------ | ---------------------------------------------------------- |
| **Identity**                 | Name + ID card pair belongs to a real registered citizen                                                           | `name`, `idNumber`                                         |
| **Identity (with validity)** | As above, plus the issue/expiry dates match the on-file record                                                     | `+ idIssueDate`, `idExpiryDate`                            |
| **Identity (face match)**    | As above, plus the supplied photo matches the photo on file                                                        | `+ facePhoto`                                              |
| **Identity-mobile**          | The mobile number is registered to that person at that ID                                                          | `name`, `idNumber`, `mobile` (any subset)                  |
| **Mobile attribution**       | Carrier, registered province, and registered city of the SIM                                                       | `mobile`                                                   |
| **Mobile location**          | Most-active work-hours city + most-active night-hours city (last 3 months)                                         | `mobile`                                                   |
| **Address verification**     | Distance segment (≤3km … >50km) between a supplied address and the mobile's `common` / `work` / `residential` area | `mobile`, `addressesToVerify[]`                            |
| **Risk — fraud**             | Presence on fraud, gambling, and money-mule blacklists; severity 0-3                                               | `mobile` or `idNumber`                                     |
| **Risk — criminal**          | Police-record flags: criminal offender, drug-related, fugitive, etc.                                               | `name`, `idNumber`                                         |
| **Bank**                     | A bank card belongs to the person identified by name + ID (+ mobile)                                               | `name`, `idNumber`, `bankCardNumber` (+ optional `mobile`) |

### Data sources & residency

All upstream calls go through a Beijing-based proxy and query official sources: Ministry of Public Security (identity & criminal), telecom carriers (mobile & location), UnionPay member banks (bank verification), and the national anti-fraud blacklist (risk). No personal data is stored by Fill Easy after the response is returned.

### Cost & rate limits

Each sub-check is a separate billable upstream call. A request with `name`, `idNumber`, `mobile`, and `bankCardNumber` fans out to **9 calls** in parallel (worst case without `addressesToVerify`). Each entry in `addressesToVerify` adds one further call. To narrow what runs, simply omit the inputs you don't want to verify — every sub-check whose required fields are present always fires.

## KYC China verification - Request

> Verify a Chinese citizen's identity, mobile, risk profile, and/or bank card in a\
> single request. You send whatever fields you have; the service decides which\
> sub-checks to run, fans them out in parallel against the upstream sources\
> (Ministry of Public Security, telecom carriers, banks, blacklists), and merges\
> the results into one response.\
> \
> \---\
> \
> \## Selecting which products to run\
> \
> By default the endpoint runs \*\*every\*\* sub-check whose required inputs are\
> present. To restrict the request to a specific set of products, supply \`run\`\
> with an array of product numbers from the\
> \[KYC Mainland China catalogue]\(#tag/KYC-China). For example, \`run: \["1", "8.3", "25"]\`\
> runs only ID & Name verification, bank account 4-factor verification, and litigation\
> records. Product numbers are strings — bank verification is addressed per factor\
> level (\`8.1\`, \`8.2.1\`, \`8.3\`).\
> \
> \| Product # | Name | Sub-checks |\
> \|---|---|---|\
> \| \`1\` | ID & Name Verify | \`identity.two-factor\` |\
> \| \`2\` | ID, Name & Face Verify | \`identity.image\` |\
> \| \`3\` | ID, Name & Date Verify | \`identity.four-factor\` |\
> \| \`4\` | ID, Name, Date & Face Verify | \`identity.four-factor\` + \`identity.image\` |\
> \| \`8.1\` | Bank Account 2FV (name + card) | \`bank.two-factor\` |\
> \| \`8.2.1\` | Bank Account 3FV (name + card + ID) | \`bank.three-factor\` |\
> \| \`8.3\` | Bank Account 4FV (name + card + ID + mobile) | \`bank.four-factor\` |\
> \| \`11\` | Telecom 2FV | \`identity.name-mobile\`, \`identity.id-mobile\` |\
> \| \`12\` | Telecom 3FV | \`identity.three-factor\` |\
> \| \`15\` | Telecom Operator Location | \`mobile.attribution\`, \`mobile.location-work\`, \`mobile.location-residential\` |\
> \| \`17\` | Phone-Address Association | \`mobile.address-verify\[N]\` (one per \`addressesToVerify\` entry) |\
> \| \`24\` | Risk Score for Adverse Records | \`risk.fraud\` |\
> \| \`25\` | Litigation Record Verification | \`litigation.records\` |\
> \| \`27\` | Credit Risk Validation | \`risk.criminal\` |\
> \
> When \`run\` is omitted or empty, the default fan-out applies and the smart-selection\
> rules below avoid paying for redundant calls. When \`run\` is supplied, each requested\
> product fires independently if its required inputs are present — so asking for both\
> product \`1\` (two-factor) and product \`3\` (four-factor) runs \*\*both\*\*, bypassing the\
> default upgrade rule.\
> \
> \---\
> \
> \## How the request fans out\
> \
> The endpoint runs every sub-check whose required inputs are present in your request,\
> with two \*\*smart-selection rules\*\* that avoid paying for redundant calls:\
> \
> \- On the \*\*identity-document axis\*\*, the strongest available variant runs and\
> &#x20; weaker ones are skipped. Specifically, \`identity.four-factor\` (which verifies the\
> &#x20; ID's validity dates in addition to name + ID) supersedes \`identity.two-factor\`\
> &#x20; when both \`idIssueDate\` and \`idExpiryDate\` are supplied.\
> \- On the \*\*identity-mobile axis\*\*, the strongest available variant runs.\
> &#x20; \`identity.three-factor\` (name + ID + mobile) supersedes \`identity.name-mobile\`\
> &#x20; and \`identity.id-mobile\` when all three fields are present.\
> \- On the \*\*bank axis\*\*, the default fan-out runs only the strongest eligible\
> &#x20; variant: \`bank.four-factor\` (name + ID + card + mobile) supersedes\
> &#x20; \`bank.three-factor\` (name + ID + card), which supersedes \`bank.two-factor\`\
> &#x20; (name + card). When you select bank products explicitly via \`run\`, each one\
> &#x20; fires independently — \`run: \["8.1", "8.3"]\` runs both 2-factor and 4-factor,\
> &#x20; and each is reported in its own \`bank2f\` / \`bank3f\` / \`bank4f\` field.\
> \
> Other sub-checks run independently — face match (\`identity.image\`) is on a\
> separate axis from document verification, mobile lookups, and risk checks.\
> \
> Every sub-check whose required fields are present \*\*always runs\*\*. There is no\
> opt-out — if you don't want a category to fire, simply don't supply its inputs.\
> \
> \### Sub-check eligibility\
> \
> \| Sub-check | Required fields | What it verifies |\
> \|---|---|---|\
> \| \`identity.two-factor\` | \`name\`, \`idNumber\` | Name + ID pair exists in MPS records |\
> \| \`identity.four-factor\` | \`+ idIssueDate\`, \`idExpiryDate\` | As above, plus dates match the on-file record |\
> \| \`identity.image\` | \`name\`, \`idNumber\`, \`facePhoto\` | Photo matches the MPS face on file |\
> \| \`identity.name-mobile\` | \`name\`, \`mobile\` | Mobile is registered to that name |\
> \| \`identity.id-mobile\` | \`idNumber\`, \`mobile\` | Mobile is registered to that ID |\
> \| \`identity.three-factor\` | \`name\`, \`idNumber\`, \`mobile\` | All three are tied to one person |\
> \| \`mobile.attribution\` | \`mobile\` | Carrier, registered province, city |\
> \| \`mobile.location-work\` | \`mobile\` | Most-active city during 07:00-19:00 weekdays (last 3 months) |\
> \| \`mobile.location-residential\` | \`mobile\` | Most-active city during 21:00-07:00 (last 3 months) |\
> \| \`mobile.address-verify\[N]\` | \`mobile\` + entry in \`addressesToVerify\` | Distance segment between the supplied address and the mobile's recorded \`common\` / \`work\` / \`residential\` area. One sub-check fires per entry, indexed \`\[0]\`, \`\[1]\`, … |\
> \| \`risk.fraud\` | \`mobile\` or \`idNumber\` | Fraud / gambling / money-mule blacklist hits |\
> \| \`risk.criminal\` | \`name\`, \`idNumber\` | Police record flags (criminal, drug, fugitive, etc.) |\
> \| \`bank.two-factor\` | \`name\`, \`bankCardNumber\` | Card is registered under that name |\
> \| \`bank.three-factor\` | \`+ idNumber\` | As above, plus the card belongs to that ID |\
> \| \`bank.four-factor\` | \`+ mobile\` | As above, plus mobile is the card's registered number |\
> \
> \---\
> \
> \## Reading the response\
> \
> The response always contains a \`summary\` object. Each sub-category (\`identity\`,\
> \`mobile\`, \`risk\`, and the \`bank2f\` / \`bank3f\` / \`bank4f\` fields) is \*\*present only\
> if its sub-check ran and returned data\*\*. Categories with only errored or\
> not-found outcomes are omitted.\
> \
> \### \`summary\` buckets\
> \
> Every attempted sub-check appears in \`summary.ran\`. From there it lands in \*\*exactly\
> one\*\* of these buckets:\
> \
> \| Bucket | Meaning |\
> \|---|---|\
> \| \`matched\` | An identity- or bank-axis check returned \`match\` |\
> \| \`unmatched\` | An identity- or bank-axis check returned \`no match\` (the call ran successfully; the answer was negative) |\
> \| \`notFound\` | The upstream had no record for the input — informational lookups or blacklists routinely return this when nothing is on file |\
> \| \`errored\` | The call itself failed (timeout, upstream service error, network). Carries \`{ check, error }\` for diagnostics |\
> \
> Mobile lookups (\`mobile.attribution\`, \`mobile.location-\*\`) and risk lookups\
> (\`risk.fraud\`, \`risk.criminal\`) have no match/no-match semantics. They appear in\
> \`ran\` and either \`notFound\` or \`errored\` — never in \`matched\`/\`unmatched\`.\
> \
> \### Result semantics by category\
> \
> \- \*\*Identity\*\* — array of \`{ type, result, verification }\`. Treat \`match\` as a\
> &#x20; positive identity signal. \`no match\` from \`three-factor\` typically means the\
> &#x20; mobile isn't tied to that person; pair it with the result from \`two-factor\` /\
> &#x20; \`four-factor\` (also returned) to disambiguate document mismatch from mobile mismatch.\
> \- \*\*Mobile\*\* — flat object with whatever the lookups returned. Fields are absent\
> &#x20; when their underlying call returned no data; check \`summary.notFound\` to tell\
> &#x20; "no data available" from "we never asked".\
> \- \*\*Risk\*\* — \`risk.fraud\` returns a fixed list of four risk types (fraud, gambling\
> &#x20; operator, gambling player, money mule) each with severity \`None\` / \`Low\` /\
> &#x20; \`Medium\` / \`High\`. \`risk.criminal\` returns a flat boolean map. \`isNormal: null\`\
> &#x20; (rather than a boolean) means the check could not complete and the records are\
> &#x20; not authoritative.\
> \- \*\*Bank\*\* — up to three independent fields, one per variant that ran:\
> &#x20; \`bank2f\` (name + card), \`bank3f\` (name + card + ID), and \`bank4f\` (name + card +\
> &#x20; ID + mobile). Each holds \`match\` / \`no match\` / \`not found\` and is present only\
> &#x20; when that variant ran. The default fan-out populates a single field (strongest\
> &#x20; eligible); selecting multiple bank products via \`run\` populates one field each.\
> \
> \---\
> \
> \## Errors\
> \
> \| Code | Meaning |\
> \|---|---|\
> \| \`200\` | Always returned when at least one sub-check was eligible. Per-check failures appear in \`summary.errored\`, never as a 4xx/5xx |\
> \| \`400\` | No sub-checks were eligible with the supplied fields (e.g. only \`facePhoto\` provided without \`name\` + \`idNumber\`) |\
> \| \`502\` | Internal failure invoking the upstream — only thrown when something fails outside the per-check fan-out |\
> \
> Partial failures are intentional: a single misbehaving upstream sub-call should not\
> prevent the rest of the response from being delivered.\
> \
> \---\
> \
> \## Common patterns\
> \
> \*\*Lightweight identity check.\*\* Send \`name\` + \`idNumber\` only — runs \`identity.two-factor\`\
> and \`risk.criminal\` for the cost of two upstream calls.\
> \
> \*\*Document verification with face match.\*\* Send \`name\`, \`idNumber\`, \`idIssueDate\`,\
> \`idExpiryDate\`, \`facePhoto\` — runs \`identity.four-factor\` + \`identity.image\` plus\
> \`risk.criminal\`. The strongest non-mobile identity confirmation available.\
> \
> \*\*Mobile-anchored screening.\*\* Send \`mobile\` only — runs \`mobile.attribution\`, both\
> location lookups, and \`risk.fraud\`. Useful when only a phone number is known.\
> \
> \*\*Full KYC.\*\* Send \`name\`, \`idNumber\`, \`mobile\`, \`bankCardNumber\` (and optionally\
> \`idIssueDate\` / \`idExpiryDate\` / \`facePhoto\`) — fans out to up to 9 calls in parallel,\
> plus one extra call per entry in \`addressesToVerify\`.\
> \
> \*\*Address verification.\*\* Pass an \`addressesToVerify\[]\` entry to ask "is this address\
> near the user's \`work\` / \`residential\` / \`common\` area?". Each entry returns a\
> distance bucket (\`≤3km\` → \`>50km\`). Useful for verifying a user's stated address\
> against where their phone is actually used — runs alongside the standard mobile\
> location lookups, which return the actual cities.\
> \
> \*\*Staged verification.\*\* To gate later steps on earlier ones (e.g. only screen risk\
> and bank after identity passes), call the endpoint twice: first with \`name\` +\
> \`idNumber\` only, then re-call with the additional fields after you've inspected\
> the identity result. Each call is independent.\
> \
> \*\*Webhook Delivery:\*\* Provide \`callbackUrl\` to receive a \`POST\` with the completed report\
> when it is ready. The webhook body is a \[\`WebhookPayload\`]\(#/components/schemas/WebhookPayload)\
> containing the same data as a \`200\` response from \`/kyc/cn/poll\`.\
> The request includes \`X-Webhook-Event: kyc.cn.report.completed\` and \`X-Request-Id\` headers,\
> plus any custom headers supplied in \`callbackHeaders\`.\
> Polling via \`/kyc/cn/poll\` remains available regardless of whether a \`callbackUrl\` is provided.<br>

```json
{"openapi":"3.1.0","info":{"title":"Fill Easy Services","version":"1.0.0"},"tags":[{"name":"KYC China","description":"KYC verification for mainland China citizens — identity, mobile, risk, and bank checks\nagainst Ministry of Public Security, telecom carrier, and banking records.\n\n## Single endpoint, smart fan-out\n\nYou send one request to [`POST /kyc/cn/request`](#tag/KYC-China/operation/kycCnRequest)\nwith whatever fields you have, then either receive the result via a webhook\n(pass `callbackUrl` in the request) or poll\n[`POST /kyc/cn/poll`](#tag/KYC-China/operation/kycCnPoll) until the result is ready. The service inspects the request, picks the strongest\nverification variant on each axis (e.g. four-factor instead of two-factor when ID dates\nare present), and runs every eligible sub-check in parallel against the upstream sources.\n\nThe merged response tells you, per category, whether the person matched, plus an\nexecution `summary` so you can tell at a glance which checks ran, which matched, which\ncame back empty, and which errored.\n\n## What can be verified\n\n| Category | Verifies | Required upstream fields |\n|---|---|---|\n| **Identity** | Name + ID card pair belongs to a real registered citizen | `name`, `idNumber` |\n| **Identity (with validity)** | As above, plus the issue/expiry dates match the on-file record | `+ idIssueDate`, `idExpiryDate` |\n| **Identity (face match)** | As above, plus the supplied photo matches the photo on file | `+ facePhoto` |\n| **Identity-mobile** | The mobile number is registered to that person at that ID | `name`, `idNumber`, `mobile` (any subset) |\n| **Mobile attribution** | Carrier, registered province, and registered city of the SIM | `mobile` |\n| **Mobile location** | Most-active work-hours city + most-active night-hours city (last 3 months) | `mobile` |\n| **Address verification** | Distance segment (≤3km … >50km) between a supplied address and the mobile's `common` / `work` / `residential` area | `mobile`, `addressesToVerify[]` |\n| **Risk — fraud** | Presence on fraud, gambling, and money-mule blacklists; severity 0-3 | `mobile` or `idNumber` |\n| **Risk — criminal** | Police-record flags: criminal offender, drug-related, fugitive, etc. | `name`, `idNumber` |\n| **Bank** | A bank card belongs to the person identified by name + ID (+ mobile) | `name`, `idNumber`, `bankCardNumber` (+ optional `mobile`) |\n\n## Data sources & residency\n\nAll upstream calls go through a Beijing-based proxy and query official sources:\nMinistry of Public Security (identity & criminal), telecom carriers (mobile & location),\nUnionPay member banks (bank verification), and the national anti-fraud blacklist (risk).\nNo personal data is stored by Fill Easy after the response is returned.\n\n## Cost & rate limits\n\nEach sub-check is a separate billable upstream call. A request with `name`, `idNumber`,\n`mobile`, and `bankCardNumber` fans out to **9 calls** in parallel (worst case without\n`addressesToVerify`). Each entry in `addressesToVerify` adds one further call. To narrow\nwhat runs, simply omit the inputs you don't want to verify — every sub-check whose\nrequired fields are present always fires.\n"}],"servers":[{"url":"sandbox.staging-api.fill-easy.com"}],"security":[{"ClientID":[],"ClientSecret":[]}],"components":{"securitySchemes":{"ClientID":{"type":"apiKey","description":"Client ID in x-client-id header.","name":"x-client-id","in":"header"}}},"paths":{"/kyc/cn/request":{"post":{"tags":["KYC China"],"summary":"KYC China verification - Request","description":"Verify a Chinese citizen's identity, mobile, risk profile, and/or bank card in a\nsingle request. You send whatever fields you have; the service decides which\nsub-checks to run, fans them out in parallel against the upstream sources\n(Ministry of Public Security, telecom carriers, banks, blacklists), and merges\nthe results into one response.\n\n---\n\n## Selecting which products to run\n\nBy default the endpoint runs **every** sub-check whose required inputs are\npresent. To restrict the request to a specific set of products, supply `run`\nwith an array of product numbers from the\n[KYC Mainland China catalogue](#tag/KYC-China). For example, `run: [\"1\", \"8.3\", \"25\"]`\nruns only ID & Name verification, bank account 4-factor verification, and litigation\nrecords. Product numbers are strings — bank verification is addressed per factor\nlevel (`8.1`, `8.2.1`, `8.3`).\n\n| Product # | Name | Sub-checks |\n|---|---|---|\n| `1` | ID & Name Verify | `identity.two-factor` |\n| `2` | ID, Name & Face Verify | `identity.image` |\n| `3` | ID, Name & Date Verify | `identity.four-factor` |\n| `4` | ID, Name, Date & Face Verify | `identity.four-factor` + `identity.image` |\n| `8.1` | Bank Account 2FV (name + card) | `bank.two-factor` |\n| `8.2.1` | Bank Account 3FV (name + card + ID) | `bank.three-factor` |\n| `8.3` | Bank Account 4FV (name + card + ID + mobile) | `bank.four-factor` |\n| `11` | Telecom 2FV | `identity.name-mobile`, `identity.id-mobile` |\n| `12` | Telecom 3FV | `identity.three-factor` |\n| `15` | Telecom Operator Location | `mobile.attribution`, `mobile.location-work`, `mobile.location-residential` |\n| `17` | Phone-Address Association | `mobile.address-verify[N]` (one per `addressesToVerify` entry) |\n| `24` | Risk Score for Adverse Records | `risk.fraud` |\n| `25` | Litigation Record Verification | `litigation.records` |\n| `27` | Credit Risk Validation | `risk.criminal` |\n\nWhen `run` is omitted or empty, the default fan-out applies and the smart-selection\nrules below avoid paying for redundant calls. When `run` is supplied, each requested\nproduct fires independently if its required inputs are present — so asking for both\nproduct `1` (two-factor) and product `3` (four-factor) runs **both**, bypassing the\ndefault upgrade rule.\n\n---\n\n## How the request fans out\n\nThe endpoint runs every sub-check whose required inputs are present in your request,\nwith two **smart-selection rules** that avoid paying for redundant calls:\n\n- On the **identity-document axis**, the strongest available variant runs and\n  weaker ones are skipped. Specifically, `identity.four-factor` (which verifies the\n  ID's validity dates in addition to name + ID) supersedes `identity.two-factor`\n  when both `idIssueDate` and `idExpiryDate` are supplied.\n- On the **identity-mobile axis**, the strongest available variant runs.\n  `identity.three-factor` (name + ID + mobile) supersedes `identity.name-mobile`\n  and `identity.id-mobile` when all three fields are present.\n- On the **bank axis**, the default fan-out runs only the strongest eligible\n  variant: `bank.four-factor` (name + ID + card + mobile) supersedes\n  `bank.three-factor` (name + ID + card), which supersedes `bank.two-factor`\n  (name + card). When you select bank products explicitly via `run`, each one\n  fires independently — `run: [\"8.1\", \"8.3\"]` runs both 2-factor and 4-factor,\n  and each is reported in its own `bank2f` / `bank3f` / `bank4f` field.\n\nOther sub-checks run independently — face match (`identity.image`) is on a\nseparate axis from document verification, mobile lookups, and risk checks.\n\nEvery sub-check whose required fields are present **always runs**. There is no\nopt-out — if you don't want a category to fire, simply don't supply its inputs.\n\n### Sub-check eligibility\n\n| Sub-check | Required fields | What it verifies |\n|---|---|---|\n| `identity.two-factor` | `name`, `idNumber` | Name + ID pair exists in MPS records |\n| `identity.four-factor` | `+ idIssueDate`, `idExpiryDate` | As above, plus dates match the on-file record |\n| `identity.image` | `name`, `idNumber`, `facePhoto` | Photo matches the MPS face on file |\n| `identity.name-mobile` | `name`, `mobile` | Mobile is registered to that name |\n| `identity.id-mobile` | `idNumber`, `mobile` | Mobile is registered to that ID |\n| `identity.three-factor` | `name`, `idNumber`, `mobile` | All three are tied to one person |\n| `mobile.attribution` | `mobile` | Carrier, registered province, city |\n| `mobile.location-work` | `mobile` | Most-active city during 07:00-19:00 weekdays (last 3 months) |\n| `mobile.location-residential` | `mobile` | Most-active city during 21:00-07:00 (last 3 months) |\n| `mobile.address-verify[N]` | `mobile` + entry in `addressesToVerify` | Distance segment between the supplied address and the mobile's recorded `common` / `work` / `residential` area. One sub-check fires per entry, indexed `[0]`, `[1]`, … |\n| `risk.fraud` | `mobile` or `idNumber` | Fraud / gambling / money-mule blacklist hits |\n| `risk.criminal` | `name`, `idNumber` | Police record flags (criminal, drug, fugitive, etc.) |\n| `bank.two-factor` | `name`, `bankCardNumber` | Card is registered under that name |\n| `bank.three-factor` | `+ idNumber` | As above, plus the card belongs to that ID |\n| `bank.four-factor` | `+ mobile` | As above, plus mobile is the card's registered number |\n\n---\n\n## Reading the response\n\nThe response always contains a `summary` object. Each sub-category (`identity`,\n`mobile`, `risk`, and the `bank2f` / `bank3f` / `bank4f` fields) is **present only\nif its sub-check ran and returned data**. Categories with only errored or\nnot-found outcomes are omitted.\n\n### `summary` buckets\n\nEvery attempted sub-check appears in `summary.ran`. From there it lands in **exactly\none** of these buckets:\n\n| Bucket | Meaning |\n|---|---|\n| `matched` | An identity- or bank-axis check returned `match` |\n| `unmatched` | An identity- or bank-axis check returned `no match` (the call ran successfully; the answer was negative) |\n| `notFound` | The upstream had no record for the input — informational lookups or blacklists routinely return this when nothing is on file |\n| `errored` | The call itself failed (timeout, upstream service error, network). Carries `{ check, error }` for diagnostics |\n\nMobile lookups (`mobile.attribution`, `mobile.location-*`) and risk lookups\n(`risk.fraud`, `risk.criminal`) have no match/no-match semantics. They appear in\n`ran` and either `notFound` or `errored` — never in `matched`/`unmatched`.\n\n### Result semantics by category\n\n- **Identity** — array of `{ type, result, verification }`. Treat `match` as a\n  positive identity signal. `no match` from `three-factor` typically means the\n  mobile isn't tied to that person; pair it with the result from `two-factor` /\n  `four-factor` (also returned) to disambiguate document mismatch from mobile mismatch.\n- **Mobile** — flat object with whatever the lookups returned. Fields are absent\n  when their underlying call returned no data; check `summary.notFound` to tell\n  \"no data available\" from \"we never asked\".\n- **Risk** — `risk.fraud` returns a fixed list of four risk types (fraud, gambling\n  operator, gambling player, money mule) each with severity `None` / `Low` /\n  `Medium` / `High`. `risk.criminal` returns a flat boolean map. `isNormal: null`\n  (rather than a boolean) means the check could not complete and the records are\n  not authoritative.\n- **Bank** — up to three independent fields, one per variant that ran:\n  `bank2f` (name + card), `bank3f` (name + card + ID), and `bank4f` (name + card +\n  ID + mobile). Each holds `match` / `no match` / `not found` and is present only\n  when that variant ran. The default fan-out populates a single field (strongest\n  eligible); selecting multiple bank products via `run` populates one field each.\n\n---\n\n## Errors\n\n| Code | Meaning |\n|---|---|\n| `200` | Always returned when at least one sub-check was eligible. Per-check failures appear in `summary.errored`, never as a 4xx/5xx |\n| `400` | No sub-checks were eligible with the supplied fields (e.g. only `facePhoto` provided without `name` + `idNumber`) |\n| `502` | Internal failure invoking the upstream — only thrown when something fails outside the per-check fan-out |\n\nPartial failures are intentional: a single misbehaving upstream sub-call should not\nprevent the rest of the response from being delivered.\n\n---\n\n## Common patterns\n\n**Lightweight identity check.** Send `name` + `idNumber` only — runs `identity.two-factor`\nand `risk.criminal` for the cost of two upstream calls.\n\n**Document verification with face match.** Send `name`, `idNumber`, `idIssueDate`,\n`idExpiryDate`, `facePhoto` — runs `identity.four-factor` + `identity.image` plus\n`risk.criminal`. The strongest non-mobile identity confirmation available.\n\n**Mobile-anchored screening.** Send `mobile` only — runs `mobile.attribution`, both\nlocation lookups, and `risk.fraud`. Useful when only a phone number is known.\n\n**Full KYC.** Send `name`, `idNumber`, `mobile`, `bankCardNumber` (and optionally\n`idIssueDate` / `idExpiryDate` / `facePhoto`) — fans out to up to 9 calls in parallel,\nplus one extra call per entry in `addressesToVerify`.\n\n**Address verification.** Pass an `addressesToVerify[]` entry to ask \"is this address\nnear the user's `work` / `residential` / `common` area?\". Each entry returns a\ndistance bucket (`≤3km` → `>50km`). Useful for verifying a user's stated address\nagainst where their phone is actually used — runs alongside the standard mobile\nlocation lookups, which return the actual cities.\n\n**Staged verification.** To gate later steps on earlier ones (e.g. only screen risk\nand bank after identity passes), call the endpoint twice: first with `name` +\n`idNumber` only, then re-call with the additional fields after you've inspected\nthe identity result. Each call is independent.\n\n**Webhook Delivery:** Provide `callbackUrl` to receive a `POST` with the completed report\nwhen it is ready. The webhook body is a [`WebhookPayload`](#/components/schemas/WebhookPayload)\ncontaining the same data as a `200` response from `/kyc/cn/poll`.\nThe request includes `X-Webhook-Event: kyc.cn.report.completed` and `X-Request-Id` headers,\nplus any custom headers supplied in `callbackHeaders`.\nPolling via `/kyc/cn/poll` remains available regardless of whether a `callbackUrl` is provided.\n","operationId":"kycCnRequest","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","description":"All fields are optional. The endpoint runs every sub-check whose required\nfields are present (see the *Sub-check eligibility* table above). At least\none sub-check must be eligible — otherwise a `400` is returned.\n","properties":{"name":{"type":"string","description":"Full legal name in **Chinese characters** (simplified). Must match the\nname on the resident ID card exactly. Latin pinyin transliterations are\nnot accepted by the upstream.\n\nEnables: identity-document checks, mobile-cross checks, bank checks, criminal records.\n"},"idNumber":{"type":"string","description":"18-digit Chinese Resident Identity Card number (居民身份证号码).\nThe 18th character may be `X` for older IDs.\n\nEnables: identity-document checks, mobile-cross checks, bank checks, fraud, criminal records.\n","pattern":"^[0-9]{17}[0-9Xx]$"},"idIssueDate":{"type":"string","description":"ID card issue date in `YYYYMMDD` format (no separators). Found on the\nback of the physical card under 签发日期.\n\nPair with `idExpiryDate` to upgrade `identity.two-factor` to the stronger\n`identity.four-factor` check that also validates the on-file dates.\n","pattern":"^[0-9]{8}$"},"idExpiryDate":{"type":"string","description":"ID card expiry date in `YYYYMMDD` format, or the literal string `长期`\nwhen the card has no expiry (issued to citizens 46+ in some cases).\nFound on the back of the physical card under 有效期限.\n"},"facePhoto":{"type":"string","description":"Base64-encoded facial photo. **Do not include the `data:image/...;base64,`\nprefix** — only the raw base64 payload.\n\nRecommended: clear front-facing photo, no occlusions, JPEG/PNG, ≤2 MB.\nEnables `identity.image`, which compares the photo against the MPS face\non file for the supplied name + ID. Requires `name` and `idNumber`.\n"},"mobile":{"type":"string","description":"11-digit mainland China mobile number. **No country code, no `+86`,\nno spaces.** First two digits must be `13`-`19`.\n\nEnables: mobile lookups, mobile-cross identity checks, fraud screening,\nbank `four-factor`. Mobile alone is enough to run mobile/risk lookups\nwithout any identity fields.\n","pattern":"^1[3-9][0-9]{9}$"},"bankCardNumber":{"type":"string","description":"Bank card number — debit or credit. Digits only, no spaces. Enables\n`bank.two-factor` (with `name`), `bank.three-factor` (also with `idNumber`),\nor `bank.four-factor` (also with `mobile`).\n"},"addressesToVerify":{"type":"array","description":"Addresses to verify against the mobile's recorded location patterns.\nEach entry asks the upstream to compute the distance segment between\nthe supplied `address` and the mobile's most-active area for the\nselected `type`. Requires `mobile`.\n\nEach entry produces one `mobile.address-verify[N]` sub-check, where\n`N` is the array index. Results appear in the response under\n`mobile.addressVerifications[]` in the same order.\n\nUp to ~10 entries per request — each is a separate billable call.\n","items":{"type":"object","required":["type","city","address"],"properties":{"type":{"type":"string","enum":["common","work","residential"],"description":"Which of the mobile's recorded locations to compare against:\n- `common` — area with overall highest mobile activity\n- `work` — most active area during 07:00-19:00 weekdays\n- `residential` — most active area during 21:00-07:00\n"},"city":{"type":"string","description":"City the address is located in (Chinese characters)."},"address":{"type":"string","description":"Street-level address (Chinese characters)."}}}},"run":{"type":"array","description":"Restrict the request to a specific set of products from the KYC\nMainland China catalogue. Product numbers are strings (e.g. `\"1\"`,\n`\"8.3\"`). When omitted or empty, every eligible sub-check runs\n(smart-selection rules apply). When supplied, only the listed\nproducts fire — and each runs independently, bypassing the default\nsupersession rules between products `1`/`3`, `11`/`12`, and the\nbank variants. Selecting multiple bank products runs each one and\nreports it in its own `bank2f` / `bank3f` / `bank4f` field.\n\nSupported values: `\"1\", \"2\", \"3\", \"4\", \"8.1\", \"8.2.1\", \"8.3\", \"11\",\n\"12\", \"15\", \"17\", \"24\", \"25\", \"27\"`. See the *Selecting which\nproducts to run* section above for the product-number → sub-check\nmapping.\n\nAny other value returns a `400` with `requestId` and a message\ndistinguishing **unimplemented** (catalogued but no upstream yet —\n`5, 6, 7, 8.2.2, 9.1, 9.2.1, 9.2.2, 9.3, 10, 13, 14, 16, 18–23, 26,\n28–35`) from **unknown** (outside the catalogue entirely).\n","items":{"type":"string"}},"callbackUrl":{"type":"string","format":"uri","pattern":"^https://.+","description":"HTTPS URL to receive a webhook POST when the report is ready.\nWhen provided, the completed report (same payload as a `200` response from `/kyc/cn/poll`)\nis delivered to this URL.\nPolling remains available as a fallback.\n"},"callbackHeaders":{"type":"object","additionalProperties":{"type":"string"},"description":"Custom HTTP headers to include in the webhook request.\nUse this to pass authentication or any other headers your endpoint requires\n(e.g. `{\"Authorization\": \"Bearer <token>\", \"X-Api-Key\": \"...\"}`).\n"}}}}}},"responses":{"200":{"description":"KYC verification request initiated. Use the returned token with `/kyc/cn/poll` to fetch the result.","content":{"application/json":{"schema":{"type":"object","required":["token","requestId"],"properties":{"token":{"type":"string","description":"JWT token encoding the request — pass it to `/kyc/cn/poll` until a `200` response\nis returned (typically within 10-30 seconds for a full KYC fan-out).\n"},"requestId":{"type":"string","description":"Stable identifier for this request. Returned on both `200` and `400`\nresponses for tracing/support. Prefixed `KYC_` followed by 12\nrandom characters.\n"}}}}}},"400":{"description":"Returned in two cases:\n- No sub-checks were eligible with the provided fields (e.g. supplying only\n  `facePhoto` without `name` and `idNumber`, or an empty request body).\n- `run` contains a product number that is not in the supported set\n  (`1, 2, 3, 4, 8, 11, 12, 15, 17, 24, 25, 27`).\n\nThe body always contains `{ \"message\": \"...\", \"requestId\": \"KYC_...\" }` —\nthe `requestId` is logged in the tracker so support can correlate the\nrejection with the originating call.\n","content":{"application/json":{"schema":{"type":"object","required":["message","requestId"],"properties":{"message":{"type":"string"},"requestId":{"type":"string"}}}}}},"502":{"description":"Internal failure invoking the upstream verification service before any sub-check\ncould run. Per-check failures during fan-out do **not** produce a 502 — they\nappear in `summary.errored` inside a successful 200 response.\n"}}}}}}
```

## KYC China verification - Poll

> Check the status of a KYC verification request initiated via\
> \[\`POST /kyc/cn/request\`]\(#tag/KYC-China/operation/kycCnRequest).\
> Returns \`202\` while the verification is still running, and \`200\` with\
> the full result when complete.\
> \
> Verification typically completes within 10-30 seconds depending on the\
> number of sub-checks and PDF rendering. Poll every 2-3 seconds.\
> \
> See the \[\`/kyc/cn/request\`]\(#tag/KYC-China/operation/kycCnRequest) documentation\
> for the response shape semantics (sub-check eligibility, summary buckets,\
> category-by-category interpretation).<br>

```json
{"openapi":"3.1.0","info":{"title":"Fill Easy Services","version":"1.0.0"},"tags":[{"name":"KYC China","description":"KYC verification for mainland China citizens — identity, mobile, risk, and bank checks\nagainst Ministry of Public Security, telecom carrier, and banking records.\n\n## Single endpoint, smart fan-out\n\nYou send one request to [`POST /kyc/cn/request`](#tag/KYC-China/operation/kycCnRequest)\nwith whatever fields you have, then either receive the result via a webhook\n(pass `callbackUrl` in the request) or poll\n[`POST /kyc/cn/poll`](#tag/KYC-China/operation/kycCnPoll) until the result is ready. The service inspects the request, picks the strongest\nverification variant on each axis (e.g. four-factor instead of two-factor when ID dates\nare present), and runs every eligible sub-check in parallel against the upstream sources.\n\nThe merged response tells you, per category, whether the person matched, plus an\nexecution `summary` so you can tell at a glance which checks ran, which matched, which\ncame back empty, and which errored.\n\n## What can be verified\n\n| Category | Verifies | Required upstream fields |\n|---|---|---|\n| **Identity** | Name + ID card pair belongs to a real registered citizen | `name`, `idNumber` |\n| **Identity (with validity)** | As above, plus the issue/expiry dates match the on-file record | `+ idIssueDate`, `idExpiryDate` |\n| **Identity (face match)** | As above, plus the supplied photo matches the photo on file | `+ facePhoto` |\n| **Identity-mobile** | The mobile number is registered to that person at that ID | `name`, `idNumber`, `mobile` (any subset) |\n| **Mobile attribution** | Carrier, registered province, and registered city of the SIM | `mobile` |\n| **Mobile location** | Most-active work-hours city + most-active night-hours city (last 3 months) | `mobile` |\n| **Address verification** | Distance segment (≤3km … >50km) between a supplied address and the mobile's `common` / `work` / `residential` area | `mobile`, `addressesToVerify[]` |\n| **Risk — fraud** | Presence on fraud, gambling, and money-mule blacklists; severity 0-3 | `mobile` or `idNumber` |\n| **Risk — criminal** | Police-record flags: criminal offender, drug-related, fugitive, etc. | `name`, `idNumber` |\n| **Bank** | A bank card belongs to the person identified by name + ID (+ mobile) | `name`, `idNumber`, `bankCardNumber` (+ optional `mobile`) |\n\n## Data sources & residency\n\nAll upstream calls go through a Beijing-based proxy and query official sources:\nMinistry of Public Security (identity & criminal), telecom carriers (mobile & location),\nUnionPay member banks (bank verification), and the national anti-fraud blacklist (risk).\nNo personal data is stored by Fill Easy after the response is returned.\n\n## Cost & rate limits\n\nEach sub-check is a separate billable upstream call. A request with `name`, `idNumber`,\n`mobile`, and `bankCardNumber` fans out to **9 calls** in parallel (worst case without\n`addressesToVerify`). Each entry in `addressesToVerify` adds one further call. To narrow\nwhat runs, simply omit the inputs you don't want to verify — every sub-check whose\nrequired fields are present always fires.\n"}],"servers":[{"url":"sandbox.staging-api.fill-easy.com"}],"security":[{"ClientID":[],"ClientSecret":[]}],"components":{"securitySchemes":{"ClientID":{"type":"apiKey","description":"Client ID in x-client-id header.","name":"x-client-id","in":"header"}},"schemas":{"Token":{"type":"string","pattern":"^[A-Za-z0-9-_]+\\.[A-Za-z0-9-_]+\\.[A-Za-z0-9-_]*$","description":"JWT token"},"LitigationStats":{"type":"object","description":"Aggregated counts and amounts for a litigation category (or all categories,\nwhen used as the `overall` block). Counts are case counts; amounts are in CNY.\n","required":["total"],"properties":{"total":{"type":"integer","description":"Total cases."},"open":{"type":"integer","description":"Open (unresolved) cases."},"closed":{"type":"integer","description":"Closed cases."},"asPlaintiff":{"type":"integer","description":"Cases where the subject was the plaintiff."},"asDefendant":{"type":"integer","description":"Cases where the subject was the defendant."},"asThirdParty":{"type":"integer","description":"Cases where the subject was a third party."},"totalAmount":{"type":"number","description":"Total monetary amount involved (CNY)."},"openAmount":{"type":"number","description":"Amount tied to open cases (CNY)."},"closedAmount":{"type":"number","description":"Amount tied to closed cases (CNY)."},"causeDistribution":{"type":"string","description":"Distribution of case causes, formatted by upstream as `Cause(count), Cause(count)`."},"locationDistribution":{"type":"string","description":"Distribution by case location."},"yearDistribution":{"type":"string","description":"Distribution by filing year."},"closingMethodDistribution":{"type":"string","description":"Distribution by closing method (e.g. judgment, mediation)."}}},"LitigationCategory":{"type":"object","required":["cases","stats"],"properties":{"cases":{"type":"array","items":{"$ref":"#/components/schemas/LitigationCase"}},"stats":{"$ref":"#/components/schemas/LitigationStats"}}},"LitigationCase":{"type":"object","description":"A single litigation record. Always includes the structural fields (case number,\ncourt, stage, parties). Optional fields are present only when the upstream service\nreturns them — criminal-specific fields (`charges`, `crimeAmount`) are absent for\nnon-criminal cases.\n","required":["caseType","caseNumber","court","courtLevel","stage","procedure","location","cause","partyRole","parties"],"properties":{"caseType":{"type":"string","description":"Case type label (e.g. `Civil First Instance`, `Criminal First Instance`, `Property Preservation Execution`)."},"caseNumber":{"type":"string"},"court":{"type":"string"},"courtLevel":{"type":"string","description":"Court level (Basic Court / Intermediate / High / Supreme)."},"stage":{"type":"string","description":"Case progress stage as returned by upstream (e.g. `Open`, `Closed`)."},"procedure":{"type":"string","description":"Trial procedure (First Instance, Second Instance, Retrial, Execution)."},"location":{"type":"string"},"cause":{"type":"string"},"partyRole":{"type":"string","description":"Subject's role in this case."},"parties":{"type":"array","items":{"$ref":"#/components/schemas/LitigationParty"}},"filingDate":{"type":"string","format":"date"},"closingDate":{"type":"string","format":"date"},"causeDetail":{"type":"string","description":"Full cause taxonomy path (comma-delimited from broad to specific)."},"closingMethod":{"type":"string","description":"How the case was closed (Judgment, Mediation, Withdrawal, etc.)."},"amount":{"type":"number","description":"Closing subject amount (CNY)."},"victoryEstimate":{"type":"string","description":"Upstream estimate of the subject's outcome (Won / Lost / Partial / Unknown)."},"charges":{"type":"string","description":"Criminal charges (criminal cases only)."},"chargesDetail":{"type":"string","description":"Full charge taxonomy path (criminal cases only)."},"crimeAmount":{"type":"number","description":"Crime amount (criminal cases only, CNY)."}}},"LitigationParty":{"type":"object","required":["name","role","type"],"properties":{"name":{"type":"string"},"role":{"type":"string","description":"Litigation status (e.g. Plaintiff, Defendant, Person Subject to Application, Third Party)."},"type":{"type":"string","description":"Party type (e.g. Natural Person, Enterprise Organization)."}}}}},"paths":{"/kyc/cn/poll":{"post":{"tags":["KYC China"],"summary":"KYC China verification - Poll","description":"Check the status of a KYC verification request initiated via\n[`POST /kyc/cn/request`](#tag/KYC-China/operation/kycCnRequest).\nReturns `202` while the verification is still running, and `200` with\nthe full result when complete.\n\nVerification typically completes within 10-30 seconds depending on the\nnumber of sub-checks and PDF rendering. Poll every 2-3 seconds.\n\nSee the [`/kyc/cn/request`](#tag/KYC-China/operation/kycCnRequest) documentation\nfor the response shape semantics (sub-check eligibility, summary buckets,\ncategory-by-category interpretation).\n","operationId":"kycCnPoll","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["token"],"properties":{"token":{"$ref":"#/components/schemas/Token"}}}}}},"responses":{"200":{"description":"KYC China result. Categories are present only when at least one of their sub-checks ran.","content":{"application/json":{"schema":{"type":"object","required":["reportMetadata","summary","submitted","pdfUrl","pdfFileName"],"properties":{"reportMetadata":{"type":"object","required":["status"],"properties":{"status":{"type":"string","enum":["completed"]}}},"submitted":{"type":"object","description":"Masked echo of the inputs that were submitted, for audit and report\nrendering. Each field is present only if it was supplied in the\nrequest. Sensitive values are masked — the first two characters are\nkept and the rest replaced with asterisks of the same length.\n","properties":{"name":{"type":"string"},"idNumber":{"type":"string"},"idIssueDate":{"type":"string"},"idExpiryDate":{"type":"string"},"facePhoto":{"type":"string","description":"Literal `provided` when a face photo was supplied; otherwise omitted."},"mobile":{"type":"string"},"bankCardNumber":{"type":"string"},"addressesToVerify":{"type":"array","items":{"type":"object","required":["type","city","address"],"properties":{"type":{"type":"string","enum":["common","work","residential"]},"city":{"type":"string"},"address":{"type":"string"}}}}}},"pdfUrl":{"type":"string","format":"uri","description":"Presigned URL to download a PDF version of this report. Valid for 7 days.\nThe underlying object is deleted after 30 days by bucket lifecycle rule.\n"},"pdfFileName":{"type":"string","description":"Suggested filename for the PDF download."},"summary":{"type":"object","required":["ran","matched","unmatched","notFound","errored"],"properties":{"ran":{"type":"array","description":"Every sub-check that was attempted.","items":{"type":"string"}},"matched":{"type":"array","description":"Identity and bank checks that returned `match`.","items":{"type":"string"}},"unmatched":{"type":"array","description":"Identity and bank checks that returned `no match`.","items":{"type":"string"}},"notFound":{"type":"array","description":"Sub-checks where the upstream had no data on file.","items":{"type":"string"}},"errored":{"type":"array","description":"Sub-checks where the upstream call itself failed.","items":{"type":"object","required":["check","error"],"properties":{"check":{"type":"string"},"error":{"type":"string"}}}}}},"identity":{"type":"array","description":"Present when at least one identity check ran. Each entry corresponds to one sub-check.","items":{"type":"object","required":["type","result","verification"],"properties":{"type":{"type":"string","enum":["two-factor","four-factor","image","name-mobile","id-mobile","three-factor"]},"result":{"type":"string","enum":["match","no match","not found"]},"verification":{"type":"string","description":"Human-readable description of what was verified."}}}},"mobile":{"type":"object","description":"Present when at least one mobile lookup returned data.","properties":{"carrier":{"type":"string"},"province":{"type":"string"},"city":{"type":"string"},"workLocation":{"type":"string","description":"Most active city during weekday work hours (07:00-19:00)."},"residentialLocation":{"type":"string","description":"Most active city during night hours (21:00-07:00)."},"addressVerifications":{"type":"array","description":"Per-entry results for each address supplied in\n`addressesToVerify[]`, in the same order as the input. The\noriginal `type`, `city`, and `address` are echoed back so\ncallers can correlate results to inputs without tracking the\nindex themselves.\n\nThe `distance` field is **present only when the upstream\nreturned a match** — its absence signals \"no data on file\"\n(the entry is also listed in `summary.notFound`). Errored\nentries are omitted from this array entirely; check\n`summary.errored` for diagnostics.\n","items":{"type":"object","required":["type","city","address"],"properties":{"type":{"type":"string","enum":["common","work","residential"]},"city":{"type":"string"},"address":{"type":"string"},"distance":{"type":"string","enum":["≤3km","≤5km","≤10km","≤20km","≤30km","≤50km",">50km"],"description":"Distance segment between the supplied address and the\nmobile's recorded location for the chosen `type`.\n"}}}}}},"risk":{"type":"object","description":"Present when at least one risk check ran.","properties":{"fraud":{"type":"array","items":{"type":"object","required":["type","level"],"properties":{"type":{"type":"string"},"level":{"type":"string","enum":["None","Low","Medium","High"]}}}},"criminal":{"type":"object","required":["isNormal","records"],"properties":{"isNormal":{"type":"boolean","nullable":true,"description":"`true` when no risk events are recorded; `false` when records exist;\n`null` when verification could not complete.\n"},"records":{"type":"object","additionalProperties":{"type":"boolean"},"description":"Map of human-readable record category to whether it applies."}}}}},"bank2f":{"type":"string","enum":["match","no match","not found"],"description":"Result of the 2-factor bank check (name + card, product `8.1`).\nPresent only when the 2FV variant ran.\n"},"bank3f":{"type":"string","enum":["match","no match","not found"],"description":"Result of the 3-factor bank check (name + card + ID, product `8.2.1`).\nPresent only when the 3FV variant ran.\n"},"bank4f":{"type":"string","enum":["match","no match","not found"],"description":"Result of the 4-factor bank check (name + card + ID + mobile, product\n`8.3`). Present only when the 4FV variant ran.\n"},"litigation":{"type":"object","description":"Judicial litigation records aggregated across civil, criminal,\nadministrative, preservation, execution, and bankruptcy case types.\nEach category is present only when at least one case exists. `overall`\nis the cross-category statistics block returned by the upstream service.\n","properties":{"overall":{"$ref":"#/components/schemas/LitigationStats"},"civil":{"$ref":"#/components/schemas/LitigationCategory"},"criminal":{"$ref":"#/components/schemas/LitigationCategory"},"administrative":{"$ref":"#/components/schemas/LitigationCategory"},"preservation":{"$ref":"#/components/schemas/LitigationCategory"},"execution":{"$ref":"#/components/schemas/LitigationCategory"},"bankruptcy":{"$ref":"#/components/schemas/LitigationCategory"}}}}}}}},"202":{"description":"KYC verification still processing — keep polling every 2-3 seconds.","content":{"application/json":{"schema":{"type":"object","required":["reportMetadata"],"properties":{"reportMetadata":{"type":"object","required":["status"],"properties":{"status":{"type":"string","enum":["processing"]}}}}}}}},"400":{"description":"Invalid or expired token."}}}}}}
```


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.fill-easy.com/kyc-china.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
