Skip to content

Preview. The API is shared with design partners and may change before launch. Register interest for sandbox access.

Errors

Phew uses HTTP status codes to signal success or failure. Errors always have the same JSON shape:

{
"error": "invalid_request",
"message": "Check the highlighted fields.",
"issues": [
{ "path": ["items", 0, "price"], "message": "Must be a positive integer in minor units." }
],
"request_id": "req_01JD9F3H5K7M9P1R3T5V7X9Z1B"
}
Field Description
error Stable, machine-readable code. Branch on this, not on message.
message Human-readable explanation. May change; don’t parse it.
issues Present for validation errors: the path to each invalid field and what’s wrong.
request_id Same as the X-Request-Id header. Include it when contacting support.
Status Meaning Retry?
200, 201 Success
400 The request is invalid; see issues No, fix the request
401 Missing or invalid credentials or signature No
403 Valid credentials, but not allowed (scope, merchant, IP) No
404 The object doesn’t exist, or isn’t visible to you No
409 Conflicts with the current state, or an idempotency key reused with a different body No
422 Valid request that can’t be processed, for example an expired offer No
429 Rate limited Yes, after Retry-After
500, 502, 503, 504 Something went wrong on our side Yes, with backoff and the same Idempotency-Key
error Status Description
invalid_request 400 Malformed JSON or a field failed validation
unauthorized 401 No credential, or the credential is invalid or revoked
signature_invalid 401 A required request signature didn’t verify
insufficient_scope 403 The credential lacks the scope this endpoint needs
ip_not_allowed 403 The request came from an IP outside your allowlist
merchant_not_allowed 403 Phew-Merchant names a merchant you can’t act for
not_found 404 No such object
idempotency_conflict 409 The Idempotency-Key was used with a different request
invalid_state 409 For example, cancelling a policy that’s already cancelled
offer_expired 422 The offer has passed expires_at; request a new one
item_not_eligible 422 The item can’t be covered
rate_limited 429 Too many requests
internal_error 500 Unexpected error; we’re alerted automatically
unavailable 503 Temporarily unavailable; retry with backoff