Errors
Handle the HTTP API's closed error-code set and structured details.
Operation failures use one JSON envelope:
1{2 "error": {3 "code": "INVALID_ARGUMENT",4 "message": "Human-readable explanation",5 "details": {}6 }7}code and message are always present. details is optional and contains machine-readable context for the specific failure.
Error codes
| Code | HTTP status | Meaning |
|---|---|---|
INVALID_ARGUMENT | 400 | The JSON or an operation argument is invalid, including a missing required confirmation. |
UNAUTHENTICATED | 401 | The bearer credential is missing or invalid. |
FORBIDDEN | 403 | The caller is authenticated but lacks permission, or a signed evidence link is invalid or expired. |
NOT_FOUND | 404 | The requested resource or evidence media does not exist in the caller's organization. |
CONFLICT | 409 | The requested mutation conflicts with existing state, such as an Environment slug already in use. |
LIMIT_REACHED | 402 | An organization capacity or entitlement limit prevents the operation. |
UNAVAILABLE | 503 | A required service or resource is temporarily unavailable. |
Unexpected internal failures are sanitized to the same UNAVAILABLE code and message The operation could not be completed., but return HTTP 500. Do not depend on internal exception text.
Invalid JSON and a JSON root that is not an object return 400 INVALID_ARGUMENT. A 401 response also carries the WWW-Authenticate challenge.
Confirmation details
Replacement operations return a preview instead of writing when confirm: true is required. For example, test_case.update_steps can return:
1{2 "error": {3 "code": "INVALID_ARGUMENT",4 "message": "Replacing all Test Case steps requires confirm: true.",5 "details": {6 "confirmRequired": true,7 "wouldChange": {8 "stepCountBefore": 4,9 "stepCountAfter": 610 }11 }12 }13}test_plan.set_members reports wouldChange.removed and wouldChange.added. environment.upsert reports the supplied fields and target platforms. Inspect the preview, then retry the same intended mutation with confirm: true and the same idempotencyKey.
Credential value guard details
test_case.create and test_case.update_steps reject a literal that targets a credential field or looks like a secret. The error names the step, the rule that matched, and safe alternatives:
1{2 "error": {3 "code": "INVALID_ARGUMENT",4 "message": "Literal credentials and secret-shaped values must use an Environment value or an Agent-chosen value.",5 "details": {6 "stepIndex": 0,7 "rule": "field",8 "alternatives": [9 {10 "kind": "environment",11 "variables": [12 "LOGIN_EMAIL",13 "LOGIN_PASSWORD"14 ]15 },16 {17 "kind": "agent"18 }19 ],20 "escape": "credential"21 }22 }23}Use valueSpec: { "kind": "environment", "variable": "LOGIN_PASSWORD" } when the value already exists in an Environment, or valueSpec: { "kind": "agent" } when the runner should choose it.
To relocate a newly supplied literal into an Environment secret, send a literal valueSpec with credential.environmentSlug. This escape hatch also requires autonomy:environments:write; otherwise the API returns 403 FORBIDDEN with the required scope and stepIndex in details. A successful relocation rewrites the stored step to an Environment reference and lists the relocation in the mutation response.