Errors¶
Every 4xx and 5xx response has the same shape, so your error handler only learns it once:
{
"detail": {
"code": "validation_error",
"message": "Tool diameter must be > 0",
"details": {"parameter": "tool_diameter", "value": -1},
"request_id": "f8b8d6f0-2b18-4c5a-9b6e-..."
}
}
code: stable snake_case identifier; safe to switch on.message: English fallback.details: endpoint-specific structured context.request_id: quote in support tickets. Echoed in theX-Request-IDresponse header.
Error codes¶
| Code | Status | Meaning |
|---|---|---|
unauthorized |
401 | Missing / invalid / expired / revoked API key. |
forbidden |
403 | Key lacks one of the route's required scopes (details.missing_scopes). |
validation_error |
400 | Generic validation failure. |
invalid_parameter |
400 | A specific parameter is out of range or unsupported. |
missing_required_field |
400 | A required body field was omitted. |
not_found |
404 | Resource does not exist for this user. |
project_not_found |
404 | details.project_id. |
equipment_not_found |
404 | details.equipment_id. |
machine_not_found |
404 | details.product_id. |
job_not_found |
404 | details.job_id. |
tool_not_found |
404 | details.tool_id. |
project_busy |
400 | A task is already running on this project (details.active_task_id). |
task_cancelled |
499 | The task was cancelled cooperatively. |
resource_ownership_error |
403 | The resource exists but is owned by a different user. |
license_error |
403 | ModuleWorks licence problem. |
storage_error |
500 | S3 / Mongo / Postgres failure. |
moduleworks_error |
500 | ModuleWorks computation failed. |
task_execution_error |
500 | Worker could not start the task. |
database_error |
500 | Postgres failure. |
internal_error |
500 | Catch-all. |
Rate limit (429)¶
{
"detail": {
"code": "validation_error",
"message": "Rate limit exceeded: 120 per minute",
"details": {"retry_after_seconds": 30},
"request_id": "..."
}
}
Headers: Retry-After, X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Reset.