Error Handling
All Debitura APIs return structured error responses with consistent formats. Across the Customer, Collection Partner, and Referral Partner APIs, error responses centre on a canonical businessErrors[] array. Most endpoints also populate legacy top-level error/message fields for backward compatibility (dual-write), including unhandled server errors (500), where error and message are both "An unexpected error occurred. Please try again later." and businessErrors[0].type is InternalError. Always read businessErrors[] for forward-compatible error handling.
Quick Reference
| Status | Meaning | Retryable |
|---|---|---|
400 | Validation failed | No — fix request |
401 | Invalid or missing API key | No — check credentials |
404 | Resource not found | No — verify ID |
422 | Business rule violation | No — see solutionUrl |
500 | Server error | Yes — exponential backoff |
API-specific: 409 (conflicts — Referral Partner client onboarding, in-flight Idempotency-Key retries on all three APIs, and Collection Partner state conflicts such as uploads to a merged case), 413/415 (file uploads on all three APIs).
Business Errors
The businessErrors[] array is returned across all endpoints when a request fails for a reason the API can describe with a typed code — most commonly business-rule violations (422), but also conflicts (409), not-found (404), invalid pagination or file uploads (400/413/415), and unexpected server errors (500). This format is consistent across all Debitura APIs (Customer, Collection Partner, and Referral Partner).
{
"error": "Your company's agreement must be signed and current before submitting cases.",
"message": "Your company's agreement must be signed and current before submitting cases.",
"businessErrors": [
{
"type": "PartnerContractNotValid",
"message": "Your company's agreement must be signed and current before submitting cases.",
"solutionUrl": ""
}
]
}
Business-rule 422s from Customer API POST /cases instead return businessErrors[] plus signingHandoff (null unless a signing step is missing), with no error/message.
| Field | Description |
|---|---|
businessErrors[].type | Error code (see table below) |
businessErrors[].message | Human-readable description |
businessErrors[].solutionUrl | Link to resolution guidance (when available) |
error | Legacy label — a free-form string, usually the human message (occasionally a distinct label such as MissingUserIdentifier). Do not assume it equals businessErrors[0].type; read businessErrors[].type for the canonical code |
message | Legacy human-readable description (kept for backward compatibility) |
Across all Debitura APIs, message (and businessErrors[].message) is deliberately generic, human-readable text. For unexpected and internal failures it never contains raw exception text, stack traces, or upstream provider/integration error bodies — those details are logged server-side only. Branch your integration logic on businessErrors[].type and the HTTP status code, never on the contents of the message string.
Error Types
Common types (not exhaustive) — branch on the types you handle and fall back on HTTP status.
| Type | Description | Resolution | solutionUrl |
|---|---|---|---|
NoPartnerAvailable | No collection partner covers the debtor's jurisdiction | Check supported countries or contact support | — |
CollectionPartnerNotFound | An explicitly supplied collectionPartnerId override does not exist or has been deleted | Verify the ID, or omit it to use automatic partner matching | — |
CreditorBlocked | Creditor account is blocked | Contact support | — |
MissingDebtCollectionContract | Debt collection contract not signed | Complete contract signing via URL | ✓ |
MissingPowerOfAttorney | Power of attorney not in place | Complete PoA process via URL | ✓ |
MissingKycVerification | Director identity verification required by collection partner | Complete KYC form via URL | ✓ |
CaseNotFound / PaymentNotFound / WebhookNotFound / DivisionNotFound / NotFound | The requested resource was not found or is not accessible — the type is usually resource-specific, with generic NotFound used for some sub-resources | Verify the ID and your access scope | — |
InvalidPagination | The page or pageSize parameters are out of range | Adjust pagination parameters — see Pagination | — |
IdempotencyConflict | The Idempotency-Key was reused with a different request body (returned as 422; in-flight retries instead get a 409 — see Idempotency) | Use a new key, or replay the original request unchanged | — |
Conflict | The request conflicts with the current state of the resource | Re-fetch the resource and retry | — |
FileTooLarge | The uploaded file exceeds the maximum allowed size | Reduce the file size and retry | — |
UnsupportedFileType | The uploaded file has an unsupported type | Use a supported file format | — |
WebhookEventsRequired | No event types were supplied when creating a webhook subscription | Include at least one valid event type | — |
WebhookInvalidEventTypes | One or more supplied webhook event types are not recognised | Use valid event types — see Webhooks | — |
WebhookInvalidUrl | The webhook subscription URL failed validation (e.g. non-HTTPS) | Provide a reachable HTTPS URL | — |
ValidationError | A generic validation failure without a more specific error type — also returned when the request body itself is not valid UTF-8 | Fix the request and retry; re-encode the request body as UTF-8 if the failure is encoding-related | — |
InternalError | An unexpected server error occurred | Retry with exponential backoff | — |
When solutionUrl is provided, it links directly to the portal page where the user can resolve the issue.
Validation Errors (400)
Returned for field-level validation failures. Keys are field names; values are arrays of error messages. Keys are field paths in PascalCase (e.g. Debtor.Email) — dictionary keys are not camelCased.
{
"Lines": ["Case total must be a positive amount"],
"Debtor.Email": ["Invalid email format"]
}
Not Found & Server Errors (404/500)
Not-found and unexpected server errors return the same structured envelope as business errors. The not-found type is usually resource-specific — CaseNotFound, PaymentNotFound, WebhookNotFound, DivisionNotFound — with a generic NotFound for some sub-resources; server errors use InternalError. Server errors never leak stack traces or internal details.
{
"error": "No case found with this ID: 3fa85f64-5717-4562-b3fc-2c963f66afa6",
"message": "No case found with this ID: 3fa85f64-5717-4562-b3fc-2c963f66afa6",
"businessErrors": [
{
"type": "CaseNotFound",
"message": "No case found with this ID: 3fa85f64-5717-4562-b3fc-2c963f66afa6",
"solutionUrl": ""
}
]
}
Problem Details (401)
Authentication errors return RFC 7807 Problem Details with Content-Type: application/problem+json.
{
"title": "Unauthorized",
"status": 401,
"detail": "API Key was not provided"
}
For an unknown key, detail is "Invalid API Key".
Framework-level field validation ([Required], [MinLength], etc.) also returns RFC 7807 ValidationProblemDetails; see the Validation Errors section above for the controller-level validation shape.
Retry Strategy
For 500 errors, use exponential backoff with max 3 retries. See Idempotency for safe retry patterns.