Error Codes
Overview
RiskOS™ APIs return errors in a consistent JSON structure with an appropriate HTTP status code.
📘
Note:
Some endpoints may omit thecodefield (legacy behavior), but the overall structure and error categories remain consistent.
Error model summary
- All errors typically include
error(customer-facing message) - Most errors include
code(machine-readable identifier) - Optional fields:
message→ internal/debug detaildetails→ structured metadatainvalid_args→ field-level validation issues
- Use
code+ HTTP status for programmatic handling - Do not rely on parsing
errorstrings
Standard error response format
JSON
{
"error": "Customer-facing error message",
"code": "MACHINE_READABLE_ERROR_CODE",
"message": "Internal error details (optional)",
"details": {
"key": "Additional context (optional)"
},
"invalid_args": [
{
"field": "field_name",
"value": "invalid_value",
"tag": "Validation error details"
}
]
}
Error fields
| Field | Type | Required | Description |
|---|---|---|---|
error |
String | Required | Customer-facing message. |
code |
String | Conditionally required | Machine-readable error code. |
message |
String | Optional | Internal/debug detail. |
details |
Object | Optional | Structured metadata. |
invalid_args |
Array of Objects | Optional | Field-level validation errors (includes field, value, and tag). |
Message types
Message types help interpret how error strings may vary and whether they are safe to parse.
- Exact → always returned as written
- Template → contains variables like
{contentType} - Dynamic → varies at runtime
- Upstream → returned from an external system
HTTP status codes
| Status | Meaning | When it occurs |
|---|---|---|
400 |
Bad Request | Invalid syntax, missing fields, invalid values |
401 |
Unauthorized | Missing or invalid authentication |
403 |
Forbidden | Authenticated but blocked by policy |
404 |
Not Found | Invalid endpoint or resource ID |
415 |
Unsupported Media Type | Invalid Content-Type |
422 |
Unprocessable Entity | Semantically invalid data |
429 |
Too Many Requests | Rate limit exceeded |
500 |
Internal Server Error | Unexpected server error |
502 |
Bad Gateway | Upstream dependency failure |
503 |
Service Unavailable | Temporary service disruption |
504 |
Gateway Timeout | Upstream timeout |
Retry transient errors such as
408,409,423,429,502,503, and504using exponential backoff.
📘
Note:
400→ structural or schema issues (invalid JSON, missing required fields)422→ valid structure, but invalid data semantics (e.g., unsupported values)
Error categories
Each error below follows a consistent pattern: HTTP status → category → meaning → troubleshooting → example. This structure is intentional to support both developer readability and machine parsing.
Validation errors
INVALID_REQUEST
HTTP: 400 Bad Request
Category: Validation
Occurs when the request contains invalid syntax, missing required fields, or unsupported values.
How to troubleshoot
- Check the
invalid_argsarray for field-level issues - Validate payload against API specification
Examples
JSON
{
"error": "invalid request payload. please refer invalid_args for details",
"code": "INVALID_REQUEST",
"invalid_args": [
{
"field": "Workflow",
"value": "",
"tag": "required"
}
]
}
JSON
{
"error": "attachment extension tws not supported",
"code": "INVALID_REQUEST"
}
INVALID_PAYLOAD
HTTP: 400 Bad Request
Category: Validation
Occurs when the request body is not valid JSON.
How to troubleshoot
- Ensure valid JSON format
- Confirm
Content-Type: application/json
JSON
{
"error": "The evaluation request body contains invalid JSON.",
"code": "INVALID_PAYLOAD"
}
UNSUPPORTED_MEDIA_TYPE
HTTP: 415 Unsupported Media Type
Category: Validation
Message Type: Template
Occurs when the request uses an unsupported Content-Type.
JSON
{
"error": "unsupported media type: {contentType}",
"code": "UNSUPPORTED_MEDIA_TYPE"
}
INVALID_ID
HTTP: 400 Bad Request
Category: Validation
Occurs when an identifier is malformed or invalid.
JSON
{
"error": "specified id is invalid",
"code": "INVALID_ID"
}
Workflow errors
WORKFLOW_NOT_FOUND
HTTP: 400 Bad Request
Category: Configuration
JSON
{
"error": "workflow not found with the given version",
"code": "WORKFLOW_NOT_FOUND"
}
WORKFLOW_NOT_PUBLISHED
HTTP: 400 Bad Request
Category: Configuration
JSON
{
"error": "workflow is not published",
"code": "WORKFLOW_NOT_PUBLISHED"
}
Authentication and authorization
AUTHENTICATION_FAILED
HTTP: 401 Unauthorized
Category: Authentication
How to troubleshoot
- Ensure
Authorization: Bearerheader is present - Verify API key is valid
JSON
{
"error": "authentication failed",
"code": "AUTHENTICATION_FAILED"
}
PERMISSION_DENIED
HTTP: 403 Forbidden
Category: Authorization
Occurs when the API key is valid but lacks required permissions.
JSON
{
"error": "you don't have permission to access this workflow",
"code": "PERMISSION_DENIED"
}
Security errors
IP_NOT_ALLOWED
HTTP: 403 Forbidden
Category: Security
JSON
{
"error": "ip address rejected",
"code": "IP_NOT_ALLOWED"
}
NO_IP_FILTER_CONFIGURED
HTTP: 403 Forbidden
Category: Security
JSON
{
"error": "ip address rejected, no filter configured",
"code": "NO_IP_FILTER_CONFIGURED"
}
Resource errors
NOT_FOUND
HTTP: 404 Not Found
Category: Resource
Note: May not include code in legacy responses.
JSON
{
"error": "evaluation record not found"
}
Request format errors
UNPROCESSABLE_ENTITY
HTTP: 422 Unprocessable Entity
Category: Validation
JSON
{
"error": "unsupported_schema",
"message": "Address country not supported"
}
Rate limiting and server errors
RATE_LIMIT
HTTP: 429 Too Many Requests
Category: Rate Limiting
How to troubleshoot
- Use the
Retry-Afterheader when provided - Otherwise apply exponential backoff
JSON
{
"error": "rate_limit",
"message": "Too many requests, slow down"
}
INTERNAL_ERROR
HTTP: 500 Internal Server Error
Category: Server
JSON
{
"error": "workflow test execution failed",
"code": "INTERNAL_ERROR"
}
BAD_GATEWAY
HTTP: 502 Bad Gateway
Category: Server
Occurs when an upstream service fails.
JSON
{
"error": "upstream service error"
}
Error code index
| Code | HTTP | Category |
|---|---|---|
| INVALID_REQUEST | 400 | Validation |
| INVALID_PAYLOAD | 400 | Validation |
| INVALID_ID | 400 | Validation |
| WORKFLOW_NOT_FOUND | 400 | Configuration |
| WORKFLOW_NOT_PUBLISHED | 400 | Configuration |
| AUTHENTICATION_FAILED | 401 | Authentication |
| PERMISSION_DENIED | 403 | Authorization |
| IP_NOT_ALLOWED | 403 | Security |
| UNSUPPORTED_MEDIA_TYPE | 415 | Validation |
| INTERNAL_ERROR | 500 | Server |
| RATE_LIMIT | 429 | Rate Limiting |
Best practices for handling errors
1. Retry behavior
2xx – Success
- 200 / 201 – Request accepted and processed successfully.
- Evaluation is created and executed; response includes
decision,eval_status, and enrichment results (each with its ownstatus_code, typically 200).
4xx – Client Errors (Do Not Retry As-Is)
- 400 – Invalid input, schema, or payload. Always permanent. Fix the request before retrying.
- 401 / 403 – Authentication or permission issues. Verify API keys, headers, and environment.
Retry-safe (Transient) Errors
- 408, 409, 423, 429, 502, 503, 504
- These indicate temporary conditions such as timeouts, rate limits, or service availability issues
Recommended Retry Strategy
- Start with a 1–2 second delay
- Double delay after each attempt (2s, 4s, 8s, 16s, …)
- Add small random jitter (±1s)
- Cap at ~5 attempts or ~1 minute total
2. Idempotency
POST /api/evaluation
- Each request is treated as a new evaluation, even if the same
idis reused. - If a client timeout occurs, RiskOS™ aborts processing and a retry will create a new evaluation.
3. Webhooks
RiskOS™ → Your Endpoint
- Your endpoint must return a 2xx (typically 200) within the timeout window
- Any 2xx response stops retries permanently
4. Troubleshooting
400 – Bad Request
Check:
- JSON schema alignment with API reference (field names, types, required fields)
- Required top-level fields (
id,timestamp,workflow) - Required enrichment-specific data (PII, address, phone, bank data)
401 / 403 – Authentication & Authorization
Verify:
- Correct API key for environment (sandbox vs production)
5. FAQs
Which HTTP errors are safe to retry?
Retry transient errors such as 408, 409, 423, 429, 502, 503, 504 using exponential backoff.
Are 429 responses possible?
Yes. RiskOS™ may return 429 for rate limiting. Handle using exponential backoff.