curl --request GET \
--url https://go.aiinsurance.io/api/v1/companies/{companyId}/policies/{policyId}/validate \
--header 'Authorization: <api-key>'import requests
url = "https://go.aiinsurance.io/api/v1/companies/{companyId}/policies/{policyId}/validate"
headers = {"Authorization": "<api-key>"}
response = requests.get(url, headers=headers)
print(response.text)const options = {method: 'GET', headers: {Authorization: '<api-key>'}};
fetch('https://go.aiinsurance.io/api/v1/companies/{companyId}/policies/{policyId}/validate', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://go.aiinsurance.io/api/v1/companies/{companyId}/policies/{policyId}/validate",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "GET",
CURLOPT_HTTPHEADER => [
"Authorization: <api-key>"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"net/http"
"io"
)
func main() {
url := "https://go.aiinsurance.io/api/v1/companies/{companyId}/policies/{policyId}/validate"
req, _ := http.NewRequest("GET", url, nil)
req.Header.Add("Authorization", "<api-key>")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.get("https://go.aiinsurance.io/api/v1/companies/{companyId}/policies/{policyId}/validate")
.header("Authorization", "<api-key>")
.asString();require 'uri'
require 'net/http'
url = URI("https://go.aiinsurance.io/api/v1/companies/{companyId}/policies/{policyId}/validate")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Get.new(url)
request["Authorization"] = '<api-key>'
response = http.request(request)
puts response.read_body{
"policyId": "550e8400-e29b-41d4-a716-446655440001",
"validatedAt": "2026-04-14T18:30:00.000Z",
"summary": {
"totalChecks": 12,
"passed": 11,
"failed": 0,
"skipped": 1
},
"results": [
{
"check": "versionRegressions",
"status": "skipped",
"scope": "version:1",
"message": "No predecessor segments to compare."
},
{
"check": "contiguity",
"status": "pass",
"scope": "version:1"
},
{
"check": "fullTermInvariance",
"status": "pass",
"scope": "version:1"
},
{
"check": "hashCorrectness",
"status": "pass",
"scope": "version:1"
},
{
"check": "noDuplicateSegments",
"status": "pass",
"scope": "version:1"
},
{
"check": "transactionSegmentExistence",
"status": "pass",
"scope": "version:1"
},
{
"check": "billingReceivableChecksum",
"status": "pass",
"scope": "version:1"
},
{
"check": "billingContinuity",
"status": "pass",
"scope": "version:1"
},
{
"check": "cancelEarnedPremium",
"status": "pass",
"scope": "policy"
},
{
"check": "cancelPerKeyFloors",
"status": "pass",
"scope": "policy"
},
{
"check": "cancelReinstatePremium",
"status": "pass",
"scope": "policy"
},
{
"check": "versionSequentiality",
"status": "pass",
"scope": "policy"
}
]
}Validate Policy
Checks one policy’s stored data for integrity problems: gaps or overlaps
between coverage segments, broken version history, cancellation and
reinstatement premium that does not match earned premium, and billing lines
that do not add up to the premium. It is read-only and changes no data. Use
Validate Policies (Batch) (validatePolicies) for many policies, and Check
Bind Conditions (checkBindConditions) to see whether a quote is ready to
bind.
Twelve checks are available, covering segment contiguity, hash
correctness, version sequentiality, full-term invariance, duplicate
detection, transaction-segment existence, version regressions,
cancel/reinstate premium consistency, and billing. By default all
checks run; use the checks parameter to select a subset.
Checks are either version-scoped (run once per policy version) or policy-scoped (run once for the whole policy). A policy with 3 versions and every check enabled produces 28 results (8 version-scoped checks x 3 versions + 4 policy-scoped checks), plus one more for each additional version-regression finding.
Use the version parameter to validate a single version instead of
all versions.
Available checks
| Check | Scope | What it validates |
|---|---|---|
contiguity | version | Segments form a contiguous date range with no gaps or overlaps |
fullTermInvariance | version | Billing and policy metadata fields are constant across all segments in a version |
hashCorrectness | version | Stored segment hash matches the computed hash of the segment data |
noDuplicateSegments | version | No adjacent segments have identical hashes |
transactionSegmentExistence | version | At least one segment exists for the version |
versionRegressions | version | Compares the predecessor at matching segment dates for vanished values, lost identities, shrinking arrays, and template replacements; reports paths and counts, never values. Leaves out the pricing, billing and rating containers (see Billing checks) |
billingReceivableChecksum | version | The receivable lines of the version’s fullTermBillingInfo add up to its fullTermPricingInfo.total (billing that states no lines passes) |
billingContinuity | version | Always reports pass: a stored version does not record the layer change its write named (see Billing checks) |
versionSequentiality | policy | All of the policy’s versions, not only those validated, are sequential starting from 1 with no gaps |
cancelEarnedPremium | policy | Cancel transaction premium matches earned premium through the cancellation date (see Cancellation checks) |
cancelPerKeyFloors | policy | Each pricing component of a CANCEL equals its own earned amount through the cancellation date (skipped for historical cancels whose components were relabelled; see Cancellation checks) |
cancelReinstatePremium | policy | Reinstate transaction premium matches the pre-cancel version premium (see Cancellation checks) |
Cancellation checks
A cancellation or reinstatement that states no fullTermPricingInfo passes
the three cancellation checks: a cancellation or reinstatement quote whose
pricing was cleared binds none, and so does one of a policy with no pricing.
A pre-cancel version with no pricing counts as a premium of 0 against a
reinstatement that states pricing. Earned premium is read from the policy’s
earning history up to the cancellation, so a later reinstatement that binds
no pricing does not change what the cancellation is judged against.
Billing checks
billingReceivableChecksum runs the receivable check a bind applies to
fullTermBillingInfo over each stored version.
A failure names the version and the gap between the price and the receivable lines.
billingContinuity always reports pass. A stored version does not record
the layer change its write named, so it cannot tell a deliberate move
between layers of the
pricing stack, such as dropping
billing, from an omission. Each write checks its own move as it is made:
a policy transaction or bind by value against the pricingStackLayerChange it names,
and a saved quote’s bind against the quote’s intended layer. The check keeps
its name, so a caller that lists it sees no change of shape.
A checks list that names neither leaves them out of the results
instead of reporting them skipped, so a list of the other checks
returns the same results as before.
versionRegressions does not compare fullTermPricingInfo,
fullTermBillingInfo, fullTermPolicyRatingResult or
crossSegmentRatingOutputs, wherever they sit, for the same reason as
billingContinuity: a cleared amendment or a move down the pricing stack
drops them on purpose. billingReceivableChecksum still checks the billing
a version states against its price.
Required permission: policy.validate
curl --request GET \
--url https://go.aiinsurance.io/api/v1/companies/{companyId}/policies/{policyId}/validate \
--header 'Authorization: <api-key>'import requests
url = "https://go.aiinsurance.io/api/v1/companies/{companyId}/policies/{policyId}/validate"
headers = {"Authorization": "<api-key>"}
response = requests.get(url, headers=headers)
print(response.text)const options = {method: 'GET', headers: {Authorization: '<api-key>'}};
fetch('https://go.aiinsurance.io/api/v1/companies/{companyId}/policies/{policyId}/validate', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://go.aiinsurance.io/api/v1/companies/{companyId}/policies/{policyId}/validate",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "GET",
CURLOPT_HTTPHEADER => [
"Authorization: <api-key>"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"net/http"
"io"
)
func main() {
url := "https://go.aiinsurance.io/api/v1/companies/{companyId}/policies/{policyId}/validate"
req, _ := http.NewRequest("GET", url, nil)
req.Header.Add("Authorization", "<api-key>")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.get("https://go.aiinsurance.io/api/v1/companies/{companyId}/policies/{policyId}/validate")
.header("Authorization", "<api-key>")
.asString();require 'uri'
require 'net/http'
url = URI("https://go.aiinsurance.io/api/v1/companies/{companyId}/policies/{policyId}/validate")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Get.new(url)
request["Authorization"] = '<api-key>'
response = http.request(request)
puts response.read_body{
"policyId": "550e8400-e29b-41d4-a716-446655440001",
"validatedAt": "2026-04-14T18:30:00.000Z",
"summary": {
"totalChecks": 12,
"passed": 11,
"failed": 0,
"skipped": 1
},
"results": [
{
"check": "versionRegressions",
"status": "skipped",
"scope": "version:1",
"message": "No predecessor segments to compare."
},
{
"check": "contiguity",
"status": "pass",
"scope": "version:1"
},
{
"check": "fullTermInvariance",
"status": "pass",
"scope": "version:1"
},
{
"check": "hashCorrectness",
"status": "pass",
"scope": "version:1"
},
{
"check": "noDuplicateSegments",
"status": "pass",
"scope": "version:1"
},
{
"check": "transactionSegmentExistence",
"status": "pass",
"scope": "version:1"
},
{
"check": "billingReceivableChecksum",
"status": "pass",
"scope": "version:1"
},
{
"check": "billingContinuity",
"status": "pass",
"scope": "version:1"
},
{
"check": "cancelEarnedPremium",
"status": "pass",
"scope": "policy"
},
{
"check": "cancelPerKeyFloors",
"status": "pass",
"scope": "policy"
},
{
"check": "cancelReinstatePremium",
"status": "pass",
"scope": "policy"
},
{
"check": "versionSequentiality",
"status": "pass",
"scope": "policy"
}
]
}Authorizations
Path Parameters
Query Parameters
Comma-separated list of check names to run (e.g.,
contiguity,hashCorrectness). If omitted, all checks run.
Unrecognized check names are silently ignored. If all provided
names are unrecognized, all checks run (same as omitting the
parameter). Check names are case-sensitive. Checks the list does
not name are reported skipped, except the two billing checks,
which are left out.
Response
Validation results for the policy
Validation results for a single policy, including a summary of pass/fail/skip counts and the individual check results.
