The Wrapped API signals failure with the status code, and explains it in the body. Per-endpoint codes are listed in the API reference; this article covers the shapes you'll actually have to handle.
The error body is plain text, not JSON
This is the thing most integrations get wrong. A failed request returns the message as a bare string with Content-Type: text/plain:
Gift card already exists with this code
There is no envelope, no error code, no problem+json. Calling response.json() on a 400 throws a parse error, and the real message is lost — which is how a duplicate-code rejection ends up in your logs as "Unexpected token G in JSON". Read the body as text when the response isn't OK:
const res = await fetch(url, { headers: { "x-api-key": key } });
if (!res.ok) {
throw new Error(`Wrapped API ${res.status}: ${await res.text()}`);
}
return res.json();
Match on the status code and treat the text as a human-readable detail. The wording isn't a stable contract.
Status codes
| Status | Meaning | What to do |
|---|---|---|
200 | Success. Create endpoints return 200, not 201. | — |
400 | The request was rejected. Body says why. | Fix the request. Don't retry unchanged. |
401 | x-api-key is missing, wrong, or the key was deleted. | Check the key. Don't retry. |
404 | The record doesn't exist on the account that owns the key. | Treat as "not found", not as an outage. |
429 | Over the rate limit. | Back off and retry. |
A 404 with the body Account not found means something different from a missing gift card: the key authenticated but no account resolved behind it. That's worth alerting on — it usually means a deleted or misconfigured account, not a bad lookup.
Common 400 messages
These come from the code paths most integrations hit. The reference lists the rest per endpoint.
| Endpoint | Message | Cause |
|---|---|---|
POST /api/GiftCard/Create | Gift card already exists with this code | The Code you supplied is already in use on the account. |
POST /api/GiftCard/Create | Gift card has already been created for this unique ID | A card with that UniqueId exists. This is the idempotency guard working — see Idempotency. |
POST /api/GiftCard/Create | SendAsGift requires ShouldSendNotification to be true | SendAsGift only controls which email is sent, not whether one is. |
POST /api/GiftCard/Create | SendAsGift requires BuyerName / requires RecipientName | The gift email is framed "from X to Y", so both names are needed. |
Handling 401
A key that worked yesterday and 401s today has almost always been deleted in Settings › Integrations and API keys. Keys don't expire and aren't rotated automatically.
Note that API keys keep working after a downgrade — authentication doesn't check the plan — so a 401 is about the key itself, not billing. See Create and manage API keys.
Handling 429
The API allows 200 requests per minute. Over that, it returns 429.
Back off rather than retrying immediately: wait, then retry with increasing delays. A tight retry loop on a 429 spends your allowance on rejected requests and keeps you over the limit.
If you need a higher limit, or you're building a partner integration, email api@wrappedgiftcards.com.
What the API doesn't do
- No
201. Creates return200. Don't branch on201. - No
422. Validation failures are400. - No retries on your behalf. This applies to webhooks too: each delivery is attempted once. See the webhook payload reference.
- No partial success. A request either applies fully or is rejected.
Common questions
Why did I get a 404 for a gift card I can see in the dashboard?
The key belongs to one Wrapped account, and lookups are scoped to it. If you have more than one account, check you're using that account's key. Code lookups are exact matches, including the dashes.
Should I retry a 400?
No. The same request will be rejected again. The exceptions are the two duplicate messages above, which usually mean the work already succeeded on an earlier attempt — look the record up rather than creating it again.
Is there a machine-readable error code?
Not currently. Branch on the HTTP status and log the body text.
