Bowmark AIdocs

Insurance

Look up insurance carriers in the regulators' own national register — the NAIC company code, the legal entity behind a consumer brand, head-office contact…

Look up insurance carriers in the regulators' own national register — the NAIC company code, the legal entity behind a consumer brand, head-office contact details, and the states each carrier is LICENSED to write in, which is not the same as where it is headquartered — and get REAL home insurance quotes and rates for a specific property address from two independent carrier panels (Insurify's marketplace, Progressive's HomeQuote Explorer). Direct API, no browser.

Also known as: insurer, carrier, insurance company, underwriter, policy, home insurance quote, homeowners insurance quote, home insurance premium, homeowners insurance rate

Call it

bowmark.insurance.searchCarriers(query: CarrierQuery, limit?: number, options?: CallOptions): Promise<CarrierSearchResult>
bowmark.insurance.findAgent(query: AgentLocatorQuery, limit?: number, options?: CallOptions): Promise<AgentSearchResult>
bowmark.insurance.getLicensing(naicCode: string, options?: CallOptions): Promise<CarrierLicensing>
bowmark.insurance.listReferralCarriers(query?: ReferralCarrierQuery, options?: CallOptions): Promise<ReferralCarrierListResult>
bowmark.insurance.getHomeQuotes(query: HomeQuoteQuery, options?: CallOptions): Promise<HomeQuoteResult>

Functions

FunctionWhat it does
searchCarriersSearches the US insurance regulators' register — { name: "GEICO" }, { licensedIn: "CA" }, or both — and returns up to limit carriers (default and max 100), alphabetical by legal name,…
findAgentFinds an insurance agent or agency to actually call, across the two carriers this reaches.
getLicensingReads the regulators' own licensing record for ONE carrier, keyed on the naicCode searchCarriers returns — the authoritative answer to whether a carrier may legally write the policy it…
listReferralCarriersLists the carriers a referral/marketplace program actually places business with — the fact a quote row never states on its face.
getHomeQuotesReturns REAL home insurance quotes — actual carrier premiums for one property address, fanned out across two independent panels: Insurify's own marketplace and Progressive's HomeQuote…

Types

// At least one filter is required — an empty query is a request for every
// licensed insurer in the country, which is a download, not a question.
type CarrierQuery = {
  name?: string        // case-insensitive SUBSTRING of the company name
  licensedIn?: string  // 2-letter state — carriers LICENSED to write there
  homeState?: string   // 2-letter state — carriers HEADQUARTERED there (a different question)
}

// One carrier as the regulators record it. Nulls mean "not reported for this
// carrier", never "we failed to read it".
type Carrier = {
  source: string              // which source this came from
  naicCode: string            // NAIC company code — the join key US insurance regulation runs on
  name: string                // full legal entity name; one consumer brand is usually SEVERAL
  shortName: string           // the register's own abbreviated statutory name
  address: string | null
  homeState: string | null    // head office — NOT a statement about where it may sell
  phone: string | null
  website: string | null
  licensedStates: string[]    // where it MAY write, per the regulators. [] = licensed nowhere,
                              // which is a real answer; this field is never null
  reportCategories: string[]  // which regulator REPORTS exist for it — NOT the lines it writes
  url: string                 // the regulator's own page for this carrier
}
type CarrierSearchResult = {
  carriers: Carrier[]         // alphabetical by legal name
  warnings: string[]          // always present; empty when nothing was dropped. A
                              // source named here returned NOTHING, which is a very
                              // different fact from "no carrier is licensed there"
}

// findAgent: two carriers, two genuinely different directories. zip searches
// Progressive's radius locator; city+state searches State Farm's directory,
// which has NO zip index at all. Supply zip alone, city+state alone, or both —
// there is no field that reaches both carriers by itself, so this type does not
// pretend one exists.
type AgentLocatorQuery = {
  zip?: string        // 5-digit US ZIP — reaches Progressive ONLY, even when
                      // city+state are also given; State Farm's own zip filter
                      // is an exact office-address match and throws on a miss,
                      // so a ZIP that is really just a search center is never
                      // auto-applied to it — filter its rows' own zip yourself
  city?: string       // required together with state — reaches State Farm
  state?: string      // required together with city — reaches State Farm
  product?: string    // Progressive-only line filter, e.g. "auto" (default), "home",
                      // "motorcycle" — see AgentProduct in the library reference
  language?: "english" | "spanish"  // Progressive-only, default "english"
}

// One agent/agency, as its own carrier's directory reports it.
type Agent = {
  source: string             // which carrier's network this came from
  name: string                // agency trading name (Progressive) or the individual
                              // agent's own name (State Farm) — each carrier's own
                              // granularity, not forced to match the other
  street: string | null
  city: string | null
  state: string | null
  zip: string | null          // this row's OWN zip, not necessarily the one searched
  phone: string | null
  url: string | null          // the agent's/agency's own detail page
  distanceMiles: number | null  // Progressive only; State Farm's city roster has no
                                // distance concept, so its rows are always null here
}
type AgentSearchResult = {
  agents: Agent[]       // grouped by carrier, each in that carrier's own order —
                        // never interleaved by proximity, since only one carrier's
                        // rows carry a real distance
  warnings: string[]    // always present. Names a carrier that was queried but
                        // dropped, AND a carrier that was never queried because the
                        // query lacked the input it needs
}

