Skip to main content
The census is the input to everything: quotes are rated from it, enrollments materialize it into the live plan, and ongoing syncs keep it true. You already have all of this data; it’s your employee roster plus dependents. PUT /groups/{groupId}/census replaces the full census. Members are upserted by email when present, otherwise by externalId, so re-pushing your roster is always safe and idempotent.

Member schema

{
  "externalId": "emp_0008",
  "firstName": "Grace",
  "lastName": "Okafor",
  "email": "grace@acme.com",
  "dob": "1990-07-03",
  "zip": "94110",
  "sexAtBirth": "female",
  "employmentType": "full_time",
  "hireDate": "2023-07-15",
  "status": "active",
  "dependents": [
    { "relationship": "spouse", "dob": "1989-08-12", "name": "Femi Okafor" }
  ]
}
FieldTypeRequiredNotes
externalIdstringNoYour employee ID. Upsert key when email is absent.
firstName, lastNamestringAt enrollmentNot needed to quote.
emailstringAt enrollmentPrimary upsert key. Members are invited to the Prescience app via this address after launch.
dobYYYY-MM-DDOne of dob | agePreferred; exact ages rate more accurately than integer ages.
ageintegerOne of dob | ageFallback when you don’t store DOB.
zipstringYes5-digit home ZIP. Drives the geographic rating factor.
sexAtBirthenumNomale | female | other.
employmentTypeenumNofull_time | part_time | contractor.
hireDateYYYY-MM-DDNo
statusenumNoactive (default) | terminated. Terminated members are excluded from rating.
dependentsarrayNoMax 6 per member. Each: relationship (required: spouse | domestic_partner | child | other), optional dob, name.
Limits: up to 10,000 members per census, 6 dependents per member.

Quoting vs enrollment requirements

Per member: zip + one of dob | age. That’s it.This is deliberate: you can generate a quote from the minimal data every HR system has, before asking anyone for names or emails. Dependent dobs sharpen the rating (a spouse without one is rated at the employee’s age; a child without one is rated as a 10-year-old), but they’re optional.

Per-row errors: bad rows never block good ones

A census write is row-by-row. Valid rows are stored; invalid rows are rejected and reported with their index. A 142-row upload with one bad ZIP stores 141 members:
{
  "groupId": "grp_8c2f41d09a3e",
  "received": 142,
  "accepted": 141,
  "memberCount": 141,
  "errors": [
    { "index": 7, "field": "zip", "message": "zip must be a 5-digit ZIP code" }
  ],
  "warnings": [
    "3 members missing email (required before enrollment)"
  ]
}
  • errors: rows that were rejected. Fix and re-PUT; upserts make re-sending the clean rows harmless.
  • warnings: non-blocking issues, today chiefly members missing email. They quote fine but will fail enrollment.
Treat accepted < received as a sync alert in your integration, not a hard failure. The group can still be quoted with the accepted members.

Reading the census back

GET /groups/{groupId}/census returns what’s stored, each member with a server-assigned memberId:
{
  "members": [
    {
      "memberId": "mem_c4a91f27e83d",
      "externalId": "emp_0001",
      "firstName": "Jordan",
      "lastName": "Reyes",
      "email": "jordan@acme.com",
      "dob": "1992-03-14",
      "zip": "94110",
      "employmentType": "full_time",
      "hireDate": "2024-03-01",
      "status": "active"
    }
  ],
  "count": 12
}
Keep memberId mapped to your employee record; it’s the handle for single-member updates (PATCH /members/{memberId}) in census sync.
Census intake is enrollment and eligibility data. Before live mode, a BAA and data processing agreement are executed covering exactly this data. See Compliance.