---
title: Referral program
description: Taking a fee on the quotes you originate, and claiming what accrues.
---
import { PANEL_URL } from "/snippets/vars.mdx";
Attach referrer addresses to a quote and a share of it accrues to you. Fees are recorded per fulfilled order, claimed in bulk as a signed voucher, and redeemed on chain by whoever holds the voucher's referrer address.
## Setting a referrer
`referrers` is a list of address and basis-point pairs on `GetQuote` and `PreviewQuote`.
```ts
const response = await hular.getQuote({
...request,
referrers: [{ address: "0x...", bps: 10 }],
});
```
The fee is priced into the quote like every other component: it appears in `fee_breakdown` as `referrer_fee`, and `amount_out` is already net of it. Preview and quote agree, so the number you show the user is the number they get.
Referrer addresses must be valid for the chain the fee accrues on. An unusable list fails the quote with `invalid referrer list`.
Your basis points come out of the user's output, not out of the operator spread. Setting a high value makes your route quote worse against competitors.
## How it accrues
Accrual happens off chain, in the operator's records. Each fulfilled order carries its referrer list in the stored order parameters, and the amount owed is computed from the deposit. The accrual is written once both the deposit and the fulfillment have settled past the per-chain deep-reorg depth, so a freshly fulfilled order becomes claimable after a short settlement delay rather than instantly. Nothing is transferred per order: there is no per-swap payout transaction, which is what keeps the fee cheap to offer.
Same-chain swaps participate too. Their fee is withheld from the swap output on chain and stays in the solver vault.
Balances are grouped by referrer address, chain, and token. A partner earning on USDC across two chains has two balances, and each is claimed separately.
## Claiming
Claiming is self-served from the partner panel at {PANEL_URL}, or programmatically through `PartnerApi`. Both require a partner session; referral earnings are not publicly queryable.
`GetPartnerReferrals` returns balances grouped by referrer, chain, and token, with the order count behind each.
`ClaimPartnerReferrer` takes a referrer, chain, and token. It marks the selected orders claimed, totals them, and returns a voucher.
Send the voucher to the router. The response includes ready-to-send calldata.
## Vouchers
A voucher is a signed instruction to pay an exact amount of one token to one referrer address. On EVM it is an EIP-712 payload (id, token, referrer, amount) signed by the operator's voucher key and redeemed against the solver vault. On Solana it is the same shape signed with ed25519 and verified through the instructions sysvar.
| Property | Behavior |
| --- | --- |
| Expiry | None. A voucher stays valid indefinitely. |
| Recipient | Fixed. It can only ever pay the referrer address embedded in it. |
| Reuse | Impossible. The router marks the id used on redemption. |
| Payer | Anyone. Redeeming from a different wallet still pays the referrer. |
```solidity
function redeemVoucher(
bytes32 id,
address token,
address referrer,
uint256 amount,
bytes calldata signature
) external;
```
`BuildVoucherRedemption` returns a prepared transaction for a given voucher and payer, which is the simpler path on Solana where the redemption needs an accompanying ed25519 instruction.
`ListPartnerVouchers` returns every voucher with its redemption status, kept current from on-chain `VoucherRedeemed` events. Use it to reconcile: a voucher that is issued but not redeemed is money sitting unclaimed, and it does not expire.
See [Partner panel](/integration/partner-panel) for the session flow behind these calls.