// getLicensing: one carrier's full licensure record, per jurisdiction.
type CarrierLicense = {
  state: string              // 2-letter jurisdiction code
  jurisdiction: string       // the regulator's own full name for it
  licensed: boolean          // may the carrier write business here at all
  status: string             // the report's own label, verbatim
  insuranceTypes: string[]   // lines licensed HERE; empty when not licensed here
}
type CarrierLicensing = {
  naicCode: string
  name: string | null        // null when the regulator files no report for this code
  states: CarrierLicense[]   // ALL 56 jurisdictions the regulator tracks, with negatives
  licensedStates: string[]   // the AUTHORITATIVE list — longer than searchCarriers's
                             // same-named field, which is a strict subset (see the
                             // module note above)
  insuranceTypes: string[]   // union across every jurisdiction; read states[].insuranceTypes
                             // for what it may write in ONE of them
  hasReport: boolean         // false ≠ "carrier does not exist" — confirm via searchCarriers
  url: string                // the regulator's own report page
  warnings: string[]         // always present; a timeoutMs clamp notice today
}

// listReferralCarriers: whose paper a referral/marketplace program's quote
// actually places — a fact the quote row itself never states.
type ReferralCarrierQuery = {
  line?: string  // narrow to one property line, e.g. "homeowners" — NOT a closed
                 // enum; an unmatched value throws, naming the lines the
                 // directory actually publishes. Omit for the whole directory.
}
type ReferralCarrier = {
  source: string             // which referral program this came from
  name: string                // as the directory writes it
  lines: string[]             // every property line this carrier is listed under
  url: string | null          // the directory's own link for this carrier
  ownedBySource: boolean | null  // true only for the referral program's OWN
                                  // paper; null when the directory linked
                                  // nothing for this row, so it said nothing
                                  // to derive an answer from
}
type ReferralCarrierListResult = {
  carriers: ReferralCarrier[]  // alphabetical by name
  warnings: string[]           // always present; names a source that timed
                               // out or failed
}

// getHomeQuotes: real homeowners premiums for one property, fanned out across
// Insurify's marketplace and Progressive's HomeQuote Explorer panel. Both
// price nothing without the caller's own identity.
type HomeQuoteQuery = {
  identity: { firstName: string, lastName: string, dob: string, email: string, phone: string }
  address: string   // street address, e.g. "686 Hamlet St"
  zip: string        // 5-digit US ZIP
  city?: string       // required TOGETHER WITH state to reach Progressive's panel
  state?: string      // 2-letter state code, required together with city
}
type HomeQuote = {
  source: string              // which panel this came from
  carrier: string
  package: string | null      // Progressive's bundling tier; always null for Insurify
  annualPremium: number | null   // whole-term premium normalized to 12 months
  monthlyPremium: number | null  // always null on a Progressive row — it publishes none
  windHailIncluded: boolean | null  // Progressive only; always null for Insurify
  quoteUrl: string | null     // Insurify's own bindUrl; always null for Progressive
}
type DeclinedHomeCarrier = {
  source: string
  carrier: string             // asked and refused to write the property — a real answer
}
type HomeQuoteResult = {
  quotes: HomeQuote[]          // cheapest annualPremium first; nulls last
  declined: DeclinedHomeCarrier[]
  warnings: string[]
}

type CallOptions = {
  timeoutMs?: number   // per-provider budget in ms, default 30000, clamped to 1000-55000.
                       // A provider slower than this is DROPPED from the results and
                       // NAMED in warnings — never silently absent
}

Examples

// Before trusting a quote: is the entity that would issue the policy actually
// licensed in my state, and what is the regulator's record on it?
const { carriers, warnings } = await bowmark.insurance.searchCarriers({
  name: "State Farm", licensedIn: "TX",
}, 25);
for (const w of warnings) log(w);
log(`${carriers.length} State Farm entities are licensed in Texas`);
return carriers.map(c => ({
  entity: c.name,            // the company on the policy, not the brand on the advert
  naicCode: c.naicCode,      // carry this: it is the key every regulator uses
  states: c.licensedStates.length,
  regulatorRecord: c.url,
}));
// Which carriers headquartered in a state are NOT licensed to sell there —
// the gap that makes "insurers in my state" a misleading search.
const { carriers } = await bowmark.insurance.searchCarriers({ homeState: "CA" }, 100);
const local = carriers.filter(c => c.licensedStates.includes("CA"));
const elsewhere = carriers.filter(c => !c.licensedStates.includes("CA"));
log(`${local.length} of ${carriers.length} CA-headquartered carriers may write in CA`);
return {
  canSellHere: local.slice(0, 5).map(c => c.name),
  headquarteredButNotLicensed: elsewhere.slice(0, 5).map(c => ({
    name: c.name, licensedIn: c.licensedStates,
  })),
};

Providers behind it

Provider
naicNAIC
progressiveProgressive
statefarmState Farm
insurifyInsurify