Log in Create workspace
Skip to content

Platform

Error responses (RFC 9457)

Learn how to recognize a failed request, decide whether to fix or retry it, and preserve the request ID when one is present. Most of /api/v1 uses an RFC 9457-style problem shape; partner, engagement, and SCIM routes also have surface-specific errors.

API docs
On this page

Start here

Turn a failed request into a useful next action. Status gives the category; detail and extra explain what to correct. Keep request_id when supplied.

Before you begin

  • The HTTP status, response headers, and unmodified response body from the failed request
  • Knowledge of which surface you called: the main API, partner or engagement API, or SCIM

Put it into practice

  1. Classify the response

    Start with the HTTP status, problem type, and content type. Routine partner and engagement failures use a compact error code, and routine SCIM failures use a SCIM document; shared rate-limit middleware returns problem JSON on all three surfaces.

  2. Choose a safe remedy

    Correct invalid input for 400 or 422, replace credentials for 401, and request the named scope for 403. For 429, back off only for type problems/rate-limited; resolve plan usage or upgrade for problems/quota-exceeded.

  3. Record useful context

    Log request_id, status, type, and a redacted detail value. Preserve extra because it can contain field messages, required scopes, quota usage, or the retry delay.

What success looks like

The integration handles each error family deliberately, shows a useful remedy, and records supplied request IDs without exposing secrets.

01 Error schema

details

Top-level fields

Problem responses include type (error URI), title, status, detail, and usually request_id. Type-specific context may appear in extra. Routine SCIM controller and authentication errors use SCIM documents; shared 429 middleware uses this problem schema.

02 Common error types

reference
Status Type URI Title
400 problems/bad-request Bad request
401 problems/unauthorized Unauthorized
403 problems/forbidden Forbidden
404 problems/not-found Not found
406 problems/not-acceptable Not acceptable
409 problems/conflict Conflict
410 problems/enrollment-expired Enrollment expired
410 problems/robot-decommissioned Robot decommissioned
415 problems/unsupported-media-type Unsupported media type
422 problems/unprocessable-entity Unprocessable entity
429 problems/rate-limited Rate limited
429 problems/quota-exceeded Plan quota exceeded
500 problems/internal-server-error Internal server error

03 Example error response

example
json
{
  "type": "https://robotscenter.net/problems/not-found",
  "title": "Not found",
  "status": 404,
  "detail": "Resource not found",
  "request_id": "req-01HQ5PX7P7F4"
}

04 Extra context

details

403 Forbidden

extra.required_scopes lists the scopes needed to access the resource. Workspace gates also set a top-level error of workspace_frozen, workspace_paused, or workspace_archived before any controller runs. Fleet mission assignment and start, plus OTA rollout, can return 403 with error workspace_unavailable when a workspace is paused or frozen; archived-workspace mutations are refused with workspace_archived. A workspace-side edit of a partner-managed webhook subscription can return 403 with error partner_managed_subscription.

422 Validation

extra.errors is an object keyed by field; each value is an array of validation messages. It is not an array of {field, message} objects.

429 Rate limited or quota

Request-rate limits use type problems/rate-limited, a retry-after header, and extra.retry_after_seconds. Quota failures use problems/quota-exceeded with extra.upgrade and extra.upgrade_url; trace and telemetry quotas also carry resource, plan, limit and usage. They do not promise retry-after, so repeated requests cannot fix the plan limit.

05 Surfaces that do not use problem JSON

details

Partner and engagement planes

Authentication and explicit domain failures under /api/v1/partner and POST /api/v1/engagements/:engagement_id/events normally return {"error": "code"}. Exceptions include shared rate-limit and failed-auth 429 responses, which are problem JSON, and changeset failures that reach the shared fallback. Inspect the actual body instead of assuming every response on these planes has one shape.

OTLP

POST /api/v1/otlp/v1/traces answers errors, including 401, 403 and 429, with an OTLP Status body {code, message}, not problem JSON. Its quota 429 sends retry-after: 60.

SCIM

SCIM controller and authentication errors use application/scim+json; last-owner and uniqueness conflicts are HTTP 409 in that format. The API rate limiter runs after SCIM authentication and returns the shared rate-limited problem JSON with retry information when its bucket is exhausted.

06 Validation error example (422)

example
json
{
  "type": "https://robotscenter.net/problems/unprocessable-entity",
  "title": "Unprocessable entity",
  "status": 422,
  "detail": "Validation failed",
  "request_id": "req-01HQ5PX7P7F4",
  "extra": {
    "errors": {
      "url": ["must be an absolute http(s) URL"],
      "event_types": ["should have at least 1 item(s)"]
    }
  }
}

Troubleshooting

The body does not have type or request_id
Check the route and content type before changing your parser. Many partner and engagement responses intentionally carry only error, while routine SCIM failures use their standard document.
A retry repeats the same failure
Re-read the status and extra fields. Fix validation, authorization, workspace state, or quota errors first; retry only transient failures and rate limits with backoff.

Where to go next

see also