Skip to main content
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.

Envelope

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" }
  ]
}
Always branch on the HTTP status code. Field names inside the body may evolve; status codes are stable.

Status codes

StatusNameMeaning
200OKSuccess.
201CreatedA new resource was created (e.g. evidence upload).
202AcceptedRequest queued — usually telemetry or async work.
204No ContentSuccess with no body.
400Bad RequestMalformed JSON or invalid parameters.
401UnauthorizedMissing, expired, or invalid token.
403ForbiddenToken lacks the scope required for this resource.
404Not FoundResource does not exist or is not visible to your operator.
409ConflictResource state prevents the operation (e.g. mission already approved).
422Unprocessable EntityValidation failed on a well-formed request.
429Too Many RequestsRate limit exceeded. Honor Retry-After.
500Internal Server ErrorUnexpected server fault. Safe to retry.
503Service UnavailableUpstream dependency degraded. Safe to retry with backoff.

What to retry

ClassRetry?Strategy
4xx (except 408, 409, 429)NoFix the request.
408 Request TimeoutYesSingle retry.
409 ConflictSometimesRe-read state, then decide.
429 Too Many RequestsYesHonor Retry-After, then exponential backoff with jitter.
5xxYesExponential backoff with jitter, capped at ~30 s.

Backoff sketch

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++;
    }
  }
}

Common errors

401 Unauthorized

{ "error": "Token expired" }
Re-run the login flow described in Authentication and retry the request once.

403 Forbidden

{ "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).

429 Too Many Requests

The response includes a Retry-After header with seconds to wait. Pause for at least that long before retrying.

503 Service Unavailable

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.

Reporting an error

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-Id response header) if present
  • A redacted copy of the request body
  • The full response body