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

# Referrals

> Enroll a user as a referrer and report referred signups — the API behind product-led referral programmes.

These two endpoints drive [product-led referrals](/affiliate/referral-widget): enroll each user as
a referrer, then tell TrackRev when a referred person signs up so the inviter earns their reward.
Both accept a **publishable** (`pk_`) or secret (`lk_`) key, so they're safe to call from the
browser.

## Enroll a referrer

<RequestExample>
  ```bash cURL theme={null}
  curl -X POST "https://app.trackrev.io/api/v1/referrals/enroll" \
    -H "Authorization: Bearer <pk_ or lk_ key>" \
    -H "Content-Type: application/json" \
    -d '{
      "email": "user@example.com",
      "external_user_id": "USER_123",
      "tier": "paid"
    }'
  ```
</RequestExample>

`POST /api/v1/referrals/enroll` — enroll a user as a referrer and mint their referral link.
Idempotent on `(workspace, external_user_id)`.

<ParamField body="email" type="string" required>The user's email.</ParamField>
<ParamField body="external_user_id" type="string" required>Your stable user id.</ParamField>
<ParamField body="tier" type="string" required>`free` or `paid` — sets the reward amount.</ParamField>
<ParamField body="program_id" type="string">Target a specific programme; defaults to your most recent one.</ParamField>
<ParamField body="name" type="string">The user's name.</ParamField>
<ParamField body="device_id" type="string">A device fingerprint, used for self-referral checks.</ParamField>

<ResponseField name="partner_id" type="string" />

<ResponseField name="program_id" type="string" />

<ResponseField name="referral_link" type="string">The user's shareable referral URL.</ResponseField>
<ResponseField name="status" type="string">The enrollment status (auto-approved for referrals).</ResponseField>

<ResponseExample>
  ```json Response theme={null}
  {
    "partner_id": "pa1...",
    "program_id": "p1...",
    "referral_link": "https://acme.trackrev.io/user-123",
    "status": "approved"
  }
  ```
</ResponseExample>

## Report a signup

<RequestExample>
  ```bash cURL theme={null}
  curl -X POST "https://app.trackrev.io/api/v1/referrals/report-signup" \
    -H "Authorization: Bearer <pk_ or lk_ key>" \
    -H "Content-Type: application/json" \
    -d '{
      "new_user_external_user_id": "USER_456",
      "email": "friend@example.com",
      "ref_code": "user-123"
    }'
  ```
</RequestExample>

`POST /api/v1/referrals/report-signup` — tell TrackRev that a referred user signed up, so the
referrer earns their reward. Idempotent per new user.

<ParamField body="new_user_external_user_id" type="string" required>The new user's id.</ParamField>
<ParamField body="email" type="string">The new user's email.</ParamField>
<ParamField body="device_id" type="string">The new user's device fingerprint (for self-referral checks).</ParamField>
<ParamField body="ref_code" type="string">The referrer's link slug — the primary way to resolve who referred them.</ParamField>
<ParamField body="_vid" type="string">A visitor id — resolves the referrer from the most recent click if no `ref_code`.</ParamField>
<ParamField body="referrer_external_user_id" type="string">Name the referrer explicitly.</ParamField>

The referrer is resolved in order: `ref_code` → `_vid` → `referrer_external_user_id`. TrackRev runs
[self-referral checks](/affiliate/fraud-detection); blocked grants are recorded as revoked and no
reward webhook fires.

<ResponseField name="matched" type="boolean">Whether a referrer was found.</ResponseField>

<ResponseField name="program_id" type="string" />

<ResponseField name="partner_id" type="string" />

<ResponseField name="blocked" type="boolean">Whether the reward was blocked as a self-referral.</ResponseField>

<ResponseField name="block_reason" type="string | null" />

<ResponseExample>
  ```json Response theme={null}
  { "matched": true, "program_id": "p1...", "partner_id": "pa1...", "blocked": false, "block_reason": null }
  ```
</ResponseExample>

<Note>
  If no referrer matches, the response is `{ "matched": false }` with a `200` status — a signup with
  no referrer isn't an error.
</Note>
