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

# Reseller API

> Automate reseller programs, invites, payouts, embeds, stock purchases, and inventory delivery

The Reseller Developer API lets a merchant or approved OAuth app manage reseller workflows without using the dashboard.

Use it when you are building:

* an internal reseller operations tool
* a partner onboarding flow
* a reseller analytics dashboard
* a headless portal for stock requests and payout operations

<Info>
  Resellers are scoped to a merchant shop. Always treat `reseller_relationship_id` as a tenant boundary, not just a record ID.
</Info>

## Scopes

Use the smallest scope set your integration needs.

| Workflow                                            | Scopes                    |
| --------------------------------------------------- | ------------------------- |
| Read program settings                               | `reseller_programs.read`  |
| Update program settings                             | `reseller_programs.write` |
| Invite or update resellers                          | `resellers.write`         |
| List resellers                                      | `resellers.read`          |
| Read reseller sales and analytics                   | `reseller_sales.read`     |
| Read payout state                                   | `reseller_payouts.read`   |
| Approve, reject, complete, or cancel payouts        | `reseller_payouts.write`  |
| Read stock transfers and inventory                  | `reseller_stock.read`     |
| Request stock, allocate stock, or deliver inventory | `reseller_stock.write`    |

## SDK Example

```ts theme={"system"}
import { ShoppexClient } from '@shoppexio/sdk';

const client = new ShoppexClient({
  apiKey: process.env.SHOPPEX_API_KEY!,
});

await client.resellerProgram.update({
  is_enabled: true,
  default_mode: 'BOTH',
  default_commission_percent: 25,
  default_wholesale_discount_percent: 35,
});

const invite = await client.resellers.invite({
  email: 'partner@example.com',
  mode: 'BOTH',
  custom_commission_percent: 30,
  product_access: [{
    product_id: '11111111-1111-4111-8111-111111111111',
    commission_percent_override: 30,
    max_quantity: 100,
  }],
});

console.log(invite.data.invitation.id);

// Once the invitation is accepted, use the reseller relationship id from
// resellers.list() or the dashboard detail view. Invitation ids are not valid
// for relationship-scoped calls.
const relationshipId = 'rel_123';

await client.resellers.createEmbedCampaign(relationshipId, {
  name: 'Discord Launch',
  product_ids: ['11111111-1111-4111-8111-111111111111'],
});
```

## Enable Program

```bash theme={"system"}
curl -X PATCH https://api.shoppex.io/dev/v1/reseller-program \
  -H "Authorization: Bearer shx_your_api_key" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: reseller-program-setup-1" \
  -d '{
    "is_enabled": true,
    "default_mode": "BOTH",
    "default_commission_percent": 25,
    "default_wholesale_discount_percent": 35,
    "min_payout_threshold": 50
  }'
```

## Invite Reseller

```bash theme={"system"}
curl -X POST https://api.shoppex.io/dev/v1/resellers/invite \
  -H "Authorization: Bearer shx_your_api_key" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: reseller-invite-partner-example" \
  -d '{
    "email": "partner@example.com",
    "mode": "BOTH",
    "custom_commission_percent": 30,
    "purchase_limit_daily": 50,
    "product_access": [
      {
        "product_id": "11111111-1111-4111-8111-111111111111",
        "commission_percent_override": 30,
        "max_quantity": 100
      }
    ]
  }'
```

After the reseller accepts the invitation, Shoppex creates the reseller relationship and links it to reseller attribution.

## Reseller Analytics

Use shop-wide analytics for overview screens:

```bash theme={"system"}
curl https://api.shoppex.io/dev/v1/resellers/analytics \
  -H "Authorization: Bearer shx_your_api_key"
```

Use relationship-specific analytics for detail screens:

```bash theme={"system"}
curl https://api.shoppex.io/dev/v1/resellers/rel_123/analytics \
  -H "Authorization: Bearer shx_your_api_key"
```

## Embed Campaigns

Create reseller-owned embed campaigns from your partner tooling:

```bash theme={"system"}
curl -X POST https://api.shoppex.io/dev/v1/resellers/rel_123/embed-campaigns \
  -H "Authorization: Bearer shx_your_api_key" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: embed-campaign-rel-123-discord" \
  -d '{
    "name": "Discord Launch",
    "product_ids": ["11111111-1111-4111-8111-111111111111"]
  }'
```

Pause or revoke a campaign without deleting its reporting history:

