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

  1. Create the consumer

    PUT /consumers/{consumer_ref} with a name. The consumer_ref is your own id for the customer whose rules apply, for example acme-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 is default.

  2. Push the requirement set and publish it

    POST /consumers/{consumer_ref}/requirement-sets with the rules as JSON, or with the SOP as text or a PDF to get a draft to review. Publish with applies_to: new. Insurance Verified evaluates an engagement only against a published version.

    Send a key to start a second set for the same consumer, for example opted-in-oa.

  3. Push a document

    POST /documents with the file, an insured_ref, and a consumer_ref, plus requirement_set when the consumer has more than one. The first document for that pair creates the insured and its engagement. You get 201 Created back: a transmission_id for the call, the engagement_id, and one entry per file in documents[].

    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.

  4. Extraction fires document.extracted

    Insurance Verified reads the file and fires document.extracted with the lines it found: coverage type, carrier, policy number, limits, and dates. Record the lines against the insured. A line's request_id is null until its clock opens.

    The same coverage type, policy number, and carrier across documents is one line.

  5. Read the surface check

    Insurance Verified measures every line against the consumer's requirement set on its face and fires verdict.issued with kind: 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.

  6. 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_risk fires at sla_target_at with no final verdict, 48 business-day hours by default. request.overdue fires at sla_hard_at, 72 by default. Extend a line's clock with POST /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 clock on POST /engagements.

  7. Read verdicts line by line

    Each line gets its verdict as soon as it resolves: verdict.issued with kind: verified and scope: 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 reads non_compliant. Every line resolved and passing reads compliant. Every line resolved with a hard rule left unconfirmed reads insufficient_evidence. A line whose clock runs out resolves timed_out, and the rule it feeds reads unverified.

    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.

  8. 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.superseded for 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 with status: pending.

    Subscribe to verdict.superseded and 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 verified when a source behind the policy confirms it: the agent or the carrier. A check on the document records a finding on the document and leaves verification.state as 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.

Next