> ## Documentation Index
> Fetch the complete documentation index at: https://docs.khaime.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Resubmit Merchant KYC

> Resubmit a KYC application after rejection or resume Stripe onboarding.

# Resubmit Merchant KYC

Resubmits a KYC application for a sub-merchant. This endpoint handles both Khaime KYC (African markets) and Stripe Connect (other markets) based on the merchant's existing submission.

<Warning>
  For **Khaime KYC**: This endpoint will fail if the merchant's KYC status is `pending_review` or `approved`. Check the current status with [Get KYC Status](/api-reference/marketplace/get-kyc-status) first.

  For **Stripe Connect**: You can call this anytime to get a fresh onboarding URL to resume or update verification.
</Warning>

## How Resubmission Works

| Provider           | When Allowed                                        | What Happens                                               |
| ------------------ | --------------------------------------------------- | ---------------------------------------------------------- |
| **Khaime KYC**     | Status is `rejected` or `additional_info_requested` | Submit new documents; creates new submission               |
| **Stripe Connect** | Anytime (with existing Stripe account)              | Returns new `onboarding_url` to resume/update verification |

## Path Parameters

<ParamField path="merchantId" type="number" required>
  The ID of the sub-merchant.
</ParamField>

***

## Request Body

### For African Countries (Khaime KYC)

Same fields as [Submit KYC](/api-reference/marketplace/submit-kyc). You can use either the structured format or legacy flat format. Provide complete data, not just changed fields.

<Tabs>
  <Tab title="Structured Format (Recommended)">
    #### Core Fields

    <ParamField body="id_country" type="string" required>
      ISO 3166-1 alpha-2 country code. Must be one of: `NG`, `GH`, `ZA`, `KE`.
    </ParamField>

    <ParamField body="account_type" type="string" required>
      Type of account. One of: `individual`, `registered_business`.
    </ParamField>

    #### Owner Object (Required)

    <ParamField body="owner" type="object" required>
      Updated owner/individual information.

      | Field             | Type   | Required | Description                                                 |
      | ----------------- | ------ | -------- | ----------------------------------------------------------- |
      | `first_name`      | string | Yes      | Owner's first name                                          |
      | `last_name`       | string | Yes      | Owner's last name                                           |
      | `date_of_birth`   | string | No       | Date of birth in `YYYY-MM-DD` format                        |
      | `phone_number`    | string | No       | Contact phone number                                        |
      | `email`           | string | No       | Contact email address                                       |
      | `id_type`         | string | Yes      | Document type: `passport`, `national_id`, `drivers_license` |
      | `id_number`       | string | Yes      | ID number (BVN, NIN, or passport number)                    |
      | `id_document_url` | string | Yes      | URL to **updated** identity document image                  |
      | `selfie_url`      | string | No       | URL to selfie photo for liveness verification               |
      | `address`         | object | Yes      | Owner's residential address                                 |
    </ParamField>

    #### Business Object (Required for registered\_business)

    <ParamField body="business" type="object">
      Required when `account_type` is `registered_business`.

      | Field                       | Type   | Required | Description                                                                        |
      | --------------------------- | ------ | -------- | ---------------------------------------------------------------------------------- |
      | `legal_name`                | string | Yes      | Registered business name                                                           |
      | `trading_name`              | string | No       | Trading/DBA name if different                                                      |
      | `registration_number`       | string | Yes      | Business registration number                                                       |
      | `tax_id`                    | string | No       | Tax identification number                                                          |
      | `business_type`             | string | No       | One of: `sole_proprietorship`, `partnership`, `llc`, `corporation`, `ngo`, `other` |
      | `website`                   | string | No       | Business website URL                                                               |
      | `phone_number`              | string | No       | Business phone number                                                              |
      | `registration_document_url` | string | Yes      | URL to certificate of incorporation                                                |
      | `additional_document_url`   | string | No       | URL to additional supporting document                                              |
      | `address`                   | object | Yes      | Business address                                                                   |
    </ParamField>

    #### Bank Account Object (Optional)

    <ParamField body="bank_account" type="object">
      Updated payout bank account details.

      | Field            | Type   | Required | Description                                                                       |
      | ---------------- | ------ | -------- | --------------------------------------------------------------------------------- |
      | `country`        | string | Yes      | Bank country code (e.g., `NG`, `GH`)                                              |
      | `bank_name`      | string | Yes\*    | Bank name from [Get Supported Banks](/api-reference/marketplace/get-payout-banks) |
      | `bank_id`        | string | Yes\*    | Bank UUID from [Get Supported Banks](/api-reference/marketplace/get-payout-banks) |
      | `account_number` | string | Yes      | Bank account number                                                               |
      | `account_name`   | string | Yes      | Name on the bank account                                                          |
      | `bank_code`      | string | No       | Bank code (if applicable)                                                         |
      | `sort_code`      | string | No       | Sort code (required for UK accounts)                                              |

      \*Either `bank_name` or `bank_id` is required.
    </ParamField>
  </Tab>

  <Tab title="Flat Format (Legacy)">
    <ParamField body="id_country" type="string" required>
      ISO 3166-1 alpha-2 country code for the identity document.
    </ParamField>

    <ParamField body="business_type" type="string" required>
      The type of business. One of: `individual`, `registered_business`.
    </ParamField>

    <ParamField body="legal_name" type="string" required>
      Full legal name of the individual or registered business.
    </ParamField>

    <ParamField body="id_document_type" type="string" required>
      Type of identity document. One of: `passport`, `national_id`, `drivers_license`.
    </ParamField>

    <ParamField body="id_document_url" type="string" required>
      Publicly accessible URL to the **updated** identity document image.
    </ParamField>

    <ParamField body="selfie_url" type="string">
      URL to an updated selfie photo.
    </ParamField>

    <ParamField body="registration_number" type="string">
      Business registration number (required for `registered_business`).
    </ParamField>

    <ParamField body="business_address" type="object">
      Physical address of the business or individual.

      | Field         | Type   | Required | Description                     |
      | ------------- | ------ | -------- | ------------------------------- |
      | `line1`       | string | Yes      | Street address line 1           |
      | `line2`       | string | No       | Street address line 2           |
      | `city`        | string | Yes      | City or town                    |
      | `state`       | string | No       | State, province, or region      |
      | `postal_code` | string | No       | Postal or ZIP code              |
      | `country`     | string | Yes      | ISO 3166-1 alpha-2 country code |
    </ParamField>

    <ParamField body="incorporation_cert_url" type="string">
      URL to the certificate of incorporation (required for `registered_business`).
    </ParamField>

    <ParamField body="bank_country" type="string">
      ISO 3166-1 alpha-2 country code for the merchant's bank.
    </ParamField>

    <ParamField body="bank_name" type="string">
      Name of the merchant's bank.
    </ParamField>

    <ParamField body="bank_account_number" type="string">
      The merchant's bank account number.
    </ParamField>

    <ParamField body="bank_account_name" type="string">
      The registered name on the bank account.
    </ParamField>

    <ParamField body="bank_sort_code" type="string">
      Bank sort code (required for UK accounts).
    </ParamField>
  </Tab>
