GUIDES

Events

Subscribe to these events and you learn when a document, a line, a request, or a verdict changes. Each one reaches you as a signed webhook POST, as a row in a scheduled batch file, or both, configured with PUT /delivery. You can subscribe to every name below. Nineteen fire today. Seven are defined and not emitted yet: document.rejected, coverage_line.expiring, coverage_line.reverification_due, coverage_line.expired, remediation.resolved, program.changed, and outreach.identity_required.

Documents

Every document event carries document_id, insured_ref, consumer_ref, and engagement_id in data, null where the push did not set them.

Event When it fires Key fields What to do
document.received A file is stored under your key, deduplicated or not. A source_document pushed to requirement-sets fires it too transmission_id, filename, sha256, size_bytes, status: received, deduplicated Mark the file received against your record
document.extracted The document's coverage lines are built doc_type, status, coverage_lines[] (coverage line objects, each with a request_id), unreadable_fields[] Store the lines and their request ids. request_id is null for a line with no open request yet
document.not_insurance The file is read and is not an insurance document doc_type Ask the insured for the right file
document.unreadable_fields Extraction reads the file but cannot make out some fields after a second read unreadable_fields[], extraction_id Ask for a legible copy. Rules that need those fields read unverified
document.failed The stored file cannot be read as sent: a damaged photo or scan that does not convert. A type the API does not accept returns 415 on POST /​documents and fires nothing reason, remediation Ask for a PDF or a JPEG. remediation says what to ask for
document.rejected Not emitted yet Nothing arrives today

Results

Event When it fires Key fields What to do
verdict.issued A surface check or a verdict is issued The verdict object: verdict_id, kind, scope, status, rules[], wording, supersedes, engagement_id, requirement_set Read kind first. kind: surface is the check on paper. kind: verified with scope: engagement is the insured's verdict, and scope: line is one line resolving
verdict.superseded A kind: verified verdict replaces an earlier one verdict_id, superseded_by, kind, scope, status Mark the old one replaced and read the new one. A new surface check sends only verdict.issued, with supersedes set

Coverage lines

The coverage line object carries coverage_line_id, coverage_type, carrier, policy_number, effective_date, expiration_date, limits, additional_insured, subrogation_waived, extends_to_children, document_class, verification (state, confirmed_by, confirmed_at, method), flags, and request.

Event When it fires Key fields What to do
coverage_line.changed A line is created, a document merges into it, its verification resolves, or another policy of its type supersedes it Coverage line object, change (created, document_merged, resolved, or superseded), previous_state, and previous_document_class on a document change Update the line on your side
coverage_line.expiring Not emitted yet Nothing arrives today
coverage_line.reverification_due Not emitted yet Nothing arrives today
coverage_line.expired Not emitted yet Nothing arrives today

Requests

request.sla_at_risk and request.overdue carry the request object: request_id, coverage_line_id, opened_at, sla_target_at, sla_hard_at, status, extensions[], total_extension_hours, final_verdict_id, and engagement_ids[].

Event When it fires Key fields What to do
request.sla_at_risk An open request reaches sla_target_at with no final verdict. Its status becomes verdict_due Request object Surface it to your operations team
request.overdue A verdict_due request passes the hard stop it opened with. Its status becomes overdue. Extensions do not delay this event today Request object Expect the line to resolve timed_out once the hard stop plus any extensions passes
request.extended Hours are added with POST /​requests/​{request_id}/​extend request_id, hours, reason, granted_at, by, total_extension_hours, hard_stop_at Push out any deadline you show internally

Evidence and contradictions

Event When it fires Key fields What to do
contradiction.detected A newly merged document states a different value than the line already holds, once per attribute coverage_line_id, attribute, values[] (held, new), sources[] (document:<id> entries) Escalate. The line carries the contradiction_open flag
evidence.attached A line's verification resolves with proof attached coverage_line_id, evidence_id, kind, verification_state Store the id if you show proof to anyone

Requirement sets

Event When it fires Key fields What to do
requirement_set.published A version is published. It is queued in both live and test mode consumer_ref, requirement_set, version, applies_to, grace_period_days, effective_on, impact Record the version in force. impact holds the same counts the preview returned

Remediation

Event When it fires Key fields What to do
remediation.opened A reviewer marks a page not usable: a page with no policy number and no carrier that matches no line, or a document Insurance Verified could not read remediation_id, ask: complete_declarations_packet, reason (policy_number_not_on_pages or page_not_usable), document_id, coverage_type, insured_ref, consumer_ref, engagement_id Ask the insured for the complete declarations packet. GET /​engagements/​{engagement_id} lists the item in outstanding[] until a document with the policy number arrives
remediation.resolved Not emitted yet Nothing arrives today

Programs

Event When it fires Key fields What to do
enrollment.changed PUT /​insureds/​{insured_ref}/​enrollments/​{program_ref} changes an enrollment. A call that changes nothing fires nothing The enrollment object, plus previous (enrolled, effective_on, ends_on before the change, null on the first enrollment) Update the insured's program status on your side. Insurance Verified re-evaluates the insured's active engagements
program.changed Not emitted yet Nothing arrives today

Outreach

Event When it fires Key fields What to do
outreach.identity_required Not emitted yet Nothing arrives today
insured_contact.missing Insurance Verified has no phone or email for the insured, and the engagement's outreach has a step to the insured. The insured's steps are skipped insured_ref, consumer_ref, engagement_id, reason: no_insured_contact, sentence Send the contact with PUT /​insureds/​{insured_ref} (contact.email, contact.phone). GET /​engagements/​{engagement_id} lists kind: insured_contact_missing in outstanding[] until a contact is on file

Delivery

Event When it fires Key fields What to do
delivery.batch_produced A batch export is written The batch: batch_id, period_start, period_end, status, trigger, produced_at, files[] Ingest the batch. GET /​exports/​{batch_id} returns signed URLs
delivery.batch_failed A batch export still fails 24 hours after it was first attempted The batch plus error Re-run the period with POST /​delivery/​batch/​run

POST /delivery/webhook/test sends one more event, ping, with data.message. It belongs to no object and exists to prove your endpoint and your signature check.

Handling events

Every delivery has the same envelope: event_id, event, occurred_at, data, and test, plus insured_ref, consumer_ref, and document_id when data carries them. The fields above live in data. test is true for test-mode events.

Check the signature before you parse anything. Recompute the HMAC-SHA256 over <timestamp>.<body> with your signing secret, compare it to X-IV-Signature, and reject a delivery whose X-IV-Timestamp is more than five minutes from your clock.

Then dedupe. Retries run for 24 hours, so store every event_id you have handled and drop repeats. A retried event can land after newer ones, so a verdict.superseded can arrive before the verdict.issued it names. Write handlers that work in any order.

When in doubt, GET the object. GET /verdicts/{verdict_id} and GET /insureds/{insured_ref}/coverage return the current state, and an event that disagrees with one of them is stale.

New event names can appear within v1. Ignore the ones you do not know.

Next