Exposure is a top-level Field Model V1 entity, managed through the unified entity CRUD endpoints at /api/v1/external/companies/{companyId}/entities/Exposure. Like all FMV1 entities, the set of available fields is configured per company.
Key Concepts:
- The request body for create and update is a flat JSON object where keys are field
referenceIds (e.g., exposureName, numberOfEmployees).
- Responses use the generic entity envelope — all field values live inside a
fieldModelV1Data object, alongside id, createdAt/createdBy, updatedAt/updatedBy, and resolved createdByName/updatedByName. There is no top-level companyId.
- Updates use merge semantics — provided fields are merged onto the existing data, a key set to
null clears that field, and omitted fields are left unchanged. PUT is accepted as an alias for PATCH.
- Get returns the exposure’s own data only — there is no cross-entity enrichment. Linked entities are not embedded; query them separately.
Framework-Required Fields
These fields are required by the framework on create:
| Field | Description |
|---|
exposureName | Display name for the exposure |
exposureType | Exposure type (Option Set value) |
Additional fields (including any custom fields) are defined per company. Discover the full set via the Configuration endpoint.
Exposures on Policies
An Exposure row is the canonical record of an insured risk; the policy side references it through exactly one platform-required link — the primary insured identity on fullTermPolicyInfo:
fullTermPolicyInfo.primaryInsuredJoin — the id of an existing Exposure (the legal entity under which insurance is granted). Create the exposure first, then reference it; new-business and renew requests are rejected if the id does not resolve to an Exposure.
fullTermPolicyInfo.primaryInsuredName — the primary insured’s display name.
Beyond that pair, how (and whether) a policy, quote, or submission embeds exposure data is entirely per-company configuration: the default configuration models a primaryInsured object plus an additionalExposures list on Policy/Quote, but a company may model a single vehicles list, named insureds, or no embedded exposures at all. Embedded exposure values are validated per-field against the Exposure configuration like any other field. See Policies — Create a Policy.
Referenced Exposures
Every Quote, Policy, and Submission configuration carries a framework-required calculated Join field, referencedExposures — the flat list of Exposure ids that record references. It powers the exposure listing screens (the Exposures tab on a quote, and the reverse Quotes / Policies / Submissions tabs on an exposure). It is recomputed from the record’s data on every write, so it is output-only: values supplied for it in a create or update request are ignored.
The Exposure side carries the matching reverse Join fields, also framework-required and output-only:
| Field | Description |
|---|
referencingQuotes | Ids of the Quotes whose referencedExposures includes this exposure |
referencingPolicies | Ids of the Policies whose referencedExposures includes this exposure |
referencingSubmissions | Ids of the Submissions whose referencedExposures includes this exposure |
The framework enforces the presence and join shape of these rows at configuration import, but the referencedExposures calculated-value expression is owned by your configuration: it must map however your spreadsheet embeds exposure data into a flat list of Exposure ids. The starter configurations ship with:
| Starter configuration | Quote / Policy expression | Submission expression |
|---|
| default | CONCAT_LISTS(primaryInsured.id, additionalExposures|map("id")) | CONCAT_LISTS(primaryInsured.id) |
| single-exposure-list | exposures|map("id") | exposures|map("id") |
If you restructure or rename your exposure-embedding fields without updating the referencedExposures expression, the exposure listing screens silently under-report. Import-time validation rejects an expression that references fields which don’t exist in the imported configuration, but it cannot detect an expression that no longer covers every place your configuration embeds exposures.
Configuration
Configuration discovery uses the unified entity configuration endpoint. Call GET /api/v1/external/companies/{companyId}/entities/exposure/configuration to retrieve a JSON Schema of the available exposure fields for your company. The schema includes:
- Field types:
string, number, boolean, object
- Option Set fields: include an
enum array of valid values
- Required fields: listed in the
required array
Field Types
| FMV1 Type | JSON Type | Description |
|---|
| Text | string | Free-text string |
| Number | number | Numeric value |
| Boolean | boolean | True/false |
| Option Set | string or number | Constrained to enum values |
| Object | object | Nested object |
Listing, Filtering & Sorting
The unified list endpoint supports the following query parameters:
| Parameter | Description |
|---|
filterText | Free-text search; matches against exposureName |
sortBy | Any configured field to sort by (default createdAt) |
sortDirection | asc or desc |
pageNumber | Zero-based page index (default 0) |
pageSize | Items per page (default 51) |
The list response is { items: [...envelope...], hasMore, totalCount }.
Permissions
| Operation | Permission |
|---|
| Get Configuration | company.insured:read |
| List / Get | company.insured:read |
| Create | company.insured:create |
| Update | insured:update |
| Delete | insured:delete |
Example Create Request
{
"exposureName": "Acme Corporation",
"exposureType": "business",
"numberOfEmployees": 150,
"riskLevel": "Medium"
}
Example Response
{
"id": "550e8400-e29b-41d4-a716-446655440200",
"fieldModelV1Data": {
"exposureName": "Acme Corporation",
"exposureType": "business",
"numberOfEmployees": 150,
"riskLevel": "Medium"
},
"createdAt": 1736937000,
"createdBy": "google-oauth2|123456789",
"updatedAt": 1736937000,
"updatedBy": null,
"createdByName": "Jane Doe",
"updatedByName": null
}
createdAt and updatedAt are epoch-second integers, not ISO strings.