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:
- File extension must be
.pdf - MIME type must be
application/pdf - File must begin with valid PDF magic bytes (
%PDF)
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.
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:
- Which insurance requirement is used (based on the contractor's entity, if applicable)
- Where the certificate appears in your Dashboard
- How insured name validation works (contractor's name or company must match)
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
- Immediate response — You receive the certificate object with
status: "pending" - Processing begins — AI parses the PDF and extracts coverage data (typically 1-2 minutes)
- Evaluation runs — Extracted data is checked against the applicable insurance requirement
- Webhook sent — You receive
certificate.approved,certificate.flagged, orcertificate.denied - Results available — Fetch detailed results using the
expandparameter
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:
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.