</Tabs>

***

### For Other Countries (Stripe Connect)

For Stripe Connect merchants, call this endpoint to get a fresh onboarding session. The merchant can then resume or update their verification on Stripe.

<Info>
  **When to use this**: If the merchant didn't complete onboarding, if their session expired, or if Stripe requires additional information.
</Info>

<ParamField body="return_url" type="string" required>
  URL to redirect the merchant after they complete Stripe onboarding. This should be a page on your platform.
</ParamField>

<ParamField body="refresh_url" type="string" required>
  URL to redirect the merchant if the Stripe onboarding link expires. Typically the same page that initiates KYC.
</ParamField>

<Note>
  You don't need to pass `country` or other fields — the system uses the existing submission data to generate a new onboarding session.
</Note>

***

## Response

### African Countries (Khaime KYC)

```json theme={null}
{
  "success": true,
  "message": "KYC resubmitted for review.",
  "data": {
    "provider": "khaime",
    "id": 47,
    "status": "pending_review",
    "business_type": "individual",
    "legal_name": "Amara Osei",
    "id_country": "NG",
    "bank_name": "Access Bank",
    "bank_account_number": "0123456789",
    "bank_account_name": "Amara Osei",
    "settlement_currency": "NGN",
    "country_mismatch": false,
    "submitted_at": "2026-04-10T14:30:00.000Z",
    "reviewed_at": null,
    "rejection_reason": null
  }
}
```

### Other Countries (Stripe Connect)

```json theme={null}
{
  "success": true,
  "message": "Continue your verification on Stripe.",
  "data": {
    "provider": "stripe",
    "submission_id": 43,
    "stripe_account_id": "acct_1234567890",
    "onboarding_url": "https://connect.stripe.com/setup/s/abc123",
    "client_secret": "accs_1234567890_secret_xyz"
  }
}
```

