The Wrapped API is a REST API for creating, looking up, adjusting and voiding gift cards from your own systems. Wrapped pushes every change to all of your connected sales channels, just as it does for changes made in the dashboard. API access is available on the Pro plan and above. Authenticate every request with an x-api-key header. The full endpoint reference is at wrappedgiftcards.readme.io.
This article covers the concepts and the most common tasks. Use the reference for every field and response.
Before you start
- Your Wrapped account must be on Pro, Plus or Enterprise.
- An Owner or Admin creates a private API key at Settings › Integrations and API keys. See Create and manage API keys.
- Each key belongs to one Wrapped account. Everything you do with it affects that account's live gift cards. There is no sandbox or test key.
- Gift cards created through the API count toward your monthly gift card allowance and can lead to overage charges. See How the monthly gift card allowance works.
The basics
| Base URL | https://api.wrappedgiftcards.com (every path starts with /api/) |
| Authentication | x-api-key: YOUR_API_KEY header on every request |
| Format | JSON request and response bodies. Request and response fields use camelCase (for example recipientEmailAddress), except the automation event endpoint, which uses snake_case. |
| Rate limit | 200 requests per minute. Requests over the limit get 429 Too Many Requests; wait and retry. |
| Currency | Amounts are in your Wrapped account's currency. |
| Higher limits or partnerships | Email api@wrappedgiftcards.com |
Keep API keys on your server. Anyone who has a key can create, change and void gift cards on your account, so never put a key in a web page, mobile app or public code repository.
Responses and errors
| Status | Meaning |
|---|---|
200 | Success. Create endpoints return 200, not 201. |
400 | The request was rejected, for example a duplicate code or unique ID, or a missing required field. The body is a plain-text message. |
401 | The x-api-key header is missing, or the key is wrong or has been deleted. |
404 | The gift card (or other record) wasn't found on the account that owns the key. |
429 | You've gone over the rate limit. |
Endpoints at a glance
| Method and path | What it does |
|---|---|
POST /api/GiftCard/Create | Create a gift card |
GET /api/GiftCard/GetByCode/{code} | Get a gift card by its code (exact match) |
GET /api/GiftCard/GetById/{id} | Get a gift card by its Wrapped ID |
GET /api/GiftCard/GetByEmail?emailAddress=… | Get gift cards sent to a recipient email address |
GET /api/GiftCard/GetByAccountPlatformIdAndSourceId | Find the Wrapped gift card for a gift card ID from a sales channel |
GET /api/GiftCard/List | List gift cards, a page at a time |
DELETE /api/GiftCard/VoidByCode/{code} | Void a gift card by code |
DELETE /api/GiftCard/VoidById/{id} | Void a gift card by ID |
GET /api/GiftCardAdjustment/ListAdjustmentsByGiftCardCode/{code} | A gift card and its adjustment history, newest first |
GET /api/GiftCardAdjustment/ListAdjustmentsByGiftCardId/{giftCardId} | The same, by gift card ID |
POST /api/GiftCardAdjustment/AddAdjustmentByGiftCardCode | Add a top-up or redemption to a gift card, by code |
POST /api/GiftCardAdjustment/AddAdjustmentByGiftCardId | Add a top-up or redemption to a gift card, by ID |
POST /api/AutomationTriggerEvents | Send an event that runs your API event automations |
GET /api/Company/Profile | Your account's business details, currency and time zone |
GET /api/Webhook/List, POST /api/Webhook/Create, DELETE /api/Webhook/Delete/{id} | Manage webhooks (see below) |
/api/WebStoreCoupon/… | List, look up, create, update and delete web store coupons |
Create a gift card
curl --request POST \
--url https://api.wrappedgiftcards.com/api/GiftCard/Create \
--header 'x-api-key: YOUR_API_KEY' \
--header 'content-type: application/json' \
--data '{
"balance": 50,
"recipientName": "Sam Lee",
"recipientEmailAddress": "sam@example.com",
"shouldSendNotification": true,
"notes": "Customer service goodwill",
"uniqueId": "crm-case-10482"
}'
The response is the new gift card, including its id, code, balance, currency, status and links such as viewBalanceUrl, appleWalletUrl and googleWalletUrl.
What happens:
- The card is created Active in your account's currency, with an initial value equal to
balance. - If you leave out
code, Wrapped generates one using your code format (Settings › Gift card rules). If you supply a code, it must not already exist on your account, and it must meet the rules of every sales channel you've connected, or the card will show a sync error there. See Gift card code format and each platform's rules. - If you leave out
expiresAtUtc, your account's default expiry is applied (if you have one). - Wrapped adds the card to every connected sales channel in the background, after the response is returned.
- The card's notes and timeline say it was created through the Wrapped API, followed by the description of the API key used.
Emails:
shouldSendNotification: truesends the usual gift card email to the recipient once the card has been added to your sales channels. Leave it out (orfalse) to send no email.shouldSendNotification: trueplussendAsGift: truesends the "gifted" email instead, frombuyerNametorecipientNamewithgiftMessage. Both names are required. AddgiftScheduledForUtcto deliver it later.disableEmails: truestops all gift card emails for this card.
Other useful fields: isPromotional (mark promotional cards such as giveaways), customField1 to customField3 (your own reference data, returned unchanged), buyerName, buyerEmailAddress and notes.
Look up a gift card by code
curl --request GET \
--url https://api.wrappedgiftcards.com/api/GiftCard/GetByCode/WRAP-XY7Q-4KLM \
--header 'x-api-key: YOUR_API_KEY'
The code must match exactly. The response has the current balance and a status of Active, Redeemed, Expired, Voided or Scheduled. A 404 means no card with that code exists on the account that owns the key.
To see how the balance got there, call ListAdjustmentsByGiftCardCode/{code}. It returns the card plus every adjustment (amount, type, notes and time), newest first.
Correct a balance with an adjustment
To change a balance so that every channel stays in step, add an adjustment in Wrapped. Wrapped records it on the card and pushes the new balance to every connected sales channel.
Only balance changes that belong to an order or sale sync into Wrapped automatically. Changing a balance directly in Shopify admin or through Shopify's Admin API (for example giftCardDebit or giftCardCredit) is not picked up by Wrapped, and the channels drift apart. Make the correction in Wrapped instead, through the API or Adjust balance in the dashboard. See How balance changes sync between Wrapped and your sales channels.
curl --request POST \
--url https://api.wrappedgiftcards.com/api/GiftCardAdjustment/AddAdjustmentByGiftCardCode \
--header 'x-api-key: YOUR_API_KEY' \
--header 'content-type: application/json' \
--data '{
"giftCardCode": "WRAP-XY7Q-4KLM",
"adjustmentAmount": -12.50,
"notes": "Correcting a balance changed in Shopify admin",
"actionedAtUtc": "2026-09-17T02:15:00Z",
"uniqueAdjustmentId": "balance-fix-2026-09-17-001"
}'
adjustmentAmountis signed. A positive amount is a top-up; a negative amount is a redemption. To set a card to a particular balance, send the difference between the current balance and the balance you want.actionedAtUtcis required. Use the time the change really happened (for example the time of the sale), in UTC. It is the date reports use.uniqueAdjustmentIdis required. See "Idempotency: safe retries" below.- The response is
true. - Adding an adjustment through the API doesn't send the customer an email.
- Vouchers can't be adjusted. They're redeemed in full, so the API returns
400.
AddAdjustmentByGiftCardId rejects a redemption larger than the card's balance. AddAdjustmentByGiftCardCode doesn't check this, so read the current balance first if you need to avoid a negative balance.
Void a gift card
curl --request DELETE \
--url https://api.wrappedgiftcards.com/api/GiftCard/VoidByCode/WRAP-XY7Q-4KLM \
--header 'x-api-key: YOUR_API_KEY'
Voiding sets the balance to $0 in Wrapped and in every connected sales channel, and the card's status becomes Voided. The card isn't deleted inside the sales channels. There's no API call to reverse a void. Voided gift cards don't count toward your monthly allowance.
Idempotency: safe retries
Network errors happen, so design retries so they can't create a card or adjustment twice:
| Endpoint | Field | What a repeat does |
|---|---|---|
| Create gift card | uniqueId (optional) | Rejected with 400 "Gift card has already been created for this unique ID" |
| Add adjustment | uniqueAdjustmentId (required) | Rejected with 400 "…has already been created for this unique ID" |
| Automation event | idempotency_key (optional) | Skipped for any automation that already ran with that key |
Unique IDs are checked per Wrapped account. Use a value from your own system, such as an order or transaction ID. If a retry gets the "already been created" response, treat the original request as successful.
Listing gift cards
GET /api/GiftCard/List returns giftCards and a totalCount.
pageSize: up to 50 (default 10).pageNumber: counts from 0. RequestpageNumber=0for the first page.since: only cards issued after this UTC time.- Results are sorted with the most recently updated cards first.
- Voided, expired and fully redeemed cards are included. Add
includeAll=trueto include deleted cards too.
Webhooks: receive gift card events
A webhook sends a JSON payload to your HTTPS URL when something happens to a gift card. Webhooks are managed only through the API; they don't appear in the dashboard.
curl --request POST \
--url https://api.wrappedgiftcards.com/api/Webhook/Create \
--header 'x-api-key: YOUR_API_KEY' \
--header 'content-type: application/json' \
--data '{
"url": "https://example.com/wrapped/webhooks",
"description": "CRM sync",
"requestHeaderVerificationToken": "a-long-random-secret"
}'
Each delivery is a POST whose WebhookTopic is one of:
| Topic | Sent when |
|---|---|
giftcard/updated | A gift card is issued, or its balance changes, and Wrapped sends its gift card notifications |
giftcard/gifted | A gift card is delivered to a recipient as a gift |
giftcard/reminder | A balance reminder is sent for a gift card |
giftcard/voided | A gift card is voided |
giftcard/expired | A gift card expires |
The payload's property names are PascalCase, for example GiftCardId, Code, Balance, FormattedBalance, Currency, Status, RecipientEmailAddress, ExpiresAtUtc, ViewBalanceUrl, IsPromotional and WebhookTopic. RequestId is new for every delivery.
Verifying deliveries. If you set requestHeaderVerificationToken, each delivery carries an HMAC-Signature-SHA256 header. Its value is the Base64-encoded HMAC-SHA256 of the raw request body, using your token as the key. The token itself isn't sent. For example, in Node.js:
const crypto = require("crypto");
function isFromWrapped(rawBody, signatureHeader, token) {
const expected = crypto.createHmac("sha256", token).update(rawBody, "utf8").digest("base64");
const received = signatureHeader || "";
return expected.length === received.length &&
crypto.timingSafeEqual(Buffer.from(expected), Buffer.from(received));
}
Things to know:
- Return any
2xxstatus quickly. Wrapped doesn't retry a failed delivery. - If deliveries to a URL keep failing, Wrapped stops sending to that webhook, and it no longer appears in
GET /api/Webhook/List. Create it again once your endpoint is working. - Deliveries are only sent while your Wrapped subscription is active.
- Adjustments added through the API don't send a
giftcard/updateddelivery.
Automation events
POST /api/AutomationTriggerEvents runs every active automation whose trigger is API event and whose Event name matches event_name. Each matching automation issues its reward to recipient_email and sends its email. This endpoint uses snake_case:
{
"event_name": "onboarding-complete",
"recipient_email": "customer@example.com",
"amount": 25,
"idempotency_key": "signup-88213",
"properties": { "first_name": "Sam" }
}
amount is optional and overrides the automation's amount. Each entry in properties is saved on the gift card and can be used in the automation's email as {{event.first_name}}. The response lists the gift cards created and, for each matching automation, a status such as Created, SkippedIdempotent or SkippedUsageLimit. See Marketing automations.
Common questions
Is the API available on the Basic plan?
No. API access is included on Pro, Plus and Enterprise. See Plans and pricing.
Is there a sandbox or test key?
No. Every key works on your live account. Test with a small card sent to your own email address, then void it; voided cards don't count toward your allowance.
Do gift cards created through the API sync to Shopify and Lightspeed?
Yes. Wrapped adds new cards, and pushes adjustments and voids, to every connected sales channel, the same as for changes made in the dashboard.
Why did I get a 401 with a key that used to work?
The key was deleted at Settings › Integrations and API keys, or it belongs to a different Wrapped account. Create a new key and update your integration. See Create and manage API keys.
Can the API change the expiry date or the recipient of an existing card?
Not through the public API. Change them in the dashboard. See Edit recipient details and resend a gift card email.
Who do I contact about building an integration?
Technology partners and anyone who needs a higher rate limit can email api@wrappedgiftcards.com. For help with your own account, see Getting help from the Wrapped team.
