POST /groups/{groupId}/quotes rates the stored census and returns the complete quote in the same response. No polling and no callback; most groups price in under a second.
Create a quote
| Field | Type | Default | Use |
|---|---|---|---|
planYearStartDate | date (YYYY-MM-DD) | First of the month at least 60 days out | Align to the employer’s current renewal date. |
priorPepmCents | integer (cents) | group.currentCoverage.pepmCents | Override the savings baseline for this quote only. |
zip plus dob | age), otherwise 422 census_required. Rate limit: 60 quote creates per hour.
The Quote object
The quickstart quote for Acme Inc (12 employees, 19 covered lives, San Francisco), section by section:status + pricingBasis: what this quote is
status + pricingBasis: what this quote is
pricingBasis is always indicative: rates are indicative pending underwriting confirmation and bind only at enrollment plus underwriting sign-off. Display this framing wherever you show the numbers; “indicative pricing” or the quote’s own assumptions strings work.status is ready for nearly all groups. See large groups below for in_review.census + monthly: the price
census + monthly: the price
monthly.totalCents is the employer’s all-in monthly cost: $6,600.96 here. pepmCents is total ÷ active employees ($550.08). byTier gives average member cost per coverage tier for display; tiers classify members by whether they cover a spouse and/or children.employeeContribution: always zero
employeeContribution: always zero
comparison: prior-cost comparison
comparison: prior-cost comparison
priorPepmCents, which comes from the quote request override or group.currentCoverage.pepmCents. If no prior PEPM was provided, the savings fields are zero. savingsPct is rounded to the nearest whole percent.fundingBreakdown: where the premium-equivalent goes
fundingBreakdown: where the premium-equivalent goes
expiresAt + assumptions: the fine print
expiresAt + assumptions: the fine print
410 quote_expired; create a fresh one. An unchanged census re-prices identically. Preserve the assumptions strings anywhere quote terms are displayed.pricing: rate card metadata
pricing: rate card metadata
| Field | Type | Description |
|---|---|---|
source | enum: code_default | default | partner | partner: integration-specific pricing configuration. default: platform default pricing configuration. code_default: built-in defaults. |
updatedAt | timestamp | When the applied rate card was last updated. Absent for code_default. |
How the engine prices a census
Deterministic and pure: the same census, start date, and pricing configuration always produce the same cents. The API returns the computed result; integrations should store the returned quote rather than reimplementing rating logic. At a high level, the rating engine uses:- Active employee and dependent census records.
- Member age at
planYearStartDate, computed fromdobor the submittedage. - Home ZIP code for geographic rating.
- Coverage tier classification from covered dependents.
- The applied pricing configuration named by
pricing.source.
You never need to reimplement any of this. It’s documented so the numbers aren’t a black box, and so your team can verify a quote by hand if they want to.
Large groups: in_review
Groups above the configured in-review employee threshold (default 200 employees) return status: "in_review" instead of ready. The monthly figures are present but held for Prescience underwriting review. When underwriting finalizes, the quote flips to ready and the quote.finalized webhook fires. Re-fetch with GET /groups/{groupId}/quotes/{quoteId}.
Show these groups a “pricing in final review” state rather than the held numbers.
Listing and re-fetching
GET /groups/{groupId}/quotes: all quotes for a group, newest first, paginated withlimit/cursor.GET /groups/{groupId}/quotes/{quoteId}: one quote, e.g. afterquote.finalized.
in_review → ready and expiry); each re-quote is a new record, so you keep a full pricing history per employer.