Skip to main content
This walkthrough takes a test key from first ping to an enrolled employer: ping → create group → upload census → quote → enroll → read the account. Every request is copy-pasteable, and every response shown is what the API returns for this census.
You need a test API key (psk_test_...). Prescience support issues keys; there is no self-serve key creation yet. Email partners@getprescience.com if you don’t have one.
1

Check your key

Export your key and hit /ping. It confirms the key is valid and tells you which mode you’re in.
export PRESCIENCE_API_KEY="psk_test_..."

curl https://www.getprescience.com/api/partner/v1/ping \
  -H "Authorization: Bearer $PRESCIENCE_API_KEY"
Response
{ "ok": true, "partner": { "id": "prt_7f3e9a2c54d1", "name": "Example HR" }, "mode": "test" }
2

Create a group

A group is one employer. companyName and domain are required; currentCoverage.pepmCents (what the employer pays per employee per month today) powers the savings comparison on the quote, so send it if you have it.
curl -X POST https://www.getprescience.com/api/partner/v1/groups \
  -H "Authorization: Bearer $PRESCIENCE_API_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: create-acme-group-1" \
  -d '{
    "externalId": "co_4821",
    "companyName": "Acme Inc",
    "domain": "acme.com",
    "address": { "line1": "548 Market St", "city": "San Francisco", "state": "CA", "zip": "94104" },
    "contact": { "name": "Dana Park", "email": "dana@acme.com", "title": "Head of People" },
    "currentCoverage": {
      "planType": "fully_insured",
      "carrier": "Anthem",
      "pepmCents": 80000,
      "renewalDate": "2026-09-01"
    }
  }'
Response (201)
{
  "id": "grp_8c2f41d09a3e",
  "mode": "test",
  "status": "created",
  "companyName": "Acme Inc",
  "domain": "acme.com",
  "externalId": "co_4821",
  "address": { "line1": "548 Market St", "city": "San Francisco", "state": "CA", "zip": "94104" },
  "contact": { "name": "Dana Park", "email": "dana@acme.com", "title": "Head of People" },
  "currentCoverage": { "planType": "fully_insured", "carrier": "Anthem", "pepmCents": 80000, "renewalDate": "2026-09-01" },
  "censusMemberCount": 0,
  "companyState": null,
  "createdAt": "2026-06-10T17:04:11Z",
  "updatedAt": "2026-06-10T17:04:11Z"
}
3

Upload the census

