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

# Your own referral page

> Build a referral page in your own design on the API: find each user's partner by your own user id, let them pick their link, and show their referrals and earnings.

The [embedded dashboard](https://docs.tolt.com/guides/refer-a-friend.md) is the quickest way to give users a referral page. When you want the page in your own design, build it on the API instead. Tolt keeps your user id on the partner as `external_id`, so you look partners up by your id and don't store anything from Tolt in your database.

Your appyour referral pageYour backendAPI keyToltplatform.tolt.com*1*GET /api/referrals*2*GET /v2/partners?external\_id=…*3*new? POST /v2/partners*4*GET links, customers, commissions*5*link, referrals, earnings

## Build it

**1. Install the SDK and set two variables**

```bash theme={"system"}
npm install @tolt/api
```

Add your [API key](https://docs.tolt.com/api-reference/authentication.md) and the id of the program users should join to your server's environment. The API key is secret, so every call below runs on your server.

```bash .env theme={"system"}
TOLT_API_KEY=tlt_live_...
TOLT_PROGRAM_ID=prg_...
```

**2. Find the user's partner**

Look the partner up by your own user id. `external_id` is unique within a program, so you get at most one.

```ts referrals.ts theme={"system"}
import { ToltApi, ToltApiClient } from "@tolt/api";

const tolt = new ToltApiClient({ token: process.env.TOLT_API_KEY! });
const programId = process.env.TOLT_PROGRAM_ID!;

export async function findPartner(userId: string) {
  const { data } = await tolt.partners.list({
    program_id: programId,
    external_id: userId,
  });
  return data[0] ?? null;
}
```

No partner means the user hasn't joined yet. Show them a field for their link and a **Create link** button.

**3. Create their link**

When they submit, create the partner with your user id and the slug they picked. The partner is active right away, and their link is `?ref=<slug>` on your site.

```ts referrals.ts theme={"system"}
export async function createLink(
  user: { id: string; email: string },
  slug: string,
) {
  try {
    const { data } = await tolt.partners.create({
      program_id: programId,
      external_id: user.id,
      email: user.email,
      link: { value: slug },
    });
    return data.link;
  } catch (error) {
    if (error instanceof ToltApi.ConflictError) return null;
    throw error;
  }
}
```

`null` means the slug is taken, so ask for another one. Send `first_name` and `last_name` too if you have them. Leave out `link` and Tolt picks the slug from their name or email.

**4. Show their link, referrals and earnings**

Load everything the page shows in one go:

```ts referrals.ts theme={"system"}
type Earned = { upcoming: number; paid: number };

export async function referralPage(partnerId: string) {
  const [links, customers, commissions, program] =
    await Promise.all([
      tolt.links.list({ partner_id: partnerId }),
      tolt.customers.list({ partner_id: partnerId }),
      tolt.commissions.list({
        partner_id: partnerId,
        limit: 100,
      }),
      tolt.programs.get({ id: programId }),
    ]);

  const earnings: Record<string, Earned> = {};
  for await (const c of commissions) {
    const key = c.currency ?? program.data.currency_code ?? "usd";
    const sum = (earnings[key] ??= { upcoming: 0, paid: 0 });
    if (c.status === "paid") sum.paid += Number(c.amount);
    if (c.status === "pending" || c.status === "approved")
      sum.upcoming += Number(c.amount);
  }

  const link = links.data[0];
  const url = new URL(program.data.website_url!);
  url.searchParams.set(link.param!, link.value!);
  return {
    url: url.toString(),
    referrals: customers.data,
    earnings,
  };
}
```

`for await` walks every page of commissions, so the totals cover all of them. `earnings` holds a total per currency, in cents, such as `{ usd: { upcoming: 4000, paid: 12000 } }`; a commission without a currency counts in the program's. `customers.list` returns the 10 newest referrals; pass `limit` for more, up to 100.

**5. Let them change their link**

```ts referrals.ts theme={"system"}
await tolt.links.update({ id: link.id, value: newSlug });
```

URLs with the old slug stop crediting them, so say so before they save.

**6. Send them to the portal for payouts**

Payout details, tax forms and identity checks stay in your partner portal. Link to it from the page:

```ts theme={"system"}
const portal = `https://${program.data.subdomain}.tolt.io/login`;
```

Use your portal's custom domain instead if it has one.

> [accordion] Edge cases
>
> * **Already a partner.** A user who joined your program before, with the same email, makes `partners.create` return `409` on `email`. Find them with `partners.list({ program_id, search: user.email })`, check the email matches exactly, and save your id with `partners.update({ id, external_id: user.id })`. From then on step 2 finds them.
> * **Changed email.** The lookup uses your user id, so a user who changes their email in your app keeps the same partner. Program emails still go to the email the partner was created with.
> * **Suspended or rejected.** Step 2 returns these partners too. Check `status` and show a short message instead of the link.
> * **Review first.** Partners created here are active right away. To approve them before they earn, create them with `status: "pending"` (see [Partner signup](https://docs.tolt.com/guides/partner-signup.md)).

## Tips

* **Show referrals with care.** They're your customers. A first name or a masked email is usually enough.
* **Hear about new referrals.** The [`customer.created`](https://docs.tolt.com/webhooks/events/customer-created) and [`commission.created`](https://docs.tolt.com/webhooks/events/commission-created) webhooks carry the `partner_id`, so you can notify the user in your app.
* **Prefer a ready-made page?** The [refer-a-friend guide](https://docs.tolt.com/guides/refer-a-friend.md) embeds a dashboard with the same data in a few lines.

> [!NOTE]
>
> Referral links only earn once your site records the click and the signup. If you haven't set that up, start with the [Quickstart](https://docs.tolt.com/quickstart.md).


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.