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.
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
-
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.
-
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.
-
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.
The integration handles each error family deliberately, shows a useful remedy, and records supplied request IDs without exposing secrets.
01 Error schema
detailsTop-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{
"type": "https://robotscenter.net/problems/not-found",
"title": "Not found",
"status": 404,
"detail": "Resource not found",
"request_id": "req-01HQ5PX7P7F4"
}
04 Extra context
details403 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
detailsPartner 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{
"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.