Insurance coverage
Define the policies you require, open a monitor for a payee, import a certificate of insurance, link a coverage, and read compliance results.
Insurance monitoring checks that a Payee carries the policies you require. You describe the required policies in a monitor configuration. A monitor tracks one Payee against that configuration. The Payee uploads a certificate of insurance (COI), Wingspan extracts and verifies the policies into coverages, and the monitor validates them.
Read Compliance and verification first for the payer and payee rules shared by order-style resources.
Resources
| Resource | What it is |
|---|---|
InsuranceMonitorConfiguration | The policies you require, with limit floors. Reusable. |
InsuranceMonitor | One payee's compliance with one configuration. |
InsuranceImport | One uploaded COI going through extraction and verification. |
InsuranceCoverage | A verified policy the payee carries. |
Endpoints
Scopes: compliance.monitor:read and :write for configurations and monitors, compliance.insurance:read and :write for coverages and imports.
1. Create a configuration
coverages is the substance. It has one entry per required policy, and policyType must be unique across entries. Each entry (AcceptedInsuranceCoverage) has:
| Field | Notes |
|---|---|
policyType | Required. One of GeneralLiability, OccupationalAccident, WorkersCompensation, ProfessionalLiability, ErrorsAndOmissions, CommercialAuto, DisabilityInsurance, CyberLiability, TechnologyErrorsAndOmissions, CommercialProperty, BusinessIncome, InlandMarine, UmbrellaLiability, ExcessLiability, ProfessionalIndemnity, PollutionLiability, CrimeInsurance, MedicalMalpractice, DirectorsAndOfficersLiability, EmploymentPracticesLiability, FiduciaryLiability, MediaLiability, PerformanceBond, PaymentBond, BidBond, MaintenanceBond, AutomobileLiability, BusinessOwnersPolicy, ContractorsPackagePolicy. |
limits | Minimum limits. Each has limitType, amount, and currency. A coverage is compliant when it meets or exceeds every one. |
appliedProvisions | Endorsements the policy must carry. |
acceptedSourceTypes | InsuranceImport (an uploaded certificate) and PlanEnrollment (a Wingspan master-policy enrollment). A configuration that omits PlanEnrollment won't accept one. |
coverageForm, policySpecificAttributes | Optional extra requirements. |
limitType values include EachOccurrence, PerOccurrence, PerClaim, PerAccident, GeneralAggregate, ProductsCompletedOperationsAggregate, PolicyAggregate, CombinedSingleLimit, EmployersLiabilityEachAccident, and others; see the reference for the full list. The EL* spellings are legacy and still appear on older configurations.
curl -X POST https://api.wingspan.app/v3/compliance/insurance-monitor-configurations \
-H "Authorization: Bearer $WINGSPAN_TOKEN" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: $(uuidgen)" \
-d '{
"externalId": "ins-standard",
"coverages": [
{
"policyType": "GeneralLiability",
"limits": [
{ "limitType": "EachOccurrence", "amount": 1000000, "currency": "USD" },
{ "limitType": "GeneralAggregate", "amount": 2000000, "currency": "USD" }
],
"acceptedSourceTypes": ["InsuranceImport"]
}
]
}'The response's id is what an InsuranceCoverage requirement definition passes as dataSourceId. There is no list route for configurations, so keep the id. coverages can't be changed after create, and PATCH accepts only externalId and metadata. To change what you require, create a new configuration and point the requirement definition at it. metadata merges key by key, and a key containing . or $ returns 422.
2. Open a monitor
POST /v3/compliance/insurance-monitors:
| Field | Type | Notes |
|---|---|---|
payerPayeeId | string, required | The relationship. |
configurationId | string | Payer only. The configuration to validate against. |
requirementId | string | Required for a payee. |
externalId | string | Payer only. |
metadata | object | Payer only. |
A create that cites a requirementId returns the monitor that is still outstanding for that relationship and configuration. A payer's direct order, an externalId, and a payer reset open a new one.
A monitor has status (Pending, Monitoring, Complete, or ForceMatched), configurationId, coverageId once linked, minimumExpiresAt, and jobs. Each job is one validation result for one required policyType, with status (Pending, Complete, Failed, Warning) and a statusReason naming the limit, provision, or date that missed.
GET /v3/compliance/insurance-monitors/{monitorId} is readable by both parties. Add expand=Configuration or expand=Coverage to inline the related resource. Either is safe to send always. A monitor with no linked coverage comes back without the coverage key. Any other value returns 422. Expansions aren't available on list rows.
3. Import a certificate
The Payee uploads the COI as a vault file, then:
curl -X POST https://api.wingspan.app/v3/compliance/insurance-imports \
-H "Authorization: Bearer $WINGSPAN_TOKEN" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: $(uuidgen)" \
-d '{ "fileId": "VAULT_FILE_ID", "insuranceMonitorId": "MONITOR_ID" }'insuranceMonitorId is only a matching hint. Monitors evaluate on their own whether verified policies satisfy them. The import is owned by the account context of the request.
status is Created, Processing, ReadyForReview, Complete, or Failed. ReadyForReview means the certificate was parsed but needs review or more policy matching before it yields a verified coverage. Each import has attemptCount, maxAttempts, coverageIds, and jobs. A job has type (Extraction or Validation) and status. Extracted policy data is on jobs[].extractedFields, one entry per policy the certificate declares, since one ACORD 25 often carries several.
To fix a wrong file before submitting, PATCH the import with a new fileId. This re-runs extraction and uses another attempt. It works on a pending or rejected import. When the import has used maxAttempts, it returns 422 with detailCode compliance.InsuranceImportAttemptLimitExceeded.
POST .../submit sends a pending import for processing into a coverage and returns the import with its new status. externalId and metadata can only be set at create, because PATCH is the re-upload path.
4. Link a coverage to a monitor
The payee calls PATCH /v3/compliance/insurance-monitors/{monitorId} with { "coverageId": "COVERAGE_ID" } to say which of its policies satisfies the requirement. A payer gets 403. A caller who is neither party gets 404.
Read coverages
GET /v3/compliance/insurance-coverages lists coverages. Filters: policyType, sourceType, sourceId, policyNumber, status, effective and expiration date bounds, and accountIds. status (Active or Expired) is derived from expirationDate. Sort by createdAt (default, newest first), updatedAt, effectiveDate, or expirationDate.
A coverage has sourceType (InsuranceImport or PlanEnrollment), policyType, carrier, policyNumber, certificateHolder, namedInsured, effectiveDate, expirationDate, limits, appliedProvisions, isVerified, and warnings. A warning is a non-blocking import check that didn't pass.
Download the certificate
GET .../insurance-monitors/{monitorId}/certificate returns a 302 to a signed URL. For a browser page that can't follow a cross-site redirect from script, use .../certificate-url:
// 200 OK
{ "url": "https://files.example.com/signed-link", "expiresAt": "2026-11-02T18:05:00Z" }Don't store the link. Call again when you need it. Both routes are payer-only. They return 404 when the caller isn't the payer, the monitor has no linked coverage, the coverage came from a plan enrollment rather than an upload, or the import has no file. They return 503 when no link could be issued.
Errors
| Status | When |
|---|---|
400 | A payee created a monitor without requirementId. Checked first. |
403 | A payer links a coverage. |
404 | No seat on payerPayeeId. A configuration or monitor you can't see. |
409 | Duplicate externalId. Submit on an import in a state that can't be submitted. |
422 | A payee monitor body with configurationId, externalId, or metadata alongside requirementId. A repeated policyType in coverages. An unsupported expand value. An import at its attempt limit. |
Events
InsuranceMonitor.Created and Updated, InsuranceImport.Created, Processed, and Submitted, InsuranceCoverage.Created and Updated.
Updated 12 minutes ago