```bash theme={"system"}
curl -X PATCH https://api.shoppex.io/dev/v1/resellers/rel_123/embed-campaigns/campaign_123 \
  -H "Authorization: Bearer shx_your_api_key" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: embed-campaign-campaign-123-pause" \
  -d '{
    "status": "PAUSED"
  }'
```

## Stock Purchase Flow

Stock Mode uses normal Shoppex invoice and payment infrastructure. The stock transfer is allocated only after payment.

```bash theme={"system"}
curl -X POST https://api.shoppex.io/dev/v1/resellers/rel_123/stock-purchases \
  -H "Authorization: Bearer shx_your_api_key" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: stock-request-rel-123-prod-123-25" \
  -d '{
    "product_id": "11111111-1111-4111-8111-111111111111",
    "quantity": 25
  }'
```

Then create the invoice:

```bash theme={"system"}
curl -X POST https://api.shoppex.io/dev/v1/resellers/rel_123/stock-transfers/transfer_123/invoice \
  -H "Authorization: Bearer shx_your_api_key" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: stock-invoice-transfer-123" \
  -d '{}'
```

Merchant-side tools can mark a stock transfer paid and allocate inventory when payment confirmation is handled outside the normal checkout path:

```bash theme={"system"}
curl -X POST https://api.shoppex.io/dev/v1/resellers/rel_123/stock-transfers/transfer_123/allocate \
  -H "Authorization: Bearer shx_your_api_key" \
  -H "Idempotency-Key: stock-allocate-transfer-123"
```

<Warning>
  Allocation is idempotent, but integrations should still send stable `Idempotency-Key` values for stock mutations.
</Warning>

## Inventory Delivery

Deliver one allocated stock item to an end customer:

```bash theme={"system"}
curl -X POST https://api.shoppex.io/dev/v1/resellers/rel_123/inventory/item_123/deliver \
  -H "Authorization: Bearer shx_your_api_key" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: stock-deliver-item-123" \
  -d '{
    "email": "customer@example.com"
  }'
```

## Reseller Fulfillment API

Reseller API keys are different from merchant Developer API keys. A merchant key starts with `shx_` and can manage a shop. A reseller key starts with `shr_` and can only operate one reseller relationship.

Use this flow when a reseller sells through their own store and wants Shoppex to deliver merchant stock without showing Shoppex to their buyer.

1. The reseller creates an API key in the Reseller Portal API tab.
2. The reseller tops up prepaid balance.
3. The external store calls the Reseller Fulfillment API after payment.
4. Shoppex debits wholesale cost from the reseller balance and delivers merchant serial stock.

```bash theme={"system"}
curl -X POST https://api.shoppex.io/reseller/v1/fulfillments \
  -H "Authorization: Bearer shr_reseller_api_key" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: order-1001-line-1" \
  -d '{
    "external_order_id": "order-1001",
    "customer_email": "buyer@example.com",
    "product_id": "11111111-1111-4111-8111-111111111111",
    "quantity": 1
  }'
```

For tools that only support a dynamic URL, use the URL template from the Reseller Portal. The path is `/reseller/v1/fulfillments/dynamic` and the required query params are `api_key`, `external_order_id`, `customer_email`, `product_id`, and `quantity`.

<Warning>
  Send a stable `external_order_id` or `Idempotency-Key`. Retries return the same fulfillment instead of debiting balance twice.
</Warning>

Check reseller prepaid balance:

```bash theme={"system"}
curl https://api.shoppex.io/reseller/v1/balance \
  -H "Authorization: Bearer shr_reseller_api_key"
```

Common errors:

* `402 Insufficient reseller prepaid balance`
* `409 Fulfillment stock is unavailable`
* `401 Invalid or inactive reseller API key`

## Webhooks

Subscribe to reseller events to keep partner portals in sync.

Important events:

* `reseller:invited`
* `reseller:accepted`
* `reseller:sale`
* `reseller:embed_campaign_created`
* `reseller:payout_requested`
* `reseller:stock_purchase_requested`
* `reseller:api_fulfillment_delivered`
* `reseller:stock_purchase_paid`
* `reseller:stock_allocated`
* `reseller:stock_item_delivered`

See [Webhook Events](/api-reference/webhooks/events) for payload examples.

## Endpoint Reference

The full generated endpoint reference is available in the **Resellers** group in the API Reference sidebar.
