# Rewards that are not cash

Free months, credit, perks, gift cards and the friend's discount, for either side, and the grants that track them.

A reward rule can give more than money, and to either side. "You both get a
free month", "Give 20% off, get 10.00 in credit", "A tote bag for every friend
who joins": each is a rule, set up exactly like a cash rule (see
[Reward rules](https://boltclaw.ai/docs/rewards)), with two more fields.

- **`reward_type`**: what it gives. `cash` (the default) is a commission, paid
  out as before; `credit`, `free_period`, `discount`, `perk` and `gift_card` are
  **grants**, given in your own system or through your Stripe.
- **`beneficiary`**: who receives it. `promoter` (the default) is the person who
  shared; `referee` is the friend who arrived through the link.

Both are fixed once the rule exists, like its event and audience: "the same
reward for someone else" is a different rule. Every rule written before is
cash for the promoter, and pays exactly as it did.

| `reward_type` | Its fields | For |
|---|---|---|
| `cash` | `kind`, `percent_bps` or `amount_minor`, `duration` | the promoter only |
| `credit` | `kind`, `percent_bps` (of the sale) or `amount_minor` | either side |
| `free_period` | `period_count`, `period_unit` (`day` 1–365 or `month` 1–36) | either side |
| `discount` | `kind`, `percent_bps` or `amount_minor`, `discount_duration` (`once`, `months` with `discount_months` 1–36, `forever`) | the friend only, on a sale, once per customer |
| `perk` | `perk_text`, your words, at most 120 characters | either side |
| `gift_card` | `kind`, `percent_bps` (of the sale) or `amount_minor` | either side |

```bash
curl -X POST https://api.boltclaw.ai/v1/referrals/programs/$PROGRAM_ID/rewards \
  -H "Authorization: Bearer $BOLTCLAW_KEY" -H "Content-Type: application/json" \
  -d '{"event": "sale", "reward_type": "free_period", "period_count": 1, "period_unit": "month", "duration": "once"}'

curl -X POST https://api.boltclaw.ai/v1/referrals/programs/$PROGRAM_ID/rewards \
  -H "Authorization: Bearer $BOLTCLAW_KEY" -H "Content-Type: application/json" \
  -d '{"event": "sale", "beneficiary": "referee", "reward_type": "discount", "kind": "percent", "percent_bps": 10000, "discount_duration": "months", "discount_months": 1}'
```

Those two rules are the "Refer a friend" template: you both get one free month.
A rule's conditions, scope, priority and per-customer ceiling work as for cash,
and each side picks its rule the same way (the most specific match wins). A
milestone bonus stays cash. Cash and grants are counted apart: a program's
monthly ceiling counts commissions only.

## Grants

What a rule that is not cash gives is a **grant**: one row per person per
reward, which says what it is, whose it is and where it stands.

| `status` | Means |
|---|---|
| `pending` | Waiting out the program's hold, in case the sale is refunded. |
| `ready` | Past the hold. Yours to give, or Bolt Claw gives it through your Stripe. |
| `fulfilled` | Given, with a reference. |
| `failed` | Could not be given yet, with your reason. You can still give it later. |
| `cancelled` | The sale was refunded or disputed before it was given. |
| `reversed` | The sale was refunded or disputed after it was given. Take it back if your own terms allow; Bolt Claw never does. |

`GET /v1/referrals/programs/{id}/grants` lists them (filter by `status`,
`type` or `recipient`), and the program's **Grants** tab shows the same with
a CSV export. Each names its recipient as you know them: one of your own users
by your `external_id`, an affiliate by their name in the program, or the friend
by your own id for the customer.

A grant for a sale reported through the API (by your server, or by an AI
assistant) is always yours to give: Bolt Claw gives automatically only for a sale
your Stripe itself reported. While Bolt Claw is giving one through Stripe, marking it
given or failed answers `409` for a few minutes, so it is never given twice.

**Give it, then say so.** When `referral.grant.ready` arrives, add the month or
the credit in your own system, then record it with your reference:

```bash
curl -X POST https://api.boltclaw.ai/v1/referrals/grants/$GRANT_ID/fulfil \
  -H "Authorization: Bearer $BOLTCLAW_KEY" -H "Content-Type: application/json" \
  -H "Idempotency-Key: grant-$GRANT_ID" \
  -d '{"reference": "CN-20931"}'
```

The same reference again answers the grant as it is and changes nothing, so a
retry is safe; a different reference for a grant already given is `409`. If it
cannot be given, `POST /v1/referrals/grants/{id}/fail` with a `reason` (shown to
you, not to the person) leaves it `failed` until you can. Both are recorded in
the activity log, and an AI assistant must always ask a person first.

**Or let Stripe give it.** With a restricted Stripe key set, for a sale your own
Stripe reported, a ready `credit` becomes a balance credit on the customer and a
ready `free_period` a free month
on their subscription, each called once (see
[Stripe codes and credits](https://boltclaw.ai/docs/referral-stripe-codes)). Anything Stripe cannot
do comes back to your list as `ready`, with the reason.

**The friend's discount** is the one grant you never give by hand: it is applied
at your checkout. Bolt Claw records it as `fulfilled` with the sale, and only
when the sale shows it was used: a discount code, a Stripe coupon or promotion
code on the payment, or `referral.discount_applied: true` in your conversion.

## What stops a reward

- **A refund or a dispute.** Any refund of the sale cancels its grants not yet
  given and marks the given ones `reversed`: a free month cannot be split.
- **Self-referral.** When the customer is the promoter themselves (your id for
  them, or the same email), neither side gets a grant and the conversion is
  flagged for you to look at.
- **Signups alone.** A rule on `lead` is held like a sale's, and the program
  gives at most `lead_grant_daily_cap` of them a day (100 by default), so
  invented signups cannot farm credit.
- **The rule's own ceiling**, `cap_minor`, for credit and gift cards: the most
  one customer earns from it in total.

## What people see

The promoter sees their grants in words on their page or in the
[referral panel](https://boltclaw.ai/docs/referral-panel): "1 month free, on its way: ready on
3 Nov", then "given on 5 Nov". The friend sees their side in the
[welcome](https://boltclaw.ai/docs/referral-welcome). A webhook event marks each step:
`referral.grant.ready`, `referral.grant.fulfilled`, `referral.grant.cancelled`
and `referral.grant.reversed` (see [Webhooks](https://boltclaw.ai/docs/webhooks)).

<!-- https://boltclaw.ai/docs/rewards-not-cash as markdown. Generated from openapi.yaml; API version 1.22.0. -->
<!-- Every /docs page answers as markdown: add .md to its path, or send Accept: text/markdown. -->
