Skip to navigation

Errors

Every error has the same shape, and its retry action tells you what to do next.
View as Markdown

Branch your code on error.code and error.retry_action.type. The message is written for a person.

The error envelope

{
"error": {
"code": "needs_information",
"message": "The quote request needs more information.",
"field_errors": [
{
"path": "application.applicant.email",
"message": "This fact is required.",
"code": "required"
}
],
"retry_action": {
"type": "supply_facts",
"summary": "Supply the missing facts and send the request again."
},
"doc_url": "https://docs.truvo.com/v1/errors/needs_information"
},
"request_id": "req_..."
}
FieldWhat it holds
error.codeOne of the codes in the table below.
error.reasonA specific reason when the code alone isn’t enough. A live key waiting for approval gets pending_review. The field is otherwise absent.
error.messageA short explanation for a person.
error.field_errorsA list of fields, each with a path, message and code, or null. A field may also include format, allowed_values or did_you_mean.
error.retry_actionWhat to do next, as a type and a summary.
error.doc_urlA link for the code, in the form https://docs.truvo.com/v1/errors/<code>. Each link opens the code table on this page.
request_idThe ID of this response. It starts with req_. Include it when you contact Truvo support at partners@truvo.com.

Every answer, success or error, carries its ID in a Request-Id header, and an error body repeats it as request_id.

Error codes

CodeHTTPWhat it means
invalid_json400The request body isn’t valid JSON.
invalid_cursor400The cursor isn’t one that this list or feed returned. It applies to every paged read: GET /v1/quote-requests, GET /v1/requests, GET /v1/event-subscriptions, and the event feed, GET /v1/events. Send a next_cursor from an earlier page of the same read, or leave the cursor out to start again.
invalid_version400The Truvo-Version header is missing, names no revision that Truvo serves, or names a revision that Truvo retired. The message says which revision to send, and field_errors[0].allowed_values lists each revision that Truvo serves, newest first. Send one of them exactly. See Versions and changes. On /v1/mcp, the code means that the MCP-Protocol-Version header names an MCP protocol version that Truvo doesn’t serve. The answer is a JSON-RPC error, so only the request log, GET /v1/requests or list_api_requests, shows the code. An MCP client that falls back to an older protocol version and connects, as Claude Code does, needs no action.
authentication_failed401The key is missing or isn’t valid.
forbidden403The key doesn’t have authority for this action.
organization_suspended403Truvo suspended your organization’s sandbox or live access. Contact Truvo support.
live_access_not_approved403The message is This live key does not have access to live operations. The reason is pending_review, field_errors is null, and retry_action is {type: "contact_support", summary: "To get live access, book a call from the Go live page: https://partners.truvo.com/dashboard/go-live"}. A signed-in member of the organization gets the message This organization does not have access to live operations., with the same reason and retry action.
wrong_key_kind403This key can’t access this endpoint.
not_found404The resource doesn’t exist, or it’s outside your authority.
conflict409The resource’s current state doesn’t allow this request. For example, another call with this request key is still running, a subscription create didn’t finish in time, another rotation of the subscription is in progress, the integration holds the most active subscriptions it may hold, the subscription is disabled, or delivery to it is off.
request_key_reused409This request key was used with different input. Send a new key.
version_conflict409A newer version exists. Read it before sending the request again.
quote_expired409Not returned yet. The quote has expired.
price_changed409Not returned yet. The quote has a newer version with a different price.
purchase_not_supported409Not returned yet. The quote has no purchase through the API.
event_cursor_expired410The event feed, GET /v1/events, keeps events for 30 days. It can’t resume from this cursor because retention deleted an event after it. Read each resource you track, then read the feed again without a cursor.
request_too_large413The request body is too large.
invalid_input422The input isn’t valid. field_errors lists the fields. When a quote request body matches the schema but Truvo refuses a field, field_errors also lists each missing fact after the refused fields, with the message This fact is required. A quote request in a state where Truvo can’t quote the line gets this code too, in the sandbox and live. field_errors names the state field. GET /v1/capabilities lists the states.
needs_information422Required facts are missing. Truvo returns this before it asks any carrier.
rate_limited429A rate limit stopped the request. The message names the limit, and the Retry-After header gives the seconds to wait.
internal_error500Something went wrong inside Truvo.
service_unavailable503A service that Truvo needs is down. Try the request again later, after the seconds in the Retry-After header.

Truvo can add a code in any revision. Give a code that you don’t know a default branch that shows error.message and links to error.doc_url.

quote_expired, price_changed, and purchase_not_supported belong to purchase operations, which the API doesn’t serve yet, so no answer returns them today.

Retry actions

TypeWhat to do
noneDon’t send the request again.
retryTry the request again later.
correct_inputFix the fields in field_errors, then send the request again.
supply_factsAdd the missing facts in field_errors, then send the request again.
read_statusRead the resource again.
use_new_request_keySend the request with a new Idempotency-Key.
waitWait, then send the request again.
contact_supportContact Truvo support with the request_id.

retry_action.after_seconds gives the number of seconds to wait. A daily limit also returns retry_action.retry_at, the time it resets.

A quote request that ends incomplete is a normal result, not an HTTP error. Stop polling it. Show status_details.message and follow its retry action if you try a new request. A retry may still return no quotes.