COI Verification · reference

When a certificate can’t be read

A blank cell and an illegible cell are different facts about a certificate, and collapsing them is how a vendor gets chased over coverage that is printed on the page. This is what our API returns instead, field by field.

The guarantee

No number, date, or true is returned unless it was quoted from the document. The extraction model is required to reproduce the literal characters it read for every value it asserts. A separate step, in code the model cannot reach, discards anything unquotable.

That step can only ever remove a claim. It has no path to create one. So the API can tell you “we couldn’t read this.” It cannot tell you “you’re covered” about a cell it never read.

Evidence is required to assert, never to deny. null and false claim nothing that could create a false pass, so they travel untouched.

Three states, because two is a lie

A certificate field is not present-or-missing. It is one of three things, and the difference decides what you should do next.

statuswhat it meanswhat you do
present We read the value and it does not meet your requirement. A real deficiency. Go to your vendor.
absent The certificate does not show this coverage at all. A real deficiency. Go to your vendor.
unreadable The value is on the document but could not be read with confidence. Not a deficiency. Ask for a clearer copy.

Three verdicts

compliant is never returned alongside an unreadable field. That is not a convention — it is enforced in code, and tested by generating thousands of random field combinations and asserting the combination cannot occur.

What it looks like

A real response for a certificate whose POLICY EXP cell reads 04/01/20** — a placeholder, not a determinable date — checked against a $2,000,000 personal & advertising injury minimum the certificate does not meet. Both failure kinds appear at once, and they read differently on purpose.

cannot_determine 1 field withheld
general_liability.personal_adv_injury requires ≥ $2,000,000 · status present $1,000,000
general_liability.policy_expiration_date valid at least 30 more days · status unreadable could not be read
"withheld": ["general_liability.policy_expiration_date"]
Present on the certificate, but we could not quote it. Ask for a clearer copy — this is not a coverage gap.

The first row is a genuine shortfall: we read $1,000,000 and your contract wants $2,000,000. The second is not a shortfall at all. An API that returned both as “deficient” would send you to your subcontractor over an expiration date that is probably fine.

withheld — the field most APIs don’t have

Every response carries a withheld array naming every value we declined to report. An absence of findings is not an absence of checking, and that applies to our own redactions too. A silent null would be indistinguishable from a coverage gap, and that ambiguity is exactly what a compliance file cannot carry.

What we don’t do

What this API is not

It reads a certificate and compares it to thresholds you supply. It does not verify that a policy is in force, that the insurer is solvent, or that the certificate is genuine — a certificate is a snapshot of what a broker typed on a date, and no document-reading API can tell you it is true. For in-force status, go to the insurer or the broker.

COI Verification API · What makes a certificate deficient · Automating ACORD 25 vendor onboarding · Blank, unreadable, or absent — for developers · Certificate holder vs additional insured

Or try it on a real certificate right now, free and without signing up: the COI checker runs the same code this API does, including the part that tells you which fields it could not read.

And if you would rather test this than take our word for it: the COI Extraction Honesty Test is an open, synthetic test set for exactly this failure — four documents, documented ground truth, free to run against any tool.

Last updated . Corrections: see About.