> This page is for For Developers.

> For clean Markdown of any page, append .md to the page URL.
> For a complete documentation index, see https://whop.ferndocs.com/llms.txt.
> For AI client integration (Claude Code, Cursor, etc.), connect to the MCP server at https://whop.ferndocs.com/_mcp/server.

# Affiliates

> Create affiliate records, assign per-plan or rev-share commission overrides, and track referral earnings.

Affiliates earn commissions for referred sales. The API flow has two parts: create an affiliate record, then add overrides that define the commission.

## How attribution works

1. You create an affiliate record for a user, then add overrides. Each override returns `product_direct_link` and `checkout_direct_link` fields. These are referral URLs the affiliate shares (they include `?a=<username>`).
2. A buyer clicks the link; Whop stores the affiliate cookie (30-day attribution window by default).
3. Buyer checks out within the window. Commission is calculated per the matching override: `standard` (per-plan, percentage or flat fee) or `rev_share` (percentage of revenue, product-specific or company-wide).
4. Commission is attributed to the affiliate and reflected in the override's `total_referral_earnings_usd` field.

> **Note**
>
> **Refunds reverse commissions.** If a buyer refunds within the window, the affiliate's earning on that sale is clawed back automatically.

> **Note**
>
> **Affiliates need a Whop company to receive payouts.** Earnings accrue on the record; payouts go to their company balance via [transfers](/developer/platforms/collect-payments-for-connected-accounts#transfers). If they do not have a company yet, onboard them with [connected account enrollment](/developer/platforms/enroll-connected-accounts).

## Create an affiliate

`user_identifier` resolves flexibly. Pass a username, email, user ID, or Discord ID. If an affiliate record already exists for the company + user pair, the existing record is returned (idempotent).

**`TypeScript`**

```typescript TypeScript
import Whop from "@whop/sdk";

const client = new Whop({ apiKey: process.env.WHOP_API_KEY });

const affiliate = await client.affiliates.create({
  company_id: "biz_xxxxxxxxxxxxx",
  user_identifier: "johndoe", // username, email, usr_xxx, or Discord ID
});

console.log(`Affiliate ${affiliate.id} created`);
```

**`Python`**

```python Python
import os
from whop_sdk import Whop

client = Whop(api_key=os.environ["WHOP_API_KEY"])

affiliate = client.affiliates.create(
    company_id="biz_xxxxxxxxxxxxx",
    user_identifier="johndoe",
)

print(f"Affiliate {affiliate.id} created")
```

## Add commission overrides

An affiliate record does not set a commission by itself. Add **overrides** to decide what the affiliate gets paid.

| Override type   | What it does                                               | Required fields                                                         |
| --------------- | ---------------------------------------------------------- | ----------------------------------------------------------------------- |
| **`standard`**  | Per-plan commission, percentage or flat fee                | `plan_id`, `commission_type`, `commission_value`, `applies_to_payments` |
| **`rev_share`** | Percentage revenue share, product-specific or company-wide | `commission_value` (always percentage); `product_id` optional           |

### Standard (per-plan)

**`TypeScript`**

```typescript TypeScript
const override = await client.affiliates.createOverride(affiliate.id, {
  override_type: "standard",
  plan_id: "plan_xxxxxxxxxxxxx",
  commission_type: "percentage",      // "percentage" or "flat_fee"
  commission_value: 40,                // 40% (or $40 if flat_fee)
  applies_to_payments: "first_payment" // "first_payment" or "all_payments"
});

// Share these with the affiliate
console.log(override.product_direct_link);
console.log(override.checkout_direct_link);
```

**`Python`**

```python Python
override = client.affiliates.create_override(
    affiliate.id,
    override_type="standard",
    plan_id="plan_xxxxxxxxxxxxx",
    commission_type="percentage",
    commission_value=40,
    applies_to_payments="first_payment",
)

print(override.product_direct_link)
print(override.checkout_direct_link)
```

`commission_value` rules:

* `"percentage"`: whole number 1–100 (`40` = 40%).
* `"flat_fee"`: dollar amount (`10` = \$10).

`applies_to_payments`:

* `"first_payment"`: affiliate earns only on the initial purchase.
* `"all_payments"`: affiliate earns on every recurring payment too.

### Rev-share (revenue percentage)

Rev-share overrides are always percentage-based. Don't pass `commission_type: "flat_fee"`.

**`TypeScript`**

```typescript TypeScript
// Product-specific: affiliate earns 30% on sales of this product
await client.affiliates.createOverride(affiliate.id, {
  override_type: "rev_share",
  product_id: "prod_xxxxxxxxxxxxx",
  commission_value: 30,
});

// Company-wide: affiliate earns 15% on every product
await client.affiliates.createOverride(affiliate.id, {
  override_type: "rev_share",
  commission_value: 15,
});
```

**`Python`**

```python Python
client.affiliates.create_override(
    affiliate.id,
    override_type="rev_share",
    product_id="prod_xxxxxxxxxxxxx",
    commission_value=30,
)

client.affiliates.create_override(
    affiliate.id,
    override_type="rev_share",
    commission_value=15,
)
```

## Manage overrides

**`TypeScript`**

```typescript TypeScript
// List all overrides for an affiliate
const overrides = await client.affiliates.listOverrides("aff_xxxxxxxxxxxxx");

// Filter by type
const standardOnly = await client.affiliates.listOverrides("aff_xxxxxxxxxxxxx", {
  override_type: "standard",
});

// Retrieve one
const o = await client.affiliates.retrieveOverride("aff_xxxxxxxxxxxxx", "aovr_xxxxxxxxxxxxx");

// Update
await client.affiliates.updateOverride("aff_xxxxxxxxxxxxx", "aovr_xxxxxxxxxxxxx", {
  commission_value: 50,
  applies_to_payments: "all_payments",
});

// Delete (for standard overrides, this also removes the affiliate from that plan)
await client.affiliates.deleteOverride("aff_xxxxxxxxxxxxx", "aovr_xxxxxxxxxxxxx");
```

**`Python`**

```python Python
overrides = client.affiliates.list_overrides("aff_xxxxxxxxxxxxx")

standard_only = client.affiliates.list_overrides(
    "aff_xxxxxxxxxxxxx",
    override_type="standard",
)

o = client.affiliates.retrieve_override("aff_xxxxxxxxxxxxx", "aovr_xxxxxxxxxxxxx")

client.affiliates.update_override(
    "aff_xxxxxxxxxxxxx",
    "aovr_xxxxxxxxxxxxx",
    commission_value=50,
    applies_to_payments="all_payments",
)

client.affiliates.delete_override("aff_xxxxxxxxxxxxx", "aovr_xxxxxxxxxxxxx")
```

## Manage affiliates

**`TypeScript`**

```typescript TypeScript
// List, optionally filtered by status
for await (const page of client.affiliates.list({
  company_id: "biz_xxxxxxxxxxxxx",
  status: "active",
})) {
  console.log(page);
}

const single = await client.affiliates.retrieve("aff_xxxxxxxxxxxxx");

// Archive blocks the affiliate from earning further commissions
await client.affiliates.archive("aff_xxxxxxxxxxxxx");
await client.affiliates.unarchive("aff_xxxxxxxxxxxxx");
```

**`Python`**

```python Python
for page in client.affiliates.list(
    company_id="biz_xxxxxxxxxxxxx",
    status="active",
):
    print(page)

single = client.affiliates.retrieve("aff_xxxxxxxxxxxxx")

client.affiliates.archive("aff_xxxxxxxxxxxxx")
client.affiliates.unarchive("aff_xxxxxxxxxxxxx")
```

## Company-level affiliate settings

Three company fields control how the affiliate program is presented to users. Update them via the Company resource.

**`TypeScript`**

```typescript TypeScript
await client.companies.update("biz_xxxxxxxxxxxxx", {
  affiliate_instructions: "Share your link on social. 30-day cookie window.",
  affiliate_application_required: true,
  featured_affiliate_product_id: "prod_xxxxxxxxxxxxx",
});
```

**`Python`**

```python Python
client.companies.update(
    "biz_xxxxxxxxxxxxx",
    affiliate_instructions="Share your link on social. 30-day cookie window.",
    affiliate_application_required=True,
    featured_affiliate_product_id="prod_xxxxxxxxxxxxx",
)
```

| Field                            | Description                                                         |
| -------------------------------- | ------------------------------------------------------------------- |
| `affiliate_instructions`         | Guidelines shown to affiliates promoting this company               |
| `affiliate_application_required` | Whether users must apply and be approved before becoming affiliates |
| `featured_affiliate_product_id`  | Which product to feature for affiliate promotion                    |

## Tracking earnings

Each override includes a `total_referral_earnings_usd` field that reflects cumulative earnings (in USD) for that specific override. Re-fetch the override (or list overrides on an affiliate) to get the current total.

> **Note**
>
> There is no dedicated `affiliate.*` webhook in v1, and the public `payment` schema does not expose affiliate linkage. Poll `listOverrides` on your payout schedule and compare the latest `total_referral_earnings_usd` values with the last values you stored.

## Override response fields

| Field                         | Description                                                                 |
| ----------------------------- | --------------------------------------------------------------------------- |
| `override_type`               | `"standard"` or `"rev_share"`                                               |
| `commission_type`             | `"percentage"` or `"flat_fee"`                                              |
| `commission_value`            | Percentage (1–100) or flat fee in dollars                                   |
| `applies_to_payments`         | `"first_payment"` or `"all_payments"` (standard only; `null` for rev-share) |
| `plan_id`                     | Plan ID (standard only)                                                     |
| `product_id`                  | Product ID (rev-share only; `null` if company-wide)                         |
| `applies_to_products`         | `"single_product"` or `"all_products"` (rev-share only)                     |
| `product_direct_link`         | Referral link to product page (standard only)                               |
| `checkout_direct_link`        | Referral link to checkout page (standard only)                              |
| `total_referral_earnings_usd` | Cumulative earnings for this override                                       |

## Next steps

#### [Pay out affiliate earnings](/developer/platforms/collect-payments-for-connected-accounts#transfers)

Transfer accrued commissions from your balance to affiliate companies.

#### [Accept payments](/developer/guides/accept-payments)

Checkout configurations attribute sales automatically when referral cookies are set.

#### [Listen to webhooks](/developer/guides/webhooks)

Use `payment.succeeded` for general sales telemetry; affiliate attribution still polls.

#### [Affiliates API reference](/api-reference/affiliates/affiliate)

Full resource. Endpoints, fields, and override schemas.