Configuration-Driven
The Policy API works with the Configuration API. The same field definitions you configure — policy fields, exposure fields, option sets — are the fields you write when creating policies through transactions.- Configure your insurance program — define fields, option sets, exposure types
- Create policies via
POST /transaction/new-business - Manage the lifecycle — endorse, cancel, reinstate, renew
- Query state — get a policy at any point in time, see full audit trail
Core Concepts
Transactions
Policies are modified through immutable transactions. Each transaction records what changed and produces a new policy version. A transaction sends its invoices too: an optionalinvoicePlan that voids and
creates the policy’s invoices with the change, committing with it, or none. A
saved quote’s bind instead names the quote’s own invoices; see
Invoicing a policy.
Calculated-field validation
Configured Policy and embedded-exposure calculations are validated as part of the transaction. If a calculation cannot compile or evaluate, or returns an invalid value, the API rejects the entire write with HTTP400 /
InvalidFieldModelV1Data, identifying the entity, field path, and cause. No
partial Policy version or embedded-exposure changes from that write are committed.
Valid null or missing results remain allowed unless another validation rule
requires a value. Existing calculation timing and preview rules are unchanged,
including calculations that need an entity ID before one is available on a new
policy. See calculated-field validation
for the shared behavior and error handling.
Segments
A segment is a date range where policy state is identical. Segments are derived from final state — they are not one-to-one with transactions. Adjacent segments with identical data are automatically merged. For example, three transactions can produce a single segment if the net effect returns the policy to a uniform state across the term.Versions
Each transaction produces a new version with a complete set of segments representing the full policy timeline. You can query any historical version. For a deeper explanation of these concepts, see Concepts. For how transactions place changes in time —effectiveDate vs transactionTimestamp, backdating, and booking ahead — see Effective Dates & the Policy Timeline. For a full worked example tracing 9 transactions through a realistic policy lifecycle, see the Lifecycle Walkthrough.
API Endpoints
Transactions (write)
Queries (read)
Contacts
Contacts are an unversioned link between a policy and a person in the
company’s Directory. They are not part of any transaction: linking or
unlinking creates no policy version and never changes coverage or pricing, and
a
contacts value inside transaction data is ignored. The current person IDs
are also hydrated into every segment’s data.contacts on the read and list
endpoints, for callers holding person.view, whichever version or effective
date is requested.
Reporting
Validation
Configuration
Sandbox reset
deleteAll is a destructive Sandbox reset operation guarded by
company.reset; it is safe to retry and returns the total rows removed.
Permissions
Example: Create a Policy
Request
POST /v1/policies/transaction/new-business
policyStartDate / policyEndDate root fields.
Response
201 Created
Key Points
- Term bounds come solely from the policy’s own
policyStartDate/policyEndDateroot fields — there are no top-level date parameters. They are ordinaryDatefields and take the canonical{ "date": "2025-01-01", "timezone": "America/New_York" }object;timezonemay be omitted and defaults toAmerica/New_York datacontains all policy-level fields at its top level — including any embedded exposure fields your configuration defines (e.g.primaryInsured/additionalExposuresin the default configuration). Their shape is whatever your tenant configuration says; they are validated per-field like any other field. From those embedded values the framework-requiredreferencingExposurescalculated field derives the flat list of Exposure ids the policy references — see Framework-Required Rows. Before 2026-08-05 these same fields sat one level deeper, infieldModelV1Data.policypolicyStatus("active"/"cancelled") is a segment-scoped policy field, so it varies across the term — read it per segment- The whole-term policy facts live at the response root.
policyNumber,policyStartDateandpolicyEndDateare on the response root and on every segment’spolicy, and nowhere else - The primary insured is derived, not sent. It comes from the policy’s own exposures; read it back from the response’s root
primaryInsuredName/primaryInsuredIdfields fullTermPricingInfois optional (a policy may carry no pricing info). SendpricingComponents— each{label, value, classification[, qualifier, earningSchedule]}, whereclassificationmust name a live entry in your company’s classification registry — and the platform computes the four read-only rollups (premium,taxes,fees,total) from them; caller-supplied rollup values are ignored and recomputed. The retiredgroup/kind/earningBasisfields are ignored and discarded on input. See Pricing Component IdentityfullTermBillingInfois optional — the term’s billing obligations per line item,{ lines: [{ invoiceType, lineItem, direction, amount }] }, free of invoices, and stored as stated. An already-billed term must restate it on endorsement, cancellation and reinstatement. See The Billing Aggregate.fullTermPolicyRatingResultis optionaltransactionTimestampis optional — defaults to the current time if omitted. When set explicitly on a later transaction it must be>=the latest already on the policy (the audit axis only moves forward); effective dates may still backdate freely. See Effective Dates & the Policy Timeline- A transaction’s
effectiveDatemust fall within the term (policyStartDate <= effectiveDate <= policyEndDate) — outside the term it is rejected with400. For howeffectiveDaterelates totransactionTimestampand to each delta’sstartDate, see Effective Dates & the Policy Timeline
Policy validation and repair
Validate Policies runs stored-data checks includingversionRegressions, which
compares each selected version with its predecessor at matching segment dates.
Findings identify paths and counts without exposing values. Versions without a
comparable predecessor are reported as skipped.
It also runs the bind’s receivable check over each stored version as
billingReceivableChecksum: the receivable lines of fullTermBillingInfo add up
to fullTermPricingInfo.total. billingContinuity always reports pass, because a
stored version does not record the layer change its write named; each write checks
its own move against the
pricing stack. With policy invoicing
disabled, both always pass. A checks list that names neither leaves them out
rather than reporting them skipped.
Staff and platform service identities can use
POST /api/v1/companies/{companyId}/policies/repair for segmentHashes,
joinHistory, or fieldValues. API keys cannot repair Policies. Hash and
relationship scans default to dry run and return a cursor for bounded continuation.
Field-value repairs require a reviewed manifest and matching pre/post fingerprints;
stale data returns 409 without writing. At companies with policy invoicing
enabled, a field-value repair cannot change fullTermBillingInfo or any pricing
value other than a component label: the dry run and the apply both return 422,
and nothing is written.