GUIDES
How it works
Send us the insurance documents and the rules they must meet. We check the paper at once, confirm the coverage with a source behind the policy, and send you the result within 72 business-day hours.
Verification runs in two stages.
| Surface check | Verdict | |
|---|---|---|
| When | As soon as extraction reads the document | Within 72 business-day hours of a line's clock opening, line by line |
| Question | Does anything on the paper contradict the rules? | Does a source behind the policy confirm the coverage, and does it meet the rules? |
| Checked against | The consumer's requirement set | The agent who issued the certificate, or the carrier behind it |
| On a pass | The clocks open on the engagement's lines | The insured is cleared |
| On a fail | The surface check reads non_compliant. No clock opens on any line until the paper passes |
The roll-up reads non_compliant when a source contradicts or denies a hard rule |
| In the API | verdict.issued, kind: surface |
verdict.issued, kind: verified, one per coverage line and a roll-up per engagement |
The surface check passes anything the paper does not contradict. A limit the certificate leaves blank, or an auto policy form it does not state, passes the surface check and goes to the source for confirmation.
After the verdict, a new document, a late answer from a source, or a reviewer's decision issues a new verdict that supersedes the old one. You set the clock length per engagement and push corrected documents at any time.
Who is who
| Party | Who | In the API |
|---|---|---|
| Verifying entity | You. The account holding the key. Outreach goes out in your name | The key. There is no id |
| Consumer | Whoever's rules apply and who receives the answer | consumer_ref, your string |
| Insured | The vendor, contractor, or company whose coverage is checked | insured_ref, your string |
| Agent and carrier | Who issued the certificate and who wrote the policy. Insurance Verified finds and contacts them | confirmed_by, and the proof on the line |
You are often both the verifying entity and the consumer. An entity checking its own vendors uses its own name as consumer_ref. An entity checking vendors on behalf of its customers has one consumer per customer. The consumer holds no key and makes no calls.
Example: a freight platform verifying the carriers it dispatches for twenty shippers is the verifying entity, each shipper is a consumer, and each carrier is an insured.
Objects
| Object | What it is | Identifier |
|---|---|---|
| Document | One file: a certificate, declarations page, policy, or endorsement. Deduplicated by hash. A new document leaves earlier ones in place | document_id |
| Coverage line | One line of coverage on one policy, merged across documents. The unit of verification | coverage_line_id |
| Verification request | The clock on one line: 48 business-day hours to target and 72 to the hard stop, by default | request_id |
| Requirement set | One consumer's rules, versioned. A consumer can carry several, each named by a key |
consumer_ref + key + version |
| Engagement | One insured against one of a consumer's requirement sets. An insured holds one engagement per requirement set it follows, and each is evaluated on its own | engagement_id |
| Surface check | Stage one. Pass or fail of what the documents claim, against the rules, for the whole engagement | verdict_id with kind: surface |
| Verdict | Stage two. Issued per line as each resolves, and as a roll-up for the engagement whenever it changes | verdict_id with kind: verified, scope: line or engagement |
| Program | A master policy or an attestation covering the insureds you enroll | program_ref |
*_ref values are your strings and opaque to us. *_id values are ours. Store both.
One pass through verification
-
Create the consumer
PUT /consumers/{consumer_ref}with aname. Theconsumer_refis your own id for the customer whose rules apply, for exampleacme-logistics. A first document also creates the consumer. Creating it here gives every later result a readable name.One consumer can hold several requirement sets, each with a
key. The default key isdefault. -
Push the requirement set and publish it
POST /consumers/{consumer_ref}/requirement-setswith the rules as JSON, or with the SOP as text or a PDF to get a draft to review. Publish withapplies_to: new. Insurance Verified evaluates an engagement only against a published version.Send a
keyto start a second set for the same consumer, for exampleopted-in-oa. -
Push a document
POST /documentswith the file, aninsured_ref, and aconsumer_ref, plusrequirement_setwhen the consumer has more than one. The first document for that pair creates the insured and its engagement. You get201 Createdback: atransmission_idfor the call, theengagement_id, and one entry per file indocuments[].The entry carries the document id and the hash. Extraction runs after the response.
GET /engagements/{engagement_id}returns the surface check, the verdict, and everything behind them as they land. -
Extraction fires
document.extractedInsurance Verified reads the file and fires
document.extractedwith the lines it found: coverage type, carrier, policy number, limits, and dates. Record the lines against the insured. A line'srequest_idisnulluntil its clock opens.The same coverage type, policy number, and carrier across documents is one line.
-
Read the surface check
Insurance Verified measures every line against the consumer's requirement set on its face and fires
verdict.issuedwithkind: surface. The check covers the whole engagement. A hard rule that fails on paper, has nothing on file yet, or has a page in review holds the clock on every line. When every hard rule passes on paper, a clock opens on each line whose rule passes.A clock starts at the later of two moments: when Insurance Verified received the document, and when the surface check passed. A surface check that stops passing closes the open clocks with
close_reason: surface_not_passed. A new clock opens when the paper passes again. -
Track verification while the clock runs
While a line is open, Insurance Verified runs the methods listed under How we verify and records every attempt on the request.
request.sla_at_riskfires atsla_target_atwith no final verdict, 48 business-day hours by default.request.overduefires atsla_hard_at, 72 by default. Extend a line's clock withPOST /requests/{request_id}/extend.Clock hours count Monday to Friday in the account's time zone. The clock pauses from Saturday 00:00 to Monday 00:00. Set different hours for one engagement with
clockonPOST /engagements. -
Read verdicts line by line
Each line gets its verdict as soon as it resolves:
verdict.issuedwithkind: verifiedandscope: line. Example: the auto line is contradicted first and its verdict goes out. General liability confirms later and gets its own verdict. The engagement roll-up,scope: engagement, is issued the first time it has an answer and superseded on every change after. A hard rule that a source contradicts or denies readsnon_compliant. Every line resolved and passing readscompliant. Every line resolved with a hard rule left unconfirmed readsinsufficient_evidence. A line whose clock runs out resolvestimed_out, and the rule it feeds readsunverified.While lines are still open and no source has failed a hard rule, Insurance Verified issues no roll-up. You read the surface check and the line verdicts so far.
-
Handle later changes
A new document, a late answer from a source, or a reviewer's decision changes the answer. Insurance Verified issues a new verdict and fires
verdict.supersededfor the one it replaces. A roll-up that reopens, for example when new paper puts a rule back on hold, is superseded by a roll-up withstatus: pending.Subscribe to
verdict.supersededand store the replacement against the insured.
How we verify
Insurance Verified checks every document on its face, then confirms each open line with a source behind the policy. The line records which method reached the answer. New methods appear in verification.method as they ship, with no change to your integration. On the line, verification.method names the method, confirmed_by names who confirmed it, and proof[] holds the evidence.
| Check on the document | What it looks for |
|---|---|
| Certificate holder | The holder box empty, generic, or the insured itself |
| Internal consistency | Insurer letters that are not listed, negative limits, an unsigned certificate |
| Date and limit arithmetic | Dates that are not on the calendar, effective after expiration, a certificate dated after it arrived, an aggregate below its per-occurrence limit |
| NAIC and carrier | A printed NAIC number that belongs to a different insurer |
| ACORD form | The ACORD 25 edition, and the standard "matter of information only" statement missing or reworded |
| PDF forensics | Edits in the file's save history, file dates after receipt, design tools and consumer PDF editors, hidden layers, boxes drawn over the page, and text a reader cannot see on the page |
| Text screen | Text in the document, its metadata, annotations, or form fields addressed to a reader or a model, invisible characters, and look-alike letters |
| Document registry | The same file or the same page received before for another insured |
| Source of transmission | A failed DMARC check on the email that carried the file, and proof mail from an address not on file |
| Producer email | An agent email on a personal mail domain |
| Photo metadata | Editing software in a photo's camera data, or no camera data |
| Live-verification link or QR | A verification link or code printed on the document |
| Confirmation at the source | verification.method |
confirmed_by |
|---|---|---|
| Email to the agent of record, read and triaged | email_agent_of_record |
broker |
| Call to the agent or the carrier, with the exchange recorded | call |
broker or carrier |
| Carrier connection: the insured signs in at their auto carrier, and the policy the carrier returns matches the certificate | carrier_feed |
carrier_feed |
A line reads
verifiedwhen a source behind the policy confirms it: the agent or the carrier. A check on the document records a finding on the document and leavesverification.stateas it was.
Each finding has a severity. needs_a_look puts the document under review by Insurance Verified and leaves the surface check as it was. do_not_rely comes only from proof: the file's save history shows a key value (a date, a limit, a policy number) replaced after the first save, or a reviewer decides the document cannot be relied on. The surface check then leaves that document out, and the rules it fed read unverified with reason document_held until a reviewer overrides the finding. GET /documents/{document_id} returns the document's integrity with its state (clear, under_review, not_relied_on) and the findings in force, as severity and title.
A confirmation sets verification.state and attaches proof. When a newly merged document states a different value than the line holds, contradiction.detected fires.
Reading a result
Every result, surface check or verdict, is one object on verdict.issued. Three fields tell you what you are reading.
| Field | What it tells you | Values |
|---|---|---|
kind |
The stage | surface: what the paper says. verified: what the sources behind the policy confirmed |
scope |
What it covers | line: one coverage line. engagement: the roll-up for the insured under this requirement set |
status |
The outcome | The table below |
Read kind first. compliant on a surface check says the paper is in order. compliant on a verdict says a source confirmed the coverage.
status |
Meaning | What you do |
|---|---|---|
pending |
On a surface check: a hard rule has nothing on file yet, only a weaker document than it demands, or a page in review. On a roll-up: the engagement reopened after an earlier roll-up | Wait for the next verdict.issued |
compliant |
Every hard rule passes. On a surface check: the paper is in order. On a verdict: a source confirmed the coverage | Clear the insured, at that stage's strength |
non_compliant |
On a surface check: the paper fails a hard rule. On a verdict: a source contradicts or denies a hard rule | Hold. The result names the rule, what it required, what it found, and the fix. Show that to the insured |
insufficient_evidence |
On a verdict: every line resolved and a hard rule has no confirmation, because the source refused, the clock ran out, or every method ran its course | Escalate to a person, or ask the insured for more |
Reading a failure
Each entry in rules[] shows both sides of every comparison.
| On the rule | What it compares |
|---|---|
rule_key, severity |
Which rule, and whether it blocks (hard) or warns (soft) |
surface |
On a kind: surface check only, the paper reading: pass, fail, not_yet, pending_review, not_applicable. Branch on this field at stage one |
result |
pass, fail, gap (coverage missing), unverified (claimed and not yet confirmed), not_applicable (skipped by a state or scope condition). Branch on this field when kind is verified |
reasons[] |
Evaluator reason codes such as verification_pending, limit_below_minimum, or policy_form_unconfirmed |
required and observed |
The value the rule asked for and the value found, for example a limit |
document_class_required and document_class_observed |
The paper the rule accepts and the paper received |
verification_required and verification_observed |
Who had to confirm it and who did |
flags[] |
Something a person may need to act on, such as timed_out, refused, or state_review_required |
wording.summary states the result in a sentence and wording.next names the fix, both written for the person who acts on it. When a page cannot be used, remediation.opened fires with ask: complete_declarations_packet, and your system asks the insured for the complete paper.
Branch on rules[]. Show wording to people. wording changes without a version bump.
A result that replaces another names it in supersedes. Results from a test key carry test: true.
Verification state on a coverage line
Every coverage line carries verification.state, which says how far verification got on that line. It feeds the rule results. Branch on the verdict status.
verification.state |
Meaning |
|---|---|
claimed |
A document says so. No source has confirmed it |
in_progress |
Verification is under way |
verified |
A source behind the policy confirmed it, with proof attached |
unable_to_verify |
Every method ran its course without an answer |
refused |
The agent declined to confirm |
contradicted |
The source's answer disagrees with the document, for example a cancelled policy |
expired |
The expiration date passed with no renewal and no confirmation |
timed_out |
The clock ran out with attempts still pending. Extend the clock to avoid it |
Two independent tests sit behind every rule. document_class is the strength of the paper, from weakest to strongest: coi (certificate), endorsement, dec_page (declarations page), policy. confirmed_by is who confirmed it: none, broker, carrier, carrier_feed. A rule can demand a level on either axis. A strong document with no confirmation reads unverified.
Time
| Moment | What fires |
|---|---|
| Seconds after the push | document.received, then document.extracted |
| After extraction | The surface check on verdict.issued |
| When the surface check passes | Clocks open on the engagement's lines |
sla_target_at, 48 business-day hours by default |
request.sla_at_risk |
sla_hard_at, 72 business-day hours by default |
request.overdue |
| On extension | request.extended |
| As each line resolves | verdict.issued with scope: line |
Every event reaches you by webhook, by scheduled batch file, or both. Events can arrive out of order. When an event and a read disagree, GET the object.