Responses & Errors
The success and error response envelopes, stable codes, and retry behavior.
Success responses
Every successful response is wrapped in a data field:
{
"data": {
"...": "endpoint-specific payload"
}
}The schema only guarantees data.products[].product_id for product-shaped
endpoints; everything else is source-specific. See each operation in the
API reference for its exact response shape.
Error responses
Every error response is wrapped the same way, regardless of endpoint:
{
"error": {
"code": "NOT_FOUND",
"status": 404,
"message": "User not found.",
"retryable": false,
"details": {}
}
}| Field | Type | Meaning |
|---|---|---|
code | string | Stable machine-readable code for the failure |
status | number | The matching HTTP status code |
message | string | Human-readable description of what went wrong |
retryable | boolean | Whether retrying the same request could succeed |
details | object | Optional extra context, shape varies by error |
Error codes
| Code | Typical meaning |
|---|---|
INVALID_REQUEST | The request was malformed — a missing or invalid parameter |
UNAUTHORIZED | The x-api-key header was missing or invalid |
FORBIDDEN | The key is valid but not allowed to access this resource |
PAYMENT_REQUIRED | Out of credits — see Credits |
NOT_FOUND | The requested resource doesn't exist |
RATE_LIMITED | Too many requests — see Rate limits |
SOURCE_UNAVAILABLE | The upstream public source is temporarily unreachable |
SOURCE_ERROR | The upstream public source returned an unexpected error |
INTERNAL_ERROR | Something went wrong on Toolzer Hub's side |
Check retryable before you retry
SOURCE_UNAVAILABLE and some INTERNAL_ERROR responses are typically
retryable: true — a short backoff-and-retry is reasonable. Treat
INVALID_REQUEST, UNAUTHORIZED, FORBIDDEN, and NOT_FOUND as not
worth retrying without changing the request first.