Credit packs

Offer one-time credit purchases to subscribed customers

View as Markdown

A credit pack lets a customer buy more credits for an existing subscription. Each pack belongs to a plan and defines how much one block of credits costs. A completed purchase adds a credit grant to the subscription.

How credit packs work

A pack has four main parts:

FieldPurpose
pricing_unitThe unit the customer buys, such as API credits or tokens
money_minorThe price in the plan currency’s smallest unit, such as cents
unit_amountThe number of credits sold for money_minor
expiration_interval_*How long purchased credits remain valid; both fields are null when they do not expire

For example, money_minor: "100" and unit_amount: "2500" means the customer pays $1.00 for 2,500 credits when the plan uses USD.

Grant calculates the purchase total from the selected credit quantity and rounds the result to the plan currency’s smallest unit.

Before you begin

In the Grant dashboard:

  1. Create the pricing unit that the pack will grant.
  2. Add the pricing unit to a billing plan.
  3. Create a credit pack on that plan and set its price and optional expiry.
  4. Make sure the customer has an active, trialing, or past_due subscription to the same plan.

Use the pack’s id in API calls. Pack codes are labels for people and are not accepted in place of credit_pack_id.

1. List a plan’s credit packs

Use the plan ID to find every pack available for that plan.

$curl https://api.trygrant.com/v1/plans/plan_123/credit-packs \
> -H "Authorization: Bearer ak_live_YOUR_API_KEY"
Response
1{
2 "success": true,
3 "credit_packs": [
4 {
5 "id": "credit_pack_123",
6 "plan_id": "plan_123",
7 "code": "100-pack",
8 "pricing_unit_id": "pricing_unit_123",
9 "pricing_unit": {
10 "id": "pricing_unit_123",
11 "code": "credits",
12 "name": "Credits"
13 },
14 "money_minor": "100",
15 "unit_amount": "2500",
16 "expiration_interval_count": 3,
17 "expiration_interval_unit": "month"
18 }
19 ],
20 "request_id": "req_abc123"
21}

See List credit packs for the full response.

2. Retrieve one pack

Fetch a pack by ID when you need to show its price or confirm its expiry rules.

$curl https://api.trygrant.com/v1/credit-packs/credit_pack_123 \
> -H "Authorization: Bearer ak_live_YOUR_API_KEY"

See Retrieve a credit pack.

Credit packs are bought through a hosted checkout page. Create a link for the customer’s subscription, then send its URL to that customer. Each link expires 24 hours after creation and completes after one purchase.

Set the quantity

Pass quantity when you know how many credits the customer will buy. The value is a number of pricing units, not a number of pack bundles.

$curl -X POST https://api.trygrant.com/v1/credit-pack-checkout-links \
> -H "Authorization: Bearer ak_live_YOUR_API_KEY" \
> -H "Content-Type: application/json" \
> -d '{
> "subscription_id": "subscription_123",
> "credit_pack_id": "credit_pack_123",
> "quantity": 5000,
> "success_url": "https://example.com/billing/success",
> "back_url": "https://example.com/billing"
> }'

The hosted page shows the fixed credit amount and its total price. The pack must belong to the subscription’s plan.

Let the customer choose

Omit quantity, or pass null, to let the customer choose a purchase amount on the hosted page. Grant shows how many credits that amount buys at the pack’s rate.

$curl -X POST https://api.trygrant.com/v1/credit-pack-checkout-links \
> -H "Authorization: Bearer ak_live_YOUR_API_KEY" \
> -H "Content-Type: application/json" \
> -d '{
> "subscription_id": "subscription_123",
> "credit_pack_id": "credit_pack_123"
> }'

Use the returned URL

The response includes the hosted checkout URL and its expiry time.

Response
1{
2 "success": true,
3 "credit_pack_checkout_link": {
4 "id": "checkout_link_123",
5 "subscription_id": "subscription_123",
6 "credit_pack_id": "credit_pack_123",
7 "quantity": "5000",
8 "url": "https://www.trygrant.com/purchase/opaque-token",
9 "token_expiration": "2026-08-07T12:00:00.000Z",
10 "success_url": "https://example.com/billing/success",
11 "back_url": "https://example.com/billing",
12 "status": "pending",
13 "created_at": "2026-08-06T12:00:00.000Z"
14 },
15 "request_id": "req_abc123"
16}

Send credit_pack_checkout_link.url to the customer tied to the subscription. Do not put the URL in public pages, logs, or analytics events because it contains the checkout token.

See Create a credit pack checkout link for the full request and response.

Redirect the customer

Both redirect fields are optional and must use HTTP or HTTPS:

  • success_url sends the customer back to your app after Grant confirms the purchase.
  • back_url sets the destination of the back action on the hosted page.

Do not treat the browser redirect as proof of payment. Read the customer’s credit balances from your server when your app needs the current balance.

What happens after payment

  1. Grant attaches the payment method to the customer.
  2. Grant creates, finalizes, and charges a one-time invoice.
  3. Grant adds a credit grant to the subscription for the purchased quantity.
  4. The link changes to completed. A later visit shows that it has already been used.
  5. If success_url is set, the hosted page sends the customer there.

If a payment fails, the customer can try again while the link remains valid. Create a new link after it expires.

Good practices

  • Store credit_pack_id with your own product or purchase option so you do not need to match on display text.
  • Read money_minor and unit_amount as strings to avoid losing precision in languages with limited integer sizes.
  • Show the pricing unit and expiry before sending a customer to checkout.
  • Create links only from your server, after it has chosen the subscription and credit_pack_id.
  • Use HTTPS redirect URLs in production.
  • Treat the checkout URL as a secret until it expires or completes.