Promote a kyb_scope=MINIMAL business customer to kyb_scope=FULL by attaching beneficial-owner data. Identity columns (registration_number, incorporation_country) are typically already on file from MINIMAL onboarding.
Eligibility checks (return 422 on failure):
- Customer exists and belongs to your platform.
- Customer is
type=business. - Customer is currently
kyb_scope=MINIMAL(or has no scope set, treated as Minimal). A FULL customer cannot be "upgraded" again. - Customer is not
PROCESSING(rejected with400— wait for the customer-level webhook before retrying).
Validation (return 422 on failure):
- At least one owner.
- Ownership percentages sum to exactly 100.
- Per-owner identity invariants (DOB ≥ 18, expiry future, valid ISO codes where supplied).
- Owner emails unique within the customer.
- If you send
registration_number/incorporation_countryoverrides, they must satisfy the same rules as create. - If you send
countryto update jurisdiction, the resultingcountryandincorporation_countrymust match.
On success:
- New owners are saved on the customer.
kyb_scopeflips toFULL.- If the customer was
VERIFIED,verification_statusflips back toPENDING(re-onboarding under stricter rules). Existing NGN VBAs are unaffected. - An audit comment is recorded.
- A
customer.status_changedwebhook fires for the verification-status transition (if any).
Important: This endpoint does NOT run the Standard readiness checks. Owner ID files are not part of this payload — upload them per-owner via POST /api/external/customer/{id}/owner/{owner}/files after the upgrade succeeds. Then call POST /api/external/customer/{id}/submit to re-verify the customer under the Standard checks.
Required scope: customer:write.
Authorization
oauth2ClientCredentials customer:writeUse your OAuth client credentials to obtain a short-lived Bearer token from POST /oauth/token.
In: header
Scope: customer:write
Path Parameters
uuidRequest Body
application/json
TypeScript Definitions
Use the request body type in TypeScript.
Response Body
application/json
application/json
application/json
application/json
application/json
curl --request POST \ --url 'https://example.com/api/external/customer/497f6eca-6276-4993-bfeb-53cbbbba6f08/upgrade-kyb-scope' \ --header 'Content-Type: application/json' \ --data '{ "trading_name": "Acme", "business_type": "llc", "incorporation_date": "2019-03-12", "industry_type": "Software & SaaS", "business_description": "B2B SaaS platform.", "website": "https://acme.example.com", "source_of_funds": "business_revenue", "estimated_annual_revenue": "1000000_4999999", "expected_monthly_payments": 250, "account_purpose": "send_receive_funds_related_parties", "owners": [ { "first_name": "Jane", "last_name": "Doe", "email": "jane@acme.example.com", "date_of_birth": "1985-04-22", "nationality": "NG", "title": "CEO", "ownership_percentage": 60, "has_control": true, "is_signer": true, "is_beneficial_owner": true, "id_document_type": "passport", "id_document_number": "A12345678", "id_document_country": "NG", "id_expiry_date": "2030-01-15", "is_pep": false }, { "first_name": "John", "last_name": "Smith", "ownership_percentage": 40, "is_beneficial_owner": true } ]}'{ "message": "Customer KYB scope upgraded to FULL. Upload owner ID files and call /submit to re-verify.", "data": { "id": "019a6da3-4a9a-7033-81b9-12489eff13ee", "type": "business", "kyb_scope": "FULL", "verification_status": "PENDING", "business_name": "Acme Nigeria Limited", "registration_number": "RC123456", "incorporation_country": "NG", "country": "NG", "owners": [ { "id": "019a6e22-8b4c-7c8d-9d12-c0c1ab3f1a90", "first_name": "Jane", "last_name": "Doe", "ownership_percentage": 60, "status": "PENDING" }, { "id": "019a6e22-8b4c-7c8d-9d12-d1d2bc4e2b91", "first_name": "John", "last_name": "Smith", "ownership_percentage": 40, "status": "PENDING" } ] }}POSTSubmit customer for verification
Locks the customer for review and starts the verification flow. The customer's `verification_status` flips out of `PENDING` (or `REJECTED` on re-submission). **Readiness check.** This endpoint runs a set of checks before flipping the customer into `PROCESSING`. The same checks run on initial submission and on re-submission after a `REJECTED` verdict. If any check fails, the response is `422`, the customer stays editable, and you can fix the gap and call `/submit` again. **For business customers, what we check depends on `kyb_scope`.** Both scopes share the same identity baseline (business name, country, registration number, country of incorporation, formation document). The only difference: FULL also requires beneficial owners. *Individual customers* - `id_file` is uploaded (via the legacy `/files` flow). *Business customers — both MINIMAL and FULL* - `business_name` is set. - `country` (registered-address country) is set and a valid ISO 3166-1 alpha-2 code. - `registration_number` is set. - `incorporation_country` is set and a valid ISO 3166-1 alpha-2 code. - `country` equals `incorporation_country` — a company's registered office sits in its country of incorporation by company law. - At least one document of a formation type: `CERTIFICATE_OF_INCORPORATION`, `ARTICLES_OF_INCORPORATION`, `BENEFICIAL_OWNERSHIP_CERTIFICATE`, `INCORPORATION_DOCUMENTS`, or `CAC_STATUS_REPORT`. *Business customers (`kyb_scope=FULL`) — additional rules* - At least one owner is attached. - The sum of every owner's `ownership_percentage` equals exactly 100. - Owner emails are unique within the customer (case-insensitive). - For each owner: `id_document_front` is uploaded; `id_document_back` is uploaded for `drivers_license`, `id_card`, and `resident_permit` types and absent for `passport`. - For each owner that has the field set: `date_of_birth` is at least 18 years ago, `id_expiry_date` is strictly after today, and `nationality` / `country` / `id_document_country` are valid ISO alpha-2 codes. **Owners are NOT required for MINIMAL customers.** They're saved on the record if you upload them but they don't gate `/submit`. **What happens on success** depends on customer type and your business settings: - *Individual + external KYC enabled* → handed to the KYC provider for review. - *Individual + external KYC disabled* → marked `VERIFIED` immediately. - *Business + auto-verify enabled* → marked `VERIFIED` immediately. Every `PENDING` and `REJECTED` owner and document is also brought to `APPROVED` so the customer record is internally consistent. - *Business + auto-verify disabled* → moves to `PROCESSING` for manual compliance review. In the manual-review flow, every `PENDING` owner and every `PENDING` KYB document flips to `PROCESSING` along with the customer so they're visibly under review and frozen from further edits. Owners and documents that were already `APPROVED` or `REJECTED` from a prior cycle are not touched. A `customer.status_changed` webhook fires for the customer-level transition. There are no per-owner or per-document webhooks. **Verification is not instant.** For individual customers, review typically completes within minutes (up to 2 hours under additional screening). For business-type customers, review typically takes 1–5 business days. Do not escalate before the standard window — listen for the `customer.status_changed` webhook. Required scope: `customer:write`.
GETList customer KYB documents
Returns every KYB document the business has registered for this customer. Each row's `url` is a 2-minute presigned link to the underlying file. The customer must be of type `business`. Required scope: `customer:read`.