curl --request POST \
--url https://www.getprescience.com/api/partner/v1/groups/{groupId}/enrollments \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '
{
"quoteId": "qt_5b9e2c7f10ad",
"signatory": {
"name": "Dana Park",
"email": "dana@acme.com",
"title": "Head of People"
}
}
'import requests
url = "https://www.getprescience.com/api/partner/v1/groups/{groupId}/enrollments"
payload = {
"quoteId": "qt_5b9e2c7f10ad",
"signatory": {
"name": "Dana Park",
"email": "dana@acme.com",
"title": "Head of People"
}
}
headers = {
"Authorization": "Bearer <token>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {Authorization: 'Bearer <token>', 'Content-Type': 'application/json'},
body: JSON.stringify({
quoteId: 'qt_5b9e2c7f10ad',
signatory: {name: 'Dana Park', email: 'dana@acme.com', title: 'Head of People'}
})
};
fetch('https://www.getprescience.com/api/partner/v1/groups/{groupId}/enrollments', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://www.getprescience.com/api/partner/v1/groups/{groupId}/enrollments",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => json_encode([
'quoteId' => 'qt_5b9e2c7f10ad',
'signatory' => [
'name' => 'Dana Park',
'email' => 'dana@acme.com',
'title' => 'Head of People'
]
]),
CURLOPT_HTTPHEADER => [
"Authorization: Bearer <token>",
"Content-Type: application/json"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"strings"
"net/http"
"io"
)
func main() {
url := "https://www.getprescience.com/api/partner/v1/groups/{groupId}/enrollments"
payload := strings.NewReader("{\n \"quoteId\": \"qt_5b9e2c7f10ad\",\n \"signatory\": {\n \"name\": \"Dana Park\",\n \"email\": \"dana@acme.com\",\n \"title\": \"Head of People\"\n }\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("Authorization", "Bearer <token>")
req.Header.Add("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.post("https://www.getprescience.com/api/partner/v1/groups/{groupId}/enrollments")
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/json")
.body("{\n \"quoteId\": \"qt_5b9e2c7f10ad\",\n \"signatory\": {\n \"name\": \"Dana Park\",\n \"email\": \"dana@acme.com\",\n \"title\": \"Head of People\"\n }\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://www.getprescience.com/api/partner/v1/groups/{groupId}/enrollments")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["Authorization"] = 'Bearer <token>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"quoteId\": \"qt_5b9e2c7f10ad\",\n \"signatory\": {\n \"name\": \"Dana Park\",\n \"email\": \"dana@acme.com\",\n \"title\": \"Head of People\"\n }\n}"
response = http.request(request)
puts response.read_body{
"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"
}{
"error": "invalid_request",
"message": "2 members are missing fields required for enrollment.",
"details": [
{
"field": "email",
"message": "email is required for enrollment",
"index": 3
},
{
"field": "lastName",
"message": "lastName is required for enrollment",
"index": 9
}
]
}{
"error": "unauthorized",
"message": "Provide a valid partner API key as `Authorization: Bearer psk_...`."
}{
"error": "not_found",
"message": "No group grp_8c2f41d09a3e found."
}{
"error": "conflict",
"message": "Group grp_8c2f41d09a3e already has an active enrollment."
}{
"error": "quote_expired",
"message": "Quote qt_5b9e2c7f10ad expired on 2026-07-10. Create a new quote."
}{
"error": "census_required",
"message": "An active census is required before enrollment."
}{
"error": "rate_limited",
"message": "Too many requests. Please retry later."
}{
"error": "server_error",
"message": "Internal error. The request was not applied."
}Create an enrollment
Locks the employer’s plan selection against a quote. Requires an unexpired ready quote and an enrollment-ready census: every active member needs firstName, lastName, and email (failures come back as invalid_request with per-member details). Prescience provisions the company (state sandbox), materializes the census, and starts the onboarding pipeline. On the hosted pathway (default) the signatory is also provisioned as an employer portal admin and receives a set-password invite; in test mode the invite email is suppressed (employerPortal.inviteSuppressed: true). Fires the enrollment.created webhook.
curl --request POST \
--url https://www.getprescience.com/api/partner/v1/groups/{groupId}/enrollments \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '
{
"quoteId": "qt_5b9e2c7f10ad",
"signatory": {
"name": "Dana Park",
"email": "dana@acme.com",
"title": "Head of People"
}
}
'import requests
url = "https://www.getprescience.com/api/partner/v1/groups/{groupId}/enrollments"
payload = {
"quoteId": "qt_5b9e2c7f10ad",
"signatory": {
"name": "Dana Park",
"email": "dana@acme.com",
"title": "Head of People"
}
}
headers = {
"Authorization": "Bearer <token>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {Authorization: 'Bearer <token>', 'Content-Type': 'application/json'},
body: JSON.stringify({
quoteId: 'qt_5b9e2c7f10ad',
signatory: {name: 'Dana Park', email: 'dana@acme.com', title: 'Head of People'}
})
};
fetch('https://www.getprescience.com/api/partner/v1/groups/{groupId}/enrollments', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://www.getprescience.com/api/partner/v1/groups/{groupId}/enrollments",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => json_encode([
'quoteId' => 'qt_5b9e2c7f10ad',
'signatory' => [
'name' => 'Dana Park',
'email' => 'dana@acme.com',
'title' => 'Head of People'
]
]),
CURLOPT_HTTPHEADER => [
"Authorization: Bearer <token>",
"Content-Type: application/json"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"strings"
"net/http"
"io"
)
func main() {
url := "https://www.getprescience.com/api/partner/v1/groups/{groupId}/enrollments"
payload := strings.NewReader("{\n \"quoteId\": \"qt_5b9e2c7f10ad\",\n \"signatory\": {\n \"name\": \"Dana Park\",\n \"email\": \"dana@acme.com\",\n \"title\": \"Head of People\"\n }\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("Authorization", "Bearer <token>")
req.Header.Add("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.post("https://www.getprescience.com/api/partner/v1/groups/{groupId}/enrollments")
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/json")
.body("{\n \"quoteId\": \"qt_5b9e2c7f10ad\",\n \"signatory\": {\n \"name\": \"Dana Park\",\n \"email\": \"dana@acme.com\",\n \"title\": \"Head of People\"\n }\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://www.getprescience.com/api/partner/v1/groups/{groupId}/enrollments")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["Authorization"] = 'Bearer <token>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"quoteId\": \"qt_5b9e2c7f10ad\",\n \"signatory\": {\n \"name\": \"Dana Park\",\n \"email\": \"dana@acme.com\",\n \"title\": \"Head of People\"\n }\n}"
response = http.request(request)
puts response.read_body{
"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"
}{
"error": "invalid_request",
"message": "2 members are missing fields required for enrollment.",
"details": [
{
"field": "email",
"message": "email is required for enrollment",
"index": 3
},
{
"field": "lastName",
"message": "lastName is required for enrollment",
"index": 9
}
]
}{
"error": "unauthorized",
"message": "Provide a valid partner API key as `Authorization: Bearer psk_...`."
}{
"error": "not_found",
"message": "No group grp_8c2f41d09a3e found."
}{
"error": "conflict",
"message": "Group grp_8c2f41d09a3e already has an active enrollment."
}{
"error": "quote_expired",
"message": "Quote qt_5b9e2c7f10ad expired on 2026-07-10. Create a new quote."
}{
"error": "census_required",
"message": "An active census is required before enrollment."
}{
"error": "rate_limited",
"message": "Too many requests. Please retry later."
}{
"error": "server_error",
"message": "Internal error. The request was not applied."
}Authorizations
Partner API key. psk_test_<32 hex> for test mode, psk_live_<32 hex> for live mode. Store them in your secrets manager on issue. Live keys are shown once; the scoped partner portal can show an active sandbox key again.
Headers
Any non-empty string; deterministic keys from your own IDs work best. Repeating the same key with the same body on the same endpoint and mode within 24 hours returns the stored successful response (with Idempotent-Replay: true) instead of re-executing. Error responses are not stored.
Path Parameters
Group ID, e.g. grp_8c2f41d09a3e.
^grp_[0-9a-f]{12}$Body
"qt_5b9e2c7f10ad"
The employer admin who selected the plan. On the hosted pathway, provisioned as the company's admin in the Prescience employer portal.
Show child attributes
Show child attributes
Defaults to the quote's planYearStartDate.
"2026-09-01"
How post-enrollment onboarding runs. hosted (default): Prescience provisions the signatory as an employer portal admin and runs onboarding, KYB, banking, and plan setup in the Prescience employer portal; track progress via GET /groups/{groupId}/enrollments/{enrollmentId} or webhooks. embedded: onboarding rendered in your own UI when enabled for the integration.
hosted, embedded Response
Enrollment created. The group status moves to enrolled.
"enr_3f7a92c81b40"
"grp_8c2f41d09a3e"
test, live active once Prescience flips the company to prod.
onboarding, active "qt_5b9e2c7f10ad"
"2026-09-01"
"acme.com"
sandbox, prod How post-enrollment onboarding runs. Stamped at creation; defaults to hosted.
hosted, embedded Recomputed from the live onboarding checklist on every read.
Show child attributes
Show child attributes
Provisioning summary for the signatory's employer portal account. Present whenever the signatory was provisioned as an employer portal admin (always on the hosted pathway).
Show child attributes
Show child attributes