If you take payments with Stripe, a friend can use their referrer's code at Stripe Checkout and the sale is still credited, a friend's discount can be a real Stripe coupon, and a free month or credit can be given for you. There are two levels, and the first needs nothing from you.
Without a key
The integration you connected on the program's Integration tab (the signing
secret and the events you send us) already does most of it. Add three events
to the endpoint in Stripe: promotion_code.created, promotion_code.updated
and customer.discount.created.
- When one of your promotion codes in Stripe has the same text as one of the program's discount codes (ignoring case), Bolt Claw remembers its id for that program only. The same code text in another merchant's Stripe never credits anybody of yours.
- A
checkout.session.completedcarrying that promotion code, or a subscription whosecustomer.discount.creatednames it, is credited to the code's referrer when no link brought the customer first. The link still wins over a code. - Codes made in Stripe before you connected are matched the first time they are
used, or paste their
promo_…ids in the program's Codes list.
Choose Snapshot, not Thin. Stripe can send events as a full snapshot or as a
thin notice with no data. A thin event carries nothing to credit, so Bolt Claw
answers it 200, records it, and the Integration tab says
payload_format: thin until you switch the endpoint to Snapshot.
With a restricted key
For coupons, promotion codes and rewards given for you, add a restricted key on the Integration tab's Codes and credits card. It is opt-in and you can remove it at any time; without it, everything falls back to the keyless behaviour above.
- Only a restricted key is accepted: one that starts
rk_, live or test. A full secret key (one that startssk_) is refused, with the reason: it can do anything in your account, and Bolt Claw should never hold that. - Give it exactly these permissions: Coupons write, Promotion codes write, Customers write (balance credit), Subscriptions write (free periods), Checkout Sessions read (line items, for rates per product).
- On save, one harmless read checks it works. It is then sealed, and never
returned, logged or repeated in an error, not even in part. The card shows
only whether a key is set, live or test, and since when
(
codes_and_creditson the integration). - It is set and removed in the dashboard only, never through the API: a credential should not pass through a script or a chat with an assistant.
What it unlocks:
- Create codes in Stripe. One coupon made from the friend's discount rule,
named so your checkout shows where it came from ("Referral: 20% off for 3
months"), then a promotion code for every active code of the program. Run it
from the Codes list, or
POST /v1/referrals/programs/{id}/stripe-codes. A code Stripe already has with the same text is linked, not made again, and every call carries anIdempotency-Keybuilt from our own id, so running it twice makes nothing twice. Deactivating a code here deactivates it there. - Rewards given for you, for sales your Stripe reported (a sale reported through
the API stays yours to give). A ready
creditgrant becomes a negative balance transaction on the customer (credit their next invoice uses); a readyfree_periodof months becomes a 100%-off coupon on their subscription for that many months, and one of days extends their trial. Each grant is sent to Stripe once (Idempotency-Key: bc-grant-<id>); anything Stripe refuses comes back to your Grants list asreadywith the reason, in our words. - Line items for one-time checkouts, so a reward rule that pays per product sees what was bought.
curl -X POST https://api.boltclaw.ai/v1/referrals/programs/$PROGRAM_ID/stripe-codes \
-H "Authorization: Bearer $BOLTCLAW_KEY" -H "Idempotency-Key: sync-codes-1"
{ "coupon": "bcref-p20-m3", "created": 12, "linked": 3, "failed": 0 }
An AI assistant must always ask a person before it does this: it changes what
your customers pay. Without a key, or without a friend's discount rule, the
answer is 409.
Errors from Stripe
A Stripe error is never forwarded. Each becomes one fixed sentence: the key was refused, the key lacks a permission, the object no longer exists, Stripe refused the request, it already exists, Stripe is limiting requests, or Stripe could not be reached. What you see on the card or the grant is always one of those.