Fetching results
Results are available once processing completes (status is no longer pending or processing). Use the expand parameter to control the level of detail returned.
Without expansion – Basic status only
curl https://api.1099policy.com/api/v1/files/certificates/cert_aBcDeFgHiJ \
-u YOUR_SECRET_KEY:
{
"id": "cert_aBcDeFgHiJ",
"contractor": "cn_abc123",
"status": "flagged",
"created": 1706745600,
"updated": 1706745620,
"filename": "acme-corp-coi-2024.pdf",
"pdf_url": "https://...",
"review_results": null
}
Abbreviated results – Summary counts
curl "https://api.1099policy.com/api/v1/files/certificates/cert_aBcDeFgHiJ?expand[]=review_results" \
-u YOUR_SECRET_KEY:
{
"id": "cert_aBcDeFgHiJ",
"contractor": "cn_abc123",
"status": "flagged",
"created": 1706745600,
"updated": 1706745620,
"filename": "acme-corp-coi-2024.pdf",
"pdf_url": "https://...",
"review_results": {
"id": "ca_xYzAbCdEfG",
"status": "flagged",
"summary": {
"total_rules": 5,
"passed": 4,
"failed": 1
},
"created": 1706745610
}
}
Full results – Complete parsed data and audit details
curl "https://api.1099policy.com/api/v1/files/certificates/cert_aBcDeFgHiJ?expand[]=review_results.full" \
-u YOUR_SECRET_KEY:
{
"id": "cert_aBcDeFgHiJ",
"contractor": "cn_abc123",
"status": "flagged",
"created": 1706745600,
"updated": 1706745620,
"filename": "acme-corp-coi-2024.pdf",
"pdf_url": "https://...",
"review_results": {
"id": "ca_xYzAbCdEfG",
"status": "flagged",
"parsed_certificate_json": {
"coverages": {
"commercial_general_liability": {
"policy_expiration_date": "03/15/2025",
"policy_number_string": "CGL-2024-001",
"limits": {
"general_aggregate_dollars": 2000000,
"each_occurrence_dollars": 1000000,
"products_completed_operations_dollars": 1000000
}
},
"workers_compensation": {
"policy_expiration_date": "06/30/2024",
"policy_number_string": "WC-789456"
}
},
"insured": {
"name": "Acme Corporation LLC"
},
"description_of_operations": {
"signature": true,
"additional_insured_names": ["Client Corp Inc."]
}
},
"audit_results": [
{
"id": "car_aB1cD2eF3g",
"rule_path": "coverages.commercial_general_liability.limits.general_aggregate_dollars",
"rule_name": null,
"result": "pass",
"message": "Coverage for commercial general liability is sufficient. The limit for general aggregate is $2,000,000, which meets the required $1,000,000.",
"manually_approved": false,
"created": 1706745611
},
{
"id": "car_oP7qR8sT9u",
"rule_path": "coverages.workers_compensation.policy_expiration_date",
"rule_name": null,
"result": "fail",
"message": "Coverage for workers compensation has expired 'policy expiration date'. Policy expired on 06/30/2024.",
"manually_approved": false,
"created": 1706745611
},
{
"id": "car_vW0xY1zA2b",
"rule_path": "description_of_operations.additional_insured_names",
"rule_name": "Additional Insured Check",
"result": "pass",
"message": "Rule for additional insureds was checked",
"manually_approved": false,
"created": 1706745612
}
],
"created": 1706745610,
"updated": 1706745615
}
}
The expand parameter also accepts bracket notation: ?expand[]=review_results[full]
When to use each expansion level
| Use case | Expansion | Why |
|---|---|---|
| Dashboard status indicator | None | Just need pass/fail status |
| Summary counts for reporting | review_results | Shows total/passed/failed without payload overhead |
| Displaying failure reasons to users | review_results.full | Need audit_results with messages |
| Debugging parsing issues | review_results.full | Need parsed_certificate_json to see extracted data |
Understanding parsed_certificate_json
The parsed_certificate_json object contains everything the AI extracted from the PDF. Use this to:
- Debug why a rule failed (was the data extracted correctly?)
- Display certificate details in your UI
- Verify the AI parsed the document as expected
Key sections:
| Field | Contains |
|---|---|
insured | The contractor/company named as insured |
certificate_holder | Your organization's info as listed on the certificate |
coverages | Coverage details organized by type |
description_of_operations | Free-text description field, including additional insured names and signature presence |
Coverage structure example
{
"coverages": {
"commercial_general_liability": {
"limits": {
"each_occurrence_dollars": 1000000,
"general_aggregate_dollars": 2000000,
"products_completed_operations_dollars": 1000000
},
"policy_number_string": "CGL-2024-001",
"policy_expiration_date": "03/15/2025"
}
}
}
Understanding audit_results
The audit_results array contains one entry for each rule evaluated:
| Field | Type | Description |
|---|---|---|
id | string | Unique identifier (prefixed with car_) |
rule_path | string or null | The data path that was checked (e.g., coverages.commercial_general_liability.limits.each_occurrence_dollars) |
rule_name | string or null | Human-readable rule name, when available |
result | string or null | pass or fail |
message | string or null | Explanation of the result |
manually_approved | boolean | Whether a compliance reviewer manually approved a failed rule |
created | integer | Unix timestamp of when the evaluation occurred |
rule_name may be null for standard coverage limit rules. Use rule_path to identify which rule was evaluated, or display the message which always describes the result.
Example: Identifying failed rules
response = requests.get(
f'https://api.1099policy.com/api/v1/files/certificates/{cert_id}?expand[]=review_results.full',
auth=('YOUR_SECRET_KEY', '')
)
cert = response.json()
if cert['review_results']:
failed_rules = [
r for r in cert['review_results']['audit_results']
if r['result'] == 'fail' and not r['manually_approved']
]
for rule in failed_rules:
# Use message for display since rule_name may be null
print(f"Failed: {rule['message']}")
Handling each status
Build your integration to handle all possible statuses:
def handle_certificate_result(certificate):
status = certificate['status']
if status == 'approved':
# All requirements met - contractor is cleared
approve_contractor(certificate['contractor'])
elif status == 'flagged':
# Some rules failed - needs review
# Fetch full results to show what failed
results = fetch_full_results(certificate['id'])
queue_for_compliance_review(certificate, results)
elif status == 'denied':
# Manually denied by compliance reviewer
notify_contractor_denied(certificate['contractor'])
elif status == 'error':
# Processing failed - see Edge Cases guide
handle_processing_error(certificate)
elif status in ['pending', 'processing']:
# Still processing - wait for webhook
pass
Status-specific guidance
| Status | Recommended action |
|---|---|
approved | Proceed with contractor onboarding or activation |
flagged | Present failed rules to compliance team for manual review. They can approve individual rules or request a new certificate. |
denied | Notify contractor. They'll need to obtain different coverage and upload a new certificate. |
error | Typically a file issue. See Edge Cases & Troubleshooting for common causes and solutions. |
Manually approved rules
When a compliance reviewer manually approves a failed rule, the manually_approved field is set to true. The rule still shows result: "fail" but is treated as passing for overall status calculation.
In your UI, you may want to distinguish these:
for rule in audit_results:
if rule['result'] == 'pass':
display_as_passed(rule)
elif rule['manually_approved']:
display_as_manually_approved(rule) # Show with different styling
else:
display_as_failed(rule)
Voided audit results
In rare cases, audit results may be voided (e.g., if evaluated against an incorrect requirement). Voided results are excluded from the API response entirely—they don't appear in audit_results and aren't counted in the summary totals. There's no need to handle them in your integration.
Missing review results
If review_results is null:
| Scenario | Explanation |
|---|---|
Status is pending or processing | Processing hasn't completed yet |
Status is error | Processing failed before results could be generated |
| Expansion parameter not included | Add ?expand[]=review_results to your request |
Always check status before attempting to access review_results.
Next: Set up webhooks to receive real-time notifications when processing completes.
