> For the complete documentation index, see [llms.txt](https://docs.fuul.xyz/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.fuul.xyz/developer-guide/referral-codes.md).

# Referral Codes

Referral codes let projects create shareable codes for their users. When a user accepts a referral code, a permanent referrer-user relationship is created. The SDK provides methods to list, generate, check, use, and delete referral codes.

Referral codes are generated by the **project** on behalf of users — they are auto-generated (random 7-char alphanumeric) and scoped to a single project. Affiliate codes can also be [activated as referral codes](/core-concepts/affiliates/referral-codes-vs-invite-codes.md#using-an-affiliate-code-as-a-referral-code) within a project.

{% hint style="info" %}
Referral codes are different from [affiliate codes](/developer-guide/creating-affiliate-links-or-codes.md). Affiliate codes are custom, created by the affiliate with a wallet signature, and embedded in tracking links (`?af=code`) for automatic attribution. Referral codes are project-generated and require the user to explicitly accept the code.

For a full comparison, see [Affiliate Codes vs Referral Codes](/core-concepts/affiliates/referral-codes-vs-invite-codes.md).
{% endhint %}

## List a user's referral codes

```typescript
import { Fuul, UserIdentifierType } from '@fuul/sdk';

const result = await Fuul.listUserReferralCodes({
  user_identifier: '0x1234...',
  user_identifier_type: UserIdentifierType.EvmAddress,
});
```

## Generating referral codes

Generate 1-50 random codes (7-char alphanumeric) on behalf of a user:

```typescript
import { Fuul, UserIdentifierType } from '@fuul/sdk';

const codes = await Fuul.generateReferralCodes({
  user_identifier: '0x1234...',
  user_identifier_type: UserIdentifierType.EvmAddress,
  quantity: 5,        // 1-50
  max_uses: 10,       // per code, or null for unlimited
});
// Returns: [{ code }, ...]
```

## Check referral status

Check whether a user was referred and with which code:

```typescript
const status = await Fuul.getReferralStatus({
  user_identifier: '0x1234...',
  user_identifier_type: UserIdentifierType.EvmAddress,
});

if (status.referred) {
  console.log('User was referred with code:', status.code);
}
```

## Check if a code is available

```typescript
const result = await Fuul.getReferralCode({ code: 'abc1234' });

if (result.available) {
  console.log('Referral code is available!');
}
```

## Accept a referral code

When a user accepts a referral code, a permanent referrer-user relationship is created — all future conversions by this user will be attributed to the referrer.

```typescript
await Fuul.useReferralCode({
  code: 'abc1234',
  user_identifier: '0x1234...',
  user_identifier_type: UserIdentifierType.EvmAddress,
  signature: '0xabc...',
  signature_message: 'I am using invite code abc1234',
  chain_id: 1, // Only for smart contract wallets
});
```

{% hint style="info" %}
The signed message must follow this exact format: `I am using invite code ${code}`

Note: the signature says "invite code" for legacy reasons — this applies to all referral codes, regardless of how your project uses them.

Requiring a signature ensures event validity and prevents fraud. This is mandatory.
{% endhint %}

## Set a referrer via API

If you manage your own referral system (e.g. a fintech or exchange with existing user relationships), you can create or update referrer-referee relationships directly through the API instead of using referral codes ([API reference](https://fuul.readme.io/reference/put_v1-user-referrers)):

```bash
curl -X PUT https://api.fuul.xyz/api/v1/user-referrers   -H "Content-Type: application/json"   -H "Authorization: Bearer your-service-role-key"   -d '{
    "user_identifier": "0x1234...",
    "user_identifier_type": "evm_address",
    "referrer_identifier": "0x5678...",
    "referrer_identifier_type": "evm_address",
    "referral_code": "abc1234"
  }'
```

If you include a `referral_code`, the code is validated and its rebate rate is locked into the relationship. The response includes a `referral_code_id` you can use to trace which code established the referral.

{% hint style="info" %}
This endpoint requires a `service_role` API key. If the user already has a referrer, the existing relationship is overwritten.
{% endhint %}

## Remove a referrer via API

To delete an admin-managed referrer-user relationship, use the `DELETE /api/v1/user-referrers` endpoint ([API reference](https://fuul.readme.io/reference/delete_v1-user-referrers)):

```bash
curl -X DELETE https://api.fuul.xyz/api/v1/user-referrers \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer your-service-role-key" \
  -d '{
    "user_identifier": "0x1234...",
    "user_identifier_type": "evm_address"
  }'
```

{% hint style="info" %}
This endpoint requires a `service_role` API key. It removes the referrer relationship for the specified user.

Add `?force=true` to the query string to force-delete all referral code associations for this user in a single call — including any that match the current referrer. Without `force`, the endpoint returns `422` if matching associations exist.
{% endhint %}

## List referral relationships via API

If you mirror Fuul's referral data into your own systems, use `GET /api/v1/user-referrers` to read the project-wide referral bridge for incremental ingestion. Each result represents one direct (level 1) referrer-user relationship, with the upstream chain nested under `referral_chain`:

```bash
curl -X GET "https://api.fuul.xyz/api/v1/user-referrers?updated_since=2026-06-01T00:00:00Z&limit=500" \
  -H "Authorization: Bearer your-service-role-key"
```

**Response shape:**

```json
{
  "results": [
    {
      "user_identifier": "0x1234...",
      "user_identifier_type": "evm_address",
      "referrer_identifier": "0x5678...",
      "referrer_identifier_type": "evm_address",
      "referral_chain": {
        "referrer_2": "0x9abc...",
        "referrer_3": null,
        "referrer_4": null
      },
      "referral_code": "abc1234",
      "source": "code_acceptance",
      "reason": "via_endpoint",
      "rebate_rate": "0.1",
      "created_at": "2026-06-01T14:30:00Z",
      "updated_at": "2026-06-01T14:30:00Z"
    }
  ],
  "next_cursor": "01J...",
  "count": 1
}
```

| Field                                              | Description                                                                                |
| -------------------------------------------------- | ------------------------------------------------------------------------------------------ |
| `referrer_identifier` / `referrer_identifier_type` | The direct (level 1) referrer                                                              |
| `referral_chain.referrer_2` … `referrer_4`         | Upstream levels 2–4, computed live at read time; `null` when there is no upstream referrer |
| `rebate_rate`                                      | Rebate rate locked into the relationship (from the referral code, when present)            |
| `next_cursor`                                      | Pass back as `after_id` to fetch the next page; `null` on the last page                    |

**Query params:** `created_since`, `updated_since` (ISO 8601), `after_id` (cursor), `limit` (default `500`, max `1000`).

{% hint style="warning" %}
This endpoint requires a `service_role` API key.

A change to an upstream relationship can alter a descendant's derived levels 2–4 **without** updating that descendant's `updated_at`. If you rely on `updated_since` for incremental syncs, run a periodic full backfill (paging with `after_id` and no time filter) to catch chain changes.
{% endhint %}

## Get user referrer

Get the current referrer for a specific user:

```typescript
import { Fuul } from '@fuul/sdk';

const referrer = await Fuul.getUserReferrer({
  user_identifier: '0x1234...',
  user_identifier_type: 'evm_address',
});
```

## Delete a referral

Allows users to remove a referral relationship they have, freeing up a use on the referral code. The referral code's usage count will be incremented by one.

```typescript
await Fuul.deleteReferral({
  code: 'abc1234',
  user_identifier: '0x1234...',
  user_identifier_type: UserIdentifierType.EvmAddress,
  referrer_identifier: '0xabcde...',
  referrer_identifier_type: UserIdentifierType.EvmAddress,
  signature: '0xabc...',
  signature_message: 'I am deleting referral for user 0x1234... from code abc1234',
});
```

{% hint style="info" %}
The signed message must follow this exact format: `I am deleting referral for user ${user_identifier} from code ${code}`
{% endhint %}

## Admin: referral code lookup

Search and inspect referral codes across all users in your project (requires admin API key):

| Endpoint                                                          | Description                                                                                              |
| ----------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------- |
| `GET /api/v1/projects/:projectId/affiliates/referral-codes`       | List referral codes with optional `search` param — ILIKE match on code or user identifier, max 200 chars |
| `GET /api/v1/projects/:projectId/affiliates/referral-codes/stats` | Aggregated stats for referral codes                                                                      |

## API reference

| Feature                             | API endpoint                                 | Reference                                                                        |
| ----------------------------------- | -------------------------------------------- | -------------------------------------------------------------------------------- |
| List user's codes                   | `GET /v1/referral-codes`                     | [View](https://fuul.readme.io/reference/getreferralcodesbyowner)                 |
| Generate codes                      | `POST /v1/referral-codes`                    | [View](https://fuul.readme.io/reference/generatereferralcodesbatch)              |
| Check code availability             | `GET /v1/referral-codes/{code}`              | [View](https://fuul.readme.io/reference/getreferralcodesbyowner-code)            |
| Update code                         | `PATCH /v1/referral-codes/{code}`            | [View](https://fuul.readme.io/reference/updatereferralcode)                      |
| Check referral status               | `GET /v1/referral-codes/status`              | [View](https://fuul.readme.io/reference/getreferralcodesbyowner-status)          |
| Use referral code                   | `PATCH /v1/referral-codes/{code}/use`        | [View](https://fuul.readme.io/reference/updatereferralcode-use)                  |
| Delete referral                     | `DELETE /v1/referral-codes/{code}/referrals` | [View](https://fuul.readme.io/reference/delete_v1-referral-codes-code-referrals) |
| Set referrer via API                | `PUT /v1/user-referrers`                     | [View](https://fuul.readme.io/reference/put_v1-user-referrers)                   |
| Remove referrer via API             | `DELETE /v1/user-referrers`                  | [View](https://fuul.readme.io/reference/delete_v1-user-referrers)                |
| List referral relationships via API | `GET /v1/user-referrers`                     | [Section above](#list-referral-relationships-via-api)                            |
| Get user referrer                   | `GET /v1/user/referrer`                      | [View](https://fuul.readme.io/reference/getuserreferrer)                         |
