Rate limits and error codes

The 60 requests a minute API limit, the JSON error envelope and every status and error_code the Shakewell Wallet public API returns, with fixes.

Last updated 2026-11-05

Rate limits

ScopeLimitOn excess
Public API (all /api/public/v1 routes)60 requests per minute, counted per IP address429, body error_code: "HTTP_ERROR"
Hosted signup registration10 requests per minute per IP address and route429 with retry_after in the body

Limits are per IP address, not per key, so servers sharing an address share the budget. On a 429, wait at least a minute before retrying, then spread bulk work over time or use the template-wide bulk notification.

Error envelope

Errors raised by the API use one JSON shape. error_code is stable, so branch on it rather than on message.

404 Not Found
{
  "error": true,
  "error_code": "WALLET_PASS_NOT_FOUND",
  "message": "Wallet pass not found.",
  "timestamp": "2026-11-05T01:23:45.000000Z"
}

Two older shapes still appear: authentication failures return { "error": "Unauthorized", "message": "..." }, and template endpoints return { "success": false, "message": "..." } for some failures.

Status and code reference

StatusCode or errorWhereFix
400PASS_NOT_INSTALLEDpush to one passWait until the customer has added the pass
401Unauthorizedany routeSend a valid key
403feature_requiredcreating keysMove to a plan with API access
403template_limit_exceededcreate templateDelete a template or upgrade
403UNAUTHORIZED_ACCESSupdate or delete templateUse a write key for your own template
403ACCOUNT_CONTEXT_MISSINGtemplatesContact support
404WALLET_PASS_NOT_FOUNDpasses, pushCheck the ID and the account
404RESOURCE_NOT_FOUNDanyCheck the resource ID
409WALLET_PASS_TEMPLATE_MISSINGupdate passRe-create the pass on a live template
422VALIDATION_ERRORany writeRead errors for field names
429HTTP_ERROR, Too Many Attempts.anyWait a minute, then retry
500WALLET_PASS_CREATE_FAILED, WALLET_PASS_UPDATE_FAILED, WALLET_PASS_DELETE_FAILED, WALLET_PASS_RETRIEVE_FAILED, WALLET_PASS_LIST_FAILEDpassesRetry with backoff, then contact support
500NOTIFICATION_SEND_FAILED, BULK_NOTIFICATION_SEND_FAILEDpushRetry with backoff
500INTERNAL_ERRORanyRetry, then contact support

Each of the common ones has its own troubleshooting page.