When something goes wrong.
Errors come back as a JSON envelope with a stable type, a human message, and a request_id you can send us when reporting an issue.
{"type": "error", "error": {
"type": "authentication_error",
"message": "Invalid or revoked API key.",
"request_id": "063f8b83-eee2-4383-a5cf-11e4bcd29d7c"
}}| HTTP | Meaning | What to do |
|---|---|---|
| 400 | Malformed body (missing/wrong-type field) | The message names the exact field - fix and retry. |
| 401 | Invalid or revoked API key | Check the key; issue a new one in the console. |
| 402 | Out of balance, no card on file, or a tier cap | Top up or add a card in the console. The response carries balance_cents and floor_cents, so you can tell which one stopped you. |
| 404 | No such memory, store, or image | Check the id. get_image also answers 404 when the memory exists but carries no image. |
| 409 | That name is already taken | Store and workspace names are unique within an account - pick another one. |
| 413 | Request body over 10MB | Base64 runs about 33% larger than the file it encodes, so resize the image before encoding it. |
| 429 | Rate limited | The SDK already retries these for you, with backoff and jitter, honouring Retry-After. Getting one means the retries ran out - lower your concurrency rather than wrapping a loop of your own around it. |
| 501 | This model's engine does not implement that endpoint | Images and revision history need a newer engine. GET /api/v1/models lists which models serve what. |
| 5xx | Server-side problem | Retry with backoff, but not blindly. The SDK does not auto-retry a 5xx here, because every call on this API is a POST and the server may have stored your request already. Resend with an idempotency key so a repeat cannot double-write, and include request_id if you contact us. |
Every error is a WosError, and each status also has a class of its own - BadRequestError, AuthenticationError, PaymentRequiredError, NotFoundError, ConflictError, RateLimitError, ServerError, APIConnectionError. Catch the one you mean to handle instead of comparing numbers.
# SDK error handling (Python) from wontopos import Client, WosError, RateLimitError, PaymentRequiredError try: mem.search("...", user_id="alice") except PaymentRequiredError: ... # 402 - top up except RateLimitError: ... # 429 - the SDK already retried; slow down except WosError as e: ... # e.status, e.message, e.request_id except (ValueError, TypeError): ... # never left the client
Some mistakes never reach us. The API key, the store id, the idempotency key and the image are all checked before the request goes out, and those raise ValueError or TypeError - not WosError. An except WosError on its own will not catch them.
Rate limits are per account, shared across all your keys, and scale with your tier - see Usage tiers. Your account's usage is shown in the console.