The Wrapped API

How the Wrapped REST API works (base URL, x-api-key authentication, rate limits, idempotency, paging and webhooks) with examples for creating a gift card, looking one up by code, correcting a balance with an adjustment and voiding a card. Pro plan and above.

Updated September 19, 2026

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 URLhttps://api.wrappedgiftcards.com (every path starts with /api/)
Authenticationx-api-key: YOUR_API_KEY header on every request
FormatJSON request and response bodies. Request and response fields use camelCase (for example recipientEmailAddress), except the automation event endpoint, which uses snake_case.
Rate limit200 requests per minute. Requests over the limit get 429 Too Many Requests; wait and retry.
CurrencyAmounts are in your Wrapped account's currency.
Higher limits or partnershipsEmail 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

StatusMeaning
200Success. Create endpoints return 200, not 201.
400The request was rejected, for example a duplicate code or unique ID, or a missing required field. The body is a plain-text message.
401The x-api-key header is missing, or the key is wrong or has been deleted.
404The gift card (or other record) wasn't found on the account that owns the key.
429You've gone over the rate limit.

Endpoints at a glance

Method and pathWhat it does
POST /api/GiftCard/CreateCreate 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/GetByAccountPlatformIdAndSourceIdFind the Wrapped gift card for a gift card ID from a sales channel
GET /api/GiftCard/ListList 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/AddAdjustmentByGiftCardCodeAdd a top-up or redemption to a gift card, by code
POST /api/GiftCardAdjustment/AddAdjustmentByGiftCardIdAdd a top-up or redemption to a gift card, by ID
POST /api/AutomationTriggerEventsSend an event that runs your API event automations
GET /api/Company/ProfileYour 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: true sends the usual gift card email to the recipient once the card has been added to your sales channels. Leave it out (or false) to send no email.
  • shouldSendNotification: true plus sendAsGift: true sends the "gifted" email instead, from buyerName to recipientName with giftMessage. Both names are required. Add giftScheduledForUtc to deliver it later.
  • disableEmails: true stops 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"
  }'
  • adjustmentAmount is 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.
  • actionedAtUtc is required. Use the time the change really happened (for example the time of the sale), in UTC. It is the date reports use.
  • uniqueAdjustmentId is 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:

EndpointFieldWhat a repeat does
Create gift carduniqueId (optional)Rejected with 400 "Gift card has already been created for this unique ID"
Add adjustmentuniqueAdjustmentId (required)Rejected with 400 "…has already been created for this unique ID"
Automation eventidempotency_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. Request pageNumber=0 for 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=true to 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:

TopicSent when
giftcard/updatedA gift card is issued, or its balance changes, and Wrapped sends its gift card notifications
giftcard/giftedA gift card is delivered to a recipient as a gift
giftcard/reminderA balance reminder is sent for a gift card
giftcard/voidedA gift card is voided
giftcard/expiredA 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 2xx status 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/updated delivery.

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.

Did this answer your question?