curl --request POST \
--url https://go.aiinsurance.io/api/v1/companies/{companyId}/quotes/{quoteId}/bind \
--header 'Authorization: <api-key>' \
--header 'Content-Type: application/json' \
--data '
{
"bindForms": true,
"invoices": "saved"
}
'{
"policyId": "550e8400-e29b-41d4-a716-446655440010",
"addedForms": [
{
"id": "550e8400-e29b-41d4-a716-446655440030",
"formNumber": "FM-0002",
"name": "Declarations"
},
{
"id": "550e8400-e29b-41d4-a716-446655440031",
"formNumber": "FM-0005",
"name": "Policy Jacket"
}
]
}Bind Quote
Binds a saved quote in one atomic call: a new business or renewal quote
becomes a new bound policy, an endorsement, cancellation or reinstatement
quote is applied to its policy, and the quote is marked bound. Pass invoices: "generate" to build the invoices from the quote’s invoice settings (payment
plan and installments), or invoices: "saved" to bind the plan saved on the
quote.
Before you bind, the quote needs the policy fields your configuration
requires at bind (such as a policy number), a saved rating when it binds
with pricing, and an intended layer:
set it with Set Quote Pricing Stack Intended Layer
(putQuotePricingStackIntendedLayer), body { "pricingStackIntendedLayer": "pricing" }. The body must state bindForms. Check Bind Conditions
(checkBindConditions) lists whatever is still missing, so call it first.
Quote door. The policy’s invoices come from the quote
(Invoicing a policy), and the bind
says which: invoices: "generate" builds them from the quote’s invoice
settings, invoices: "saved" binds the plan saved on the quote, and
leaving it out binds none, which is refused while the quote holds a plan,
and on a change that moves the billing the policy’s existing invoices add
up to.
A saved quote’s bind binds the quote’s state, so it never takes an
invoicePlan: put a plan you wrote on the quote first with
Attach Quote Invoice Plan,
where Check Bind Conditions
can check it before anything commits. Nor does it take a layer: the bind
lands at the quote’s intended layer (see
The intended layer below).
Binds a quote into a policy in a single, atomic call — the one-call
convenience over hand-rolling a new-business transaction from the quote’s
data. The quote is read server-side. The body is required: it must state
bindForms (see Policy forms below).
On success the quote is linked to the resulting policy (quoteStatus becomes
bound, and the quote points at the policy) and the policy is created — both
in one transaction, so a quote can never end up bound to a policy that was
not created, or vice versa.
Policy forms. The bind says whether it adds the quote’s recommended
Policy forms, with bindForms; leaving it out returns
400 BIND_FORMS_REQUIRED. bindForms: false binds with the forms the
quote holds and adds none. With bindForms: true, when the quote’s
recommended Policy forms were never added (a quote created through the
API, or one built in the app whose bind flow never reached its Policy
Forms step), the bind adds them first: the company’s auto-added forms
rules run on the quote as it stands, and every matching Policy form it
doesn’t have, and that nobody removed, joins the bind packet, filled with
the bound policy’s values. It adds nothing for a quote created with
entityCreateOptions.autoAddForms: false. The response’s addedForms lists the forms the
bind added, in rank order. bindForms: true needs form.create and
form.edit as well: without them the bind returns
403 BIND_FORMS_FORBIDDEN, even when there is nothing to add. If the
forms cannot be added, the bind returns 500 POLICY_FORMS_NOT_ADDED and
nothing is bound: retry it, or bind with bindForms: false. A quote
changed while its forms are being added is refused with 409; bind it
again. See
Recommended forms on quote create.
Which quote types can bind. The endpoint dispatches on the quote’s type,
and all five types bind here. newBusiness and renewal mint a
brand-new policy (a renewal’s new policy is linked back to the expiring
term); endorsement, cancellation, and reinstatement transact against
their existing source policy in place. The response policyId is the policy
the transaction landed on — the new policy for newBusiness / renewal, the
existing source policy for the in-place types.
Bindable states. A quote binds from inProgress or complete, with the
same checks either way. An integrator that quotes in its own app skips
Complete and binds the in-progress quote with invoices: "generate"; after
a Complete that generated the invoices (entityUpdateOptions.invoices: "generate" on the update that completes the quote), bind them with
invoices: "saved"
(Rate, Quote, Bind). A quote
that is already bound returns 409 — the error body carries
referencingPolicy (the policy it is already bound to) so you can recover the
id without another call. A cancelled quote returns 409.
Validation. The quote must satisfy the same policy-create rules a
new-business transaction enforces — notably the term bounds on the quote’s
own policyStartDate and policyEndDate root fields, and a resolvable
primary insured among its exposures. A quote that fails them returns a
structured 400.
Required policy fields come from the quote. A bind builds the policy
only from the quote’s data: every field the quote and the policy share
(same referenceId and value type) is copied unchanged, your company’s
QUOTE_TO_POLICY Conversion Rules
state the exceptions, and the policy’s calculated fields fill in the rest.
A required policy field, such as policyNumber, therefore reaches the
policy one of two ways: the quote carries a value that the conversion
copies, or your configuration calculates it at bind (for example, from a
policy-number sequence). Export your configuration to see which applies to
each field. When neither supplies a value, the bind returns
400 InvalidEntityShape naming the field (for example,
'policyNumber' is required but null). To supply it, set the value on the
quote with Update Entity
(PATCH …/entities/quote/{quoteId}), then bind.
A change quote names its policy and date. An endorsement,
cancellation or reinstatement quote binds against the policy in its
referencingPolicy, from the date in its endorsementEffectiveDate,
cancellationEffectiveDate or reinstatementDate. A quote saved from
Generate Quote from Policy
has neither until you set them, unless your Conversion Rules write them,
and without them the bind returns 400 (for example, Endorsement quote … is missing its source policy / effective date metadata). An endorsement
runs to its endorsementEndDate, or to policyEndDate when that is
null; a change to a list item that the policy already drops before then
ends the day before the item leaves.
Invoices. invoices: "generate" generates the plan as
Generate Quote Invoices
does, without saving it on the quote; a plan saved there is not applied.
Either plan is checked again at bind, against the policy’s invoices and
the quote’s billing at that moment, and its invoices commit with the policy
version. A bind that leaves invoices out on a policy that has invoices is
refused with 422 finv2-quote-invoices-do-not-match-pricing when the change
moves the billing those invoices add up to; bind it with
invoices: "generate". Quote invoicing
explains settings, payees and endorsement handling, and
Invoice plans lists each
refusal with its fix. A refused bind saves nothing.
Billing. Stores the quote’s billing as stated, without scaling, restoring or carrying billing from the policy: a quote whose billing calculation states none binds no billing. Kept and new invoices must still add up to the billing, as Invoice plans explains.
The intended layer. The bind must leave the policy at
the quote’s intended layer: the layer of the
pricing stack (base, pricing,
billing or invoicing) chosen for the quote with
Set Quote Pricing Stack Intended Layer,
in the entityCreateOptions.pricingSetup of the quote’s create, or on the
app’s Billing step.
The check reads what the bind would write: the
pricing and billing it prepares and, for an endorsement, cancellation or
reinstatement, the policy’s active invoices less the plan’s voids plus its
creates (a bind of no invoices keeps them all); a new business or renewal quote
counts only the plan’s creates. A quote with no intended layer returns
422 quote-pricing-stack-intended-layer-required. A bind that would leave the policy at
another layer returns 422 quote-pricing-stack-intended-layer-mismatch, whose message
names the intended layer, the layer the bind would reach, the first part that
differs and the request that fixes it, with your ids. Nothing is saved. A saved
quote’s bind runs no other layer check, so an endorsement, cancellation or
reinstatement quote can move a policy to any layer its data reaches. The bind
writes the pricing the quote holds, null included: a quote whose pricing is
null, with no billing or active invoices, binds the policy at base. Any
intended layer can be chosen whatever the quote’s data is; choosing one changes
only the choice.
An out-of-date rating. A quote rated in the app, or rated through the
API and saved with saveToQuote: true, keeps a record of the inputs each
rating workflow read and the rater versions that priced it.
When one of those inputs or the quote’s term changes after the rating, the
workflow’s rating setup changes in a way that could move the price, a newer
version of a rater it used goes live, or, for an endorsement, the policy it
endorses gets a newer version, that workflow’s rating is out of date. The
message names each change: a newer policy version names both versions.
Check Bind Conditions
reports it as an advisory. Binding the quote then needs
confirmStaleRating: true, which binds using the rating the quote holds;
without it the bind returns 409 quote-rating-out-of-date, naming the
workflows in outOfDateWorkflows, and nothing is saved. A rating that is
current, or whose freshness cannot be checked (rating outputs a client
wrote to the quote with Update Entity, or a workflow with a stage that does
not list its inputs), never needs it.
Required permission: quote.bind
curl --request POST \
--url https://go.aiinsurance.io/api/v1/companies/{companyId}/quotes/{quoteId}/bind \
--header 'Authorization: <api-key>' \
--header 'Content-Type: application/json' \
--data '
{
"bindForms": true,
"invoices": "saved"
}
'{
"policyId": "550e8400-e29b-41d4-a716-446655440010",
"addedForms": [
{
"id": "550e8400-e29b-41d4-a716-446655440030",
"formNumber": "FM-0002",
"name": "Declarations"
},
{
"id": "550e8400-e29b-41d4-a716-446655440031",
"formNumber": "FM-0005",
"name": "Policy Jacket"
}
]
}Authorizations
Path Parameters
Body
Whether the bind adds the quote's recommended Policy forms.
true adds the ones the quote never got (see Policy forms
above) and needs form.create and form.edit; if they cannot
be added, nothing is bound. false binds with the forms the
quote holds and adds none. Leaving it out returns
400 BIND_FORMS_REQUIRED.
Which of the quote's invoices the bind applies: generate
builds them from the quote's invoice settings, saved binds the
plan saved on the quote. Omit it to bind none; that is refused
with 409 while the quote holds a plan, and with 422 when
the policy has invoices and the change moves its billing.
generate, saved Confirms binding a quote whose rating is out of date — an
input its rating workflow read, its term, the workflow's
rating setup, a rater it used, which now has a newer
version, or, for an endorsement, the version of the policy
it endorses changed after it was rated. Accepted on every
bind. A bind of an
out-of-date rating without it is refused with
409 quote-rating-out-of-date.
Response
The quote was bound. Returns the id of the resulting policy and the recommended Policy forms the bind added.
