> ## Documentation Index
> Fetch the complete documentation index at: https://docs.fluz.app/llms.txt
> Use this file to discover all available pages before exploring further.

# Purchase in Bulk

A single `purchaseGiftCard` call buys **exactly one** gift card, for **one offer** at **one rate**. There is no `quantity` field, and a single call is never split across multiple offers or rates. To buy several cards, send the mutation multiple times — once per card, each with its own unique `idempotencyKey`.

How each call chooses its offer and rate depends on whether you pass `offerId` or `merchantSlug`.

### Purchase flow at a glance

![](https://files.readme.io/bf6ad80159ab3e0beecb76d51f498a4093b793bf7368288abe62e5c81b2b36c5-diagram.svg)

### `offerId` — pin a specific offer and rate

When you pass `offerId`, the purchase is locked to that exact offer and its rate. If that offer can no longer be fulfilled (for example, a stock-tracked offer that has sold out), the call **fails** — it will **not** silently substitute a different offer. See the out-of-stock error below.

### `merchantSlug` — auto-select the best available offer

When you pass `merchantSlug` (without `offerId`), the system selects the **best available in-stock offer** for that merchant **at the moment of each call**. Because selection happens per call, repeated purchases for the same merchant can resolve to **different offers** as availability changes.

### Fixed vs. variable offers and stock

* **Fixed-denomination offers** are stock-tracked per denomination. Once a denomination is depleted, it is no longer selectable, and any further calls pinned to it (via `offerId`) return an out-of-stock error.
* **Variable offers** are not stock-limited in the same way. They typically remain available and act as the fallback when a fixed/stocked offer runs out. A variable offer often carries a **different (frequently lower) reward rate** than the fixed offer it replaces.

> 📘 What happens when you buy more cards than are in stock
>
> Suppose a merchant's best offer is a fixed, stock-tracked offer with only **8** units left, and you want **10** cards (i.e. 10 separate `purchaseGiftCard` calls):
>
> * **Using** `offerId` (pinned to the fixed offer): the first 8 calls succeed; the 9th and 10th calls **fail** with an out-of-stock error. No automatic fallback to another offer or rate occurs.
> * **Using** `merchantSlug` (auto-select): the first 8 calls purchase on the fixed offer; once it is depleted, the remaining calls auto-select the **next-best available offer** — which may be a **variable offer at a lower reward rate**.
>
> In every case each card is purchased atomically at the offer and rate resolved for that individual call — there is no blended or partially-fulfilled order.

### Protecting your rate with `minRewardRate`

When you buy with `merchantSlug`, use `minRewardRate` to set a reward-rate floor. Before purchasing, the system checks the best available rate for the merchant, amount, and payment method; if that rate is **below your** `minRewardRate` (or no rate can be quoted), the call **fails** instead of buying at the lower rate. This is the recommended way to avoid unintentionally purchasing the remaining cards on a lower-rate variable offer after a higher-rate stocked offer sells out.

> 🚧 `minRewardRate` only applies to `merchantSlug` purchases.
>
> If you provide `offerId`, `minRewardRate` is ignored (the offer — and its rate — is already fixed). The floor is evaluated per call, so include it on every call when buying multiple cards.

### Out-of-stock error

When an offer can no longer be fulfilled due to stock, the mutation returns:

```json theme={null}
{
  "code": "GC-0009",
  "message": "This offer is currently out of stock. Please select a different amount or try again later."
}
```

Re-quote with `getOfferQuote` / `getMerchants` to find the current best available offer before retrying.

> 📘
>
> ### What happens when you buy more cards than are in stockSuppose a merchant's best offer is a fixed, stock-tracked offer with only **8** units left and you want **10** cards (10 separate `purchaseGiftCard` calls):
>
> * **Using** `offerId` (pinned to the fixed offer): the first 8 calls succeed at the stocked rate; the 9th and 10th calls **fail** with `GC-0009`. No automatic fallback to another offer or rate occurs.
> * **Using** `merchantSlug` (auto-select): the first 8 calls purchase on the fixed offer at the higher rate; once it is depleted, the remaining calls auto-select the **next-best available offer** — which may be a **variable offer at a lower reward rate**.

> 🚧
>
> ### Protect your rate with `minRewardRate`en buying with `merchantSlug`, set `minRewardRate` to a reward-rate floor. Before each purchase the system checks the best available rate for the merchant, amount, and payment method; if that rate is **below** your `minRewardRate` (or no rate can be quoted), the call **fails** instead of buying at the lower rate. This is the recommended way to avoid unintentionally purchasing the remaining cards on a lower-rate variable offer after a higher-rate stocked offer sells out.
>
> `minRewardRate` is **ignored** when you provide `offerId` (the rate is already fixed), and it is evaluated **per call** — include it on every call when buying multiple cards.

To check stock before you buy, see [Get Inventory On Stocked Offers](/get-inventory).
