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

# Conversion Rules

> Choose and transform the values written between Quotes and Policies with explicitly authored JEXL rules.

Conversion Rules determine which values move between a Quote and a Policy, where
those values are written, and how they are transformed. They let your application
and policy models serve different purposes: a Quote can collect separate name
fields while the resulting Policy stores a combined customer name, for example.

For a plain-language introduction, see
[Quote ↔ Policy conversion rules](/app/features/conversion-rules) in the app
guide. This page is the authoring reference.

Each rule belongs to your company's field-model configuration. You explicitly
choose the mapping and its expression. Matching field names establish no mapping;
an absent optional rule is valid and causes no conversion write to that destination.

## When rules run

| Direction         | When it runs                                                  | Transaction types                                         |
| ----------------- | ------------------------------------------------------------- | --------------------------------------------------------- |
| `POLICY_TO_QUOTE` | Generate editable Quote data from an existing Policy segment. | `ENDORSE`, `CANCEL`, `REINSTATE`, `RENEW`                 |
| `QUOTE_TO_POLICY` | Convert Quote data into the Policy values used by Bind.       | `NEW_BUSINESS`, `ENDORSE`, `CANCEL`, `REINSTATE`, `RENEW` |

New business has no source Policy, so it has no `POLICY_TO_QUOTE` rule set. Author
each direction separately: a rule combining two Quote fields into one Policy
field does not specify how to split that value when generating another Quote.

For cancellation and reinstatement, `QUOTE_TO_POLICY` rules are framework-only.
These transactions change lifecycle state; ordinary field edits belong in an
endorsement. Required framework rules and platform lifecycle processing remain
separate from your optional business mappings.

Generate returns an editable draft without storing a Quote. Bind evaluates the
Quote-to-Policy rules using the submitted or persisted Quote data. Editing a
generated draft therefore affects the values available to Bind.

## Author a mapping

Add rules to the `conversionRules` array in your configuration. A row has four
properties:

| Property          | Meaning                                                   |
| ----------------- | --------------------------------------------------------- |
| `direction`       | Which entity supplies the values and which receives them. |
| `transactionType` | The transaction in which this rule applies.               |
| `destinationPath` | The destination field to write.                           |
| `expression`      | A JEXL expression that produces the value.                |

For example, this rule writes a Quote's `applicantName` into a Policy's
`customerName`:

```json theme={null}
{
  "direction": "QUOTE_TO_POLICY",
  "transactionType": "NEW_BUSINESS",
  "destinationPath": "customerName",
  "expression": "source.applicantName"
}
```

This is one optional row, **not a complete import body**. Both fields must exist
in their respective models, have compatible types and cardinalities, and the
destination must permit tenant writes. Here both are Single String fields.
Keep your other authored rules and all required framework rows when adding it.

The combination of direction, transaction type, and destination path is unique.
You can author a different expression for `customerName` during `RENEW`, but
cannot give it two writers within `QUOTE_TO_POLICY/NEW_BUSINESS`.

## Transform values with JEXL

Expressions can combine values, use conditional logic, perform arithmetic, and
call supported pure functions. For example, replace the expression above with:

```text theme={null}
source.firstName + ' ' + source.lastName
```

For `firstName = "Alex"` and `lastName = "Morgan"`, the result is `"Alex Morgan"`.
Declare both source fields as Single String fields.

These examples illustrate other business mappings. Their source fields must be
declared and their destination types must match the expression results.

| Expression                                                      | Result                                                                       | Destination type                    |
| --------------------------------------------------------------- | ---------------------------------------------------------------------------- | ----------------------------------- |
| `source.useTradingName ? source.tradingName : source.legalName` | Select the trading or legal name using a Boolean choice.                     | Single String                       |
| `source.employeeCount + source.contractorCount`                 | Sum two Number inputs.                                                       | Single Number                       |
| `ADD_YEARS(transaction.effectiveDate, 1)`                       | Calculate a date one year after the transaction's effective date.            | Single Date                         |
| `source.removeNotes ? CLEAR() : source.notes`                   | Clear notes when the Boolean choice is true; otherwise use the source notes. | Single String, or an explicit clear |

Date arithmetic can express a renewal end date through a tenant-authored
`POLICY_TO_QUOTE/RENEW` rule. It does not grant permission to overwrite a
framework-pinned date rule in another scope.

### Available inputs

| Input                         | Meaning                                                                                     |
| ----------------------------- | ------------------------------------------------------------------------------------------- |
| `source.<field>`              | The resolved source Policy segment or Quote field data, according to direction.             |
| `transaction.effectiveDate`   | The server-authoritative effective date, formatted `YYYY-MM-DD`.                            |
| `transaction.endDate`         | The optional endorsement term end date; `null` when absent and for other transaction types. |
| `transaction.transactionType` | The transaction type, such as `ENDORSE` or `RENEW`.                                         |

Use `source.applicantName`, not bare `applicantName`. Every rule sees the same
source and transaction inputs. Rules cannot read another rule's output, and row
order does not control execution. To combine values, read the original source
fields together in one expression.

Only pure, deterministic functions are allowed: the same inputs must produce the
same result. Explicit date arithmetic is supported; reading the current clock,
querying other records, allocating identifiers, or making external calls is not.
JEXL expressions are not arbitrary JavaScript programs. Configuration validation
rejects unsupported or unsafe function calls.

### Omit, clear, or write

| Outcome                       | Conversion behavior               |
| ----------------------------- | --------------------------------- |
| No optional rule              | No write to that destination.     |
| Rule evaluates to `undefined` | Omit that destination write.      |
| Rule evaluates to `null`      | Explicitly clear the destination. |
| Rule returns another value    | Write that value.                 |

Use `CLEAR()` for an explicit null result. Bare `null` is rejected: JEXL treats it
as an identifier rather than a null literal. Referencing a nonexistent field is
also invalid; it is not a way to request omission.

“No write” describes the conversion step. Required framework values and
transaction lifecycle behavior still apply. If an expression fails structurally,
the conversion fails; it does not silently supply a replacement value or return
a partially converted result.

## Destinations and required rules

A rule can target a top-level field or a nested field through Single-cardinality
objects, such as `mailingAddress.city`. Whole List values can be assigned when
types and cardinalities match. Indexed paths, wildcards, per-list-item destination
paths, and traversal through Joins are not supported.

Within one direction and transaction type, `mailingAddress` and
`mailingAddress.city` cannot both have writers. Different sibling fields can.

Your configuration includes required framework rules for platform-owned values.
Keep their destinations and expressions intact. Optional tenant rules cannot
write system-managed fields or replace pinned framework behavior. Import rejects
missing or changed framework rules, including on a first import or a forced import.

## Maintain and validate your configuration

New companies receive an authored starter configuration, including required
Conversion Rules. Customize that configuration for your business:

1. Export the current configuration through the [Configuration API](/api-reference/configuration/overview).
2. Review the rules affected by your field or business change. Decide the mapping
   independently for each direction and transaction type.
3. Edit those rules while preserving the complete configuration and required rows.
4. Validate the complete body or use an import dry run. Fix invalid source
   references, destinations, expressions, types, cardinalities, or overlapping writers.
5. Import through your normal review process, then verify the intended Generate
   and Bind behavior in a test environment.

When renaming or removing a field, update rules that reference it. Adding a field
requires reviewing the desired business behavior, not automatically adding a rule.
Keeping an optional destination unmapped is valid.
