Uploading certificates | 1099Policy

Uploading certificates

This guide covers how to upload Certificates of Insurance via the API, including file requirements, contractor association, and handling multiple uploads.

Basic upload

Submit a COI PDF associated with a contractor:

curl https://api.1099policy.com/api/v1/files/certificates \
  -u YOUR_SECRET_KEY: \
  -F "contractor=cn_abc123" \
  -F "certificate=@/path/to/certificate.pdf"

Response:

{
  "id": "ci_YnsHeB9PTo",
  "contractor": "cn_abc123",
  "status": "pending",
  "created": 1760509809,
  "filename": "certificate.pdf",
  "review_results": null
}

The certificate is queued for processing. You'll receive a webhook when evaluation completes.

File requirements

Requirement Details
Format PDF only
Maximum size 15 MB
Pages analyzed First 2 pages only

Format validation

The system validates PDF files at three levels:

Other formats (images, Word documents, scanned TIFFs) are rejected.

Page limit

Only the first 2 pages of each PDF are sent to the AI for analysis. Ensure all critical coverage information—limits, expiration dates, certificate holder, additional insureds—appears on these pages.

Multi-page certificates

Most standard ACORD forms include all relevant information on the first page. Multi-page certificates with coverage details on page 3+ may result in missing data and failed rules. If you need to relax this requirement for your tenant, contact your account rep at support@1099policy.com.

Contractor association

Every certificate must be associated with a contractor. The contractor record must exist before uploading:

# Create contractor first
curl https://api.1099policy.com/api/v1/contractors \
  -u YOUR_SECRET_KEY: \
  -d email="jane@example.com" \
  -d first_name="Jane" \
  -d last_name="Smith"

# Then upload their certificate
curl https://api.1099policy.com/api/v1/files/certificates \
  -u YOUR_SECRET_KEY: \
  -F "contractor=cn_abc123" \
  -F "certificate=@/path/to/certificate.pdf"

The contractor association determines:

Multiple certificates per contractor

Contractors can have multiple certificates. Each upload creates an independent record with its own evaluation results.

Common scenarios:

Scenario Behavior
Contractor uploads updated certificate Both old and new certificates exist independently. Determine which to use based on created timestamp or status.
Certificate uploaded while another is processing Both process independently. No locking or deduplication.
Different coverage types on separate certificates Each certificate is evaluated against the full requirement. Consider whether your requirement expects all coverages on one certificate.

Finding the latest approved certificate

import requests

response = requests.get(
    'https://api.1099policy.com/api/v1/files/certificates',
    auth=('YOUR_SECRET_KEY', ''),
    params={'contractor': 'cn_abc123'}
)
certificates = response.json()['data']

# Filter to approved certificates
approved = [c for c in certificates if c['status'] == 'approved']

# Get most recent
if approved:
    latest = max(approved, key=lambda x: x['created'])

Re-uploading after errors

If a certificate ends up in error status, you can upload a new one. Common reasons to re-upload:

Issue Solution
Corrupted or blank PDF Obtain a valid PDF from the contractor
Poor scan quality Request a clearer scan or digital copy
Critical info on page 3+ Ask contractor for a certificate with coverage details on pages 1-2
Unsupported date format Request certificate with dates in MM/DD/YYYY, MM/DD/YY, or YYYY-MM-DD format

There's no "retry" endpoint—simply upload the corrected PDF as a new certificate:

curl https://api.1099policy.com/api/v1/files/certificates \
  -u YOUR_SECRET_KEY: \
  -F "contractor=cn_abc123" \
  -F "certificate=@/path/to/corrected-certificate.pdf"

The original errored certificate remains in your records for reference.

What happens after upload

  1. Immediate response — You receive the certificate object with status: "pending"
  2. Processing begins — AI parses the PDF and extracts coverage data (typically 1-2 minutes)
  3. Evaluation runs — Extracted data is checked against the applicable insurance requirement
  4. Webhook sent — You receive certificate.approved, certificate.flagged, or certificate.denied
  5. Results available — Fetch detailed results using the expand parameter

See Working with Review Results for how to interpret the evaluation output.

Deleting certificates

To remove a certificate:

curl -X DELETE https://api.1099policy.com/api/v1/files/certificates/ci_YnsHeB9PTo \
  -u YOUR_SECRET_KEY:

Soft deletes

Deletes are soft deletes. The certificate is hidden from normal queries but retained for audit purposes.

Next: Learn how to work with review results to understand evaluation outcomes.