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

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

<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).
</Note>

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

<CodeGroup>
  ```typescript TypeScript theme={null}
  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 theme={null}
  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")
  ```
</CodeGroup>

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

<CodeGroup>
  ```typescript TypeScript theme={null}
  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 theme={null}
  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)
  ```
</CodeGroup>

`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"`.

<CodeGroup>
  ```typescript TypeScript theme={null}
  // 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 theme={null}
  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,
  )
  ```
</CodeGroup>

## Manage overrides

<CodeGroup>
  ```typescript TypeScript theme={null}
  // 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 theme={null}
  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")
  ```
</CodeGroup>

## Manage affiliates

<CodeGroup>
  ```typescript TypeScript theme={null}
  // 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 theme={null}
  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")
  ```
</CodeGroup>

## Company-level affiliate settings

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

<CodeGroup>
  ```typescript TypeScript theme={null}
  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 theme={null}
  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",
  )
  ```
</CodeGroup>

| 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.
</Note>

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

<CardGroup cols={2}>
  <Card title="Pay out affiliate earnings" href="/developer/platforms/collect-payments-for-connected-accounts#transfers">
    Transfer accrued commissions from your balance to affiliate companies.
  </Card>

  <Card title="Accept payments" href="/developer/guides/accept-payments">
    Checkout configurations attribute sales automatically when referral cookies are set.
  </Card>

  <Card title="Listen to webhooks" href="/developer/guides/webhooks">
    Use `payment.succeeded` for general sales telemetry; affiliate attribution still polls.
  </Card>

  <Card title="Affiliates API reference" href="/api-reference/affiliates/affiliate">
    Full resource. Endpoints, fields, and override schemas.
  </Card>
</CardGroup>