PUT /census replaces the full census. To quote, each member only needs a zip and one of dob | age. You almost certainly have both already. Names and emails are required later, at enrollment.This is Acme’s real census: 12 employees, 19 covered lives.
curl -X PUT https://www.getprescience.com/api/partner/v1/groups/grp_8c2f41d09a3e/census \
  -H "Authorization: Bearer $PRESCIENCE_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "members": [
      { "externalId": "emp_0001", "firstName": "Jordan", "lastName": "Reyes", "email": "jordan@acme.com", "dob": "1992-03-14", "zip": "94110", "employmentType": "full_time", "hireDate": "2024-03-01" },
      { "externalId": "emp_0002", "firstName": "Priya", "lastName": "Natarajan", "email": "priya@acme.com", "dob": "1997-06-21", "zip": "94110", "employmentType": "full_time", "hireDate": "2025-01-20" },
      { "externalId": "emp_0003", "firstName": "Sam", "lastName": "Whitfield", "email": "sam@acme.com", "dob": "1985-01-30", "zip": "94110", "employmentType": "full_time", "hireDate": "2022-08-15" },
      { "externalId": "emp_0004", "firstName": "Elena", "lastName": "Sokolov", "email": "elena@acme.com", "dob": "1998-11-08", "zip": "94110", "employmentType": "full_time", "hireDate": "2025-06-02" },
      { "externalId": "emp_0005", "firstName": "Marcus", "lastName": "Tran", "email": "marcus@acme.com", "dob": "1988-05-17", "zip": "94110", "employmentType": "full_time", "hireDate": "2023-02-27" },
      { "externalId": "emp_0006", "firstName": "Aiko", "lastName": "Tanaka", "email": "aiko@acme.com", "dob": "2001-02-09", "zip": "94110", "employmentType": "full_time", "hireDate": "2025-09-08" },
      { "externalId": "emp_0007", "firstName": "Dev", "lastName": "Sharma", "email": "dev@acme.com", "dob": "1995-04-26", "zip": "94110", "employmentType": "full_time", "hireDate": "2024-11-11" },
      { "externalId": "emp_0008", "firstName": "Grace", "lastName": "Okafor", "email": "grace@acme.com", "dob": "1990-07-03", "zip": "94110", "employmentType": "full_time", "hireDate": "2023-07-15",
        "dependents": [ { "relationship": "spouse", "dob": "1989-08-12", "name": "Femi Okafor" } ] },
      { "externalId": "emp_0009", "firstName": "Tom", "lastName": "Becker", "email": "tom@acme.com", "dob": "1974-02-27", "zip": "94110", "employmentType": "full_time", "hireDate": "2022-01-10",
        "dependents": [ { "relationship": "spouse", "dob": "1976-05-19", "name": "Anja Becker" } ] },
      { "externalId": "emp_0010", "firstName": "Lena", "lastName": "Fischer", "email": "lena@acme.com", "dob": "1993-01-15", "zip": "94110", "employmentType": "full_time", "hireDate": "2024-09-30",
        "dependents": [ { "relationship": "child", "dob": "2019-10-02", "name": "Mia Fischer" } ] },
      { "externalId": "emp_0011", "firstName": "Noah", "lastName": "Kim", "email": "noah@acme.com", "dob": "1982-06-30", "zip": "94110", "employmentType": "full_time", "hireDate": "2022-05-23",
        "dependents": [ { "relationship": "spouse", "dob": "1983-04-11", "name": "Sarah Kim" }, { "relationship": "child", "dob": "2015-09-21", "name": "Eli Kim" } ] },
      { "externalId": "emp_0012", "firstName": "Rachel", "lastName": "Adler", "email": "rachel@acme.com", "dob": "1987-03-08", "zip": "94110", "employmentType": "full_time", "hireDate": "2023-10-02",
        "dependents": [ { "relationship": "spouse", "dob": "1986-07-22", "name": "Ben Adler" }, { "relationship": "child", "dob": "2018-12-05", "name": "Maya Adler" } ] }
    ]
  }'
Response (200)
{
  "groupId": "grp_8c2f41d09a3e",
  "received": 12,
  "accepted": 12,
  "memberCount": 12,
  "errors": [],
  "warnings": []
}
Bad rows never block good ones: they come back in errors with the row index while everything else is stored. Details in the census guide.
4

Create the quote

One POST, empty body, full quote in the same response. The plan year start defaults to the first of the month at least 60 days out, and the savings baseline comes from the pepmCents you set on the group.
curl -X POST https://www.getprescience.com/api/partner/v1/groups/grp_8c2f41d09a3e/quotes \
  -H "Authorization: Bearer $PRESCIENCE_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{}'
