Quoting API Guide
This guide explains how to reproduce the "Create and bind a quote" workflow from the BriteCore Help Center with the public API surface that lives under /api/v2/quotes. It covers the lifecycle from quote creation through binding, and includes concrete JSON examples, headers, and troubleshooting guidance for anyone automating quoting flows through BriteCore.
Audience & Scope
- Audience: Carrier engineering teams, distribution partners, and internal tools that orchestrate quoting on behalf of agencies or policyholders.
- Scope: REST-style endpoints in
lib/api/v2/quotes.py, accessory services (prefill, underwriting, contact screening), and the data structures defined inlib/domain/quote.py. - Out of scope: Legacy
/v1RPC calls, downstream billing issuance, and UI-specific concerns already handled in the help-center article.
Core Concepts
| Concept | Description |
|---|---|
| Quote | A draft policy intent. Each quote has an id, a policy_id, and a mutable revision that holds risks, insureds, and premium artifacts. |
| Revision | Each material change creates a revision. Most endpoints act on the latest non-archived revision, but renewal and endorsement APIs let you specify external_system_reference or policy_number. |
| External System Reference | Optional string you can set to correlate BriteCore quotes with CRM/raters. Many endpoints accept either id or external_system_reference. |
| Statuses | Quotes move from open → ready-to-apply → application → submitted → committed. Binding transitions the status to committed (policy issued). |
| Transaction Types | new-business, endorsement, and renewal enumerate how the quote should be treated by downstream services. |
Authentication & Environment
- Base URL:
<environment>/api/v2/quotes/<function_name>(e.g.,https://carrier.example.com/api/v2/quotes/create_full_quote). - Headers:
Authorization: Bearer <JWT>(or the session cookie provided by the auth service).Content-Type: application/jsonfor all write operations.X-BriteCore-Tenantwhen operating in a multi-tenant deployment.
- Idempotency: Provide a stable
external_system_referencewhen you need retries; the platform will deduplicate by that reference.
Workflow Mapping
| Help-Center Step | API Step(s) |
|---|---|
| Start quote, pick line of business | create_full_quote or list_available_offers → create_full_quote |
| Add applicant & risk details | modify_full_quote, prefill_quote, prefill_violations, get_quote_properties_summary |
| Answer underwriting questions | Included in create_full_quote / modify_full_quote payloads |
| Run rating | rate_full_quote or create_and_rate_full_quote, optionally get_estimated_quote |
| Review UW or compliance holds | evaluate_contact_screening, prefill_loss_history, summary |
| Bind & issue | bind_full_quote, submit_application, issue_full_quote |
Endpoint Summary
| Purpose | Method | Path | Notes |
|---|---|---|---|
| Create quote | POST | /api/v2/quotes/create_full_quote | Accepts full payload (policy type, risks, insureds, billing). Returns quote + policy identifiers. |
| Modify quote | PATCH | /api/v2/quotes/modify_full_quote | Partial updates for incremental build-out. |
| Retrieve quote | POST | /api/v2/quotes/retrieve_full_quote | Provide id or external_system_reference. |
| Delete quote | DELETE | /api/v2/quotes/delete_full_quote | Hard delete when allowed by business rules. |
| Rate quote | POST | /api/v2/quotes/rate_full_quote | Persists rating results on the revision. |
| Stateless create + rate | POST | /api/v2/quotes/create_and_rate_full_quote | Useful for quick price checks without committing. |
| Bind | POST | /api/v2/quotes/bind_full_quote | Optionally submit_bound=true to immediately mark as issued. |
| Submit application | POST | /api/v2/quotes/submit_application | Converts quote → application; collects payment in UI. |
| Issue policy | POST | /api/v2/quotes/issue_full_quote | Final issuance once payments clear. |
| Prefill drivers/vehicles | POST | /api/v2/quotes/prefill_quote | Augments risks with external data. |
| Contact screening | POST | /api/v2/quotes/evaluate_contact_screening | AML/KYC review before bind. |
| Renew / copy / endorse | POST | /api/v2/quotes/create_renewal_quote, /copy_quote, /create_endorsement_quote | Reuse exposures for follow-on transactions. |
Convention: Every endpoint uses camel-case function names because the routes are generated directly from
lib/api/v2/quotes.py. HTTP verbs shown above are recommendations; internally the routes accept JSON bodies regardless of the verb, but align with the suggested semantics when building integrations.
Step-by-Step Implementation
1. Create a Quote Shell
Use POST /api/v2/quotes/create_full_quote to establish the policy type, effective date, term, underwriting answers, and initial risks. Either policy_type_id or policy_type_external_system_reference is required.
{
"policy_type_id": "b37d8a92-0412-41a0-8f57-8b08f53f0480",
"effective_date": "2025-12-01",
"term_type": "Annual",
"transaction_type": "new-business",
"state": "IL",
"underwriting_questions": [
{"id": "occupancy", "answer": "Owner"},
{"id": "prior_losses", "answer": "None"}
],
"named_insureds": [
{
"display_name": "Sasha Rivera",
"contact_type": "individual",
"addresses": [
{"type": "mailing", "address": "10 Main St", "city": "Chicago", "state": "IL", "postal_code": "60601"}
]
}
],
"risks": [
{
"risk_type": "Property",
"display_name": "Primary Dwelling",
"address_line1": "10 Main St",
"address_city": "Chicago",
"address_state": "IL",
"address_zip": "60601",
"construction_type": "Frame",
"year_built": 2018,
"square_footage": 2200,
"coverage_groups": [
{
"id": "dwelling",
"coverages": [
{"id": "CovA", "limit": 450000},
{"id": "CovB", "limit": 45000}
]
}
]
}
],
"billing_information": {
"payment_plan_id": "03fe57c4-418c-4c6a-8d7b-2cb7c5a689c1",
"bill_whom": "insured",
"bill_how": "direct"
},
"external_system_reference": "CRM-QUOTE-28721"
}
Response excerpt:
{
"id": "b74c40d7-9f94-4b9e-9c7c-2d6e8ffb2f16",
"policy_id": "18724783-4ad3-4f0a-824d-9339bc42f2d9",
"policy_number": "HO-00001234",
"status": "open",
"written_premium": 1285.44,
"risks": [...],
"named_insureds": [...],
"warnings": []
}
Best practices
- Always persist the returned
idandpolicy_id. - Provide underwriting answers up front so later validations match UI expectations from the help article.
- Supply
external_system_referenceto make retries idempotent.
2. Enrich the Quote
Use prefill_quote, prefill_violations, or prefill_loss_history to import drivers, vehicles, and prior losses when the UI would normally prompt the user:
curl -X POST \
"$BASE_URL/api/v2/quotes/prefill_quote" \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{"id":"b74c40d7-9f94-4b9e-9c7c-2d6e8ffb2f16","force_run":true}'
Modify the quote incrementally with PATCH /api/v2/quotes/modify_full_quote. Only fields you send are changed; all others stay intact.
{
"id": "b74c40d7-9f94-4b9e-9c7c-2d6e8ffb2f16",
"risks": [
{
"id": "9af6d49f-6aa9-46e0-bb5f-e826e4395858",
"coverage_groups": [
{
"id": "dwelling",
"coverages": [
{"id": "CovA", "limit": 500000},
{"id": "CovE", "limit": 300000, "deductible": 1000}
]
}
]
}
],
"billing_information": {
"bill_whom": "mortgagee",
"bill_how": "agency"
}
}
To add additional applicants, send more named_insureds. To associate an agent, use associate_agentcy_to_quote(quote_id, contact_id).
3. Validate and Prefill Underwriting Data
get_quote_properties_summary(quote_id): returns structure and risk counts—helpful for UI summary panes.summary(quote_id): aggregates total premium, fees, and outstanding tasks.evaluate_contact_screening(id, skip_integrations=false): kicks off AML/KYC checks prior to bind.prefill_loss_history(quote_id)andprefill_violations(quote_id)mirror the UI's "Import loss history" flow from the help page. When new events are discovered, the API flagsrate_updated=trueso you know to re-rate.
4. Rate the Quote
POST /api/v2/quotes/rate_full_quote recalculates premium and persists the result on the revision. When you need a sandboxed price without saving the quote, use create_and_rate_full_quote with stateless=true.
curl -X POST "$BASE_URL/api/v2/quotes/rate_full_quote" \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{"id":"b74c40d7-9f94-4b9e-9c7c-2d6e8ffb2f16","debug":true}'
Response fields include written_premium, annual_fee, and any warnings. Re-run rating after every material update just as the UI requires the user to click Rate per the help article.
5. Resolve Underwriting & Compliance Holds
Before bind, mirror the UI's underwriting tab by:
- Calling
evaluate_contact_screeningfor sanction checks. - Reading
summary(quote_id)to confirm all underwriting questions are answered. - Invoking
update_e_delivery_enabled(revision_id, value)if electronic delivery consents were gathered outside BriteCore.
6. Bind and Issue
Two options map to the "Bind" step from the help article:
- Application-first:
submit_application(quote_id, submit_bound=false)transitions the quote into application status so human underwriters can review payment or e-signatures. - Direct bind:
bind_full_quote(id, submit_bound=true)both binds and submits, skipping the intermediate status when your workflow already satisfied underwriting.
Issuance finishes the lifecycle:
curl -X POST "$BASE_URL/api/v2/quotes/issue_full_quote" \
-H "Authorization: Bearer $TOKEN" \
-d '{"id":"b74c40d7-9f94-4b9e-9c7c-2d6e8ffb2f16"}'
After the bind call returns, expect status to change to committed and policy_status to active. Use retrieve_full_quote to pull the final revision for downstream document generation.
Advanced Scenarios
Stateless Estimates
create_and_rate_full_quote accepts { "quote": <CreateFullQuoteRequest>, "rate_quote": true, "stateless": true }. Because nothing is committed, it's perfect for instant pricing widgets that only need an estimated premium.
Copying or Renewing
copy_quote(quote_id, inception_date)duplicates the risks into a brand-new revision, mirroring the "Copy" UI button.create_renewal_quote({"policy_number": "HO-00001234"})produces a renewal revision using the latest committed term. Validate that the revision is pending or committed before calling, as enforced by the service.
Endorsements and Changes
create_endorsement_quote seeds an endorsement quote using QuoteEndorsementRequestModel (policy number, effective date, change summary). After adjustments, call submit_change(quote_id) to finalize.
Error Handling & Troubleshooting
| Symptom | Likely Cause | Fix |
|---|---|---|
400 ValidationError: policy_type_id or policy_type_external_system_reference must be provided | Missing identifiers in create_full_quote. | Provide at least one identifier, plus state if only policy_type_external_system_reference is used. |
409 Quote already bound | bind_full_quote invoked twice. | Use retrieve_full_quote to check status before retrying or rely on external_system_reference idempotency. |
RateQuoteFailedMetric emitted | Rating service raised exceptions (bad coverage limit, missing territory). | Inspect response warnings/validations, adjust coverages, and re-rate. |
Empty array from prefill_quote | Prefill integrations returned nothing. | Allow UI/manual entry or retry with force_run=true after updating addresses. |
Log identifiers (quote_id, policy_id, external_system_reference) in every integration call so you can cross-reference with the UI audit history described in the help article.
Testing Checklist
- Happy path: Create → modify → rate → bind with valid payment info.
- UW hold: Force
pending-uw-reviewby leaving an underwriting question blank; confirmsummaryreflects outstanding tasks. - Prefill retry: Trigger
prefill_loss_historytwice to ensure idempotency resetting the quote rate when new events surface. - Renewal: Use
create_renewal_quotefollowed byrate_full_quoteto verify carry-forward of prior data. - Error paths: Intentionally send an invalid coverage limit to confirm
validationsbubble up to your calling application.
Appendix: Key Data Shapes
- Underwriting Question:
{ "id": "string", "answer": "string", "notes": "optional" } - Named Insured:
{ "display_name": "Acme LLC", "contact_type": "organization", "contact_id": "optional", "addresses": [ ... ] } - Risk (Property): Inherits from
PropertyModelwith address, construction, protection class, and nestedcoverage_groups. Keep addresses complete soprefill_quotecan enrich ISO data. - Billing Info:
{ "payment_plan_id": "uuid", "bill_whom": "insured|agency|mortgagee", "bill_how": "direct|account-current", "first_bill_date": "YYYY-MM-DD" }