Sell prepaid credits
Say customers buy credits in packs, and every member of a customer’s team spends from the same balance. That’s a balance limit on the team, with grants when they buy.
1. Create the balance
Section titled “1. Create the balance”The window total never resets. The amount is what every team starts
with, here 100 free credits:
curl -X POST https://api.limitry.com/v1/limits \ -H "Authorization: Bearer $LIMITRY_API_KEY" \ -H "Content-Type: application/json" \ -d '{"name":"Credits","subjectKind":"team","action":"*", "amount":100,"unit":"credits","window":"total"}'2. Add credits when a customer pays
Section titled “2. Add credits when a customer pays”In your payment webhook, grant what they bought. Use the payment’s id as the idempotency key, so a redelivered webhook can’t add credits twice:
curl -X POST https://api.limitry.com/v1/limits/$LIMIT_ID/grants \ -H "Authorization: Bearer $LIMITRY_API_KEY" \ -H "Content-Type: application/json" \ -H "Idempotency-Key: payment_8231" \ -d '{ "subject": { "kind": "team", "id": "t_42" }, "amount": 5000, "note": "5,000-credit pack" }'3. Spend from the team’s balance
Section titled “3. Spend from the team’s balance”Check as the user, and name the team as the shared subject. Any limits you set on the user still apply as well:
const report = await limits.guard( { subject: { kind: "user", id: user.id }, shared: [{ kind: "team", id: user.teamId }], action: "report", cost: 25, }, () => buildReport(params),);However many teammates spend at the same moment, the balance never goes below zero.
4. When the balance runs out
Section titled “4. When the balance runs out”The check says no, with retryAfterSeconds: null, because waiting won’t
help. Use that to offer a top-up rather than “try again later”.
To show the balance in your product, read remaining from any check’s
answer, or make a preview check, which counts nothing.
Related: Pools, balances and budgets, Idempotency.