curl -X GET "https://api.khaime.com/api/v1/merchants/123/kyc" \
-H "X-API-Key: pk_sandbox_your_key"
Marketplace
Get Merchant KYC Status
Retrieve the current KYC verification status for a sub-merchant.
GET
/
merchants
/
{merchantId}
/
kyc
curl -X GET "https://api.khaime.com/api/v1/merchants/123/kyc" \
-H "X-API-Key: pk_sandbox_your_key"
Intro
Returns a sub-merchant’s current KYC verification status and latest submission details — whether they can accept payments and receive payouts right now — for both Khaime KYC (African markets) and Stripe Connect (everywhere else).Context
This is the read side of the KYC lifecycle: call it after Submit KYC to see the outcome, poll it while a merchant is mid-onboarding, and check it before deciding whether to send traffic to Resubmit KYC. It’s also the cheapest way to confirm a merchant is ready before you attempt a charge with theirsub_merchant_id.
Hows
Path parameters
number
required
The ID of the sub-merchant.
Response — Khaime KYC merchant
{
"success": true,
"message": "KYC status retrieved",
"data": {
"provider": "khaime",
"status": "approved",
"verification_status": "kyc_approved",
"can_accept_payments": true,
"can_receive_payouts": true,
"khaime_submission": {
"id": 42,
"status": "approved",
"business_type": "individual",
"settlement_currency": "NGN",
"country_mismatch": false,
"submitted_at": "2026-04-10T12:00:00.000Z",
"reviewed_at": "2026-04-10T14:30:00.000Z",
"rejection_reason": null
},
"connect_onboarding": null
}
}
Response — Stripe Connect merchant
{
"success": true,
"message": "KYC status retrieved",
"data": {
"provider": "stripe",
"status": "approved",
"verification_status": "kyc_approved",
"can_accept_payments": true,
"can_receive_payouts": true,
"khaime_submission": null,
"stripe_connect": {
"account_id": "acct_1234567890",
"charges_enabled": true,
"payouts_enabled": true,
"requirements": {
"currently_due": [],
"eventually_due": [],
"past_due": []
},
"onboarding_url": null
}
}
}
Response fields
| Field | Type | Description |
|---|---|---|
provider | string | KYC provider: khaime or stripe |
status | string | Normalized status: not_started, pending, approved, rejected, action_required |
verification_status | string | Same status with a kyc_ prefix (see values below) — kept for backward compatibility |
can_accept_payments | boolean | Whether the merchant can be charged right now |
can_receive_payouts | boolean | Whether the merchant can receive payouts right now |
verification_status values
| Value | Description |
|---|---|
kyc_not_started | No KYC has been submitted yet |
kyc_pending_review | Submission is awaiting review |
kyc_approved | Approved — merchant can receive payouts |
kyc_rejected | Rejected — resubmission required |
kyc_additional_info_requested | Reviewer has asked for more information |
kyc_revoked | Previously-approved KYC has since been revoked |
khaime_submission object (African markets)
Present when the merchant is on Khaime KYC (NG, GH, ZA, KE).
| Field | Type | Description |
|---|---|---|
id | number | KYC submission ID |
status | string | pending_review, approved, rejected, additional_info_requested, revoked |
business_type | string | individual or registered_business |
settlement_currency | string | Currency locked in for this merchant’s payouts |
country_mismatch | boolean | true if the identity document’s country and the bank’s country differ — this doesn’t block approval on its own, but flags the submission for closer review |
submitted_at | string | ISO 8601 submission timestamp |
reviewed_at | string | null | ISO 8601 review timestamp, or null if still pending |
rejection_reason | string | null | Reason for rejection, if rejected |
This status endpoint returns a smaller, summary view — it does not echo back
legal_name, id_country, or bank account details. If you need those, they’re in the response from Submit KYC or Resubmit KYC, or from Get Merchant Details.stripe_connect object (non-African markets)
Present when the merchant is on Stripe Connect.
| Field | Type | Description |
|---|---|---|
account_id | string | Stripe Connect account ID |
charges_enabled | boolean | Can accept charges |
payouts_enabled | boolean | Can receive payouts |
requirements | object | Outstanding onboarding requirements |
requirements.currently_due | array | Fields Stripe needs right now |
requirements.eventually_due | array | Fields needed eventually |
requirements.past_due | array | Overdue fields — account may already be restricted |
onboarding_url | string | null | URL to resume onboarding, if incomplete |
Determining readiness
const isReady = response.data.can_accept_payments && response.data.can_receive_payouts;
khaime_submission, stripe_connect) are for showing merchants and your own team more detail — you shouldn’t need to branch on provider just to decide if a merchant is chargeable.
Error cases
| Status | Error | Fix |
|---|---|---|
401 | Missing or invalid X-API-Key header | Include a valid Partner API key |
403 | This endpoint is restricted to marketplace operators | Your API key must belong to a marketplace operator account |
404 | Active merchant relationship not found | The merchant is not linked to your marketplace |
curl -X GET "https://api.khaime.com/api/v1/merchants/123/kyc" \
-H "X-API-Key: pk_sandbox_your_key"
Whys
A single normalizedstatus on top of two providers’ native statuses. Khaime KYC and Stripe Connect model verification completely differently internally (a review queue status vs. charges_enabled/payouts_enabled flags plus outstanding requirements). Rather than making you learn both models, the endpoint reduces both down to the same handful of status values and two booleans you can act on immediately.
verification_status kept alongside status. It predates the normalized status field and is retained so existing integrations built against the kyc_-prefixed values keep working.
Why nots
- Not a KYC submission or update endpoint. This is read-only — use Submit KYC or Resubmit KYC to change anything.
- Doesn’t return bank account details. For bank details on file, use Get Merchant Details or the response from the submit/resubmit endpoints.
- Not a live poll of Stripe. The Stripe fields reflect the last state Khaime received via webhook (or, occasionally, an on-demand refresh) — not necessarily this exact second’s state on Stripe’s side. For most integrations the lag is immaterial, but don’t treat this as a real-time Stripe API proxy.
Related
- Submit KYC — submit a new KYC application
- Resubmit KYC — resubmit after rejection
- Setup Payout — configure bank details for payout
