Skip to main content

Error Reference

Standard error response format and error codes for the apptor flow API.


Error Response Format​

All API errors return a consistent JSON structure:

{
"status": 400,
"message": "Validation failed: 'name' is required",
"path": "/process/create",
"timestamp": "2026-02-20T10:00:00Z"
}
FieldTypeDescription
statusintegerHTTP status code
messagestringHuman-readable error description
pathstringThe request path that caused the error
timestampstringISO 8601 timestamp of the error

Some endpoints return additional fields for validation errors:

{
"status": 422,
"message": "Validation failed",
"errors": [
{ "field": "name", "message": "must not be blank" },
{ "field": "processId", "message": "must not be null" }
],
"path": "/process/create",
"timestamp": "2026-02-20T10:00:00Z"
}

HTTP Status Codes​

200 OK​

Request succeeded. Response body contains the result.

201 Created​

Resource was successfully created. Response body contains the new resource.

400 Bad Request​

The request was malformed or contained invalid data.

Common causes:

  • Missing required fields in the request body
  • Invalid field types or formats
  • Workflow JSON is not valid (when creating/updating a workflow definition)
{
"status": 400,
"message": "Invalid processText: JSON parse error at line 5",
"path": "/process/create"
}

401 Unauthorized​

Authentication failed or no credentials were provided.

Common causes:

  • Missing Authorization header
  • Expired JWT token
  • Invalid or revoked API key
  • Suspended API key
{
"status": 401,
"message": "Unauthorized: invalid or expired API key",
"path": "/process/exec"
}

Fix: Re-authenticate (get a fresh JWT) or verify your API key is active and correctly formatted as apk_{keyId}_{secret} in the X-API-Key header.

403 Forbidden​

The authenticated user/key exists but lacks the required permission.

Common causes:

  • JWT user does not have the required permission (e.g., WORKFLOW_CREATE)
  • API key does not have the required role/permission
  • Attempting to access another organization's resources
{
"status": 403,
"message": "Forbidden: missing permission WORKFLOW_CREATE",
"path": "/process/create"
}

Fix: Check which permissions are required for the endpoint. Assign the appropriate role to the user or API key.

404 Not Found​

The requested resource does not exist, or you do not have access to it.

Common causes:

  • Invalid processId, processInstanceId, userId, etc.
  • Resource belongs to a different organization
  • Resource was deleted
{
"status": 404,
"message": "Workflow proc_abc123 not found",
"path": "/process/proc_abc123"
}

409 Conflict​

The request conflicts with existing state.

Common causes:

  • Creating a resource with a name that already exists
  • Attempting to activate an already-active resource
{
"status": 409,
"message": "A secret with name 'OPENAI_API_KEY' already exists",
"path": "/secrets"
}

422 Unprocessable Entity​

The request body is syntactically valid but semantically invalid.

Common causes:

  • Field-level validation failures
  • Business rule violations
{
"status": 422,
"message": "Validation failed",
"errors": [
{ "field": "email", "message": "must be a valid email address" }
],
"path": "/users"
}

429 Too Many Requests​

The API key's rate limit has been exceeded.

Headers included:

X-RateLimit-Limit: 60
X-RateLimit-Remaining: 0
X-RateLimit-Reset: 1708430460
Retry-After: 32
{
"status": 429,
"message": "Rate limit exceeded: 60 requests per minute",
"path": "/process/exec"
}

Fix: Wait for the Retry-After duration before retrying. Consider increasing the rate limit on the API key or distributing load across multiple keys.

500 Internal Server Error​

An unexpected error occurred on the server.

{
"status": 500,
"message": "An internal error occurred. Reference: err_20260220_abc123",
"path": "/process/exec"
}

Fix: Note the error reference and contact support. Do not retry immediately — log the reference for investigation.

503 Service Unavailable​

The server is temporarily unavailable (maintenance, overload).


Execution-Specific Errors​

When a workflow execution fails, the stateCd on the process instance is set to 2 (Failed). The execution detail endpoint returns the failed node's information:

{
"processInstanceId": "inst_xyz789",
"stateCd": 2,
"nodeInstances": [
{
"nodeId": "rest-call-1",
"nodeName": "Call Payment API",
"nodeType": "serviceTask",
"statusCd": 3,
"variables": {
"_error": "Connection refused: https://api.payments.com/charge",
"_errorCode": "CONNECTION_ERROR"
}
}
]
}

Execution Error Codes​

_errorCodeMeaning
CONNECTION_ERRORService task could not connect to the remote endpoint
HTTP_ERROR_{status}Service task received an HTTP error response (e.g., HTTP_ERROR_500)
TIMEOUTNode exceeded its configured timeout
SCRIPT_ERRORScript task threw an uncaught exception
AI_ERRORAI task encountered an error from the LLM provider
VARIABLE_NOT_FOUNDA required variable was null or undefined at execution time
CONDITION_ERRORIf/Else condition expression could not be evaluated
SUBPROCESS_ERRORA called subprocess or call process failed
CANCELLEDNode was cancelled by an admin or boundary event

Authentication Error Details​

ScenarioStatusMessage
No Authorization header401Unauthorized: no credentials provided
Invalid JWT signature401Unauthorized: invalid token
Expired JWT401Unauthorized: token expired
Unknown API key ID401Unauthorized: invalid or expired API key
Revoked API key401Unauthorized: API key has been revoked
Suspended API key401Unauthorized: API key is suspended
Expired API key401Unauthorized: API key has expired
Wrong organization403Forbidden: resource not in your organization
Missing permission403Forbidden: missing permission {PERMISSION_KEY}

Handling Errors in Code​

JavaScript / TypeScript​

async function executeWorkflow(processId, data, apiKey) {
const response = await fetch('/process/exec', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'X-API-Key': apiKey
},
body: JSON.stringify({ processId, data })
});

if (!response.ok) {
const error = await response.json();

switch (response.status) {
case 401:
throw new Error(`Authentication failed: ${error.message}`);
case 403:
throw new Error(`Permission denied: ${error.message}`);
case 404:
throw new Error(`Workflow not found: ${processId}`);
case 429:
const retryAfter = response.headers.get('Retry-After');
throw new RateLimitError(`Rate limit exceeded`, parseInt(retryAfter));
default:
throw new Error(`API error ${response.status}: ${error.message}`);
}
}

return response.json();
}

Java​

HttpResponse<String> response = httpClient.send(request, BodyHandlers.ofString());

if (response.statusCode() >= 400) {
var error = objectMapper.readValue(response.body(), ApiError.class);

switch (response.statusCode()) {
case 401 -> throw new AuthenticationException(error.getMessage());
case 403 -> throw new PermissionException(error.getMessage());
case 404 -> throw new ResourceNotFoundException(error.getMessage());
case 429 -> throw new RateLimitException(error.getMessage());
default -> throw new ApiException(response.statusCode(), error.getMessage());
}
}

Rate Limit Headers​

Every API response includes current rate limit state (when using API key auth):

X-RateLimit-Limit-Minute: 60
X-RateLimit-Remaining-Minute: 45
X-RateLimit-Limit-Hour: 1000
X-RateLimit-Remaining-Hour: 872

Monitor these headers to avoid hitting 429 errors proactively.