| title | Errors |
|---|---|
| description | Error envelope, status codes, and retry guidance for the ResQ APIs. |
Both ResQ APIs use standard HTTP status codes and return a small JSON envelope on failure. Treat the status code as authoritative; treat the body as diagnostic detail meant for logs and operator surfaces — not for control flow.
The Infrastructure API returns:
{ "error": "Invalid credentials" }The Coordination API returns either the same shape or a richer envelope on endpoints that report multiple failures:
{
"error": "validation_failed",
"message": "field 'mission_id' is required",
"details": [
{ "path": "mission_id", "rule": "required" }
]
}| Status | Name | Meaning |
|---|---|---|
200 |
OK | Success. |
201 |
Created | A new resource was created (e.g. evidence upload). |
202 |
Accepted | Request queued — usually telemetry or async work. |
204 |
No Content | Success with no body. |
400 |
Bad Request | Malformed JSON or invalid parameters. |
401 |
Unauthorized | Missing, expired, or invalid token. |
403 |
Forbidden | Token lacks the scope required for this resource. |
404 |
Not Found | Resource does not exist or is not visible to your operator. |
409 |
Conflict | Resource state prevents the operation (e.g. mission already approved). |
422 |
Unprocessable Entity | Validation failed on a well-formed request. |
429 |
Too Many Requests | Rate limit exceeded. Honor Retry-After. |
500 |
Internal Server Error | Unexpected server fault. Safe to retry. |
503 |
Service Unavailable | Upstream dependency degraded. Safe to retry with backoff. |
| Class | Retry? | Strategy |
|---|---|---|
4xx (except 408, 409, 429) |
No | Fix the request. |
408 Request Timeout |
Yes | Single retry. |
409 Conflict |
Sometimes | Re-read state, then decide. |
429 Too Many Requests |
Yes | Honor Retry-After, then exponential backoff with jitter. |
5xx |
Yes | Exponential backoff with jitter, capped at ~30 s. |
async function withRetry<T>(fn: () => Promise<T>, max = 4): Promise<T> {
let attempt = 0;
while (true) {
try {
return await fn();
} catch (err: any) {
const status = err?.status ?? 0;
const retryable = status === 429 || status >= 500;
if (!retryable || attempt >= max) throw err;
const base = 250 * 2 ** attempt;
const jitter = Math.random() * base;
await new Promise((r) => setTimeout(r, base + jitter));
attempt++;
}
}
}{ "error": "Token expired" }Re-run the login flow described in Authentication and retry the request once.
{ "error": "Insufficient scope: missions.approve" }The operator is authenticated but does not have the required scope. Surface this to the user; do not retry. Mission-approval flows in particular require HITL-authorized operators (EU AI Act Art. 14).
The response includes a Retry-After header with seconds to wait. Pause for
at least that long before retrying.
The mesh or an upstream dependency is degraded. The Coordination API is designed to keep operating in this state — telemetry ingestion will buffer locally on the edge and retry. Idempotent client requests should retry with backoff.
If you hit a reproducible failure that does not match this reference, open an issue in the docs repository with:
- HTTP method, path, and status code
- Request ID (
X-Request-Idresponse header) if present - A redacted copy of the request body
- The full response body