# ACORD 25 COI Checker: Certificate of Insurance Compliance (`hanielazevedo/acord-25-coi-checker`) Actor

ACORD 25 certificate of insurance (COI) checker: reads COI PDFs (fillable, flattened or scanned) into JSON and checks limits, expiry, additional insured, waiver of subrogation, primary/non-contributory and holder. PASS/FAIL/REVIEW with reasons and per-field confidence. Rules-based, no AI.

- **URL**: https://apify.com/hanielazevedo/acord-25-coi-checker.md
- **Developed by:** [Haniel Azevedo](https://apify.com/hanielazevedo) (community)
- **Categories:** Business, Automation, Developer tools
- **Security:** Limited permissions
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $80.00 / 1,000 certificate checkeds

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.

Learn more: https://docs.apify.com/actors/running/actors-in-store.md#pay-per-event

## What's an Apify Actor?

An Actor is a serverless cloud program that runs on the Apify platform. It has two run modes.
In Batch mode, an Actor accepts a well-defined JSON input, performs an action which can take anything from a few seconds to a few hours,
and optionally produces a well-defined JSON output, datasets with results, or files in key-value store.
In Standby mode, an Actor provides a web server which can be used as a website, API, or an MCP server.

Apify vocabulary and the platform model are defined once, in the agent quickstart at https://apify.com/agents.md.

## How to integrate an Actor?

If asked about integration, you help developers integrate Actors into their projects.
You adapt to their stack and deliver integrations that are safe, well-documented, and production-ready.

Do not guess an integration path. Every one of them is in the agent quickstart at https://apify.com/agents.md: the Apify MCP server, Agent Skills with the Apify CLI, the JavaScript and Python clients, the REST API, and the account-free path for an agent with no human to sign in. It also carries the rule on stating cost before the first paid run.

For examples already wired to this Actor's own input schema, see the [API](#api) section below.

Each client library has reference documentation the quickstart does not restate: [JavaScript/TypeScript](https://docs.apify.com/api/client/js/docs.md) (`npm install apify-client`) and [Python](https://docs.apify.com/api/client/python/docs.md) (`pip install apify-client`).

# README

## ACORD 25 COI Checker: Certificate of Insurance Compliance

**Turn ACORD 25 certificate of insurance PDFs into structured JSON and a PASS / FAIL / REVIEW verdict against your insurance requirements.** It is built for developers and AI agents: you call it over the API, it reads fillable, flattened and scanned certificates, and it returns every field with a confidence score.

- Extracts the producer, insured, insurers A–F with NAIC numbers, every coverage line (insurer letter, policy number, effective/expiration dates, limits, ADDL INSD / SUBR WVD), the description of operations, ACORD 101 additional remarks, the certificate holder and the form edition (2010/05, 2014/01, 2016/03).
- Checks limits (GL, auto CSL, umbrella, WC/EL), expiry (with "must not expire within N days"), additional insured, waiver of subrogation, primary & non-contributory wording and certificate holder name.
- **Rules only, no AI/LLM**, so the same PDF always gives the same answer. Your certificates are never sent to a third-party model.
- **Pay per certificate checked.** Files that fail, blank forms, scans with OCR off and the sample certificate are free.

***

### Who it is for

- **Developers** building vendor / subcontractor onboarding, property management, construction compliance or procurement tools who need COI data in JSON and do not want to maintain a PDF parser.
- **AI agents** (Claude, ChatGPT, Cursor and others through the Apify MCP server) that receive a COI and need a reliable yes/no with reasons rather than a guess from a vision model.
- **Risk / compliance teams** who want a CSV of every certificate with its verdict.

### Example input

The Console form is prefilled with a real public certificate (Cornell University's sample ACORD 25) and a typical requirement set. Click **Start** without changing anything:

```json
{
  "pdfUrls": [
    "https://scl.cornell.edu/sites/scl/files/documents/OSFL-COI-Correct%20Sample%20Updated.pdf"
  ],
  "requirements": {
    "glEachOccurrenceMin": 1000000,
    "glGeneralAggregateMin": 2000000,
    "autoCombinedSingleLimitMin": 1000000,
    "additionalInsuredRequired": true,
    "primaryNonContributoryRequired": true,
    "certificateHolderName": "Cornell University",
    "minDaysUntilExpiry": 30,
    "asOfDate": "2021-01-15"
  }
}
```

### Example output

That run takes about 9 seconds and returns one certificate with verdict **PASS**: GL $1M / $2M with additional insured, auto CSL $1M, holder name matches, and nothing expires within 30 days of the `asOfDate`. The sample certificate is free. Trimmed result (run of 1 Nov 2026):

```json
{
  "fileName": "OSFL-COI-Correct Sample Updated.pdf",
  "verdict": "PASS",
  "reasonCodes": [],
  "asOfDate": "2021-01-15",
  "insuredName": "SAMPLE VENDOR",
  "certificateHolderName": "CORNELL UNIVERSITY, It's",
  "earliestExpirationDate": "2021-10-01",
  "overallConfidence": 0.95,
  "certificate": {
    "inputType": "flattened",
    "formEdition": "2014/01",
    "producer": {
      "name": "SAMPLE BROKER"
    },
    "coverages": {
      "generalLiability": {
        "insurerLetter": "A",
        "policyNumber": "CGL 123456",
        "effectiveDate": "2020-10-01",
        "expirationDate": "2021-10-01",
        "additionalInsured": true,
        "limits": {
          "eachOccurrence": 1000000,
          "generalAggregate": 2000000,
          "productsCompletedOpsAggregate": 1000000
        }
      },
      "autoLiability": {
        "insurerLetter": "A",
        "policyNumber": "CAL 987654",
        "expirationDate": "2021-10-01",
        "limits": {
          "combinedSingleLimit": 1000000
        }
      }
    }
  },
  "demo": true,
  "charged": false
}
```

### Quick start (API)

#### Python (`pip install apify-client`)

```python
from apify_client import ApifyClient

client = ApifyClient("<YOUR_APIFY_TOKEN>")
run = client.actor("hanielazevedo/acord-25-coi-checker").call(run_input={
    "pdfUrls": ["https://scl.cornell.edu/sites/scl/files/documents/OSFL-COI-Correct%20Sample%20Updated.pdf"],
    "requirements": {
        "glEachOccurrenceMin": 1000000,
        "glGeneralAggregateMin": 2000000,
        "autoCombinedSingleLimitMin": 1000000,
        "wcElEachAccidentMin": 1000000,
        "additionalInsuredRequired": True,
        "waiverOfSubrogationRequired": True,
        "primaryNonContributoryRequired": True,
        "certificateHolderName": "Riverside Property Management LLC",
        "minDaysUntilExpiry": 30
    }
})
for cert in client.dataset(run["defaultDatasetId"]).iterate_items():
    if cert["recordType"] == "certificate":
        print(cert["fileName"], cert["verdict"], cert["reasonCodes"])
    else:
        print(cert["fileName"], "ERROR", cert["errorCode"], cert["errorMessage"])
```

#### JavaScript / TypeScript (`npm i apify-client`)

```js
import { ApifyClient } from 'apify-client';

const client = new ApifyClient({ token: process.env.APIFY_TOKEN });
const run = await client.actor('hanielazevedo/acord-25-coi-checker').call({
    pdfUrls: ['https://scl.cornell.edu/sites/scl/files/documents/OSFL-COI-Correct%20Sample%20Updated.pdf'],
    requirements: { glEachOccurrenceMin: 1000000, additionalInsuredRequired: true, minDaysUntilExpiry: 30 },
});
const { items } = await client.dataset(run.defaultDatasetId).listItems();
for (const c of items) console.log(c.fileName, c.verdict ?? c.errorCode, c.reasonCodes ?? c.errorMessage);
```

#### Plain HTTP (one call, returns the dataset)

```bash
curl -X POST "https://api.apify.com/v2/acts/hanielazevedo~acord-25-coi-checker/run-sync-get-dataset-items" \
  -H "Authorization: Bearer $APIFY_TOKEN" -H "Content-Type: application/json" \
  -d '{"pdfUrls":["https://scl.cornell.edu/sites/scl/files/documents/OSFL-COI-Correct%20Sample%20Updated.pdf"],"requirements":{"glEachOccurrenceMin":1000000}}'
```

#### AI agents (MCP)

Add the Apify MCP server with this Actor as a tool:

```json
{
  "mcpServers": {
    "apify": {
      "url": "https://mcp.apify.com/?tools=hanielazevedo/acord-25-coi-checker",
      "headers": { "Authorization": "Bearer <YOUR_APIFY_TOKEN>" }
    }
  }
}
```

The agent can then call the tool with `pdfUrls` and `requirements` and read `verdict`, `reasons[].message` and `lowConfidenceFields`. Each reason has a human-readable message the agent can quote back to the user.

#### PDFs that are not public

The Actor runs with **limited permissions**, so it can only read storage you hand to it. Upload the PDFs to an Apify key-value store (Console → Storage → Key-value stores, or `client.key_value_store(id).set_record("acme.pdf", data, "application/pdf")`), then pass `"pdfStore": "<store id or name>"`. You can add `"pdfKeys": ["acme.pdf"]` to process only some records. Selecting the store grants read-only access to that one store, for that run only.

### Step by step (Console)

1. Open the Actor and click **Try for free**. The input is prefilled with a public sample certificate from Cornell University, which is processed for free.
2. Paste your PDF links into **Certificate PDF URLs**, or pick a key-value store that holds your PDFs.
3. Optionally, fill **Requirements** with the JSON for the limits and endorsements you need (see below).
4. Click **Start**. Each certificate becomes one row in the **Output** tab, and `SUMMARY.csv` in the key-value store holds one line per certificate for Excel or Google Sheets.

### Input

| Field | Type | Description |
|---|---|---|
| `pdfUrls` | string\[] | Public http(s) links to COI PDFs. One PDF may hold several certificates and ACORD 101 pages. |
| `pdfStore` | string | Key-value store with PDFs (read-only access, granted for this run only). |
| `pdfKeys` | string\[] | Optional record keys inside `pdfStore`. Defaults to every `*.pdf`. |
| `requirements` | object | Optional checks, all keys optional (below). |
| `enableOcr` | boolean | Read scanned certificates with open-source Tesseract OCR (default `true`). |
| `minFieldConfidence` | "0.6"–"0.9" | Fields below this are listed in `lowConfidenceFields`, and if one is used in a decision the verdict becomes REVIEW. Default `0.8`. |
| `maxCertificates` | integer | Safety cap per run (default 200). |
| `maxFileSizeMb` | integer | Larger files are rejected free of charge (default 20). |

#### `requirements` keys

| Key | Meaning |
|---|---|
| `glEachOccurrenceMin`, `glGeneralAggregateMin`, `glProductsCompletedOpsMin` | General liability minimums (USD) |
| `autoCombinedSingleLimitMin` | Auto liability combined single limit |
| `umbrellaEachOccurrenceMin`, `umbrellaAggregateMin` | Umbrella / excess minimums |
| `wcElEachAccidentMin`, `wcElDiseaseEachEmployeeMin`, `wcElDiseasePolicyLimitMin` | Employers' liability minimums |
| `allowUmbrellaToMeetLimits` | Default `true`. A GL or auto shortfall is covered by the umbrella (reason `UMBRELLA_USED_TO_MEET_LIMIT`, INFO). |
| `requireGeneralLiability`, `requireAutoLiability`, `requireUmbrella`, `requireWorkersCompensation` | The coverage must be listed |
| `additionalInsuredRequired` + `additionalInsuredOn` | ADDL INSD must be marked on these coverages (default `["generalLiability"]`) |
| `waiverOfSubrogationRequired` + `waiverOfSubrogationOn` | SUBR WVD must be marked (default `["generalLiability","workersCompensation"]`) |
| `primaryNonContributoryRequired` | "Primary and non-contributory" must appear in the description / remarks |
| `certificateHolderName`, `insuredName` | Fuzzy name match that tolerates case, punctuation, "Inc./LLC" and OCR slips |
| `minDaysUntilExpiry`, `asOfDate` | Policies must not expire within N days of `asOfDate` (YYYY-MM-DD, default today UTC) |

Any coverage that is not listed in your requirements is still date-checked, but problems with it are reported as `INFO` and do not change the verdict. Unknown keys fail the run immediately, so a typo can't silently pass everything.

### Output

There is one dataset item per certificate (`recordType: "certificate"`) or per failed file (`recordType: "error"`). This example is shortened:

```json
{
  "recordType": "certificate",
  "fileName": "acme-roofing-2026.pdf",
  "verdict": "FAIL",
  "reasonCodes": ["GL_EACH_OCCURRENCE_BELOW_MIN", "SUBR_WAIVER_MISSING"],
  "reasons": [
    {"code": "GL_EACH_OCCURRENCE_BELOW_MIN", "severity": "FAIL",
     "message": "General liability eachOccurrence is $1,000,000, required $2,000,000.",
     "fields": ["coverages.generalLiability.limits.eachOccurrence"], "actual": 1000000, "required": 2000000},
    {"code": "SUBR_WAIVER_MISSING", "severity": "FAIL",
     "message": "General liability: waiver of subrogation is not indicated.",
     "fields": ["coverages.generalLiability.subrogationWaived"]},
    {"code": "EXPIRES_WITHIN_N_DAYS", "severity": "INFO",
     "message": "Auto liability expires on 2020-10-12, 41 days after 2020-09-01 (minimum 60)."}
  ],
  "asOfDate": "2020-09-01",
  "insuredName": "ABC Company 12345",
  "certificateHolderName": "CITY OF TEMECULA",
  "earliestExpirationDate": "2020-10-12",
  "certificate": {
    "pageNumber": 1, "inputType": "flattened", "formEdition": "2016/03", "ocrUsed": false,
    "certificateDate": "2020-08-24", "certificateNumber": "1907915241",
    "producer": {"name": "Clifford & Bradford Insurance Agency", "phone": "...", "email": "..."},
    "insured": {"name": "ABC Company 12345", "address": "..."},
    "insurers": {"A": {"name": "United Financial Casualty Co.", "naic": "11770"}, "B": {"name": "West American Ins Co.", "naic": "44393"}},
    "coverages": {
      "generalLiability": {"present": true, "insurerLetter": "B", "policyNumber": "GL-123456",
        "effectiveDate": "2019-12-12", "expirationDate": "2020-12-12", "additionalInsured": true, "subrogationWaived": false,
        "commercialGeneralLiability": true, "occurrence": true, "claimsMade": false, "aggregateAppliesPer": null,
        "limits": {"eachOccurrence": 1000000, "damageToRentedPremises": 500000, "medicalExpense": 5000,
                   "personalAdvertisingInjury": 1000000, "generalAggregate": 2000000, "productsCompletedOpsAggregate": 2000000}},
      "autoLiability": {"present": true, "insurerLetter": "A", "policyNumber": "AUTO7891011", "anyAuto": false,
        "scheduledAutos": true, "hiredAutosOnly": true, "nonOwnedAutosOnly": true, "limits": {"combinedSingleLimit": 1000000}},
      "umbrellaLiability": {"present": false},
      "workersCompensation": {"present": true, "insurerLetter": "C", "policyNumber": "WC12131415", "perStatute": false,
        "limits": {"elEachAccident": 1000000, "elDiseaseEachEmployee": 1000000, "elDiseasePolicyLimit": 1000000}},
      "otherCoverages": []
    },
    "descriptionOfOperations": "...", "additionalRemarks": [],
    "certificateHolder": {"name": "CITY OF TEMECULA", "address": "..."}
  },
  "fieldConfidence": {"coverages.generalLiability.limits.eachOccurrence": 0.95, "...": 0.95},
  "lowConfidenceFields": [],
  "overallConfidence": 0.95,
  "charged": true
}
```

- **Verdicts.** `PASS` means every requirement was met. `FAIL` means at least one requirement was clearly not met. `REVIEW` means a human should look: a field used in a decision is unreadable or low-confidence, an endorsement appears only in the description, or the policy is not yet effective.
- **Confidence.** Fillable PDF widgets score 0.99 and the text layer 0.95. Scanned (OCR) fields are lower and scale with how well the page aligned to the ACORD template.
- **`SUMMARY.csv`** sits in the run's default key-value store, with its link in `OUTPUT.summaryCsvUrl`. It has one row per certificate or error, including the verdict, reason codes, main policy numbers, limits and expiration dates.
- **`OUTPUT`** holds the run totals: files, certificates, pass / fail / review and charged.

#### Error codes (never charged)

`INVALID_INPUT`, `INVALID_URL`, `BLOCKED_URL`, `DNS_ERROR`, `DOWNLOAD_FAILED`, `DOWNLOAD_TIMEOUT`, `ACCESS_DENIED`, `NOT_FOUND`, `HTTP_ERROR`, `FILE_TOO_LARGE`, `EMPTY_FILE`, `UNSUPPORTED_FORMAT`, `CORRUPT_FILE`, `ENCRYPTED_PDF`, `SCANNED_NOT_SUPPORTED`, `OCR_FAILED`, `NOT_ACORD25`, `NO_DATA_FOUND`, `PARSE_FAILED`, `BUDGET_EXCEEDED`. Each comes with a `retryable` flag.

### Accuracy

These results are field-level, measured on a test set with hand-checked ground truth. The parser was frozen before the held-out set was scored, and the held-out set was scored once.

| Set | Certificates | Fields | Accuracy |
|---|---|---|---|
| Development | 47 | 2,540 | **99.2 %** |
| Held-out (never used for tuning) | 46 | 2,562 | **98.6 %** |
| Held-out: real public sample COIs | 6 | 227 | 97.8 % |
| Held-out: fillable / flattened / shifted PDFs | | | 100 % / 99.5 % / 99.7 % |
| Held-out: scanned (OCR) PDFs | | | 95.1 % |

The sets mix real sample certificates published by universities and public agencies with synthetic ACORD 25 PDFs (2010 and 2016 layouts) generated with known values. The synthetic PDFs come in fillable, flattened, page-shifted and 300-dpi scanned variants with noise and skew.

### Pricing

Pricing is pay per event: **$0.08** per `cert-checked` event, one per certificate that was parsed successfully. A PDF with 3 certificate pages counts as 3 events. ACORD 101 remark pages, failed files, blank forms, scans with OCR turned off and the sample certificate are free. The run stops charging when it reaches your **maximum total charge**, and the remaining certificates are reported as `BUDGET_EXCEEDED` without being charged.

### FAQ

**Does it use AI?** No. It aligns each page to the ACORD 25 template geometry and reads every box with deterministic rules. OCR uses the open-source Tesseract engine and runs inside the Actor, so no document leaves Apify.

**Which forms are supported?** ACORD 25 Certificate of Liability Insurance in the 2010/05, 2014/01 and 2016/03 editions, as fillable, flattened (printed to PDF) or scanned files. ACORD 101 Additional Remarks pages are attached to the preceding certificate as `additionalRemarks`. Other ACORD forms (24, 27, 28, etc.) are returned as `NOT_ACORD25` and are free.

**How is "additional insured" decided?** The ADDL INSD box on each required coverage line comes first. If the box is empty but the description says the holder is an additional insured, the verdict is REVIEW (`ADDL_INSD_ONLY_IN_DESCRIPTION`), because many contracts require the box.

**Can it check that the policy is real?** No. A COI is informational only. This Actor checks what the certificate says, not whether the insurer would honor it. Verify with the producer or carrier for high-risk work.

**Can I send images (JPG/PNG)?** Not yet. Convert them to PDF first.

**Is my data stored?** Results stay in your own Apify storage. The Actor runs with limited permissions and can only read the store you select.

### Limitations

- **Scanned certificates** are slower (about 5–15 s per page) and less accurate (about 95 % of fields). Long names can be truncated, and a few characters may be misread. Most scans should be expected to return REVIEW.
- **Very long insurer names** that run into the NAIC column on flattened PDFs may be cut off. For example, "…Company of Pittsburgh, PA" can come back as "…of Pittsburg".
- **Two "other coverage" rows** with the same insurer row height (e.g., Professional and Cyber) can be merged into one `otherCoverages` entry.
- **ADDL/SUBR marks** that sit far below their coverage line in a hand-edited form can be missed.
- Handwritten certificates, photos taken at an angle, rotated pages and non-English forms are not supported.
- The verdict is a screening aid, not legal or insurance advice.

### Other Actors by Haniel

- [Insurance Loss Run Extractor: Loss Run PDF to Excel & CSV](https://apify.com/hanielazevedo/insurance-loss-run-extractor): Extract claims and policy-year totals from carrier loss run PDFs into Excel, CSV and JSON, each row checked against the report totals. $0.04 per validated claim.
- [Spec Book to Submittal Register (CSI MasterFormat, Procore)](https://apify.com/hanielazevedo/spec-book-submittal-register): Turn a construction project manual (spec book PDF) into a submittal register and a Procore import CSV, by CSI MasterFormat section. $0.05 per spec page.
- [Rent Roll to Excel: Yardi, AppFolio & RealPage Normalizer](https://apify.com/hanielazevedo/rent-roll-normalizer): Normalize Yardi, AppFolio, RealPage, Entrata and Buildium rent rolls (XLSX, CSV, PDF) into one validated Excel with occupancy and loss-to-lease. $0.02 per unit.
- [PDF to Markdown Converter & PDF Text Extractor (OCR, DOCX)](https://apify.com/hanielazevedo/document-to-markdown-ocr): PDF, scanned PDF, DOCX, HTML and images to clean Markdown or text for RAG and AI agents. $3 per 1,000 documents.

# Actor input Schema

## `pdfUrls` (type: `array`):

Public http(s) links to ACORD 25 certificate of insurance PDFs. A PDF may hold several certificates (one per page) and ACORD 101 additional-remarks pages. To use files from your Apify account, put them in a key-value store and select it below: this Actor runs with limited permissions and cannot read a store you have not selected. The prefilled public sample certificate (Cornell University) is processed free of charge.

## `pdfStore` (type: `string`):

Your Apify key-value store holding certificate PDFs (Console > Storage > Key-value stores). Selecting it grants this run read-only access to that one store. Without record keys, every record whose key ends in ".pdf" is processed.

## `pdfKeys` (type: `array`):

Optional. Keys of the PDF records in the selected store, e.g. "acme-coi-2026.pdf". Leave empty to use every "\*.pdf" record.

## `requirements` (type: `object`):

Optional. What each certificate must meet. All keys optional; amounts in USD. Limits: glEachOccurrenceMin, glGeneralAggregateMin, glProductsCompletedOpsMin, autoCombinedSingleLimitMin, umbrellaEachOccurrenceMin, umbrellaAggregateMin, wcElEachAccidentMin, wcElDiseaseEachEmployeeMin, wcElDiseasePolicyLimitMin. Flags: additionalInsuredRequired, waiverOfSubrogationRequired, primaryNonContributoryRequired, requireWorkersCompensation, requireAutoLiability, requireGeneralLiability, requireUmbrella, allowUmbrellaToMeetLimits (default true). Lists: additionalInsuredOn (default \["generalLiability"]), waiverOfSubrogationOn (default \["generalLiability","workersCompensation"]). Names/dates: certificateHolderName, insuredName, minDaysUntilExpiry, asOfDate (YYYY-MM-DD, default today UTC). Without requirements, certificates are only checked for expired policies and unreadable fields.

## `enableOcr` (type: `boolean`):

Read image-only (scanned/photographed) certificates with the open-source Tesseract OCR engine. OCR results get lower confidence and usually a REVIEW verdict. When off, scans return SCANNED_NOT_SUPPORTED and are not charged.

## `minFieldConfidence` (type: `string`):

Fields read below this confidence are listed in lowConfidenceFields. If a field used for a decision is below it, the verdict becomes REVIEW instead of PASS/FAIL.

## `maxCertificates` (type: `integer`):

Safety cap: processing stops after this many certificates.

## `maxFileSizeMb` (type: `integer`):

Larger files are rejected (not charged).

## Actor input object example

```json
{
  "pdfUrls": [
    "https://scl.cornell.edu/sites/scl/files/documents/OSFL-COI-Correct%20Sample%20Updated.pdf"
  ],
  "requirements": {
    "glEachOccurrenceMin": 1000000,
    "glGeneralAggregateMin": 2000000,
    "autoCombinedSingleLimitMin": 1000000,
    "additionalInsuredRequired": true,
    "primaryNonContributoryRequired": true,
    "certificateHolderName": "Cornell University",
    "minDaysUntilExpiry": 30,
    "asOfDate": "2021-01-15"
  },
  "enableOcr": true,
  "minFieldConfidence": "0.8",
  "maxCertificates": 200,
  "maxFileSizeMb": 20
}
```

# Actor output Schema

## `results` (type: `string`):

No description

## `summaryCsv` (type: `string`):

No description

## `summary` (type: `string`):

No description

# API

You can run this Actor programmatically using our API. Below are code examples in JavaScript, Python, and CLI, as well as the OpenAPI specification and MCP server setup.

## JavaScript example

```javascript
import { ApifyClient } from 'apify-client';

// Initialize the ApifyClient with your Apify API token
// Replace the '<YOUR_API_TOKEN>' with your token
const client = new ApifyClient({
    token: '<YOUR_API_TOKEN>',
});

// Prepare Actor input
const input = {
    "pdfUrls": [
        "https://scl.cornell.edu/sites/scl/files/documents/OSFL-COI-Correct%20Sample%20Updated.pdf"
    ],
    "requirements": {
        "glEachOccurrenceMin": 1000000,
        "glGeneralAggregateMin": 2000000,
        "autoCombinedSingleLimitMin": 1000000,
        "additionalInsuredRequired": true,
        "primaryNonContributoryRequired": true,
        "certificateHolderName": "Cornell University",
        "minDaysUntilExpiry": 30,
        "asOfDate": "2021-01-15"
    }
};

// Run the Actor and wait for it to finish
const run = await client.actor("hanielazevedo/acord-25-coi-checker").call(input);

// Fetch and print Actor results from the run's dataset (if any)
console.log('Results from dataset');
console.log(`💾 Check your data here: https://console.apify.com/storage/datasets/${run.defaultDatasetId}`);
const { items } = await client.dataset(run.defaultDatasetId).listItems();
items.forEach((item) => {
    console.dir(item);
});

// 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/js/docs

```

## Python example

```python
from apify_client import ApifyClient

# Initialize the ApifyClient with your Apify API token
# Replace '<YOUR_API_TOKEN>' with your token.
client = ApifyClient("<YOUR_API_TOKEN>")

# Prepare the Actor input
run_input = {
    "pdfUrls": ["https://scl.cornell.edu/sites/scl/files/documents/OSFL-COI-Correct%20Sample%20Updated.pdf"],
    "requirements": {
        "glEachOccurrenceMin": 1000000,
        "glGeneralAggregateMin": 2000000,
        "autoCombinedSingleLimitMin": 1000000,
        "additionalInsuredRequired": True,
        "primaryNonContributoryRequired": True,
        "certificateHolderName": "Cornell University",
        "minDaysUntilExpiry": 30,
        "asOfDate": "2021-01-15",
    },
}

# Run the Actor and wait for it to finish
run = client.actor("hanielazevedo/acord-25-coi-checker").call(run_input=run_input)

# Fetch and print Actor results from the run's dataset (if there are any)
print(f"💾 Check your data here: https://console.apify.com/storage/datasets/{run.default_dataset_id}")
for item in client.dataset(run.default_dataset_id).iterate_items():
    print(item)

# 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/python/docs/quick-start

```

## CLI example

```bash
echo '{
  "pdfUrls": [
    "https://scl.cornell.edu/sites/scl/files/documents/OSFL-COI-Correct%20Sample%20Updated.pdf"
  ],
  "requirements": {
    "glEachOccurrenceMin": 1000000,
    "glGeneralAggregateMin": 2000000,
    "autoCombinedSingleLimitMin": 1000000,
    "additionalInsuredRequired": true,
    "primaryNonContributoryRequired": true,
    "certificateHolderName": "Cornell University",
    "minDaysUntilExpiry": 30,
    "asOfDate": "2021-01-15"
  }
}' |
apify call hanielazevedo/acord-25-coi-checker --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,hanielazevedo/acord-25-coi-checker"
        }
    }
}
```

The hosted server signs you in with OAuth on first connect, so no API token belongs in this config. Clients without OAuth support can send an `Authorization: Bearer <APIFY_API_TOKEN>` header instead, using a token from API & Integrations in Apify Console (https://console.apify.com/settings/integrations).

## OpenAPI specification

Download the OpenAPI definition: https://api.apify.com/v2/actors/EDem9pZ00jB2zsp2S/builds/GDzALoBpfu69tnf5x/openapi.json
