> ## Documentation Index
> Fetch the complete documentation index at: https://docs.aiinsurance.io/llms.txt
> Use this file to discover all available pages before exploring further.

# API Changelog

## V1 API Changelog

Track changes, additions, and deprecations to the V1 API.

***

### 2026-05-15

#### New: Company Files API (folders + files)

Added 10 endpoints for managing company-level folders and files:

**Folders:** `POST`, `GET`, `GET /{folderId}`, `PATCH /{folderId}`, `DELETE /{folderId}` under `/api/v1/external/companies/{companyId}/folders`

**Files:** `POST` (multipart upload), `GET /{fileId}`, `GET /{fileId}/content` (binary download), `PATCH /{fileId}`, `DELETE /{fileId}` under `/api/v1/external/companies/{companyId}/files`

Key capabilities:

* Create nested folder hierarchies with `parentFolderId`
* Upload files via `multipart/form-data`, optionally placing them in a folder
* Stream binary file content with correct `Content-Type` and `Content-Disposition` headers
* Rename and move files/folders (including moving to root by setting parent to `null`)
* Recursive soft-delete of folders (deletes all contents)

All endpoints use `company.file:{action}` permissions. See the [Company Files overview](/api-v1-reference/company-files/overview) for details.

<Note>
  These are company-level file endpoints only. Entity-scoped file endpoints (attached to exposures, policies, events) are planned for a future release.
</Note>

***

### 2026-05-07

#### New endpoint: Update Expected Totals for V1 events

Added `PATCH /api/v1/external/companies/{companyId}/events/{eventId}/financials/expected-totals`
for Field Model V1 events.

The legacy expected-totals endpoint at `/api/external/...` relies on an internal `type` column
that is always `null` for V1-created events, causing a `TypeMismatch` error. This new endpoint
resolves the event type from `fieldModelV1Data.eventType` instead.

The request body is identical to the legacy endpoint (`type`, `categoryId`, `expectedTotal`,
optional `asOfDate`). The `type` field is still required for permission routing.

***

### 2026-05-01

#### Event→Policy relationship migrated to `eventPolicy` Join field (additive)

Event responses now surface the associated policy in two places: the existing
top-level `policyId` and the new `eventPolicy` key inside `fieldModelV1Data`.
Both reflect the same value — `policyId` stays at the top level for backwards
compatibility, while `eventPolicy` is the underlying `Join: Policy` field
where the value is stored.

**What changed:**

* `GET /api/v1/external/companies/{companyId}/events` and `/events/{eventId}`
  responses include `eventPolicy` inside `fieldModelV1Data` alongside the
  pre-existing top-level `policyId`. No fields were removed.
* `POST` and `PUT` event endpoints continue to accept `policyId` as a
  top-level request param. The server maps it to
  `fieldModelV1Data.eventPolicy` internally; clients that already submit
  `policyId` need no changes.
* `policyId` is no longer stored on a dedicated `events.policy_id` column on
  the FMV1 read/write paths — it now lives in `fieldModelV1Data.eventPolicy`,
  consistent with how `eventInsureds` was migrated previously. The external
  API contract is unchanged for existing integrators.

This is a non-breaking change. Integrators can ignore `eventPolicy` and
continue using `policyId`, or migrate to reading the value from
`fieldModelV1Data.eventPolicy` to align with the rest of the field model.

***

#### `Address.zipCode` must be a JSON string (breaking)

`Address` object-primitive writes that send `zipCode` as a JSON number are now rejected with `400` and `problemCode: "InvalidAddressZipCode"`. Previously, numeric ZIPs were accepted by the API but silently lost their leading zeros — `02140` parses as `2140`, corrupting the stored address.

**Affected endpoints:** every FMV1 create/update endpoint that can carry an `Address` value (top-level field or nested inside a custom object), including all exposure, event, quote, basic-policy, segmented-policy-transaction, and custom-object writes.

