If you've ever been tasked with adding a "send a reward" feature to a product — an employee recognition flow, a referral payout, a survey incentive — you've probably hit the closed loop vs. open loop question somewhere in the spec doc.
Most devs treat it as a product decision and move on. It's actually an infrastructure decision, and getting it wrong means rebuilding.
Let me explain what I mean.
The surface-level difference
Closed loop = branded to a specific merchant (Amazon, Starbucks, Nike). Cheaper per dollar of face value, no Visa/MC network fees, but only spendable in one place.
Open loop = runs on Visa/Mastercard/Amex, spendable anywhere. Higher fees ($3–6 activation per card), sometimes inactivity fees after 12 months, but maximum recipient flexibility.
From a user perspective: closed loop is a brand experience, open loop is basically a prepaid debit card.
From a developer perspective, the difference runs deeper.
The API reality
Most gift card providers — especially open loop — weren't built for programmatic use. They were built for retail. That means:
No real-time issuance API. You're often placing batch orders and waiting.
Redemption codes delivered via CSV or email, not webhook.
No status endpoint to check whether a card was redeemed.
Manual reconciliation when cards are unused or expire.
Per-card minimums that break your "send $10 to 500 users" flow.
Closed loop cards from major retailers (Amazon, for example) have better API support in some cases — but you're locked into their ecosystem, their terms, and their rate limits.
The result: you end up building a lot of glue code around a system that wasn't designed to be integrated.
What a proper rewards API looks like
If you're building this properly, here's what you actually want:
// What you want your reward flow to look like
const reward = await giftsClient.createReward({
recipientEmail: "user@example.com",
value: 25.00,
currency: "USD",
options: [
{ type: "closed_loop", brands: ["amazon", "target", "nike"] },
{ type: "open_loop", network: "visa" }
],
expiresAt: "2025-12-31"
});
// Recipient gets a selection — they pick what to redeem
// You get a webhook when they do
The sender controls the value and the menu of options. The recipient picks. You get an event.
That's it. No CSV. No batch delay. No manual reconciliation.
The third model: multi-brand catalogs
There's a third architecture worth knowing about — and it solves the core tension between closed and open loop.
Instead of picking one card type, you expose the recipient to a curated catalog (Amazon, Apple, Uber, Airbnb, 200+ brands) and let them choose where to apply a fixed value balance.
From an integration standpoint this is cleaner:
One API call to create the reward
One webhook when it's redeemed
No per-card Visa activation fees
Redemption tracking built in
Global catalogs with localized brands per country
// Example: Multi-brand reward with catalog
const reward = await giftsClient.createReward({
recipientEmail: "user@example.com",
value: 50.00,
currency: "USD",
catalogFilter: {
categories: ["retail", "food", "travel"],
countries: ["US", "GB", "DE"] // localized per recipient
}
});
// reward.redemptionUrl → send to recipient
// reward.status → "pending" | "redeemed" | "expired"
This is what GIFQ's API is built around — B2B-native reward infrastructure with real-time issuance, webhook events, and a global brand catalog across 30+ countries.
When does card type actually matter in your code?
A few real scenarios:
The thing worth checking before you build
Before you commit to a gift card provider for your integration, ask:
Is there a real-time issuance API, or am I batch ordering?
Do I get a webhook on redemption, or do I have to poll?
Can I set a value and let the recipient pick the brand?
How does international distribution work — localized catalogs or manual per-country setup?
What happens to unredeemed value — does it expire and disappear, or does it return to my account?
The answers will tell you whether you're looking at a retail gift card reseller with a thin API layer, or actual rewards infrastructure.
The closed loop vs. open loop debate is real but it's downstream of a more important question: does this provider have an API worth building on?
Happy to dig into any part of this — webhook patterns, idempotency for bulk sends, handling expiry edge cases. Drop a comment.

Top comments (0)