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 with 400 — 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_country overrides, they must satisfy the same rules as create.
  • If you send country to update jurisdiction, the resulting country and incorporation_country must match.

On success:

  1. New owners are saved on the customer.
  2. kyb_scope flips to FULL.
  3. If the customer was VERIFIED, verification_status flips back to PENDING (re-onboarding under stricter rules). Existing NGN VBAs are unaffected.
  4. An audit comment is recorded.
  5. A customer.status_changed webhook 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.

POSTapi-prod.blaaiz.com/api/external/customer/{customer}/upgrade-kyb-scope

Authorization

oauth2ClientCredentials customer:write
AuthorizationBearer <token>

Use your OAuth client credentials to obtain a short-lived Bearer token from POST /oauth/token.

In: header

Scope: customer:write

Path Parameters

customer*string
Formatuuid

Request Body

application/json

TypeScript Definitions

Use the request body type in TypeScript.

Response Body

application/json

application/json

application/json

application/json

application/json

Upgrade a business customer from MINIMAL to FULL KYB
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`.