Guides
View as MarkdownHandling errors
Every endpoint uses one error shape. The HTTP status is meaningful: code is the general class
of error, and details.error is the specific Groupon code to branch your logic on.
json
{
"code": "aborted",
"message": "Displayed price no longer valid",
"details": {
"error": "PRICE_MISMATCH",
"errorMessage": "Displayed price no longer valid",
"requestId": "c0ffee00-...",
"path": "$.items[0]", "expectedPrice": 4500, "currentPrice": 4900, "currency": "USD", "currencyPrecision": 2
}
}One helper for every endpoint
ts
function grouponErrorCode(body: any): string {
return body?.details?.error ?? body?.code ?? "UNKNOWN";
}
function grouponRequestId(body: any): string | undefined {
return body?.details?.requestId;
}Error codes
| details.error | HTTP | code | Meaning / what to do |
|---|---|---|---|
| BAD_REQUEST | 400 | invalid_argument | A field is missing or invalid, or a cursor is bad. errorMessage names the field. Fix the request; for a cursor error, restart the walk. |
| FORBIDDEN | 403 | permission_denied | Outside your inventory scope, or the storefront is deactivated. Do not retry. |
| INVALID_PRODUCT_ID | 404 | not_found | The product is gone, or the cart has no such line. For a product: mark it not listable. For a cart line: read the cart, and if it comes back empty, create a new one. |
| INVALID_CART_ID | 404 | not_found | No such cart for your storefront: it never existed, or another storefront created it. Do not retry: create a new cart from your local copy. |
| INVALID_BOOKING_UUID | 404 | not_found | No such order placed from your carts. Do not retry. Show a neutral message. |
| PRODUCT_NOT_CARTABLE | 400 | failed_precondition | The deal needs a time-slot booking. Remove it from your listing. |
| CART_ITEM_LIMIT | 400 | failed_precondition | More than 20 different options in a cart. details carries limit and actual. |
| PRICE_MISMATCH | 409 | aborted | expectedPrice differs from the live price. details.currentPrice is the live per-unit price; details.path points at the item. Nothing was changed: update your price, ask the shopper to confirm, retry. |
| INVALID_BOOKING_STATE, UNPROCESSABLE_ENTITY | 400 / 409 | failed_precondition | Reserved. Treat as a non-retryable failure. |
| RATE_LIMITED | 429 | resource_exhausted | Too many requests for this storefront right now. Our own limit is 600 requests per storefront per minute, counted by the calendar minute across all of the storefront's keys. details.retryAfterSeconds says how many seconds are left until it starts again. |
| UPSTREAM_UNAVAILABLE | 503 | unavailable | Groupon could not answer right now. Retry with backoff, except adding cart items (see the rule below). |
HTTP 401 with code: "unauthenticated" means a missing, wrong, revoked or expired key, on every
endpoint that takes one. The message is the same whatever the reason, so it never tells anybody
whether a key exists. Do not retry; alert an operator.
Retry policy
Decide whether to retry from the error code first, not the HTTP status alone.
| Situation | Retry? |
|---|---|
| UPSTREAM_UNAVAILABLE, a network error, a timeout, or a 5xx with no Groupon error code | Yes. Exponential backoff, max 5 tries. Exception: adding cart items, below. |
| RATE_LIMITED (429) | Yes, but wait at least details.retryAfterSeconds seconds first. The answer carries no Retry-After header today. When retryAfterSeconds is missing (Groupon's own limit, passed on), back off exponentially. |
| Any retryable failure on adding items to a cart | No. Read the cart, compare, then add only what is missing. |
| Any retryable failure on creating a cart | Yes. A retry creates a separate new cart, which is harmless. Use the id from the call that succeeded. |
| BAD_REQUEST with a cursor problem on the products list | Not the same page. Discard the cursor and restart the walk from page 1. See Syncing the catalog. |
| BAD_REQUEST, FORBIDDEN, INVALID_PRODUCT_ID, PRODUCT_NOT_CARTABLE, PRICE_MISMATCH, CART_ITEM_LIMIT, INVALID_BOOKING_UUID, INVALID_BOOKING_STATE, UNPROCESSABLE_ENTITY, INVALID_CART_ID | No. Handle the code as described above. |
| HTTP 401 (authentication failure) | No. Alert an operator: check the key was copied correctly, or mint a new one. |
A booking read never changes the order, so it is always safe to retry.