Troubleshoot REST API requests
Diagnose and resolve common issues when integrating with the automation orchestrator REST API, including authorization failures, validation errors, resource conflicts, and pagination problems.
403 Forbidden responses
A 403 Forbidden response with the AUTHORIZATION_DENIED error code indicates that the authenticated user lacks the required permission for the requested action. The response body includes the action and resource type that were denied:
{
"type": "https://api.example.com/errors/forbidden",
"title": "Authorization Denied",
"detail": "Not authorized to perform create on workflow",
"code": "AUTHORIZATION_DENIED",
"retryable": false
}To identify the missing permission, note the action and resource type from the detail field in the error response. Then send a POST request to the /api/v1/authz/can_i endpoint to verify your permissions. Replace access_token with a valid JSON Web Token (JWT):
$ curl -X POST https://orchestrator-host/api/v1/authz/can_i \
-H "Authorization: Bearer access_token" \
-H "Content-Type: application/json" \
-d '{
"action": "create",
"resource_type": "workflow",
"resource_project": "project_name_or_uuid"
}'Check the response for the allowed field and the denial_reason:
{
"allowed": false,
"denied": false,
"matched_policy": "",
"denial_reason": "",
"denied_by": ""
}An empty matched_policy with allowed: false means no policy grants your user access to that action. A non-empty denied_by means an explicit deny policy is blocking access.
To list all permissions assigned to your user, send a POST request to the /api/v1/authz/what_can_i endpoint.
Service account WebSocket restriction
Service accounts cannot obtain WebSocket tickets. If a service account attempts to exchange a JWT for a WebSocket ticket, the API returns a 403 Forbidden response. The response includes the X-Auth-Failure-Type: service_account_forbidden header. Use user credentials for WebSocket connections.
For project-scoped resources such as workflows and credentials, include the resource_project field in your can_i request. A permission that applies at the system level might not apply within a specific project scope.
409 Conflict errors
A 409 Conflict response occurs when a request conflicts with the current state of a resource.
Name conflict (NAME_CONFLICT)
Returned when you attempt to create or rename a resource by using a name that already exists within the same scope. Resource names must be unique within their resource type and project. To resolve the conflict, choose a different name or delete the existing resource first.
Resource names must match the pattern ^[a-zA-Z0-9]([a-zA-Z0-9:_-]*[a-zA-Z0-9])?$ and must not exceed 255 characters.
Integrity constraint violation (INTEGRITY_CONSTRAINT_VIOLATION)
Returned when a database uniqueness constraint is violated for fields other than the name. Verify that the values you are submitting do not duplicate existing records.
Version conflict (WORKFLOW_VERSION_CONFLICT)
Returned when you send a PATCH or publish request with an expected_version field. This error occurs when another user has saved a newer version since you last retrieved the workflow. The response body includes conflict metadata:
{
"type": "https://api.example.com/errors/resource-conflict",
"title": "Version Conflict",
"detail": "A newer version of this workflow has been saved by another user",
"code": "WORKFLOW_VERSION_CONFLICT",
"retryable": false,
"current_version": 5,
"expected_version": 3,
"created_by_username": "other.user",
"created_at": "2026-07-06T14:30:00Z"
}To resolve a version conflict, retrieve the latest version of the workflow by using GET /api/v1/workflows/{workflow_id}. Merge your changes into the latest version, then retry the PATCH or publish request with the updated expected_version value.
The expected_version field is optional. If you omit it, the save or publish operation proceeds without a version check.
422 Validation errors
A 422 Unprocessable Entity response with the REQUEST_VALIDATION_ERROR code indicates that the request body failed field-level validation. The detail field lists each validation failure with the field path and error message:
{
"type": "https://api.example.com/errors/validation-error",
"title": "Request Validation Error",
"detail": "Validation failed: name: String should have at least 1 character; description: String should have at most 2,000 characters",
"code": "REQUEST_VALIDATION_ERROR",
"retryable": false
}Common validation failures:
| Field | Constraint |
|---|---|
name |
Must be between 1 and 255 characters. Must start and end with a letter or digit and can contain letters, digits, colons, hyphens, and underscores. Spaces and special characters are not permitted. |
description |
Must not exceed 2,000 characters. |
UUID fields (such asproject_id) |
Must contain a valid UUID format. An invalid UUID returns auuid_parsing error for the specific path parameter. |
| Filter parameters | Query string filter values that do not match the expected type for the field return aVALIDATION_ERROR with a description of the type mismatch. |
Pagination edge cases
The API uses cursor-based pagination with base64-encoded cursor tokens. Be aware of the following edge cases.
Empty result set
When no resources match your query, the API returns an empty resources array with next and prev set to null. Do not treat a null next cursor as an error.
Malformed cursor token
Cursors that cannot be base64-decoded or contain invalid JSON return a 422 Unprocessable Entity error. Cursor tokens that exceed 1,024 bytes also return a 422 validation error. Only cursors that decode to valid JSON but contain unexpected structure are silently handled.
Cursor stability
Cursors reference a specific resource ID and timestamp. If the referenced resource is deleted between paginated requests, the API advances to the next valid position. There is no cursor expiration timeout. However, results might change if resources are created or deleted between page requests.
Maximum page size
The limit parameter is capped at 100 items per page. Values above 100 are silently reduced to 100.
Token version invalidation
A valid-looking access token can be rejected with a 401 Unauthorized response and the TOKEN_STALE error code:
{
"type": "https://api.example.com/errors/unauthorized",
"title": "Unauthorized",
"detail": "Token is outdated, please refresh",
"code": "TOKEN_STALE",
"retryable": true
}The automation orchestrator tracks a token_version counter per user. Each access token includes a token_ver claim recorded at the time of issuance. When the server-side counter advances past the value in your token, the token is considered stale.
Events that increment the token version:
- The user logs out (the logout endpoint increments the token version before revoking the session).
- An administrator resets the user's session or changes the user's security settings.
- A global token revocation is triggered.
Because the retryable field is true, call the /api/v1/auth/refresh endpoint to obtain a new access token with the current version. If the refresh token has also been revoked, re-authenticate with your credentials or identity provider.
The /api/v1/auth/refresh and /api/v1/auth/logout endpoints are exempt from stale token rejection so that clients can still refresh or log out.
Common integration mistakes
Missing or incorrect content type
Set the Content-Type header to application/json for all requests that include a JSON body. File upload endpoints require multipart/form-data instead. Omitting the content type header on POST or PUT requests results in a 422 validation error. The server cannot parse the request body without this header.
Missing project scope in resource operations
For project-scoped resources such as workflows, credentials, and inventories, your authorization check must include the project context. A permission granted at the system level does not automatically apply to project-scoped operations. Verify that the user's policies include the correct project scope by using the /api/v1/authz/can_i endpoint with the resource_project field populated.
Treating error responses as plain JSON
All error responses use the application/problem+json content type, not application/json. If your HTTP client validates response content types strictly, configure it to accept both content types. The error body follows the RFC 9457 Problem Details format with type, title, detail, code, and retryable fields.
Ignoring the retryable field
Check the retryable field in error responses before implementing retry logic. Errors with "retryable": true, such as TOKEN_STALE and INTERNAL_SERVER_ERROR, might succeed on retry. Errors with "retryable": false, such as validation and authorization failures, require a change in the request before retrying.
Disabled user account
If a user account is disabled after a token is issued, all API requests with that token return 401 Unauthorized. The error code is ACCOUNT_DISABLED. Contact an administrator to re-enable the account.
Disabled or deleted service account credential
If a service account credential is disabled or deleted after an access token is issued, subsequent API requests return 401 Unauthorized. The token remains structurally valid, but the server rejects it because the issuing credential is no longer active.
To resolve, check whether the credential used to obtain the token has been disabled or deleted. If the credential was disabled, ask an administrator to re-enable it and then request a new token. If the credential was deleted, create a new credential for the service account and authenticate again.