Skip to main content
The FMV1 Policy API manages policies through immutable transactions. Each transaction (new business, endorsement, cancellation, reinstatement, renewal) produces a new policy version with a complete set of time-based segments.

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.
  1. Configure your insurance program — define fields, option sets, exposure types
  2. Create policies via POST /transaction/new-business
  3. Manage the lifecycle — endorse, cancel, reinstate, renew
  4. 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. Every transaction may also carry an optional invoicePlan: a fully explicit keep/void/create plan for the policy’s invoice set. Omit it to create no invoices. If a pricing change restates a policy that already has active invoices, the plan is required and must conserve every pricing component against the new contract; the policy version and invoice batch commit atomically.

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)

Reporting

Validation

Configuration

Permissions

Example: Create a Policy

Request

POST /v1/policies/transaction/new-business
There are no top-level date parameters — the policy term comes solely from the policy’s own policyStartDate / policyEndDate root fields.

Response

201 Created

Key Points

  • Term bounds come solely from the policy’s own policyStartDate / policyEndDate root fields — there are no top-level date parameters. They are ordinary Date fields, so either generic shape works: { "date": "2025-01-01", "timezone": "America/New_York" } or { "year": 2025, "month": 1, "day": 1, "timezone": "America/New_York" }
  • data contains all policy-level fields at its top level — including any embedded exposure fields your configuration defines (e.g. primaryInsured / additionalExposures in 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-required referencedExposures calculated 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, in fieldModelV1Data.policy
  • policyStatus ("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, policyStartDate and policyEndDate are on the response root and on every segment’s policy, 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 / primaryInsuredId fields
  • fullTermPricingInfo is optional (a policy may carry no pricing info). Send pricingComponents — each {label, group, kind, value[, earningBasis]} — and the platform computes the five read-only rollups (premium, taxes, fees, brokerCommission, programCommission) from them; caller-supplied rollup values are ignored and recomputed. fullTermPolicyRatingResult is optional
  • transactionTimestamp is 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 effectiveDate must fall within the term (policyStartDate <= effectiveDate <= policyEndDate) — outside the term it is rejected with 400. For how effectiveDate relates to transactionTimestamp and to each delta’s startDate, see Effective Dates & the Policy Timeline