Skip to main content
The FMV1 Configuration API provides JSON-native endpoints for exporting and importing company configuration. This is the programmatic interface to the configuration pipeline. A Seed endpoint also puts a company into a usable configuration state directly from the framework’s code-defined starter content — no configuration body required. It runs the same validate → compare → apply pipeline over starter content built in-memory. Choose what gets seeded with either a named starterSheet variant or an explicit modules selection (checkbox granularity), and set replace: true to overwrite a company that is already configured. The seed surface is machine-discoverable: List Seed Options (GET /configuration/seed/options) returns the valid starter variants and the default plus the full starter-module catalog (each module’s axis group and defaults), and Generate Seed Configuration (POST /configuration/seed/generate) returns the exact JSON config a seed would apply — without seeding or mutating the company — ready to review/edit and POST to import.

Authentication

These endpoints require an API key created with the FMV1_CONFIGURATION_MANAGER role. Standard API keys (e.g., those with CARRIER_ADMIN) will not have the required permissions.To create an API key with this role, go to Settings > API Keys and select the FMV1 Configuration Manager role when generating the key.

Workflow

The JSON round-trip workflow is:
  1. Export — Pull current config as a structured JSON body
  2. Edit the JSON
  3. Import — Apply the edited JSON body to the database
export → edit → import is a lossless, machine-to-machine round-trip. To put a fresh company into a usable baseline configuration, Seed the framework’s code-defined starter content directly — a single call. The seed workflow is: List Seed Options to discover the variants → Generate Seed Configuration to get the starter config as JSON (no mutation) → edit it → Import to apply it.

API Endpoints

The Configuration Management endpoints are listed in the left navigation:
  • Export Configuration (POST /configuration/export) — Return current config as a structured JSON body. The output is the exact shape import accepts, so export → edit → import is a lossless round-trip.
  • Get Configuration Metadata (POST /configuration/metadata) — Return a stable config version token plus last-modified / last-imported timestamps, without the full config body. Use it for cheap staleness checks before pulling the full export payload.
  • Import Configuration (POST /configuration/import) — Apply a structured JSON configuration body to the database.
  • Seed Configuration (POST /configuration/seed) — Apply code-defined starter content to the database. Select it by named starterSheet variant or explicit modules; refuses to overwrite an already-configured company unless replace: true.
  • List Seed Options (GET /configuration/seed/options) — Discover the valid starterSheet variants, their descriptions, and the default, plus the full starter-module catalog for the modules selection
  • Generate Seed Configuration (POST /configuration/seed/generate) — Return the JSON config a seed would apply, without seeding or mutating the company. The output is import-compatible.
  • Start Data Validation Run (POST /configuration/data-validation-runs) — Start a background scan that classifies every stored record against a configuration. Send a complete configuration body to scan a candidate, or send no body at all to scan the live configuration. Returns a runId to poll.
  • Get Data Validation Run (GET /configuration/data-validation-runs/{runId}) — Poll a run’s status and its running counts of records scanned, adhering, holding undeclared keys, and breaking.
  • List Data Validation Run Findings (GET /configuration/data-validation-runs/{runId}/findings) — Page through which records would not survive the scanned configuration and why. Paginated (page / pageSize) because a poll must not re-transfer thousands of findings; filter with entityType to build a per-type view.

Checking configuration against stored data

Validate and compare are configuration-only: neither reads a single stored record, which is why both answer instantly regardless of how much data a company holds. They tell you a configuration is well-formed and how it differs from the current one — not whether the records you already have would survive it. Data validation runs answer that second question. A run reads every stored record of every entity type and classifies each one, so the natural order before a risky import is: validate (is the config well-formed?) → compare (what changes?) → a run (which of my records would break?) → import. Four properties are worth knowing before you build against it:
  • A run snapshots its configuration when it starts, so a verdict cannot drift — an import that lands mid-scan does not change what the scan is measuring against.
  • Starts collapse and are capped. Starting a run whose configuration matches one already in flight returns that run’s id with outcome: "duplicate" instead of starting a second scan (pass ?force=true to override). A company may have 3 runs in flight; a 4th distinct configuration is refused with a 429 carrying inFlightRunIds so you can poll those instead.
  • The counts and the detail are separate reads. The poll is fixed-size — status plus four counts — and findings is a separate, paginated endpoint, so polling a run costs the same whether the book is clean or badly broken. Poll until the run is terminal, then page the findings once.
  • A run’s status and findings stay readable for as long as the run exists. Nothing removes a run or its findings on a timer, so a run started months ago still answers in full. A run’s age is never a failure on either by-id read: neither reports a run as too old to read, and a run id that belongs to no run of this company is a 404.

Permissions


Framework-Required Rows

Some configuration rows are required by the framework: the import rejects a configuration that omits them or changes their type, cardinality, or join shape. Most framework-required rows also have a fixed calculated value the import enforces byte-for-byte, but a few are flagged customer-supplied: the row’s presence and shape are enforced, while its JEXL calculated-value expression is yours to author and maintain. The main example is referencedExposures on Quote, Policy, and Submission.

Configuration Categories

The compare endpoint returns change counts for each category: