Errors
Every failure, including one raised by an insurer behind this API, answers the same envelope. Branch on error.code, never on message.
The envelopelink
{
"error": {
"code": "VALIDATION_FAILED",
"message": "formData failed 1 validation rule(s) declared by form form_motor_quote@1.",
"correlationId": "req_3e681b28-bd97-4128-ac6a-d5bd8502072b",
"retryable": false,
"retryAfterSeconds": null,
"fieldErrors": [
{ "field": "vehicle.age", "code": "max", "message": { "en": "Must be at most 60." } }
]
}
}| Field | What it tells you |
|---|---|
code | What went wrong, as a stable code. |
message | A developer-facing explanation. Not for end users, and it may change between releases. |
correlationId | The request id. Quote it when you contact support. |
retryable | Whether repeating the identical request could succeed. |
retryAfterSeconds | How long to wait before retrying, when it matters. |
fieldErrors | Each offending field, with its own code and message. Show these next to the right inputs. |
details | Extra context, such as details.reason on a 403. |
When an insurer raised the failure, its own correlation id is kept as details.providerCorrelationId, and its OIIS code and status pass through unchanged. Expect codes beyond the ones listed on an operation, and treat an unknown code as its HTTP status.
Statuseslink
| Status | Meaning |
|---|---|
| 400 | The request is malformed. fieldErrors names every offending field, path parameters and headers included. |
| 401 | The x-api-key header is missing, malformed, unknown or inactive, or its secret does not match. |
| 403 | The key is valid but the business may not use it. details.reason is BUSINESS_SUSPENDED, PRODUCTION_NOT_ACTIVATED or IP_NOT_ALLOWED. |
| 404 | No such record, or one your business does not own. The two are deliberately the same. |
| 409 | The request conflicts with the current state, such as a reused Idempotency-Key, an expired or used quote, QUOTE_PENDING, AMOUNT_MISMATCH or PRODUCT_NOT_PURCHASABLE. Read error.code. |
| 413 | The body is over 1 MiB (PAYLOAD_TOO_LARGE), or the insurer refused the file size (UPLOAD_TOO_LARGE). |
| 422 | The request cannot be applied as sent, or the insurer's own response was unusable. See below. |
| 429 | The per-minute budget is spent. Wait Retry-After seconds. |
| 500 | Something failed on this side. The message is deliberately generic. |
| 502 | The insurer answered with something unusable, such as an unreadable options payload or a document too large to hold. |
| 503 | The insurer has no usable credentials in this environment (MAINTENANCE), so no call was made. Contact support. |
Reading a 422link
| Code | Whose to fix | What to do |
|---|---|---|
VALIDATION_FAILED naming your fields | Yours | Correct the named answers and retry with a new Idempotency-Key. If the form was never fetched, fetch it first. |
VALIDATION_FAILED naming JSON pointers such as /status | The insurer's | The insurer's response failed the OIIS schema. Retrying will not help. Contact support. |
CONFIGURATION_INVALID | Support | The configuration is not one this insurer supports. |
FEATURE_NOT_SUPPORTED | Nobody | The insurer does not offer it. details.feature names it. Tell your customer to contact the insurer. |
PAN_DATA_REJECTED | Yours | Remove the card data. Send your processor's reference instead. |
Retrying safelylink
- Retry only when
retryableistrue, on 429, or after a network error. - Wait
retryAfterSecondsorRetry-Afterwhen present, otherwise back off exponentially. - Resend a write with the same
Idempotency-Keyand body, so it still happens once.