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

# Referral Commissions

> View referral history and dispute commissions earned through Hub discovery

## Overview

When an AI agent discovers your listing through Hub and the interaction results in a completed transaction, ezForge records a **referral** linking the discovery event to the transaction. Listing owners can view their referral history, track commission amounts, and dispute any attributed commission through these endpoints.

<Info>
  Referral commission tracking requires a transaction-capable MCP server (bookings, orders, or purchases). All listing tiers (Basic, Featured, Premium) generate commissions. Ready servers receive referral token integration automatically.
</Info>

## Commission rates

| Transaction type | Rate                       | Cap  |
| ---------------- | -------------------------- | ---- |
| Booking          | 1% of transaction amount   | \$50 |
| Order            | 1.5% of transaction amount | \$50 |
| Quote            | \$2.00 flat                | —    |
| Custom           | 0.5% of transaction amount | \$50 |

Basic listing owners receive a commission-free ramp on the first \$500/month of transaction volume. Featured and Premium listings do not receive this ramp.

## Referral lifecycle

| Status       | Meaning                                                            |
| ------------ | ------------------------------------------------------------------ |
| `pending`    | Token generated; awaiting transaction attribution (24-hour window) |
| `attributed` | Transaction matched; commission calculated but not yet collected   |
| `paid`       | Commission collected via Stripe Connect                            |
| `expired`    | No transaction attributed within 24 hours                          |
| `disputed`   | Listing owner has disputed the attributed commission               |

**Authentication:** All referral endpoints require session authentication (dashboard login). Hub API key auth is not supported.

**Rate limits:**

| Operation                                | Tier   | Limit                      |
| ---------------------------------------- | ------ | -------------------------- |
| `GET /api/v1/hub/referrals`              | `free` | Standard per-IP rate limit |
| `POST /api/v1/hub/referrals/:id/dispute` | `free` | Standard per-IP rate limit |

***

## List referral history

```
GET /api/v1/hub/referrals
```

Returns a cursor-paginated list of referrals for all Hub listings owned by the authenticated user, ordered by referral ID ascending (chronological). All listing tiers generate commissions; Basic listings receive a commission-free ramp on the first \$500/month of facilitated volume (see commission rates above).

**Authentication:** Session cookie (dashboard login).

**Query parameters:**

| Parameter | Type    | Default | Description                                          |
| --------- | ------- | ------- | ---------------------------------------------------- |
| `limit`   | integer | 20      | Max items to return (1–100)                          |
| `cursor`  | string  | —       | Opaque cursor from a previous response `meta.cursor` |

**Response `200`:**

```json theme={null}
{
  "data": [
    {
      "id": "01J9Z3K2M4N5P6Q7R8S9T0U1V2",
      "referralToken": "hub_ref_01J9Z3K2M4N5P6Q7R8S9T0U1V2",
      "listingId": "01J9Z3K2M4N5P6Q7R8S9T0U1V3",
      "apiKeyId": "01J9Z3K2M4N5P6Q7R8S9T0U1V4",
      "querySnapshot": { "q": "plumber detroit", "vertical": "plumbing" },
      "discoveredAt": "2026-04-20T14:00:00Z",
      "expiresAt": "2026-04-21T14:00:00Z",
      "transactionId": "pi_3OxyzABC123",
      "transactionAmount": 15000,
      "commissionAmount": 150,
      "commissionRate": "1%",
      "status": "attributed",
      "attributedAt": "2026-04-20T16:30:00Z"
    }
  ],
  "meta": {
    "hasMore": true,
    "cursor": "MDFKOVozSzJNNE41UDZRN1I4UzlUMFUxVjI"
  }
}
```

**Response fields:**

| Field               | Type              | Description                                                                |
| ------------------- | ----------------- | -------------------------------------------------------------------------- |
| `id`                | string            | Referral record ID (ULID)                                                  |
| `referralToken`     | string            | Token embedded in search results (`hub_ref_{ulid}`)                        |
| `listingId`         | string            | Hub listing ID that generated this referral                                |
| `apiKeyId`          | string            | Hub API key used by the discovering agent                                  |
| `querySnapshot`     | object            | Search query context that produced this referral                           |
| `discoveredAt`      | string (ISO 8601) | When the agent discovered the listing                                      |
| `expiresAt`         | string (ISO 8601) | Attribution window expiry (24 hours after discovery)                       |
| `transactionId`     | string \| null    | Stripe `PaymentIntent` ID, once attributed                                 |
| `transactionAmount` | integer \| null   | Transaction amount in cents                                                |
| `commissionAmount`  | integer \| null   | Commission owed in cents                                                   |
| `commissionRate`    | string \| null    | Human-readable rate label (e.g. `"1%"`, `"flat $2"`)                       |
| `status`            | string            | Referral status: `pending`, `attributed`, `paid`, `expired`, or `disputed` |
| `attributedAt`      | string \| null    | When the transaction was attributed to this referral                       |

**Errors:**

| Code  | Description         |
| ----- | ------------------- |
| `401` | Not authenticated   |
| `429` | Rate limit exceeded |

***

## Dispute a commission

```
POST /api/v1/hub/referrals/:id/dispute
```

Flags an `attributed` referral for manual review by the ezForge team. Only the listing owner may dispute, and only referrals in `attributed` status can be disputed — referrals that are already `paid`, `expired`, or `disputed` will return an error.

**Authentication:** Session cookie (dashboard login).

**Path parameters:**

| Parameter | Description                                         |
| --------- | --------------------------------------------------- |
| `id`      | Referral ID (ULID) from `GET /api/v1/hub/referrals` |

**Request body:** None required.

**Response `200`:**

```json theme={null}
{
  "data": {
    "id": "01J9Z3K2M4N5P6Q7R8S9T0U1V2",
    "referralToken": "hub_ref_01J9Z3K2M4N5P6Q7R8S9T0U1V2",
    "listingId": "01J9Z3K2M4N5P6Q7R8S9T0U1V3",
    "apiKeyId": "01J9Z3K2M4N5P6Q7R8S9T0U1V4",
    "querySnapshot": { "q": "plumber detroit", "vertical": "plumbing" },
    "discoveredAt": "2026-04-20T14:00:00Z",
    "expiresAt": "2026-04-21T14:00:00Z",
    "transactionId": "pi_3OxyzABC123",
    "transactionAmount": 15000,
    "commissionAmount": 150,
    "commissionRate": "1%",
    "status": "disputed",
    "attributedAt": "2026-04-20T16:30:00Z"
  }
}
```

**Errors:**

| Code  | Description                                                                            |
| ----- | -------------------------------------------------------------------------------------- |
| `401` | Not authenticated                                                                      |
| `404` | Referral not found or not owned by the authenticated user                              |
| `409` | Referral is not in `attributed` status (e.g. already `paid`, `expired`, or `disputed`) |
| `429` | Rate limit exceeded                                                                    |

***

## Using referral tokens

Referral tokens (`hub_ref_{ulid}`) are automatically included in Hub search results and listing detail responses when accessed via a Hub API key. Pass the token from your agent's transaction context to the Stripe `PaymentIntent` metadata field `hub_referral_id` to trigger attribution.

```json theme={null}
{
  "metadata": {
    "hub_referral_id": "hub_ref_01J9Z3K2M4N5P6Q7R8S9T0U1V2"
  }
}
```

ezForge listens for `payment_intent.succeeded` webhooks and automatically matches the token, computes the commission, and updates the referral status. No additional integration is required for Ready servers — referral token injection is handled automatically.

See [Analytics](/hub/analytics) for commission tracking within the Hub dashboard.
