> ## 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.

# Link Merchant

> Link an existing Khaime business as a sub-merchant in your marketplace.

# Link Merchant

Link a business that **already has a Khaime account** to your marketplace as a sub-merchant. Use this when onboarding merchants who signed up independently before joining your marketplace.

<Note>
  If the business doesn't have a Khaime account yet, use [Create Merchant](/api-reference/marketplace/create-merchant) (single) or [Import Merchants](/api-reference/marketplace/import-merchants) (bulk) instead — both create the account for you. This endpoint only links existing accounts.
</Note>

## Request Body

<ParamField body="business_email" type="string" required>
  Email of the existing Khaime business to link. Must match an account exactly — there's no fuzzy matching.
</ParamField>

<ParamField body="commission_rate" type="number">
  Decimal commission rate between `0` and `1` for this merchant. If omitted, the merchant **inherits your marketplace's default rate dynamically** — meaning if you change your portfolio default later, this merchant's effective rate changes too. Pass an explicit value only if you want this merchant pinned to a fixed rate regardless of future default changes.
</ParamField>

## What happens depends on prior state

<Warning>
  The response `data` shape differs depending on which of these three cases applies — don't assume a fixed schema.
</Warning>

**1. Not linked before** → creates a new relationship, `status: active`. Response is `201`.

```json theme={null}
{
  "success": true,
  "message": "Merchant linked to marketplace successfully",
  "data": {
    "id": 14,
    "merchant_id": 892,
    "business_name": "Ade Leatherworks",
    "business_email": "ade@leatherworks.com",
    "commission_rate": 0.05,
    "commission_rate_inherited": true,
    "marketplace_id": 42,
    "status": "active"
  }
}
```

**2. Already linked and active** → no-op, idempotent. Response is `200` and **omits `commission_rate_inherited` and `marketplace_id`** present in case 1:

```json theme={null}
{
  "success": true,
  "message": "Merchant is already linked and active in your marketplace",
  "data": {
    "id": 14,
    "merchant_id": 892,
    "business_name": "Ade Leatherworks",
    "business_email": "ade@leatherworks.com",
    "commission_rate": "0.0500",
    "status": "active"
  }
}
```

**3. Previously linked, then suspended** → reactivates the existing relationship (`status: active`, `joined_at` reset to now). Response is `200`, shape matches case 1 (includes `commission_rate_inherited`), message `"Merchant reactivated in your marketplace"`.

In all three cases, if `commission_rate` is explicitly provided, it overwrites the stored rate; if omitted on reactivation, the previously stored rate is kept.

<Warning>
  **`commission_rate`'s type is inconsistent across these three cases** — don't assume it's always a number. The column is `DECIMAL(5,4)` in Postgres, and Sequelize returns DECIMAL columns as **strings** unless the code explicitly wraps them in `Number()`.

  * Case 1 (new link): always a JS number (or `null`) — explicitly computed with `Number(...)`.
  * Case 2 (already active): the **raw DB value** — a decimal **string** like `"0.0500"` (or `null`), not wrapped.
  * Case 3 (reactivated): a string if a previously stored rate exists and you didn't pass an explicit `commission_rate`; a number only if it falls back to the computed default.

  If you're storing this value, parse it with `Number(...)` on your side regardless of which case you hit — don't rely on `typeof commission_rate === 'number'`.
</Warning>

## Error Codes

| Status | Error Code                 | Cause                                                                                                                 |
| ------ | -------------------------- | --------------------------------------------------------------------------------------------------------------------- |
| `403`  | `AUTH_PERMISSION_DENIED`   | Your business isn't a marketplace operator. Run [Setup Marketplace](/api-reference/marketplace/setup) first.          |
| `400`  | `VALIDATION_MISSING_FIELD` | `business_email` is missing.                                                                                          |
| `400`  | `VALIDATION_FAILED`        | `commission_rate` given but outside `0`–`1`, or you tried to link your own business as its own sub-merchant.          |
| `404`  | `BUSINESS_NOT_FOUND`       | No Khaime account exists with that email — use [Create Merchant](/api-reference/marketplace/create-merchant) instead. |

<RequestExample>
  ```bash cURL theme={null}
  curl -X POST https://api.khaime.com/api/v1/partner/marketplace/merchants/link \
    -H "X-API-Key: pk_sandbox_your_key" \
    -H "Content-Type: application/json" \
    -d '{
      "business_email": "ade@leatherworks.com",
      "commission_rate": 0.05
    }'
  ```
</RequestExample>