Response (201)
{
  "id": "qt_5b9e2c7f10ad",
  "groupId": "grp_8c2f41d09a3e",
  "mode": "test",
  "status": "ready",
  "pricingBasis": "indicative",
  "plan": { "id": "diamond", "name": "Prescience Diamond" },
  "planYearStartDate": "2026-09-01",
  "expiresAt": "2026-07-10T17:22:05Z",
  "census": {
    "employees": 12,
    "coveredLives": 19,
    "tiers": { "employeeOnly": 7, "employeeSpouse": 2, "employeeChildren": 1, "family": 2 }
  },
  "monthly": {
    "totalCents": 660096,
    "pepmCents": 55008,
    "byTier": {
      "employeeOnly": { "count": 7, "avgCents": 34047 },
      "employeeSpouse": { "count": 2, "avgCents": 89166 },
      "employeeChildren": { "count": 1, "avgCents": 53987 },
      "family": { "count": 2, "avgCents": 94724 }
    }
  },
  "annual": { "totalCents": 7921152 },
  "employeeContribution": { "premiumCents": 0 },
  "comparison": {
    "priorPepmCents": 80000,
    "savingsMonthlyCents": 299904,
    "savingsAnnualCents": 3598848,
    "savingsPct": 31
  },
  "fundingBreakdown": {
    "expectedClaimsPct": 78,
    "stopLossPct": 12,
    "careNavigationPct": 10,
    "adminFeesPct": 0,
    "note": "Illustrative split of the premium-equivalent."
  },
  "assumptions": [
    "Rates are indicative pending underwriting confirmation.",
    "Census accepted as submitted; material changes re-rate."
  ],
  "pricing": { "source": "code_default" },
  "createdAt": "2026-06-10T17:22:05Z"
}
Read it like this: monthly.totalCents is the all-in monthly amount, monthly.pepmCents is the employee-normalized amount, and comparison is calculated from the prior-plan PEPM sent on the group. Field-by-field details are in the quotes guide.
Quotes are indicative pending underwriting confirmation. They become binding only at enrollment plus underwriting sign-off. Say so wherever you display them.
5

Enroll the employer

When the employer accepts the quote, create the enrollment. The signatory is the employer admin who made the selection; Prescience provisions them as the company’s admin in the Prescience employer portal and runs onboarding there (the default onboardingMode: "hosted"; see the enrollment guide).
curl -X POST https://www.getprescience.com/api/partner/v1/groups/grp_8c2f41d09a3e/enrollments \
  -H "Authorization: Bearer $PRESCIENCE_API_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: enroll-acme-1" \
  -d '{
    "quoteId": "qt_5b9e2c7f10ad",
    "signatory": { "name": "Dana Park", "email": "dana@acme.com", "title": "Head of People" }
  }'
Response (201)
{
  "id": "enr_3f7a92c81b40",
  "groupId": "grp_8c2f41d09a3e",
  "mode": "test",
  "status": "onboarding",
  "quoteId": "qt_5b9e2c7f10ad",
  "startDate": "2026-09-01",
  "companyDomain": "acme.com",
  "companyState": "sandbox",
  "onboardingMode": "hosted",
  "employerPortal": {
    "provisioned": true,
    "signinUrl": "https://www.getprescience.com/signin",
    "inviteSuppressed": true
  },
  "onboarding": { "percentComplete": 0, "blockingRemaining": 0 },
  "nextSteps": [
    "Prescience onboarding call scheduled with the employer",
    "Employer completes KYB + plan setup in the Prescience portal",
    "Prescience activates the group (state → prod)"
  ],
  "createdAt": "2026-06-12T09:14:32Z"
}
From here, Prescience runs onboarding, KYB, banking, and plan setup with the employer directly in the Prescience employer portal, then activation (sandboxprod). No code on your side; poll GET /enrollments/{enrollmentId} or listen for webhooks. employerPortal confirms the signatory’s portal account: this is a test-mode key, so inviteSuppressed is true. Test mode never sends outbound email; in live mode the signatory receives a set-password invite. The sandbox company is fully functional but flagged test: true and never activated; no money moves.
6

Read the account

Once enrolled, GET /account returns funding, premium-equivalent totals, spend by category, and savings, all aggregate and de-identified.
curl https://www.getprescience.com/api/partner/v1/groups/grp_8c2f41d09a3e/account \
  -H "Authorization: Bearer $PRESCIENCE_API_KEY"
The benefits tab guide maps every field to a UI element, with the full in-force payload for this group.

Where to next

Read plan metadata

Static plan fields plus group-specific quote pricing.

Set up webhooks

Signed events for enrollment, activation, and finalized quotes.

Sync your census

New hires, terminations, and COBRA: one call each.

Go live

BAA, data handling, and what changes between test and live.