| Field               | Description                                                                                                  |
| ------------------- | ------------------------------------------------------------------------------------------------------------ |
| `onboarding_url`    | Fresh URL to redirect the merchant to Stripe's hosted onboarding                                             |
| `client_secret`     | Fresh secret for [Stripe Connect Embedded Components](https://stripe.com/docs/connect/onboarding/quickstart) |
| `stripe_account_id` | The existing Stripe Connect account ID                                                                       |

<Tip>
  **Embedded vs Redirect**: Use `onboarding_url` for a simple redirect flow. Use `client_secret` with Stripe.js for embedded onboarding that keeps users on your site.
</Tip>

***

## Data Storage

All resubmitted KYC data is stored in the **KycSubmissions** table:

| Field          | Storage Location                                     |
| -------------- | ---------------------------------------------------- |
| KYC documents  | `KycSubmissions.id_document_url`, `selfie_url`, etc. |
| Owner info     | `KycSubmissions.owner_info` (JSON)                   |
| Business info  | `KycSubmissions.business_info` (JSON)                |
| Bank details   | `KycSubmissions.bank_info` (JSON) + flat fields      |
| Status         | `KycSubmissions.status`                              |
| Stripe account | `KycSubmissions.stripe_account_id`                   |

<Info>
  **Important**: The `KycSubmissions` table is the single source of truth. Legacy fields in `Educatorportfolio` are deprecated.
</Info>

***

## Error Codes

| Status | Error                                                          | Fix                                                                                                     |
| ------ | -------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------- |
| `400`  | `Can only resubmit after rejection or additional info request` | Check status first — only Khaime KYC with `rejected` or `additional_info_requested` status can resubmit |
| `400`  | `No KYC submission found`                                      | Use [Submit KYC](/api-reference/marketplace/submit-kyc) for first-time submission                       |
| `400`  | `KYC is already approved`                                      | No resubmission needed — merchant is already verified                                                   |
| `400`  | `New KYC documents are required for resubmission`              | Include complete KYC data for Khaime KYC resubmit                                                       |
| `400`  | `Stripe account not found`                                     | Contact support — the Stripe Connect account is missing                                                 |
| `401`  | `Unauthorized`                                                 | Include a valid `X-API-Key` header                                                                      |
| `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                                                          |

***

<RequestExample>
  ```bash cURL (Nigeria - Resubmit with Structured Format) theme={null}
  curl -X POST "https://api.khaime.com/api/v1/partner/marketplace/merchants/123/kyc/resubmit" \
    -H "X-API-Key: pk_sandbox_your_key" \
    -H "Content-Type: application/json" \
    -d '{
      "id_country": "NG",
      "account_type": "individual",
      "owner": {
        "first_name": "Amara",
        "last_name": "Osei",
        "id_type": "passport",
        "id_number": "A12345678",
        "id_document_url": "https://cdn.example.com/docs/amara-passport-v2.jpg",
        "selfie_url": "https://cdn.example.com/docs/amara-selfie-v2.jpg",
        "address": {
          "street": "12 Victoria Island",
          "city": "Lagos",
          "state": "Lagos",
          "postal_code": "101001",
          "country": "NG"
        }
      },
      "bank_account": {
        "country": "NG",
        "bank_name": "Access Bank",
        "account_number": "0123456789",
        "account_name": "Amara Osei"
      }
    }'
  ```

  ```bash cURL (Nigeria - Resubmit Legacy Format) theme={null}
  curl -X POST "https://api.khaime.com/api/v1/partner/marketplace/merchants/123/kyc/resubmit" \
    -H "X-API-Key: pk_sandbox_your_key" \
    -H "Content-Type: application/json" \
    -d '{
      "id_country": "NG",
      "business_type": "individual",
      "legal_name": "Amara Osei",
      "id_document_type": "passport",
      "id_document_url": "https://cdn.example.com/docs/amara-passport-v2.jpg",
      "business_address": {
        "line1": "12 Victoria Island",
        "city": "Lagos",
        "state": "Lagos",
        "postal_code": "101001",
        "country": "NG"
      },
      "bank_country": "NG",
      "bank_name": "Access Bank",
      "bank_account_number": "0123456789",
      "bank_account_name": "Amara Osei"
    }'
  ```

  ```bash cURL (United States - Resume Stripe Onboarding) theme={null}
  curl -X POST "https://api.khaime.com/api/v1/partner/marketplace/merchants/456/kyc/resubmit" \
    -H "X-API-Key: pk_sandbox_your_key" \
    -H "Content-Type: application/json" \
    -d '{
      "return_url": "https://yourplatform.com/merchants/456/kyc-complete",
      "refresh_url": "https://yourplatform.com/merchants/456/kyc"
    }'
  ```

  ```bash cURL (United Kingdom - Resume Stripe Onboarding) theme={null}
  curl -X POST "https://api.khaime.com/api/v1/partner/marketplace/merchants/789/kyc/resubmit" \
    -H "X-API-Key: pk_sandbox_your_key" \
    -H "Content-Type: application/json" \
    -d '{
      "return_url": "https://yourplatform.com/merchants/789/kyc-complete",
      "refresh_url": "https://yourplatform.com/merchants/789/kyc"
    }'
  ```
</RequestExample>

***

## Related

* [Get KYC Status](/api-reference/marketplace/get-kyc-status) — check before resubmitting
* [Submit KYC](/api-reference/marketplace/submit-kyc) — for first-time submissions
* [Add Bank Account](/api-reference/marketplace/add-bank-account) — add or update bank details separately
