Skip to content

Errors

Errors carry a detail object with a stable code and a plain-language message, plus the fields that code needs:

{ "detail": { "code": "invalid_answers", "message": "…", "errors": [ … ] } }

A few older validators return a string ({"detail": "…"}), and framework validation errors return a list of {loc, msg, type}. React to the HTTP status and code; show message to people.

Status What to do
401 The token is missing, expired or revoked. Get a new token once; if that fails, stop.
403 Stop. Don’t retry. The token is valid but not allowed to do this, and the same call fails the same way until a person changes the access. Show the detail to a person and send any remaining work by email.
404 Not found, or it belongs to another brokerage.
409 / 422 Fix the request as detail says. The same request sent again gets the same answer.
429 Back off. Wait the Retry-After seconds before the next call, and don’t fire queued calls in the meantime. A daily cap resets the next day.
503 Retry the same call once, after Retry-After when it is set.

No Hedge Instant Quote market fits the risk, so nothing was created. Returned by POST /broker/submissions and POST /broker/intake (and reported as instant_available: false by POST /broker/appetite/instant). The API never reaches binding or specialty markets; email Hedge instead, with everything email_us lists:

{
"detail": {
"code": "no_instant_market",
"message": "…",
"email_us": {
"address": "submissions@hedgespecialty.com",
"what_to_include": [
"ACORD 125 (Commercial Insurance Application)",
"ACORD 126 (General Liability)",
"Hedge Contractors Supplemental (HEDGE_03)",
"Your description of the operations, the requested effective date and limits"
]
}
}
}

From intake, the body also carries read: what Hedge could read from the documents and text. Don’t retry with reshaped facts; email the risk.

A field the flow needs is absent; fields[] names them. A create needs applicant.insured_name, narrative, lines_of_business and a state (primary_state, or the mailing address state).

A program_ids entry is not a Hedge Instant Quote market you can reach (POST /broker/requirements, POST /broker/submissions). Use the program_ids POST /broker/appetite/instant returns.

One or more answers were refused, and nothing was saved: answers are all or nothing. Each entry in errors[] names the market (when the answer was one market’s own), the question and the reason:

{
"detail": {
"code": "invalid_answers",
"message": "…",
"errors": [ { "program_id": "6f1c2a0e-…", "key": "annual_revenue", "message": "Enter a number of 0 or more." } ]
}
}

A shared_answers key that no market on the file asks is not an error: it is ignored and named in warnings[], and the rest is saved.

POST .../quote reports each market in results[]. A market that still needs answers comes back not_ready with its missing[]:

{ "program_id": "77aa…", "outcome": "not_ready", "status": 409,
"missing": [ { "key": "annual_revenue", "id": "annual_revenue", "label": "Annual revenue", "message": "Answer this question." } ] }

The other outcomes are requested, already_quoting, already_quoted, preparing and not_a_fit (with reason). The response is 200 when at least one market was requested or is already in progress, and 409 with the same body when none was.

POST .../finalize on a file created over the API. There is no marketing to release: answer with PATCH .../answers and quote with POST .../quote.

POST .../quotes/{quote_id}/bind-link:

Status code Meaning
409 quote_not_available, quote_expired, quote_not_bindable The quote can’t be bound now; reason says why when set. The quote read’s bind.blocked_reason says the same.
409 insured_link_unavailable for: insured on a market that does not take the insured’s own payment. Use for: broker.
409 insured_link_refused The insured link can’t be issued for this quote.
409 assumptions_unconfirmed for: insured while assumptions behind the quote stand unconfirmed. The body lists them; confirm them with the broker, then send attest_assumptions.
409 brokerage_portal_disabled Your brokerage’s portal access is off. Contact Hedge.
422 producer_email missing or not an active portal user, insured_email_required, or insured_email_invalid.
429 More than 20 links an hour for one quote.
503 proposal_unavailable Try again shortly.

The token can’t do this. Common causes:

  • Submit access is off for your brokerage. Hedge turns it on per brokerage; until then tokens are issued without broker_submit and every submit call is refused. A brokerage admin requests it in the portal.
  • The token lacks the scope for the call, the brokerage is paused, or the key was revoked.

A 403 will not change on retry. Stop.

Each API key or connected user gets, per minute:

Limit
Reads (GET) 120
Writes (every other method, MCP write tools included) 60

Daily caps per brokerage also apply: 100 creates, 100 intake calls, 500 uploads and 150 appetite checks. Over a limit the API answers 429 with a Retry-After header in seconds.

A dependency is briefly unavailable, or Hedge couldn’t count a write just now. Your input is kept; retry the same call once after Retry-After.

Status Meaning
422 Malformed request: a body that isn’t valid JSON (JSON decode error) or doesn’t fit the schema. errors[] says where.
409 A reused Idempotency-Key with different inputs, or one still in flight.
413 A file is over the limit: 15 MB per file and 60 MB per intake call.
415 Not a supported document type.