<!-- @copy docs audience=human url=/docs -->
# Docs

> For AI agents: the site index is [/llms.txt](https://go-foresee.com/llms.txt) and the full text is [/llms-full.txt](https://go-foresee.com/llms-full.txt).

Foresee enables AI assistants to compare home and auto insurance across every carrier and coverage option, by providing instant, accurate, detailed quote estimates. 

### Using Foresee  

Foresee hosts two MCP servers: 

Users who want a simple, low-friction quote estimate without giving up their PII use: 

    https://mcp.go-foresee.com/mcp

Users who also want to confirm quotes estimates directly with carriers can dispatch Foresee's computer use agents via:

    https://agents.go-foresee.com/mcp

Neither server requires authentication.

### Tools

Foresee publishes two tools on the MCP servers:

| Tool | Purpose | agents. | mcp. | 
|---|---|---|---|
| `quote_insurance` |  Generate instant, accurate, detailed quote estimates | ✅ | ✅ |
| `live_carrier_quotes` | Confirm quote estimates with carriers | ✅ | ❌ | 

## Tool 1: `quote_insurance`

Purpose: generate instant, itemized quote estimates from the carriers Foresee supports, across the lines and states Foresee currently serves, in one call.

### Input Parameters

| Parameter | Type | Required | Details |
|---|---|---|---|
| `profile` | object | yes | see Profile |
| `lines` | object | yes | Keys are the lines to price (`auto`, `home`, `renters`); values are that line's coverage options (see Coverage options) |
| `carriers` | string[] | no | Defaults to "all carriers" |
| `include_failures` | boolean | no | `true` |

### Profile

**Core Profile**

There is a core input `profile`, plus additional blocks for auto and home/renters insurance. 
The only required fields are age (or `dob`), ZIP, and (for auto insurance) vehicle details. 

Omitted optional fields become **declared assumptions**: we choose a conservative stand-in, reported back as `assumptions` — e.g. `auto.vehicles[].annual_mileage` = 12000, with a `tighten_by` entry listing the assumptions which would move the price the most. `prior_insurance` means insurance for the same line; `companion_policies` means insurance for a different line


| Field | Type | Required |
|---|---|---|
| `zip_code` | string | **yes** |
| `age` | integer | **yes** |
| `dob` | string, `YYYY-MM-DD` | accepted alternative to `age` |
| `city` | string | no |
| `gender` | string | no |
| `marital_status` | string | no |
| `education` | string | no |
| `employment_status` | string | no |
| `occupation` | string | no |
| `credit_range` | string | no |
| `home_ownership_status` | string | no |
| `residence_type` | string | no |
| `military_affiliation` | string | no |
| `memberships` | string[] | no |
| `effective_date` | string | no |
| `prior_insurance` | object | no |
| `companion_policies` | object[] — `{line, carrier}` | no |

`companion_policies` lists policies the household already holds, each with the carrier that writes it — `{"line": "home", "carrier": "State Farm"}`. A carrier's multi-policy discount applies only to a policy it writes, so a held policy with no carrier earns none, and the quote asks for the carrier under `tighten_by`.


**Auto Insurance Profile**

| Field | Type | Required |
|---|---|---|
| `auto.vehicles[].year` | integer | **yes** |
| `auto.vehicles[].make` | string | **yes** |
| `auto.vehicles[].model` | string | **yes** |
| `auto.vehicles[].ownership` | string | no |
| `auto.vehicles[].annual_mileage` | integer | no |
| `auto.vehicles[].primary_use` | string | no |
| `auto.vehicles[].garaging_zip` | string | no |
| `auto.drivers[].relation` | string | no (`self` for the first) |
| `auto.drivers[].dob` | string | no |
| `auto.drivers[].years_licensed` | integer | no |
| `auto.drivers[].accidents` | object[] | no |
| `auto.drivers[].violations` | object[] | no |
| `auto.drivers[].sr22_required` | boolean | no |

`accidents` and `violations` are lists of dated entries — `{"on": "2025-01", "kind": "speeding"}`, `{"on": "2023-06-15", "at_fault": true}` — where an empty list is a clean record. An entry missing `on` (or a violation missing `kind`) is refused, naming its path.

**Home & Renters Insurance Profile**

| Field | Type | Required |
|---|---|---|
| `property.year_built` | integer | no |
| `property.construction_type` | string | no |
| `property.roof_type` | string | no |
| `property.square_feet` | integer | no |
| `property.protection_class` | string | no |
| `property.replacement_cost` | integer | no |
| `property.devices` | string[] | no |
| `property.losses` | object[] | no |


### Coverage options

Each key in `lines` takes that line's coverage options. Nothing is priced at a server default: the options you pass are the ones priced.

**Auto** 

| Option | Type | Required | What it covers |
|---|---|---|---|
| `bi` | string | yes | Bodily injury liability: injuries you cause to other people. Per-person/per-accident limit in $000s, e.g. `"100/300"` |
| `pd` | integer | yes | Property damage liability: damage you cause to other people's cars and property. Limit in $000s, e.g. `100` |
| `coll_deductible` | integer | yes | Collision: damage to your own car from a crash, whoever is at fault. The deductible you pay per claim, in dollars |
| `comp_deductible` | integer | yes | Comprehensive: damage to your own car from anything other than a crash — theft, fire, hail, vandalism, hitting an animal. The deductible you pay per claim, in dollars |
| `um` | string | no | Uninsured/underinsured motorist: your injuries when the at-fault driver has no or too little insurance. Per-person/per-accident limit in $000s, e.g. `"100/300"` |
| `medpay` | integer | no | Medical payments: medical bills for you and your passengers, whoever is at fault. Limit in dollars, e.g. `5000` |

**Home**

| Option | Type | Required | What it covers |
|---|---|---|---|
| `coverage_a` | integer | yes | Dwelling: rebuilding the house itself. Limit in dollars, usually the replacement cost |
| `coverage_e` | integer | yes | Personal liability: injuries or damage you're legally responsible for, on or off the property. Limit in dollars |
| `coverage_f` | integer | yes | Medical payments to others: a guest's medical bills after an injury on your property, whoever is at fault. Limit in dollars |
| `aop_deductible` | integer | yes | All-other-perils deductible: what you pay per claim for everything except perils with their own deductible (such as earthquake). In dollars |

Coverages B (other structures, such as a detached garage or fence), C (personal property — your belongings), and D (loss of use — living costs while the house can't be lived in) are not asked in dollars — they come back in `sel` as ratios of Coverage A that were priced.

**Renters**

| Option | Type | Required | What it covers |
|---|---|---|---|
| `coverage_c` | integer | yes | Personal property: your belongings. Limit in dollars |
| `coverage_e` | integer | yes | Personal liability: injuries or damage you're legally responsible for. Limit in dollars |
| `coverage_f` | integer | yes | Medical payments to others: a guest's medical bills after an injury in your home, whoever is at fault. Limit in dollars |
| `deductible` | integer | yes | What you pay per claim before coverage starts. In dollars |
| `coverage_d` | integer | no | Loss of use: extra living costs if you have to move out while the place is repaired. Limit in dollars |

### Response format

A priced result arrives entirely in `structuredContent`; `content` is empty. The
rating detail is the `dense` field: compact machine text, one section per line,
shown in the `response` blocks below. Beside it sit the headline fields per line
under `by_line` (carriers with `monthly`, `confidence_interval`,
`carrier_quote_url`, `warnings`, `rated_vs_asked`; plus `assumptions`,
`tighten_by`, `failures`), and `presentation` (how to present the prices),
`bundle` and `skipped` at the top. Refusals
(`profile_required`, `coverage_required`) are plain JSON with no `dense`.

| Prefix | Frequency | Meaning |
|---|---|---|
| `Q` | once per line | What was priced: state, line of business, coverage selection |
| `assumptions:` | once per line | Assumptions made by Foresee; `high_impact: true` means that this field materially moves the quote estimate |
| `tighten_by:` | once per line | The profile paths of the missing facts that would most move the price |
| `not_priced:` | when applicable | Carriers excluded, with the reason |
| `C` | once per carrier | Carrier, writing entity, monthly premium (point estimate and confidence interval) |
| `W` | as needed | A note on the carrier above, e.g. no online quote page |
| `L` | once per carrier | Monthly cost per coverage, under codes that mean the same coverage at every carrier (`BI`, `PD`, `UMBI`, `MEDPAY`, `COMP`, `COLL`…); `A+B` is one premium covering both, `FEE` a flat fee |
| `D` | per carrier | Price ladders: for each coverage lever, every offered rung as ±$/mo against the quoted monthly, everything else held at the selection. `+0.00` marks the selected rung; `(asked X)` = X isn't offered and the price sits at the nearest offered rung. Re-price from `D`; don't re-call |


---

### Example: auto

A 41-year-old in ZIP 90066 with a 2021 Honda Civic. 

Mercury shows the plain carrier cell; Travelers rates through two possible writing entities, so its cell carries a `ci` segment (the placement span). USAA lands in `not_priced` with the carrier's own reason.


```request
{
  "profile": {
    "zip_code": "90066",
    "age": 41,
    "auto": {"vehicles": [{"year": 2021, "make": "Honda", "model": "Civic"}]}
  },
  "lines": {"auto": {"bi": "100/300", "pd": 100, "coll_deductible": 500, "comp_deductible": 500}},
  "carriers": ["mercury", "travelers", "usaa"]
}
```

Every omitted profile field comes back as a declared assumption — the fat `assumptions:`
block below is caused by the thin request above, and `tighten_by:` lists the nine answers
that would most move the price. Mercury shows the plain carrier cell; Travelers rates through
two possible writing entities, so its cell carries a `ci` segment (the placement span). USAA lands in `not_priced`
with the carrier's own reason.

```response
Q CA auto sel={"bi":"100/300","coll_deductible":500,"comp_deductible":500,"pd":100}
assumptions: [{"assumed":"Single","field":"marital_status","high_impact":false},{"assumed":12000,"field":"auto.vehicles[].annual_mileage","high_impact":true},{"assumed":"Commute","field":"auto.vehicles[].primary_use","high_impact":true},{"assumed":15,"field":"auto.vehicles[].one_way_miles","high_impact":true},{"assumed":5,"field":"auto.vehicles[].commute_days","high_impact":false},{"assumed":16,"field":"auto.drivers[].age_first_licensed","high_impact":true,"note":"CA Good Driver discount (at least 20% off every CA price here, INS §1861.025) is granted on this assumption: it rates the applicant as licensed 3+ years. If they were first licensed less than 3 years ago, these prices are understated — send auto.drivers[].age_first_licensed (or date_first_licensed / years_licensed on the same driver) and re-quote."},{"assumed":[],"field":"auto.drivers[].accidents","high_impact":true},{"assumed":[],"field":"auto.drivers[].violations","high_impact":true},{"assumed":false,"field":"prior_insurance.insured","high_impact":true},{"assumed":null,"field":"home_ownership_status","high_impact":false},{"assumed":null,"field":"occupation","high_impact":true},{"assumed":null,"field":"memberships","high_impact":true}]
tighten_by: auto.vehicles[].annual_mileage,auto.vehicles[].primary_use,auto.vehicles[].one_way_miles,auto.drivers[].age_first_licensed,auto.drivers[].accidents,auto.drivers[].violations,prior_insurance.insured,occupation,memberships
not_priced: usaa:USAA: military families only — set military_affiliation to quote.
C mercury|Mercury Insurance Company|235.11
L BI:56.33,PD:44.10,UMBI:16.85,MEDPAY:0.97,COMP:17.49,COLL:99.38
D bi 100/300=30/60:-9.70,50/100:-6.72,100/300:+0.00,250/500:+12.31,300/300:+12.68,500/500:+23.13
D pd 100=15:-7.99,25:-6.39,50:-2.88,100:+0.00,250:+2.56,300:+3.83
D coll_deductible 500=100:+19.87,200:+14.91,250:+12.42,500:+0.00,1000:-9.94,2000:-29.81,2500:-39.75
D comp_deductible 500=25:+25.74,50:+17.88,100:+11.00,200:+6.09,250:+2.75,500:+0.00,1000:-2.75,2000:-5.70,2500:-8.06
C travelers|Travelers Commercial Insurance Company|368.50|ci 327.21-415.00
L BI:149.00,PD:70.17,COMP:15.50,COLL:114.33,UMBI:19.50
D bi 100/300=15/30:-61.67,25/50:-39.33,30/60:-32.83,50/100:-13.50,100/300:+0.00,250/500:+12.50,500/500:+16.67,1000/1000:+52.67
D pd 100=5:-21.50,10:-10.50,15:-6.67,25:-2.83,50:-0.67,100:+0.00,250:+0.50,300:+0.83,500:+1.17
D coll_deductible 500=100:+22.17,250:+13.17,500:+0.00,1000:-19.33,1500:-34.50,2500:-56.50,5000:-86.00
D comp_deductible 500=0:+11.17,50:+9.67,100:+8.00,250:+2.17,500:+0.00,1000:-1.67,1500:-3.67,2500:-6.50,5000:-10.50
```

---

### Example: home

The same 41-year-old as above, insuring a frame house built in 1998 with a replacement cost of $450,000:

```request
{
  "profile": {
    "zip_code": "90066",
    "age": 41,
    "property": {"year_built": 1998, "construction_type": "frame", "replacement_cost": 450000}
  },
  "lines": {"home": {"coverage_a": 450000, "coverage_e": 300000, "coverage_f": 1000, "aop_deductible": 1000}},
  "carriers": ["mercury", "autoclub"]
}
```

`sel` echoes B/C/D as the ratios of Coverage A that were priced. Each carrier's `L` is its
base premium (`HO_BASE`) plus fees. Dwelling facts are in `assumptions:`/`tighten_by:` — here roof type, protection class, and a clean loss history.

```response
Q CA home sel={"aop_deductible":1000,"coverage_a":450000,"coverage_b_pct":0.1,"coverage_c_pct":0.5,"coverage_d_pct":0.2,"coverage_e":300000,"coverage_f":1000}
assumptions: [{"assumed":"Asphalt Shingle","field":"property.roof_type","high_impact":false},{"assumed":1,"field":"property.stories","high_impact":false},{"assumed":2,"field":"property.bathrooms","high_impact":false},{"assumed":1,"field":"property.units","high_impact":false},{"assumed":"owner occupied","field":"property.occupancy","high_impact":false},{"assumed":5,"field":"property.protection_class","high_impact":true},{"assumed":"Attached","field":"property.garage","high_impact":false},{"assumed":"Single","field":"marital_status","high_impact":false},{"assumed":[],"field":"property.losses","high_impact":true}]
tighten_by: property.protection_class,property.losses
C mercury|CALIFORNIA AUTOMOBILE INS CO|123.67
L HO_BASE:118.76,FEE:3.75,FEE:1.16,FEE:0.01
D aop_deductible 1000=500:+13.38,1000:+0.00,1500:-5.38,2500:-21.45,3500:-26.58,5000:-37.01,10000:-48.28,25000:-63.01,50000:-72.51
D coverage_a 450000=30000:-90.60,65000:-82.94,95000:-76.38,130000:-68.81,165000:-61.24,195000:-54.76,230000:-47.27,265000:-39.79,295000:-33.39,330000:-25.82,365000:-18.34,395000:-11.94,430000:-4.37,445000:-1.17,450000:+0.00,455000:+1.01,465000:+3.20,500000:+10.86,570000:+26.34,630000:+39.88,700000:+56.03,770000:+72.77,830000:+87.49,900000:+105.41,970000:+124.09,2500000:+523.01,6000000:+1464.79
D coverage_e 300000=100000:-1.34,200000:-0.58,300000:+0.00,500000:+0.68,1000000:+4.04
D coverage_f 1000=1000:+0.00,2000:+0.17,5000:+0.42
C autoclub|Interinsurance Exchange of the Automobile Club|146.10
L HO_BASE:144.50,FEE:1.60
D aop_deductible 1000=500:+20.98,750:+7.59,1000:+0.00,1500:-11.45,2000:-16.93,3000:-21.06,5000:-25.36,10000:-28.73,15000:-51.90,20000:-63.44,25000:-71.53,30000:-77.34,50000:-90.49
D coverage_a 450000=60000:-120.65,90000:-115.51,110000:-110.96,130000:-105.66,150000:-99.59,170000:-92.85,190000:-86.53,220000:-76.17,250000:-64.54,280000:-54.09,320000:-40.02,350000:-29.15,360000:-26.54,400000:-16.00,440000:-3.62,450000:+0.00,460000:+2.45,480000:+9.44,550000:+32.95,650000:+77.19,750000:+98.00,850000:+116.62,950000:+147.71,2000000:+475.47,4000000:+1099.41,10000000:+2982.24
```

---

### Example: renters

A different household at the same ZIP: a 27-year-old renter:

```request
{
  "profile": {"zip_code": "90066", "dob": "1998-11-11"},
  "lines": {"renters": {"coverage_c": 30000, "coverage_e": 100000, "coverage_f": 1000, "deductible": 500}},
  "carriers": ["farmers", "usaa"]
}
```

```response
Q CA renters sel={"coverage_c":30000,"coverage_e":100000,"coverage_f":1000,"deductible":500}
assumptions: [{"assumed":2000,"field":"property.year_built","high_impact":false},{"assumed":5,"field":"property.protection_class","high_impact":false},{"assumed":"Single","field":"marital_status","high_impact":false},{"assumed":[],"field":"property.losses","high_impact":true}]
tighten_by: property.losses
not_priced: usaa:USAA: military families only — set military_affiliation to quote.
C farmers|Fire Insurance Exchange|29.88
L RENTERS_BASE:29.17,FEE:0.42,FEE:0.30
D deductible 500=100:+5.89,250:+1.85,500:+0.00,1000:-2.61,1500:-4.29,2500:-6.73
D coverage_c 30000=4000:-16.33,10000:-11.95,17000:-7.15,23000:-3.87,29000:-0.59,30000:+0.00,31000:+0.51,37000:+3.79,43000:+7.07,49000:+10.36,55000:+13.64,62000:+17.43,68000:+20.71,74000:+23.99,81000:+27.78,87000:+31.06,93000:+34.35,100000:+38.14,106000:+41.42,112000:+44.70,118000:+47.99,125000:+51.77,131000:+55.06,137000:+58.34,144000:+62.13,150000:+65.41
D coverage_e 100000=100000:+0.00,300000:+3.28,500000:+5.56,1000000:+10.69
```

---

### Example: auto + renters

The same 27-year-old renter, now with a car. Empty `violations` and `accidents` lists mean a clean record, so the driving-record questions leave `assumptions:` entirely. 

```request
{
  "profile": {
    "zip_code": "90066",
    "age": 27,
    "prior_insurance": {"insured": true, "carrier": "GEICO", "since": "2019"},
    "auto": {"drivers": [{"violations": [], "accidents": []}],
             "vehicles": [{"year": 2021, "make": "Honda", "model": "Civic", "annual_mileage": 9000}]},
    "property": {"year_built": 1978, "square_feet": 850}
  },
  "lines": {
    "auto": {"bi": "100/300", "pd": 100, "coll_deductible": 500, "comp_deductible": 500},
    "renters": {"coverage_c": 30000, "coverage_e": 100000, "coverage_f": 1000, "deductible": 500}
  },
  "carriers": ["farmers", "mercury"]
}
```

Since we now provide record, mileage, and insurance history,the auto `assumptions:` shrink to eight entries and its `tighten_by:` to five. 
The renters section declares its own dwelling stand-ins. Mercury prices auto only; Farmers prices both lines.

```response
Q CA auto sel={"bi":"100/300","coll_deductible":500,"comp_deductible":500,"pd":100}
assumptions: [{"assumed":"Single","field":"marital_status","high_impact":false},{"assumed":"Commute","field":"auto.vehicles[].primary_use","high_impact":true},{"assumed":15,"field":"auto.vehicles[].one_way_miles","high_impact":true},{"assumed":5,"field":"auto.vehicles[].commute_days","high_impact":false},{"assumed":16,"field":"auto.drivers[].age_first_licensed","high_impact":true,"note":"CA Good Driver discount (at least 20% off every CA price here, INS §1861.025) is granted on this assumption: it rates the applicant as licensed 3+ years. If they were first licensed less than 3 years ago, these prices are understated — send auto.drivers[].age_first_licensed (or date_first_licensed / years_licensed on the same driver) and re-quote."},{"assumed":null,"field":"home_ownership_status","high_impact":false},{"assumed":null,"field":"occupation","high_impact":true},{"assumed":null,"field":"memberships","high_impact":true}]
tighten_by: auto.vehicles[].primary_use,auto.vehicles[].one_way_miles,auto.drivers[].age_first_licensed,occupation,memberships
C mercury|Mercury Insurance Company|289.94
L BI:66.80,PD:52.55,UMBI:17.38,MEDPAY:1.05,COMP:23.50,COLL:128.67
D bi 100/300=30/60:-11.50,50/100:-7.96,100/300:+0.00,250/500:+14.60,300/300:+15.04,500/500:+27.43
D pd 100=15:-9.52,25:-7.61,50:-3.43,100:+0.00,250:+3.05,300:+4.57
D coll_deductible 500=100:+25.74,200:+19.30,250:+16.09,500:+0.00,1000:-12.87,2000:-38.60,2500:-51.47
D comp_deductible 500=25:+34.59,50:+24.03,100:+14.79,200:+8.19,250:+3.70,500:+0.00,1000:-3.70,2000:-7.66,2500:-10.83
C farmers|Farmers Insurance Exchange|398.00
L BI:111.83,PD:73.33,UMBI:28.33,UMPD:1.50,MEDPAY:13.33,COMP:34.00,COLL:133.17,FEE:2.50
D bi 100/300=30/60:-23.83,50/100:-14.67,100/300:+0.00,250/500:+9.83,500/500:+23.83,500/1000:+29.83
D pd 100=15:-8.83,25:-5.00,50:-1.50,100:+0.00,250:+1.33,500:+3.17
D coll_deductible 500=250:+30.67,500:+0.00,750:-13.67,1000:-23.50,1500:-37.50,2500:-56.33,5000:-87.00
D comp_deductible 500=100:+23.67,250:+9.17,500:+0.00,750:-7.17,1000:-10.67,1500:-13.50,2500:-18.83,5000:-21.17
Q CA renters sel={"coverage_c":30000,"coverage_e":100000,"coverage_f":1000,"deductible":500}
assumptions: [{"assumed":5,"field":"property.protection_class","high_impact":false},{"assumed":"Single","field":"marital_status","high_impact":false},{"assumed":[],"field":"property.losses","high_impact":true}]
tighten_by: property.losses
not_priced: mercury:no filed-rate renters program served in CA yet
C farmers|Fire Insurance Exchange|29.88
L RENTERS_BASE:29.17,FEE:0.42,FEE:0.30
D deductible 500=100:+5.89,250:+1.85,500:+0.00,1000:-2.61,1500:-4.29,2500:-6.73
D coverage_c 30000=4000:-16.33,10000:-11.95,17000:-7.15,23000:-3.87,29000:-0.59,30000:+0.00,31000:+0.51,37000:+3.79,43000:+7.07,49000:+10.36,55000:+13.64,62000:+17.43,68000:+20.71,74000:+23.99,81000:+27.78,87000:+31.06,93000:+34.35,100000:+38.14,106000:+41.42,112000:+44.70,118000:+47.99,125000:+51.77,131000:+55.06,137000:+58.34,144000:+62.13,150000:+65.41
D coverage_e 100000=100000:+0.00,300000:+3.28,500000:+5.56,1000000:+10.69
```

---

## Tool 2: `live_carrier_quotes`

Purpose: confirm quote estimates on the carriers' own quote sites. 

This tool is idempotent: the first call commissions the computer use agents; calling again with the same arguments collects progress and results from the first call.

A live dispatch submits the user's real details to the carriers, who may perform a soft credit check. User's consent is gathered before the tool is called.

Foresee only collects quotes; it does not take payment or bind insurance.

### Input Parameters

| Parameter | Type | Required | Details |
|---|---|---|---|
| `profile` | object | yes | Same fields as `quote_insurance` — the rating facts |
| `lines` | object | yes | One key per line to walk, each value that line's ask (see below); several keys commission bundled walks |
| `user_authorization` | string | yes | The user's in-chat affirmation, verbatim (e.g. `yes, go ahead`) |
| `identity` | object | usually | The user's details. |
| `carriers` | string[] | no | Restrict the fan; defaults to every carrier with a validated walk for the lines + state |

**`lines`**

| Line | Ask | Why |
|---|---|---|
| `auto` | **required** — the same four axes as `quote_insurance` (`bi`, `pd`, `coll_deductible`, `comp_deductible`), as actual numbers | The limits and deductibles the agents ask the carriers' forms for |
| `home` | **none** — `{"home": null}` | The carrier's own form prices its package (dwelling amount from its replacement-cost estimate); the agents report what it chose. A supplied ask is refused loudly, not silently ignored |
| `renters` | **required** — `coverage_c`, `coverage_e`, `coverage_f`, `deductible`, as actual dollars | The agents type the user's numbers on the form instead of accepting its defaults; Foresee never invents them |

Several keys at once commission bundled walks: each carrier that writes all the named lines is driven through its own multi-line quote flow and reports per-line premiums plus its own bundle total; a carrier writing only some of the lines is walked for those alone. Per-line ask rules are unchanged by bundling.

**`identity`**

| Field | Type | Required | Details |
|---|---|---|---|
| `first_name` | string | yes | Legal first name |
| `last_name` | string | yes | Legal last name |
| `dob` | string, `YYYY-MM-DD` | yes | |
| `street` | string | yes | Street address (line 1) |
| `unit` | string | no | Apartment/unit (line 2) |
| `city` | string | yes | |
| `zip_code` | string | no | Only when it differs from the profile's |
| `email` | string | yes | Carriers send the quote here |
| `phone` | string | no | |

### Response

| Field | Meaning |
|---|---|
| `status` | `in_progress` / `partial` / `complete` — re-call with the same arguments to collect |
| `agents` | One entry per carrier (see below) |
| `note` | What to do next, e.g. re-call timing, or that a prior run's results were returned |
| `authorization_recorded` | On the receipt: the consent record was stored before any carrier saw the risk |
| `skipped` | Carriers NOT dispatched, each with the reason (`no_deterministic_walk`, `missing_facts` with the facts named) |
| `not_dispatched` | Engine-priced carriers this dispatch will not walk, with why (`held: …`, `no_walk`, `not_walked`, `offline`, `not_sold`) — a recommendation the walk lane cannot confirm never silently vanishes |
| `needs` | On a `missing_facts` refusal: per-carrier facts to collect from the user, with exact schema paths — and, for closed-vocabulary fields, the accepted `values` |
| `assumptions` | Unasserted minor form facts the walks resolved to declared no-claim answers: the profile path (`field`) and the value submitted (`assumed`) — relay every one with the results |
| `error` / `detail` | Every refusal is a structured `{"error", "detail"}` dict |

Each `agents` entry:

| Field | When | Meaning |
|---|---|---|
| `carrier_key`, `carrier` | always | Roster key + display name |
| `status` | always | `in_progress` / `complete` / `failed` |
| `lines` | always | The lines this walk covers — several on a bundled walk |
| `stage`, `eta_seconds_remaining` | in progress | Where the walk is; time left against the carrier's typical flow |
| `quote.premium` | quoted | **Verbatim as the carrier's page printed it** (`"$857.80"`) — never parsed, rounded, or derived |
| `quote.term_months` | quoted | The term the printed premium covers |
| `quote.premium_by_line` | quoted, bundled walk | Each line's premium as the page printed it, beside the bundle total in `quote.premium` |
| `quote.breakdown` | quoted | The page's own line items, its own labels |
| `quote.bound` | quoted, newer walks | Cover read off the priced page — what the form actually bound, vs what was asked |
| `quote.variants` | quoted | Additional priced packages the page offered |
| `quote.quote_number` | quoted | The carrier's retrieval number, when the page shows one |
| `quote.evidence_recorded` | quoted | Screenshot evidence exists server-side (internal URIs never ride the wire) |
| `declined: true` + `detail` | declined | The carrier reviewed the details and refused to quote. **An answer, not an error** — relay it |
| `detail` | failed | The walk's own words for where and why it stopped |

### Refusals

Every refusal is a structured `{"error", "detail"}` object — nothing was
submitted to any carrier unless the row below says otherwise.

| Code | When | What to do |
|---|---|---|
| `profile_required` | Household facts sent at the top level, no `profile` wrapper | Re-call with the facts wrapped as shown in the refusal's `example_arguments` |
| `authorization_required` | Called without the user's go-ahead | Explain the consent facts, get a yes, pass it verbatim in `user_authorization` |
| `bad_identity` | A `drivers_license_number` shaped like an SSN | SSNs are never collected; send the licence number as printed on the licence |
| `bad_profile` | A profile field fails validation | `detail` names the field |
| `one_line_per_dispatch` | An empty `lines` map | Name at least one line to walk |
| `unknown_line` | A line with no walk (e.g. `umbrella`) | `detail` lists the lines live dispatch knows |
| `coverage_selection_required` | An auto or renters walk without full limits and deductibles | Re-call with the numbers — the walks type real values, never defaults |
| `bad_ask` | A home walk given a coverage ask | Send `{"home": null}` — the carrier's own form prices its package |
| `missing_facts` | No requested carrier's form can be filled from the profile | Ask the user for the `needs[].fields[]` facts (using their `values` where served) and re-call — see below |
| `no_carriers` | No carrier has a validated walk for that line + state | Fall back to `quote_insurance` |
| `launch_failed` | The agents couldn't start | Nothing reached any carrier — retrying is safe |

---

### Example: auto

A Fresno household confirming GEICO's own number. The profile carries the facts
GEICO's form insists on (ownership, purchase timing, prior insurance, age first
licensed…); `identity` is the real applicant; the ask is the same four axes as
`quote_insurance`.

```request
{
  "profile": {
    "zip_code": "93722",
    "dob": "1954-07-02",
    "gender": "Male",
    "marital_status": "Married",
    "education": "Bachelors",
    "employment_status": "Employed",
    "occupation": "Accountant or CPA",
    "home_ownership_status": "Own",
    "prior_insurance": {"insured": true, "limits": "not sure"},
    "auto": {
      "vehicles": [{
        "year": 2024, "make": "Ford", "model": "Maverick",
        "ownership": "Financed", "annual_mileage": 11000,
        "primary_use": "pleasure", "purchase_date": "2026-08"
      }],
      "drivers": [{
        "relation": "self", "age_first_licensed": 16,
        "years_licensed_outside_us": 0, "defensive_driving_course": true,
        "accidents": [], "violations": []
      }]
    }
  },
  "identity": {
    "first_name": "Cornelius", "last_name": "Beaumont", "dob": "1954-07-02",
    "street": "4381 W Spruce Ave", "city": "Fresno", "zip_code": "93722",
    "email": "cornelius.beaumont@example.com", "phone": "559-555-0164"
  },
  "lines": {"auto": {"bi": "100/300", "pd": 100, "coll_deductible": 500, "comp_deductible": 500}},
  "carriers": ["geico"],
  "user_authorization": "yes, go ahead and get me GEICO's real quote"
}
```
```response
{
  "status": "in_progress",
  "authorization_recorded": true,
  "agents": [
    {
      "carrier_key": "geico",
      "carrier": "GEICO",
      "method": "browser_agent",
      "detail": "deterministic Foresee agent completing the carrier's own quote flow with the user's details",
      "eta_seconds": 480
    }
  ],
  "skipped": [],
  "note": "1 carrier(s) are being quoted live. Collect results by calling this tool again with the same arguments after a few minutes."
}
```

Re-calling with the same arguments later collects the finished walk.
The premium is the page's own string; `breakdown` is the page's own labels
(GEICO printed two packages side by side); `term_months` says what the number
covers — $857.80 **per 6 months**, not per month.

```response
{
  "status": "complete",
  "agents": [
    {
      "carrier_key": "geico",
      "carrier": "GEICO",
      "method": "browser_agent",
      "status": "complete",
      "quote": {
        "premium": "$857.80",
        "currency": "USD",
        "term_months": 6,
        "quote_number": null,
        "breakdown": {
          "Less Coverage": "$857.80",
          "More Coverage": "$870.70"
        },
        "evidence_recorded": true
      }
    }
  ]
}
```