fieldType in your configuration is one of:
Object: AddressObject: AddressV2Object: CurrencyObject: DateObject: StringOrNumber
NumberLimit is not an object primitive — it is a custom object. A common point of confusion: coverage limits in the default tenant configuration are modelled as a NumberLimit custom object ({ numberLimitName, numberLimitAmount }), with Coverage.coverageLimits typed as a list of them. Its keys and requiredness come from the tenant configuration, not from the framework, so it is documented as a custom-object example (see the Fmv1NumberLimit schema), not on this page. There is no built-in CoverageLimit primitive.Required-completeness rule
If an object-primitive field is provided in a create/update payload, its required sub-fields (listed per primitive below) must each be present and non-empty. A missing required sub-field is rejected with HTTP400 and a problem code naming the offending sub-field:
StringOrNumber slot, a Date without a timezone, a partial Address). The required set is listed in each primitive’s section below — only those sub-fields fire the rule.
The rule only fires when the parent field is provided. Omitting the field entirely is unchanged — object-primitive fields can still be optional at the field-definition level.
What counts as missing: null, undefined, or empty string (""). Numeric 0 and Boolean false are valid values. Whitespace-only strings (e.g. " ") currently slip past this validator — trim sub-field strings client-side before submitting.
Custom objects keep their own rules. Sub-fields of a custom object (including NumberLimit) follow each sub-field’s own requiredCondition from your configuration; only object primitives’ required sub-fields are strict-by-default.
This rule applies to every FMV1 external write endpoint:
POSTexposures, events, quotes- All segmented policy transactions (
new-business,endorse,renew) POSTcustom objects (including an object-primitive sub-field nested inside a custom object)
Address
Structured postal address as a single flat set of components. Used wherever a property, mailing, or risk location appears in your field model. This is the legacy address primitive — see AddressV2 for its successor.Address stays fully supported for every field still typed Object: Address.
Required sub-fields: none. A partial address (e.g. street + city, no county) is valid — Address sub-fields are all optional, so the required-completeness rule never fires for Address. (Whether an address must exist at all is governed by the embedding field’s own required condition.)
AddressV2
The successor toAddress. A postal address modelled as an authoritative entered address plus an optional geocode computed from it.
AddressV2 is not a superset of Address — the sub-fields are renamed and re-nested. A payload written for Address is not a valid AddressV2, and vice versa. Check the field’s configured type before writing it; see the warning at the top of this page.
Read one half or the other, never a blend. enteredAddress is what a person typed or confirmed, and is the half to render as the address. geocode carries provider output only — county, coordinates, precision. There is deliberately no county in enteredAddress and no street text in geocode.
Required sub-fields: none at the top level; all three are optional, as is every sub-field of enteredAddress. The one requiredness rule sits inside geocode: if you send a geocode object at all, status and source must both be present and non-empty.
enteredAddress
There is no
county here. County is provider output and lives on geocode.
geocode
Never typed or edited by a user. null when no geocode has been recorded.
granularity, most precise first:
Writing an AddressV2 field
Send enteredAddress. The platform geocodes server-side on save and fills geocode for you:
- Geocoding never gates the write. A provider miss or outage is recorded as an
"unmatched"or"failed"geocode, not a4xxor5xxon your save. - You can supply your own geocode. Send it with
source: "provided"and it is stored as given, with no provider lookup. Ageocodesent with any othersourceis discarded and replaced by the platform’s own result. - An unchanged entered address keeps its geocode verbatim.
address2is excluded from the components the geocode is computed from, so adding a suite number to an already-matched address does not re-geocode it or lose its match. - Only top-level
AddressV2fields are geocoded on save. AnAddressV2value nested inside a custom object is stored as you send it.
Currency
A monetary value with its currency code. Required sub-fields:value. code is optional.
Date
A calendar date with an optional timezone, stored in the canonical DMY form. Required sub-fields (DMY shape):day, month, year. timezone is optional — persisted dates may lack one.
The API accepts two input shapes for a generic Date field:
timezone is required (it has no DMY fields to fall back on):
policyStartDate / policyEndDate on policy transactions are ordinary Date fields and take either shape. (They additionally still accept a full ISO 8601 string carrying a UTC offset — e.g. "2026-03-15T00:00:00-05:00" — as backward compatibility for existing clients.) See the policy transaction endpoints.
StringOrNumber
A discriminated value that is either a string or a number, chosen per-row. The two typed slots are mutually exclusive — the inactive one isnull.
Required sub-fields: kind. The text / number slots are optional (the inactive slot is null).
Cardinality
Any of these object primitives can appear as a single value or as a list, depending on how the field is configured. List-cardinality fields enforce the same per-primitive required-completeness rule per array element — each item must satisfy its primitive’s required sub-fields.Related
- V1 API Changelog — the strict-validation rule was rolled out on 2026-04-28 and corrected to per-primitive requiredness on 2026-06-26.
