Skip to main content
POST

Intro

Submits a Know Your Customer (KYC) application for a sub-merchant in your marketplace — the identity, business, and bank verification step that must be approved before that merchant can receive payouts or be charged against.

Context

KYC sits between merchant creation and payout. The flow is: create or link the merchant, submit KYC, then check outcome with Get KYC Status — if rejected, correct and retry with Resubmit KYC. Khaime routes verification to one of two providers based on the merchant’s country, and this single endpoint handles both:
The merchant must already exist in your marketplace before you submit KYC for them. Create or link them first via Create Merchant.
Bank details can be included in the same request (African markets only) or configured separately with Setup Merchant Payout — the two ultimately write to the same verification record, so either order works.

Hows

Path parameters

number
required
The ID of the sub-merchant.

Request body — African countries (Khaime KYC)

string
required
ISO 3166-1 alpha-2 country code. Must be one of NG, GH, ZA, KE.
string
required
individual or registered_business.

Owner object (required)

object
required

Business object (required when account_type is registered_business)

object

Bank account object (optional at submission time)

object
* Either bank_name or bank_id must be present. For the most reliable result, pass bank_name — it’s what the rest of the payout pipeline reads back.
If you skip bank_account here, add it afterward with Setup Merchant Payout. For NG merchants specifically, using Setup Payout also resolves the bank to the correct local transfer rail — worth doing even if you already sent bank details with KYC.

Request body — everywhere else (Stripe Connect)

For non-African countries, Stripe collects identity, business, and bank information directly through its hosted flow — you only supply enough to start the session.
string
required
ISO 3166-1 alpha-2 country code (e.g. US, GB, CA, DE, FR, AU).
string
individual or registered_business. Defaults to individual.
string
Settlement currency for payouts. Derived from country if omitted.
string
required
Where the merchant lands after completing Stripe onboarding. Must be a page on your platform, not Khaime’s.
string
required
Where the merchant lands if the onboarding link expires or they exit early. Typically the same page that started KYC.

Response — African countries

Some African submissions with a matching, recognized bank can come back with status: "approved" immediately rather than pending_review — treat both as a valid outcome and always read status from the response instead of assuming a fixed 24-hour wait.

Response — everywhere else (Stripe Connect)

Calling this endpoint again for a merchant who already has an active Stripe session reuses their existing connected account and simply returns a fresh session — it will not create a duplicate Stripe account.

Error cases

Field-level validation failures (missing required nested fields like owner.id_document_url) are caught before your handler code runs and return a plain { message, details } body with no error_code. Business-rule failures caught inside the handler (missing country, missing Stripe redirect URLs, permission checks) return the standard envelope with error_code: VALIDATION_FAILED, AUTH_PERMISSION_DENIED, or BUSINESS_NOT_FOUND.

Whys

One endpoint, two providers. Rather than forcing you to branch on country before calling the API, the endpoint inspects id_country/country and routes internally. This keeps your integration code simple — the trade-off is that the request shape genuinely differs by provider, so read the country column before building your payload. Structured owner/business/bank_account objects. Khaime KYC used to accept a flat list of top-level fields (legal_name, id_document_type, business_address, and similar). The API has moved to nested objects because the shape maps directly onto the underlying identity, business, and bank records reviewers work from, and it scales cleanly to fields like business.tax_id that don’t have an obvious flat-field name. Only the structured format is accepted now — see Why Nots. Stripe for everything outside Africa. Building and maintaining compliant identity verification per country is Stripe’s core product; Khaime’s own reviewers focus on the African markets where Stripe Connect’s coverage and payout rails are thinner. This is also why non-African submissions barely validate anything server-side — Stripe owns that surface.

Why nots

  • The legacy flat request format no longer works. Fields like legal_name, id_document_type, business_address, incorporation_cert_url, bank_country, or top-level bank_name/bank_account_number are silently stripped by request validation before they reach any handling code. A request built only with those fields will fail with account_type is required / owner object is required for African markets, because none of your data survived. Always use the structured owner / business / bank_account objects.
  • This is not a document upload endpoint. id_document_url, selfie_url, and the business document URLs must already be publicly reachable (e.g., hosted on your own storage or CDN) before you call this endpoint. Khaime does not host uploads for you here.
  • Not a status endpoint. The response tells you the outcome of this submission, not the merchant’s current overall verification state — poll Get KYC Status for that.
  • Approved KYC is locked. Calling this endpoint again for a merchant whose KYC is already approved won’t change anything for Khaime KYC merchants and isn’t the right tool for updating bank details post-approval — use Update Merchant Payout instead.
  • No automatic retries against Stripe. If Stripe onboarding creation fails transiently, you need to call this endpoint again yourself; nothing retries it for you.

Next Steps