**What to send:** quote ZIP codes in your payload — `"zipCode": "02140"`, never `"zipCode": 02140`. The [Address sub-field reference](/api-v1-reference/object-primitives/overview#address) and the [`Fmv1Address` OpenAPI schema](/api-v1-reference/object-primitives/overview#address) both call this out explicitly.

**Why this is most likely to bite:**

* **Spreadsheets** (Excel / Google Sheets) auto-coerce ZIP-shaped cells to numbers — export as text or wrap in `=TEXT(...)` before serializing.
* **OpenAPI clients / codegen** that infer the `zipCode` JSON type from a sample value rather than the schema (which has always been `type: string`).
* **LLM-generated requests** that "helpfully" unquote numeric-looking strings.

The geocoded shape returned by [`GET /resolve-address`](/api-v1-reference/address-tools/resolve-address) already returns `zipCode` as a string — paste responses straight into your write payload and you avoid this failure.

***

### 2026-04-29

#### Documentation: Object Primitives + Address Tools

* New [Object Primitives reference page](/api-v1-reference/object-primitives/overview) documenting the five FMV1 built-in object shapes (`Address`, `CoverageLimit`, `Currency`, `Date`, `QuoteBindError`) — sub-field tables, JSON examples, the strict-completeness rule, and List cardinality.
* New [Resolve Address](/api-v1-reference/address-tools/resolve-address) endpoint page surfacing the V1-relevant pre-flight utility for deriving a complete `Address` (including `county`) from a freeform input string. The endpoint itself was added on 2026-04-27 under the legacy URL — this page exposes it to V1 integrators directly.
* OpenAPI spec now exports reusable `Fmv1Address`, `Fmv1CoverageLimit`, `Fmv1Currency`, `Fmv1Date`, and `Fmv1QuoteBindError` schemas under `components.schemas` for client-codegen consumers. Schemas mark every sub-field as `required`.

***

### 2026-04-28

#### Strict object-primitive sub-field validation (breaking)

When a request body for an FMV1 create/update endpoint includes an object-primitive value (`Address`, `CoverageLimit`, `Currency`, `Date`, `QuoteBindError`), every declared sub-field must now be present and non-empty. Affected endpoints:

* `POST/PATCH /api/v1/external/companies/{companyId}/exposures` and `/exposures/{id}`
* `POST/PATCH /api/v1/external/companies/{companyId}/events` and `/events/{id}`
* `POST/PATCH /api/v1/external/companies/{companyId}/quotes` and `/quotes/{id}`
* `POST /api/v1/external/companies/{companyId}/policies` (Basic Policies)
* All segmented policy transaction endpoints (`new-business`, `endorse`, `renew`)
* `POST/PATCH /api/v1/external/companies/{companyId}/custom-objects/{objectType}` and `/{objectId}`

**What changed:**

* A `null`, `undefined`, or empty-string (`""`) sub-field on a present object-primitive value now returns `400` with `Field '<parentField>' is missing required sub-field '<refId>'`. Previously, partial object primitives were silently accepted and surfaced as confusing rating errors downstream. The most common case is `Address` without `county` — call `GET /api/external/companies/{companyId}/resolve-address` first if upstream data lacks county.
* Numeric `0` (e.g. `Currency.value: 0`) and Boolean `false` are still valid — the rule only treats `null` / `undefined` / `""` as missing.
* **Whitespace-only strings (e.g. `"   "`) are NOT treated as missing** by this validator. A consumer sending `county: "   "` will pass this check; downstream rating may still reject it. Trim/normalize sub-field strings client-side before submitting.
* Custom-object sub-fields keep their existing `requiredCondition` rules unchanged.
* Omitting the parent object-primitive field entirely is unchanged — the strict rule only fires when the parent value is provided.

***

### 2026-04-20

* **Bind Quote** — documented under Basic Policies: `POST /api/v1/external/companies/{companyId}/quotes/{quoteId}/bind`. Binds a Field Model V1 quote to create a Basic Policy. Returns `{ policyId, policyNumber, bindErrors }`. Requires `company.quote:create`.

***

### 2026-04-17

* **Basic Policies API** — introduced as a simplified CRUD alternative to the transaction-based Policy API at `GET/POST /api/v1/external/companies/{companyId}/policies` and `GET/DELETE /api/v1/external/companies/{companyId}/policies/{policyId}`. Request body is a flat field-model object with nested `exposures`. See the [Basic Policies overview](/api-v1-reference/policies/basic-overview).
* **List Basic Policies** supports `id`, `policyNumberFilterText` (substring match on `policyNumber` only), and `filters` (structured per-field `FieldModelV1ListFilter[]` against any FMV1 field or system column, combined with AND).
* Removed the "Deprecated" group from the V1 docs. The previous CRUD endpoint shape (`{ referenceId, startsAtDate, endsAtDate, segments: [...] }`) is no longer documented; use the new flat-shape Basic Policies API instead.
