Skip to main content

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

Commission rates

Transaction typeRateCap
Booking1% of transaction amount$50
Order1.5% of transaction amount$50
Quote$2.00 flat
Custom0.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

StatusMeaning
pendingToken generated; awaiting transaction attribution (24-hour window)
attributedTransaction matched; commission calculated but not yet collected
paidCommission collected via Stripe Connect
expiredNo transaction attributed within 24 hours
disputedListing owner has disputed the attributed commission
Authentication: All referral endpoints require session authentication (dashboard login). Hub API key auth is not supported. Rate limits:
OperationTierLimit
GET /api/v1/hub/referralsfreeStandard per-IP rate limit
POST /api/v1/hub/referrals/:id/disputefreeStandard 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:
ParameterTypeDefaultDescription
limitinteger20Max items to return (1–100)
cursorstringOpaque cursor from a previous response meta.cursor
Response 200:
{
  "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:
FieldTypeDescription
idstringReferral record ID (ULID)
referralTokenstringToken embedded in search results (hub_ref_{ulid})
listingIdstringHub listing ID that generated this referral
apiKeyIdstringHub API key used by the discovering agent
querySnapshotobjectSearch query context that produced this referral
discoveredAtstring (ISO 8601)When the agent discovered the listing
expiresAtstring (ISO 8601)Attribution window expiry (24 hours after discovery)
transactionIdstring | nullStripe PaymentIntent ID, once attributed
transactionAmountinteger | nullTransaction amount in cents
commissionAmountinteger | nullCommission owed in cents
commissionRatestring | nullHuman-readable rate label (e.g. "1%", "flat $2")
statusstringReferral status: pending, attributed, paid, expired, or disputed
attributedAtstring | nullWhen the transaction was attributed to this referral
Errors:
CodeDescription
401Not authenticated
429Rate 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:
ParameterDescription
idReferral ID (ULID) from GET /api/v1/hub/referrals
Request body: None required. Response 200:
{
  "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:
CodeDescription
401Not authenticated
404Referral not found or not owned by the authenticated user
409Referral is not in attributed status (e.g. already paid, expired, or disputed)
429Rate 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.
{
  "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 for commission tracking within the Hub dashboard.