Search docs...

Search docs...

Search docs...

Working with review results

Working with review results

Working with review results

Working with review results

Once a certificate is processed, you can retrieve detailed results to understand what passed, what failed, and why. This guide covers how to fetch results and handle each status type in your application.

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

bash
curl https://api.1099policy.com/api/v1/files/certificates/cert_aBcDeFgHiJ \
  -u YOUR_SECRET_KEY:
json
{
  "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

bash
curl "https://api.1099policy.com/api/v1/files/certificates/cert_aBcDeFgHiJ?expand[]=review_results" \
  -u YOUR_SECRET_KEY:
json
{
  "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

bash
curl "https://api.1099policy.com/api/v1/files/certificates/cert_aBcDeFgHiJ?expand[]=review_results.full" \
  -u YOUR_SECRET_KEY:
json
{
  "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
  }
}
Expand notation

The expand parameter also accepts bracket notation: ?expand[]=review_results[full]

When to use each expansion level

Use caseExpansionWhy
Dashboard status indicatorNoneJust need pass/fail status
Summary counts for reportingreview_resultsShows total/passed/failed without payload overhead
Displaying failure reasons to usersreview_results.fullNeed audit_results with messages
Debugging parsing issuesreview_results.fullNeed 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:

FieldContains
insuredThe contractor/company named as insured
certificate_holderYour organization's info as listed on the certificate
coveragesCoverage details organized by type
description_of_operationsFree-text description field, including additional insured names and signature presence

Coverage structure example

json
{
  "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:

FieldTypeDescription
idstringUnique identifier (prefixed with car_)
rule_pathstring or nullThe data path that was checked (e.g., coverages.commercial_general_liability.limits.each_occurrence_dollars)
rule_namestring or nullHuman-readable rule name, when available
resultstring or nullpass or fail
messagestring or nullExplanation of the result
manually_approvedbooleanWhether a compliance reviewer manually approved a failed rule
createdintegerUnix timestamp of when the evaluation occurred
Null rule_name

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

python
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:

python
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

StatusRecommended action
approvedProceed with contractor onboarding or activation
flaggedPresent failed rules to compliance team for manual review. They can approve individual rules or request a new certificate.
deniedNotify contractor. They'll need to obtain different coverage and upload a new certificate.
errorTypically 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:

python
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:

ScenarioExplanation
Status is pending or processingProcessing hasn't completed yet
Status is errorProcessing failed before results could be generated
Expansion parameter not includedAdd ?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.

Was this page helpful?

Yes

No

Was this page helpful?

Yes

No

Was this page helpful?

Yes

No

Was this page helpful?

Yes

No

Was this page helpful?

Yes

No

Was this page helpful?

Yes

No

Uploading certificates

Using webhooks

© Copyright 2024. All rights reserved.

© Copyright 2024. All rights reserved.

© Copyright 2024. All rights reserved.

© Copyright 2024. All rights reserved.

© Copyright 2024. All rights reserved.

© Copyright 2024. All rights reserved.