curl --request POST \
--url https://go.aiinsurance.io/api/v1/companies/{companyId}/quotes/{quoteId}/invoicing/generate \
--header 'Authorization: <api-key>' \
--header 'Content-Type: application/json' \
--data '{}'import requests
url = "https://go.aiinsurance.io/api/v1/companies/{companyId}/quotes/{quoteId}/invoicing/generate"
payload = {}
headers = {
"Authorization": "<api-key>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {Authorization: '<api-key>', 'Content-Type': 'application/json'},
body: JSON.stringify({})
};
fetch('https://go.aiinsurance.io/api/v1/companies/{companyId}/quotes/{quoteId}/invoicing/generate', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://go.aiinsurance.io/api/v1/companies/{companyId}/quotes/{quoteId}/invoicing/generate",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => json_encode([
]),
CURLOPT_HTTPHEADER => [
"Authorization: <api-key>",
"Content-Type: application/json"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"strings"
"net/http"
"io"
)
func main() {
url := "https://go.aiinsurance.io/api/v1/companies/{companyId}/quotes/{quoteId}/invoicing/generate"
payload := strings.NewReader("{}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("Authorization", "<api-key>")
req.Header.Add("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.post("https://go.aiinsurance.io/api/v1/companies/{companyId}/quotes/{quoteId}/invoicing/generate")
.header("Authorization", "<api-key>")
.header("Content-Type", "application/json")
.body("{}")
.asString();require 'uri'
require 'net/http'
url = URI("https://go.aiinsurance.io/api/v1/companies/{companyId}/quotes/{quoteId}/invoicing/generate")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["Authorization"] = '<api-key>'
request["Content-Type"] = 'application/json'
request.body = "{}"
response = http.request(request)
puts response.read_body{
"quoteId": "550e8400-e29b-41d4-a716-446655440002",
"settings": {
"schedule": {
"paymentPeriod": "quarterly",
"installmentCount": 4,
"firstDueDate": "2026-01-01",
"owedLeadTimeDays": 14,
"avoidWeekendSends": true,
"downPayment": null
},
"payees": [
{
"group": "Policy Invoice",
"payeeId": "550e8400-e29b-41d4-a716-446655440010"
}
],
"endorsementHandling": {
"mode": "void",
"status": "scheduled"
}
},
"settingsSource": "quote",
"plan": {
"incurredDate": "2026-01-01",
"voidInvoices": [],
"creates": [
{
"group": "Policy Invoice",
"dueDate": "2026-01-01",
"scheduledDate": "2025-12-18",
"payeeId": "550e8400-e29b-41d4-a716-446655440010",
"lineItems": [
{
"label": "Premium",
"amountCents": 125000
}
]
},
{
"group": "Policy Invoice",
"dueDate": "2026-04-01",
"scheduledDate": "2026-03-18",
"payeeId": "550e8400-e29b-41d4-a716-446655440010",
"lineItems": [
{
"label": "Premium",
"amountCents": 125000
}
]
},
{
"group": "Policy Invoice",
"dueDate": "2026-07-01",
"scheduledDate": "2026-06-17",
"payeeId": "550e8400-e29b-41d4-a716-446655440010",
"lineItems": [
{
"label": "Premium",
"amountCents": 125000
}
]
},
{
"group": "Policy Invoice",
"dueDate": "2026-10-01",
"scheduledDate": "2026-09-17",
"payeeId": "550e8400-e29b-41d4-a716-446655440010",
"lineItems": [
{
"label": "Premium",
"amountCents": 125000
}
]
}
]
}
}Generate Quote Invoices
Quote door. A quote owns its invoices. This generates them onto the quote from its settings, as Generate Invoices does in the app’s Billing step, and saves them as the quote’s plan, which binding the quote uses.
It reads the quote as saved. The invoices add up to the quote’s
fullTermBillingInfo, line item by line item. On an endorsement,
cancellation or reinstatement, the policy’s current invoices are kept or
voided by the settings’ endorsementHandling; kept invoices count toward
the billing, so new invoices bill only the rest. Paid invoices and
invoices with payments are never voided, and excess they carry beyond the
billing is credited on the same line. Each run starts from the policy’s
current invoices and replaces any plan on the quote, generated or
attached.
The settings it used are saved on the quote too, so settingsSource
becomes quote; a null installment count is saved as the number of
installments generated. Send no body, or {}. See
Quote invoicing for where
settings and payees come from.
Refusals. A run that cannot generate returns
422 finv2-payment-generation-refused with the reasons, and saves nothing.
When a setting can fix it (a payee, the installment count, lead days,
the first due date, the down payment, or an endorsement handling that
voids invoices the billing no longer covers), the message ends:
“Change the quote’s invoice settings with PUT
/api/v1/companies//quotes//invoicing/settings, then
generate again.” A quote whose fullTermBillingInfo is null or has no
lines has nothing to add up to, and the message names that field. A payee
the invoice type does not accept returns
422 finv2-policy-create-payee-invalid with the same settings fix. With
policy invoicing disabled, this returns
403 finv2-policy-invoicing-disabled. A bound or cancelled quote returns
409.
Required permission: quote.edit
curl --request POST \
--url https://go.aiinsurance.io/api/v1/companies/{companyId}/quotes/{quoteId}/invoicing/generate \
--header 'Authorization: <api-key>' \
--header 'Content-Type: application/json' \
--data '{}'import requests
url = "https://go.aiinsurance.io/api/v1/companies/{companyId}/quotes/{quoteId}/invoicing/generate"
payload = {}
headers = {
"Authorization": "<api-key>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {Authorization: '<api-key>', 'Content-Type': 'application/json'},
body: JSON.stringify({})
};
fetch('https://go.aiinsurance.io/api/v1/companies/{companyId}/quotes/{quoteId}/invoicing/generate', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://go.aiinsurance.io/api/v1/companies/{companyId}/quotes/{quoteId}/invoicing/generate",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => json_encode([
]),
CURLOPT_HTTPHEADER => [
"Authorization: <api-key>",
"Content-Type: application/json"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"strings"
"net/http"
"io"
)
func main() {
url := "https://go.aiinsurance.io/api/v1/companies/{companyId}/quotes/{quoteId}/invoicing/generate"
payload := strings.NewReader("{}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("Authorization", "<api-key>")
req.Header.Add("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.post("https://go.aiinsurance.io/api/v1/companies/{companyId}/quotes/{quoteId}/invoicing/generate")
.header("Authorization", "<api-key>")
.header("Content-Type", "application/json")
.body("{}")
.asString();require 'uri'
require 'net/http'
url = URI("https://go.aiinsurance.io/api/v1/companies/{companyId}/quotes/{quoteId}/invoicing/generate")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["Authorization"] = '<api-key>'
request["Content-Type"] = 'application/json'
request.body = "{}"
response = http.request(request)
puts response.read_body{
"quoteId": "550e8400-e29b-41d4-a716-446655440002",
"settings": {
"schedule": {
"paymentPeriod": "quarterly",
"installmentCount": 4,
"firstDueDate": "2026-01-01",
"owedLeadTimeDays": 14,
"avoidWeekendSends": true,
"downPayment": null
},
"payees": [
{
"group": "Policy Invoice",
"payeeId": "550e8400-e29b-41d4-a716-446655440010"
}
],
"endorsementHandling": {
"mode": "void",
"status": "scheduled"
}
},
"settingsSource": "quote",
"plan": {
"incurredDate": "2026-01-01",
"voidInvoices": [],
"creates": [
{
"group": "Policy Invoice",
"dueDate": "2026-01-01",
"scheduledDate": "2025-12-18",
"payeeId": "550e8400-e29b-41d4-a716-446655440010",
"lineItems": [
{
"label": "Premium",
"amountCents": 125000
}
]
},
{
"group": "Policy Invoice",
"dueDate": "2026-04-01",
"scheduledDate": "2026-03-18",
"payeeId": "550e8400-e29b-41d4-a716-446655440010",
"lineItems": [
{
"label": "Premium",
"amountCents": 125000
}
]
},
{
"group": "Policy Invoice",
"dueDate": "2026-07-01",
"scheduledDate": "2026-06-17",
"payeeId": "550e8400-e29b-41d4-a716-446655440010",
"lineItems": [
{
"label": "Premium",
"amountCents": 125000
}
]
},
{
"group": "Policy Invoice",
"dueDate": "2026-10-01",
"scheduledDate": "2026-09-17",
"payeeId": "550e8400-e29b-41d4-a716-446655440010",
"lineItems": [
{
"label": "Premium",
"amountCents": 125000
}
]
}
]
}
}Authorizations
API key authentication. Send your raw API key as the Authorization header value with NO scheme prefix — Authorization: YOUR-API-KEY. Do NOT prefix it with Bearer or ApiKey, and do not use an X-API-Key header; those are not accepted.
Path Parameters
Company identifier
Quote identifier
Body
The body is of type object.
Response
The quote's invoicing, with the generated plan and the settings it used.
A quote's invoicing: the settings it generates invoices from and the plan saved on it. Binding the quote uses them. Every quote invoicing endpoint returns this.
The settings a quote generates its invoices from. A PUT sends every field and replaces them all. A GET returns the same shape, so you can change a field of a GET's settings and send the object back.
Show child attributes
Show child attributes
Where settings come from. quote once the quote has settings of its own: saved with Replace Quote Invoice Settings, kept by Generate Quote Invoices, or saved in the app's Billing step. A plan attached without settings counts too, because its schedule is what settings shows. company-defaults while nothing on the quote sets them: settings are the company's payment defaults, applied to this quote.
quote, company-defaults The plan saved on the quote, or null when it holds none.
- Option 1
- Option 2
Show child attributes
Show child attributes
