Errors¶
Use HTTP status and the JSON error body together.
Error response shape¶
Error responses use this envelope:
{
"error": {
"code": "VALIDATION_ERROR",
"message": "name is too short after normalization",
"details": {
"field": "name",
"nameNorm": "ab"
}
}
}
Fields:
error.code: machine-readable error classificationerror.message: English fallback/debug summaryerror.details: optional structured context
For localized customer-facing UI, map error.code to your own copy. Do not rely on error.message as localized display text.
Retryability matrix¶
| HTTP status | error.code |
Meaning | Retry? | What to do |
|---|---|---|---|---|
400 |
INVALID_REQUEST |
Malformed JSON or invalid request shape/value | No | Fix request construction before retrying |
401 |
UNAUTHORIZED |
Missing or invalid partner API key | No | Fix credentials or configuration |
422 |
VALIDATION_ERROR |
Request payload is well-formed JSON but fails validation/business constraints | No | Correct the payload |
429 |
RATE_LIMITED |
Per-key rate limit exceeded | Yes | Wait for Retry-After, then retry gradually |
500 |
INTERNAL_ERROR |
Unexpected server-side failure | Yes | Retry with bounded backoff and jitter |
502 |
UPSTREAM_ERROR |
Upstream dependency failed or returned an invalid response | Yes | Retry with bounded backoff and jitter |
504 |
UPSTREAM_TIMEOUT |
Upstream dependency timed out | Yes | Retry with bounded backoff and jitter |
Authentication failures¶
The current partner API contract returns 401 for missing or invalid standard partner keys.
{
"error": {
"code": "UNAUTHORIZED",
"message": "Missing or invalid API key"
}
}
The partner docs do not currently define a separate 403 entitlement response for normal X-API-Key authentication.
Validation and request failures¶
Use 400 for malformed requests and 422 for payloads that are syntactically valid but rejected by validation rules.
Example 400:
{
"error": {
"code": "INVALID_REQUEST",
"message": "Malformed request",
"details": {
"errors": [
"JSON decode error"
]
}
}
}
Example 422:
{
"error": {
"code": "VALIDATION_ERROR",
"message": "ownerSurname is required for sole proprietorship checks",
"details": {
"field": "ownerSurname"
}
}
}
Rate limiting failures¶
When the rate limit is exceeded, the API returns:
- HTTP
429 error.code = RATE_LIMITEDRetry-Afterresponse headererror.details.retryAfterin the body
Example:
{
"error": {
"code": "RATE_LIMITED",
"message": "Rate limit exceeded. Try again in 12 seconds.",
"details": {
"retryAfter": 12
}
}
}
Transient server-side failures¶
These are retryable when your request is otherwise valid:
500 INTERNAL_ERROR502 UPSTREAM_ERROR504 UPSTREAM_TIMEOUT
Use bounded retries with jitter. Do not retry forever.
Client implementation pattern¶
- Treat HTTP status as transport execution status.
- Treat top-level
overallStatusas business outcome only on successful200assessment responses. - Treat
error.code,issues[].code, anddrivers[].codeas stable integration keys. - Treat all
messagefields as English fallback/debug copy. - Persist
traceIdon successful responses for support. - Log endpoint, status, request timestamp in UTC, and any available
traceIdor rate-limit headers. - Prefer
Retry-Afterover local retry timing when both are present.
See API Reference > Rate Limits for header-level rate-limit behavior.