Error codes and retry guidance

API Error codes Retry HTTP status

This article covers the status codes the ReceiptRoller API returns when a call fails, the shape of the response body, and which errors are safe to retry. Error bodies do not share one format across all endpoints: most are a simple JSON object {"error": "..."}, and 401 and 403 come back with no body at all. Decide what happened from the status code first, and use the body to find the cause.

The shape of an error body

  • Most errors are JSON with a short description or code in error. Some endpoints add fields such as message, error_description or reason.
  • A 400 caused by malformed JSON, or by a non-number in a numeric field, has a body whose errors lists the reason for each field.
  • 401 and 403 come back with no body.
  • An unexpected error inside the server returns 500 with {"error": "an unexpected error occurred"}.
{ "error": "product not found in this business account" }

{ "error": "slot_unavailable", "reason": "...", "message": "..." }

There is no shared list of error codes and no request ID field for support enquiries.

Status codes

CodeMeaningRetry
200Success. Most creates also return 200 (for example, creating a product)—
201Created, on some create endpoints (for example, store posts)—
204Success with no body, for example on delete—
400A required field is missing, or a value or format is wrongNo (fix the request)
401No token, or the token is invalid or expiredOnce, after refreshing the token
402The business account's plan does not include the feature (for example, Google Business Profile)No
403Missing scope, an organizationId that differs from the token's, not a member, or a role that is not enoughNo
404The item does not exist in the business accountNo
409A conflict with the current state (for example, a coupon code already in use, or a booking slot that is full)No (read the current state and decide)
429Too many requests, on the few endpoints that have a limitAfter waiting (Rate limiting and throttling)
500An unexpected error inside the serverA few times, with growing waits
502 / 503An outside service failed, or a temporary clash (for example, two redemptions of the same pass at once)A few times, with growing waits

The statuses each endpoint can return are listed in the API reference.

Token endpoint errors

POST /api/v1/auth/token returns errors in the OAuth format.

StatuserrorCause
400invalid_requestThe body could not be read, or code or refresh_token is missing
400unsupported_grant_typegrant_type has a value that is not supported
401invalid_grant, invalid_client and othersThe code or refresh token is not valid, or client authentication failed. error_description has the detail

If refreshing with a refresh token returns 401, don't retry; ask the user to authorize again.

Retry guidance

  • Retry only on 429, 5xx, timeouts and connection errors. For 5xx, double the wait each time (1 s, 2 s, 4 s and so on), add some random jitter, and stop after a few attempts.
  • For 429, wait the number of seconds in Retry-After if it is present, or about a minute if it is not.
  • Any 4xx other than 401 gives the same result however many times you send it.
  • There is no general Idempotency-Key header. Resending a create POST after a timeout can create a duplicate, so check whether the item was created before sending it again.
  • Pass redemption and its undo (POST /api/v1/reservations/passes/{passId}/redeem and .../unredeem) and time-clock punches (POST /api/v1/stores/{storeId}/timecards/punch) take an idempotencyKey in the body. Resending with the same key returns the result already recorded, with "replayed": true, and nothing is applied twice.

Related articles

Published: 2026-04-27 Updated: 2026-10-26
About this topic
Developer API
See the feature
Tags
API (23) OAuth (18) Android (10) iOS (8) Webhook (5) App registration (4) Node.js (4) PIM (4) POS Integration (4) Quickstart (4)
Related articles