From ca6589ffc288e022a83ef25e069548f068f05a96 Mon Sep 17 00:00:00 2001 From: jaymantri Date: Tue, 8 Sep 2026 15:24:53 -0700 Subject: [PATCH 1/2] docs: refresh sandbox verification suffix behavior Match the sandbox customer-verification behavior shipped in lightsparkdev/webdev: - #34311 Unregulated preset and the Skip verification paperwork switch - #34343 Business 003 resolves UNVERIFIED - #34357 Verification webhooks: IN_PROGRESS then one outcome event - #34451 Switch ON: businesses resolve from the suffix at create Co-authored-by: Cursor --- .../snippets/kyc/kyb-sandbox-suffixes.mdx | 25 +++++++++---------- mintlify/snippets/kyc/kyc-unregulated.mdx | 2 +- mintlify/snippets/sandbox-verification.mdx | 22 ++++++++++------ 3 files changed, 27 insertions(+), 22 deletions(-) diff --git a/mintlify/snippets/kyc/kyb-sandbox-suffixes.mdx b/mintlify/snippets/kyc/kyb-sandbox-suffixes.mdx index e033296c2..20b1ccfcb 100644 --- a/mintlify/snippets/kyc/kyb-sandbox-suffixes.mdx +++ b/mintlify/snippets/kyc/kyb-sandbox-suffixes.mdx @@ -1,19 +1,18 @@ -Business customers are always created with `kybStatus: UNVERIFIED`. The **last 3 characters** of `businessInfo.registrationNumber` decide what happens when the business is verified — whether you submit with `POST /verifications` or send the business through a hosted KYB link: +The **last 3 characters** of `businessInfo.registrationNumber` decide the business's `kybStatus`. The same suffix applies whether you submit with `POST /verifications` or the applicant completes the hosted flow. When that outcome applies depends on your platform: -| Suffix | Outcome | -|--------|---------| -| **003** | No auto-decision. Document and UBO verification run for real — the hosted flow asks for company documents and beneficial owners, and `POST /verifications` applies normal validation (`RESOLVE_ERRORS` until the data is complete). **Use this to test the link flow.** | -| **001** | Same as `003` — no auto-decision, normal validation applies | -| **002** | `kybStatus: REJECTED` (`verificationStatus: REJECTED`). Data and document validation is skipped only on a regulated platform or with **Skip verification paperwork** on; by default the packet is validated first | -| **Any other** | `kybStatus: APPROVED` (`verificationStatus: APPROVED`). Data and document validation is skipped only on a regulated platform or with **Skip verification paperwork** on; by default the packet is validated first | +- **Regulated platforms** — the business is `APPROVED` at creation. The suffix is not read, and **Skip verification paperwork** does not apply. +- **Unregulated platforms** (the default, with **Skip verification paperwork** off) — the business is created `UNVERIFIED` and stays there until you submit with `POST /verifications`. The packet is validated first. An incomplete submission returns `RESOLVE_ERRORS` whatever the suffix; the suffix decides the result once the submission is complete. +- **Unregulated platforms with Skip verification paperwork** turned on in the sandbox dashboard's Configuration — the suffix resolves the business at creation. No documents, beneficial owners, or `POST /verifications` call are needed. Creation emits the matching `CUSTOMER.KYB_*` webhook only; it creates no verification and emits no `VERIFICATION.*` event. Before the first `POST /verifications`, a `PATCH` that changes `registrationNumber` re-derives the status from the new suffix while the business is not final. On `POST /verifications`, the suffix is read before the packet check. -Business customers never resolve at creation — the outcome lands on the first verification submission, whether you make it with `POST /verifications` or the applicant completes the hosted flow. What happens on that submission depends on your platform: +| Suffix | Resolved `kybStatus` | Behavior on `POST /verifications` | +|--------|----------------------|-----------------------------------| +| **001** | `PENDING` | With a complete packet: `verificationStatus: IN_PROGRESS`, `kybStatus: PENDING`, and every beneficial owner `PENDING` — simulates a business waiting on review | +| **002** | `REJECTED` | Returns `400` once resolved — the business is terminally rejected | +| **003** | `UNVERIFIED` | `verificationStatus: RESOLVE_ERRORS` with a `POOR_QUALITY_DOCUMENT` error — simulates a correctable provider rejection. Change the suffix and resubmit to reach a final outcome | +| **Any other** | `APPROVED` | Returns `400` once resolved — the business is approved | -- **Unregulated platforms** (the default, with **Skip verification paperwork** off) — the packet is validated first. A business with incomplete data returns `RESOLVE_ERRORS` whatever its suffix, and the suffix resolves only once the submission is complete. -- **Regulated platforms**, and unregulated platforms with **Skip verification paperwork** on — a final suffix (`002` or any non-`001`/`003` value) resolves before the packet is validated, so it lands even on an incomplete submission. `001` and `003` still require a complete packet. +Once a business customer reaches `APPROVED` or `REJECTED`, that status is final: further `POST /verifications` calls return `400`, and changing `registrationNumber` does not re-derive it. Create a new business customer when you want to exercise a different outcome. -Where a final suffix resolves without packet validation — a regulated platform, or **Skip verification paperwork** on — a registration number that doesn't end in `001`, `002`, or `003` is **auto-approved at its first submission**. The hosted flow then has nothing left to verify, so it asks for no documents and no beneficial owners — which looks exactly like a broken KYB flow but isn't. Always use a `003` suffix when you want to exercise document and UBO collection. +With **Skip verification paperwork** on, a registration number that doesn't end in `001`, `002`, or `003` is **approved at creation**. The hosted flow then has nothing left to verify, so it asks for no documents and no beneficial owners — which looks exactly like a broken KYB flow but isn't. Always use a `003` suffix when you want to exercise document and UBO collection with the switch on. - -Once a business customer is approved or rejected, further `POST /verifications` calls return `400`. diff --git a/mintlify/snippets/kyc/kyc-unregulated.mdx b/mintlify/snippets/kyc/kyc-unregulated.mdx index c1cebb63e..fdc69032a 100644 --- a/mintlify/snippets/kyc/kyc-unregulated.mdx +++ b/mintlify/snippets/kyc/kyc-unregulated.mdx @@ -164,7 +164,7 @@ The response field is named `kycUrl` for both customer types; for a `BUSINESS` c -Testing the business flow in sandbox: by default the hosted flow collects the full packet, and a `businessInfo.registrationNumber` **not** ending in `001`, `002`, or `003` auto-approves the customer once that submission is complete. With **Skip verification paperwork** on, that suffix resolves before any packet validation, leaving the hosted flow nothing to verify — so it asks for no documents and no beneficial owners. Use a `003` suffix to exercise document and UBO collection. See [Sandbox testing](/api-reference/sandbox-testing). +Testing the business flow in sandbox: by default the hosted flow collects the full packet, and a `businessInfo.registrationNumber` **not** ending in `001`, `002`, or `003` auto-approves the customer once that submission is complete. With **Skip verification paperwork** on, that suffix approves the business at creation, leaving the hosted flow nothing to verify — so it asks for no documents and no beneficial owners. Use a `003` suffix to exercise document and UBO collection. See [Sandbox testing](/api-reference/sandbox-testing). ### Direct API Onboarding diff --git a/mintlify/snippets/sandbox-verification.mdx b/mintlify/snippets/sandbox-verification.mdx index e9a92cd26..a0d98a0d4 100644 --- a/mintlify/snippets/sandbox-verification.mdx +++ b/mintlify/snippets/sandbox-verification.mdx @@ -2,12 +2,15 @@ import KybSandboxSuffixes from '/snippets/kyc/kyb-sandbox-suffixes.mdx' In sandbox, you can trigger specific KYC/KYB verification outcomes using magic suffixes in customer and beneficial owner fields. These let you test different verification flows without waiting for real review. +On `POST /verifications`, the first submission emits `VERIFICATION.IN_PROGRESS` and then one `VERIFICATION.` event for the outcome. A later submission emits one `VERIFICATION.` event when its status or `errors` change. The matching `CUSTOMER.KYC_*` or `CUSTOMER.KYB_*` event fires when `kycStatus` or `kybStatus` changes. + ### Individual customer verification (KYC) The **last 3 characters** of the `fullName` on `POST /customers` (with `customerType: INDIVIDUAL`) decide the customer's `kycStatus`. When that outcome applies depends on your platform: - **Unregulated platforms** (the default, with **Skip verification paperwork** off) — the customer is created `UNVERIFIED` and stays there until you submit with `POST /verifications`. An incomplete submission returns `RESOLVE_ERRORS`; the suffix decides the result once the submission is complete. -- **Regulated platforms**, and unregulated platforms with **Skip verification paperwork** turned on in the sandbox dashboard's Configuration — the suffix resolves the customer at creation, with no documents required. `002` and any value other than `001`/`003` are terminal there. `001` and `003` land at `PENDING` and `UNVERIFIED`, which you can still submit for verification — and that submission carries the full data and document requirements below. +- **Unregulated platforms with Skip verification paperwork** turned on in the sandbox dashboard's Configuration — the suffix resolves the customer at creation, with no documents required. Creation emits the matching `CUSTOMER.KYC_*` webhook only; it creates no verification and emits no `VERIFICATION.*` event. `002` and any value other than `001`/`003` are terminal there. `001` and `003` land at `PENDING` and `UNVERIFIED`, which you can still submit for verification — and that submission carries the full data and document requirements below. Before the first `POST /verifications`, a `PATCH` that changes `fullName` re-derives the status from the new suffix while the customer is not final. +- **Regulated platforms** — the customer is `APPROVED` at creation. The suffix is not read, and **Skip verification paperwork** does not apply. | Suffix | Resolved `kycStatus` | Behavior on `POST /verifications` | |--------|----------------------|-----------------------------------| @@ -18,9 +21,9 @@ The **last 3 characters** of the `fullName` on `POST /customers` (with `customer Once a customer reaches `APPROVED` or `REJECTED`, that status is final: further `POST /verifications` calls return `400`, and renaming the customer does not re-derive it. Create a new customer when you want to exercise a different outcome. -Where the suffix resolves at creation, only `001` and `003` customers can be submitted for verification. Use any non-suffixed name to mint ready-to-transact approved customers, and a `001` name to exercise the full submission flow. +With **Skip verification paperwork** on, only `001` and `003` customers can be submitted for verification. Use any non-suffixed name to mint ready-to-transact approved customers, and a `001` name to exercise the full submission flow. -Where a submission is required — the default unregulated path, and `001`/`003` on any path — it carries the same data requirements as production: full name, birth date, nationality, `idType` + `identifier`, address, and an identity document uploaded via `POST /documents`. Anything missing comes back as `verificationStatus: RESOLVE_ERRORS` with one entry per problem in `errors`: +Where a submission is required — the default unregulated path, and `001`/`003` with the switch on — it carries the same data requirements as production: full name, birth date, nationality, `idType` + `identifier`, address, and an identity document uploaded via `POST /documents`. Anything missing comes back as `verificationStatus: RESOLVE_ERRORS` with one entry per problem in `errors`: ```json { @@ -42,11 +45,11 @@ Where a submission is required — the default unregulated path, and `001`/`003` } ``` -Fix-and-resubmit example — the standard integration loop on the default unregulated path, with **Skip verification paperwork** off. A `001` suffix behaves the same way where the suffix resolves at creation, since `001` and `003` always require a complete packet; a terminal suffix on that path resolves without one, and `POST /verifications` then returns `400`. +Fix-and-resubmit example — the standard integration loop on the default unregulated path, with **Skip verification paperwork** off. A `001` suffix behaves the same way with **Skip verification paperwork** on, since `001` and `003` always require a complete packet; a terminal suffix on that path resolves at creation, and `POST /verifications` then returns `400`. - A `fullName` ending in `001` leaves the customer submittable rather than resolving it terminally — `UNVERIFIED` on an unregulated platform, `PENDING` where the suffix resolves at creation. Persist the returned `id` for the following steps. + A `fullName` ending in `001` leaves the customer submittable rather than resolving it terminally — `UNVERIFIED` on an unregulated platform, `PENDING` with **Skip verification paperwork** on. Persist the returned `id` for the following steps. ```bash curl -X POST "https://api.lightspark.com/grid/2025-10-13/customers" \ @@ -113,14 +116,17 @@ Fix-and-resubmit example — the standard integration loop on the default unregu -For direct API onboarding, `001` and `003` both require complete business information, business documents, and at least one beneficial owner before `POST /verifications` moves past `RESOLVE_ERRORS`. On an unregulated platform every suffix goes through that check first, so an incomplete `002` business reports its missing data before it rejects. For the hosted flow, see [Configuring customers](/payouts-and-b2b/onboarding/configuring-customers#hosted-kyc-and-kyb-link-flow). +For direct API onboarding with **Skip verification paperwork** off, every suffix requires complete business information, business documents, and at least one beneficial owner before `POST /verifications` moves past `RESOLVE_ERRORS` — an incomplete `002` business reports its missing data before it rejects. With the switch on, `POST /verifications` reads the suffix before the packet check: a `003` business returns `RESOLVE_ERRORS` with a `POOR_QUALITY_DOCUMENT` error with no packet, and a `001` business still needs the complete packet before `POST /verifications` moves past `RESOLVE_ERRORS`. For the hosted flow, see [Configuring customers](/payouts-and-b2b/onboarding/configuring-customers#hosted-kyc-and-kyb-link-flow). ### Beneficial owner KYC -When a business customer resolves terminally through its registration-number suffix, each of its beneficial owners is resolved at the same moment using the **last 3 characters** of the `lastName` in that owner's `personalInfo`: +When `POST /verifications` resolves a business from its registration-number suffix, each of its beneficial owners is resolved at the same moment using the **last 3 characters** of the `lastName` in that owner's `personalInfo`: | Suffix | `kycStatus` | Behavior | |--------|------------|----------| | **001** | `PENDING` | KYC verification remains pending | -| **002** | `REJECTED` | KYC verification is rejected | +| **002** | `REJECTED` | KYC verification is rejected, and the business is `REJECTED` with it | +| **003** | `UNVERIFIED` | KYC verification can be retried | | **Any other** | `APPROVED` | KYC verification is approved | + +A `001` registration number does not read owner suffixes: the business and every owner go to `PENDING`. On a `003` business, owners with an approving suffix keep their current status until the business reaches a final outcome. With **Skip verification paperwork** on, a business with a final suffix resolves at creation before any owner exists, so use a `003` registration number when you want to test owners. From 303fef074337f1e69b18076515d6c66a6124b24c Mon Sep 17 00:00:00 2001 From: jaymantri Date: Tue, 8 Sep 2026 15:27:10 -0700 Subject: [PATCH 2/2] docs: changelog entry for sandbox business suffix at create Co-authored-by: Cursor --- mintlify/changelog.mdx | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/mintlify/changelog.mdx b/mintlify/changelog.mdx index 2a85ca899..156c6cd11 100644 --- a/mintlify/changelog.mdx +++ b/mintlify/changelog.mdx @@ -32,6 +32,20 @@ payments is a separate enum and is unaffected. See [Reconciliation](/cards/transactions/reconciliation). +## Sandbox businesses resolve from the suffix at create + +With **Skip verification paperwork** on, a sandbox business on an unregulated platform now +gets its result when you create it, the same way an individual does. + +- The last 3 characters of `businessInfo.registrationNumber` set `kybStatus` at create: + `001` → `PENDING`, `002` → `REJECTED`, `003` → `UNVERIFIED`, any other value → + `APPROVED`. No documents, beneficial owners, or `POST /verifications` call are needed. +- Create emits the matching `CUSTOMER.KYB_*` webhook only. It creates no verification and + emits no `VERIFICATION.*` event. +- With the switch off, and on regulated platforms, nothing changes. + +See the business suffix table in [sandbox testing](/api-reference/sandbox-testing). + ## Sandbox KYC and KYB follow the production flow Unregulated sandbox platforms now resolve a customer's verification from a submitted @@ -58,7 +72,8 @@ submit, and resolve loop you run in production. - To keep the previous fast path, open **Configuration** in your sandbox dashboard and turn on **Skip verification paperwork**. A terminal suffix then resolves with no documents: individuals at create, businesses at their first submission. `001` and `003` still require - a complete packet. Turn it off when you want to test the full flow again. + a complete packet (changed later in September 2026—see above). Turn it off when you want + to test the full flow again. Walk through the fix-and-resubmit loop in [sandbox testing](/api-reference/sandbox-testing).