Errors
The shape of every PricklyMails API error response, the stable translation key each one carries, and how to handle each status code.
The shape
Every error returns the same JSON, with no stack traces, SQL, or file paths:
Response
{ "error": { "code": "authenticate_user.invalid_credentials", "message": "authenticate_user.invalid_credentials" } }
The code is a stable translation key, not localized text.
Your client maps it to a message in the user's language at render time, so error copy lives on your side and never changes under you.
Status codes
- 400 Bad Request: malformed input (invalid email, bad UUID, unknown query value, a batch under 20 addresses).
- 401 Unauthorized: missing or invalid key or token.
- 402 Payment Required: the wallet has no balance to reserve the job.
Distinct from
403so you can prompt a top-up rather than a permission fix. - 403 Forbidden: the key is missing the required scope or check.
- 404 Not Found: no such resource for your account (a UUID owned by someone else looks identical to a missing one).
- 408 Request Timeout: the request exceeded the server's processing budget (
request.timeout); safe to retry. - 409 Conflict: for example an idempotency key reused with a different body.
- 429 Too Many Requests: rate limit exceeded.
The response carries
Retry-After.
No enumeration
Authentication failures return the same error for an unknown email and a wrong password, so responses never reveal whether an account exists.