Population
Your whole panel at once. Aggregate counts (panel size, worklist priority tiers, rising risk, care gaps by measure) with small-cell suppression: counts below the minimum cell are withheld, and so is any cell that could be recovered by subtraction. Five eCQM-style quality measures and the Million Hearts ABCS as suppressed rates; these are NOT a certified eCQM calculation. A QRDA Category III file for 2026 with true counts, not submission-validated, audited. Asynchronous FHIR Bulk Data export of the panel, identified (each patient's sharing choices apply) or HIPAA Safe Harbor de-identified, audited per file. Programme reporting: HRSA UDS tables and the UDS+ FHIR submission for health centres, EPSDT screening counts (explicitly not a CMS-416 report), social-needs screening and referral counts, and HEDIS only where your organisation holds an NCQA licence and uploaded its own measure definitions (Norvya ships no HEDIS logic). Medical practices and programme clinics only.
- Who calls it
- Core for Federal (via primes), State & local government, Insurers (incl. Medicaid managed care); useful for Independent practices, Hospitals and health systems
- Before production
- No gate of its own; your market's “Before production” applies.
- Sandbox
- Build against synthetic members first. What each sandbox holds
- Standards
- eCQM-style measures (not certified); QRDA Category III; FHIR Bulk Data; UDS+
Markets that use this family
- Independent practices (useful)
- Federal (via primes) (core)
- State & local government (core)
- Insurers (incl. Medicaid managed care) (core)
- Hospitals and health systems (useful)
Scopes
| Scope | Allows |
|---|---|
population.aggregate.read | Read aggregate counts for your whole active panel (worklist tiers, rising risk, care gaps); every count below the small-cell minimum is suppressed, no ids (medical practices only). |
population.export | Run asynchronous FHIR Bulk Data exports of your panel, identified (each patient's sharing choices apply) or HIPAA Safe Harbor de-identified; audited per file (medical practices only). |
population.measures.export | Download the QRDA Category III file for the 2026 period: TRUE counts, not submission-validated, audited and refused when the audit log is down (medical practices only). |
population.measures.read | Read five eCQM-style quality measures and the Million Hearts ABCS as suppressed rates; NOT a certified eCQM calculation (medical practices only). |
Endpoints
Aggregate picture of your whole panel, small cells suppressed
Panel size; patients by worklist priority tier and rising risk from the latest completed worklist run (named, with when it finished); open care gaps by measure and gap code for the current measurement year. Counts only: no member_refs, no ids, no free text. Every count from 1 to min_cell - 1 is withheld, and further cells are withheld when one could otherwise be recovered by subtracting from a total (the `suppression` field says how). Medical practices only (409 not_a_medical_practice).
Errors specific to this call
409not_a_medical_practiceAll responses
200Successful Response401Unauthorized403Forbidden404Not Found409Conflict422Unprocessable Entity429Too Many Requests503Service UnavailableCodes every call can return are in Errors & limits.
curl -s "https://norvya.fly.dev/v1/population/summary" \
-H "Authorization: Bearer $TOKEN"import os
import requests
BASE = "https://norvya.fly.dev"
TOKEN = os.environ["TOKEN"]
resp = requests.get(
BASE + "/v1/population/summary",
headers={"Authorization": f"Bearer {TOKEN}"},
timeout=30,
)
resp.raise_for_status()
print(resp.json())// Node.js 18+ (ES module). Keep production credentials on your server.
const BASE = "https://norvya.fly.dev";
const url = new URL(`${BASE}/v1/population/summary`);
const res = await fetch(url, {
method: "GET",
headers: {
Authorization: `Bearer ${process.env.TOKEN}`,
},
});
if (!res.ok) throw new Error(`${res.status} ${await res.text()}`);
console.log(await res.json());{
"generated_at": "string",
"min_cell": 5,
"suppression": "string",
"panel": {
"active_members": {
"count": 42,
"suppressed": false
},
"adults": {
"count": 42,
"suppressed": false
},
"children": {
"count": 42,
"suppressed": false
}
},
"worklist": {
"run": {
"id": 311,
"status": "completed",
"started_at": "2026-10-16T05:00:02Z",
"finished_at": "2026-10-16T05:03:40Z"
},
"cohort": {
"count": 42,
"suppressed": false
},
"by_priority": {},
"rising_risk": {
"rising": {
"count": 42,
"suppressed": false
},
"not_rising": {
"count": 42,
"suppressed": false
},
"compared_with_run": {
"id": 0,
"finished_at": "string"
},
"definition": "string"
},
"ranking": "string"
},
"care_gaps": {
"period_start": "string",
"period_end": "string",
"certified": false,
"measures": [
{
"measure_id": "cms165_bp_control",
"cms_id": "CMS165v14",
"title": "string",
"inverse": false,
"open_gaps": {},
"by_gap": []
}
],
"definition": "string"
}
}The response is the shape from the schema, not live data.
Try it in your sandbox
Quality measures and Million Hearts ABCS for your panel (not certified)
Five eCQM-style measures (CMS165v14, CMS122v14, CMS2v15, CMS138v14, CMS69v14) and the CDC Million Hearts ABCS, as rates whose numerators and denominators are withheld below min_cell (with complementary suppression). `certified` is always false: this is NOT a certified eCQM calculation (no CQL, no encounters; each measure lists `not_modelled`). The measure identifiers are valid for the 2026 period only (`spec_version_valid`). 422 invalid_period / period_too_long.
Parameters
YYYY-MM-DD (default: 1 January this year).
YYYY-MM-DD (default: 31 December this year); at most 366 days after period_start.
Errors specific to this call
422invalid_periodAll responses
200Successful Response401Unauthorized403Forbidden404Not Found409Conflict422Unprocessable Entity429Too Many Requests503Service UnavailableCodes every call can return are in Errors & limits.
curl -s "https://norvya.fly.dev/v1/population/measures" \
-H "Authorization: Bearer $TOKEN"import os
import requests
BASE = "https://norvya.fly.dev"
TOKEN = os.environ["TOKEN"]
resp = requests.get(
BASE + "/v1/population/measures",
headers={"Authorization": f"Bearer {TOKEN}"},
timeout=30,
)
resp.raise_for_status()
print(resp.json())// Node.js 18+ (ES module). Keep production credentials on your server.
const BASE = "https://norvya.fly.dev";
const url = new URL(`${BASE}/v1/population/measures`);
const res = await fetch(url, {
method: "GET",
headers: {
Authorization: `Bearer ${process.env.TOKEN}`,
},
});
if (!res.ok) throw new Error(`${res.status} ${await res.text()}`);
console.log(await res.json());{
"generated_at": "string",
"period_start": "string",
"period_end": "string",
"min_cell": 0,
"suppression": "string",
"certified": false,
"certification_statement": "string",
"encounter_basis": "active_panel_link",
"spec_source": "string",
"qrda3_available": false,
"measures": [
{
"measure_id": "cms165_bp_control",
"cms_id": "CMS165v14",
"version": "v14",
"version_specific_id": "string",
"mips_quality_id": "236",
"title": "string",
"inverse": false,
"spec_version_valid": false,
"initial_population": {
"count": 42,
"suppressed": false
},
"denominator": {
"count": 42,
"suppressed": false
},
"denominator_exclusions": {
"count": 42,
"suppressed": false
},
"denominator_exceptions": {
"count": 42,
"suppressed": false
},
"numerator": {
"count": 42,
"suppressed": false
},
"performance_denominator": {
"count": 42,
"suppressed": false
},
"performance_rate": 0.0,
"suppressed": false,
"source_tiers": {},
"age_unknown": {
"count": 42,
"suppressed": false
},
"populations": [
{}
],
"not_modelled": [
"string"
]
}
],
"million_hearts": {}
}The response is the shape from the schema, not live data.
Try it in your sandbox
QRDA Category III file for the 2026 period (true counts, not submission-validated)
The QRDA III document from Norvya's quality-measures engine: TRUE counts (a submission with suppressed counts would be invalid), labelled NOT SUBMISSION-VALIDATED, with no CMS EHR Certification ID (Norvya is not ONC-certified). X-Norvya-Validation-Gaps lists what keeps it from validating. 2026 performance period only (422 measure_version_unavailable). Every download is a chained PHI_EXPORT audit row and is refused (503) when the audit log is down.
Parameters
YYYY-MM-DD, within 2026.
YYYY-MM-DD, within 2026.
MIPS_GROUP | MIPS_INDIV
9-digit TIN (default: the practice's).
10-digit NPI (MIPS_INDIV).
All responses
200QRDA Category III XML (NOT SUBMISSION-VALIDATED).401Unauthorized403Forbidden404Not Found409Conflict422Unprocessable Entity429Too Many Requests503Service UnavailableCodes every call can return are in Errors & limits.
curl -s "https://norvya.fly.dev/v1/population/measures/qrda3" \
-H "Authorization: Bearer $TOKEN"import os
import requests
BASE = "https://norvya.fly.dev"
TOKEN = os.environ["TOKEN"]
resp = requests.get(
BASE + "/v1/population/measures/qrda3",
headers={"Authorization": f"Bearer {TOKEN}"},
timeout=30,
)
resp.raise_for_status()
print(resp.json())// Node.js 18+ (ES module). Keep production credentials on your server.
const BASE = "https://norvya.fly.dev";
const url = new URL(`${BASE}/v1/population/measures/qrda3`);
const res = await fetch(url, {
method: "GET",
headers: {
Authorization: `Bearer ${process.env.TOKEN}`,
},
});
if (!res.ok) throw new Error(`${res.status} ${await res.text()}`);
console.log(await res.json());Try it in your sandbox
Start an asynchronous FHIR Bulk Data export of your panel
Queues an export of every active patient of your practice as one NDJSON file per FHIR resource type (US Core-shaped, the same builders as Norvya's provider $export). deidentify=none: identified, each patient scoped by their sharing choices with your practice (and your own records under practice-of-record with a BAA), exactly as the provider export. deidentify=safe_harbor: HIPAA Safe Harbor (random per-export patient ids that do not link across exports, dates reduced to the year, birth year omitted at 90+, three-digit ZIP, free text removed, record numbers removed, DocumentReference left out), refused if any direct identifier survives. Poll the status_url or subscribe to population.export_completed. One export at a time per client (409 export_in_progress). Files expire after 24 hours. An identified export needs a BAA on file for your practice (409 population_export_baa_required); Safe Harbor does not. Kick-off, completion and every file download are chained PHI_EXPORT audit rows (503 when the audit log is down).
Request body
Content type: application/json
Errors specific to this call
409export_in_progress409population_export_baa_required503whenAll responses
202Successful Response401Unauthorized403Forbidden404Not Found409Conflict422Unprocessable Entity429Too Many Requests503Service UnavailableCodes every call can return are in Errors & limits.
curl -s -X POST "https://norvya.fly.dev/v1/population/exports" \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{
"types": [
"string"
],
"since": "string",
"deidentify": "none"
}'import os
import requests
BASE = "https://norvya.fly.dev"
TOKEN = os.environ["TOKEN"]
resp = requests.post(
BASE + "/v1/population/exports",
headers={"Authorization": f"Bearer {TOKEN}"},
json={
"types": [
"string",
],
"since": "string",
"deidentify": "none",
},
timeout=30,
)
resp.raise_for_status()
print(resp.json())// Node.js 18+ (ES module). Keep production credentials on your server.
const BASE = "https://norvya.fly.dev";
const url = new URL(`${BASE}/v1/population/exports`);
const res = await fetch(url, {
method: "POST",
headers: {
Authorization: `Bearer ${process.env.TOKEN}`,
"Content-Type": "application/json",
},
body: JSON.stringify({
"types": [
"string"
],
"since": "string",
"deidentify": "none"
}),
});
if (!res.ok) throw new Error(`${res.status} ${await res.text()}`);
console.log(await res.json());{
"export_id": "9f1c2b7e4a5d4c3b8e7f6a5b4c3d2e1f",
"status": "accepted",
"status_url": "/v1/population/exports/9f1c2b7e4a5d4c3b8e7f6a5b4c3d2e1f"
}The response is the shape from the schema, not live data.
Try it in your sandbox
Status and manifest of one export
200 with `status` while it runs and once it ends; the manifest (FHIR Bulk Data shape: output[{type, url, count}], requiresAccessToken, transactionTime, plus `deidentified`) once completed. 404 export_not_found for an export another client or organisation started; 410 export_expired / export_deleted.
Parameters
Errors specific to this call
200with410export_expiredAll responses
200Successful Response401Unauthorized403Forbidden404Not Found409Conflict410Gone422Unprocessable Entity429Too Many Requests503Service UnavailableCodes every call can return are in Errors & limits.
curl -s "https://norvya.fly.dev/v1/population/exports/$EXPORT_ID" \
-H "Authorization: Bearer $TOKEN"import os
import requests
BASE = "https://norvya.fly.dev"
TOKEN = os.environ["TOKEN"]
export_id = os.environ["EXPORT_ID"]
resp = requests.get(
f"{BASE}/v1/population/exports/{export_id}",
headers={"Authorization": f"Bearer {TOKEN}"},
timeout=30,
)
resp.raise_for_status()
print(resp.json())// Node.js 18+ (ES module). Keep production credentials on your server.
const BASE = "https://norvya.fly.dev";
const export_id = process.env.EXPORT_ID;
const url = new URL(`${BASE}/v1/population/exports/${encodeURIComponent(export_id)}`);
const res = await fetch(url, {
method: "GET",
headers: {
Authorization: `Bearer ${process.env.TOKEN}`,
},
});
if (!res.ok) throw new Error(`${res.status} ${await res.text()}`);
console.log(await res.json());{
"export_id": "string",
"status": "string",
"progress": "string",
"deidentify": "string",
"created_at": "string",
"expires_at": "string",
"error": "string",
"manifest": {
"transactionTime": "string",
"request": "string",
"requiresAccessToken": false,
"output": [
{
"type": "Observation",
"url": "string",
"count": 0
}
],
"error": [
null
],
"deidentified": false
}
}The response is the shape from the schema, not live data.
Try it in your sandbox
Cancel or delete an export
Cancels a running export or deletes a finished one's files. Idempotent (204 again for an export already deleted or expired).
Parameters
Errors specific to this call
204againAll responses
204Successful Response401Unauthorized403Forbidden404Not Found409Conflict422Unprocessable Entity429Too Many Requests503Service UnavailableCodes every call can return are in Errors & limits.
curl -s -X DELETE "https://norvya.fly.dev/v1/population/exports/$EXPORT_ID" \
-H "Authorization: Bearer $TOKEN"import os
import requests
BASE = "https://norvya.fly.dev"
TOKEN = os.environ["TOKEN"]
export_id = os.environ["EXPORT_ID"]
resp = requests.delete(
f"{BASE}/v1/population/exports/{export_id}",
headers={"Authorization": f"Bearer {TOKEN}"},
timeout=30,
)
resp.raise_for_status()
print(resp.status_code)// Node.js 18+ (ES module). Keep production credentials on your server.
const BASE = "https://norvya.fly.dev";
const export_id = process.env.EXPORT_ID;
const url = new URL(`${BASE}/v1/population/exports/${encodeURIComponent(export_id)}`);
const res = await fetch(url, {
method: "DELETE",
headers: {
Authorization: `Bearer ${process.env.TOKEN}`,
},
});
if (!res.ok) throw new Error(`${res.status} ${await res.text()}`);
console.log(res.status);No response body.The response is the shape from the schema, not live data.
Try it in your sandbox
Download one NDJSON file of a completed export
application/fhir+ndjson, one resource per line. Every download is a chained PHI_EXPORT audit row, written BEFORE the file is returned and refused (503) when the audit log is down. 409 export_not_ready while it runs; 404 export_file_not_found; 410 once expired or deleted.
Parameters
Errors specific to this call
409export_not_ready404export_file_not_found410onceAll responses
200One NDJSON file.401Unauthorized403Forbidden404Not Found409Conflict410Gone422Unprocessable Entity429Too Many Requests503Service UnavailableCodes every call can return are in Errors & limits.
curl -s "https://norvya.fly.dev/v1/population/exports/$EXPORT_ID/files/$NAME" \
-H "Authorization: Bearer $TOKEN"import os
import requests
BASE = "https://norvya.fly.dev"
TOKEN = os.environ["TOKEN"]
export_id = os.environ["EXPORT_ID"]
name = os.environ["NAME"]
resp = requests.get(
f"{BASE}/v1/population/exports/{export_id}/files/{name}",
headers={"Authorization": f"Bearer {TOKEN}"},
timeout=30,
)
resp.raise_for_status()
print(resp.json())// Node.js 18+ (ES module). Keep production credentials on your server.
const BASE = "https://norvya.fly.dev";
const export_id = process.env.EXPORT_ID;
const name = process.env.NAME;
const url = new URL(`${BASE}/v1/population/exports/${encodeURIComponent(export_id)}/files/${encodeURIComponent(name)}`);
const res = await fetch(url, {
method: "GET",
headers: {
Authorization: `Bearer ${process.env.TOKEN}`,
},
});
if (!res.ok) throw new Error(`${res.status} ${await res.text()}`);
console.log(await res.json());Try it in your sandbox
Social needs prevalence and closed-loop rates for your panel, small cells suppressed
Screening rate, any unmet need, each domain's positive rate (housing, food, transportation, utilities), your referrals by status with the closed and needs-met rates, and members with a need you have not referred. Counts as cells, primary + complementary suppression; members who do not share their medical history are counted, never examined.
Parameters
YYYY-MM-DD (default: 365 days before end).
YYYY-MM-DD (default: today).
All responses
200Successful Response401Unauthorized403Forbidden404Not Found409Conflict422Unprocessable Entity429Too Many Requests503Service UnavailableCodes every call can return are in Errors & limits.
curl -s "https://norvya.fly.dev/v1/population/social-needs" \
-H "Authorization: Bearer $TOKEN"import os
import requests
BASE = "https://norvya.fly.dev"
TOKEN = os.environ["TOKEN"]
resp = requests.get(
BASE + "/v1/population/social-needs",
headers={"Authorization": f"Bearer {TOKEN}"},
timeout=30,
)
resp.raise_for_status()
print(resp.json())// Node.js 18+ (ES module). Keep production credentials on your server.
const BASE = "https://norvya.fly.dev";
const url = new URL(`${BASE}/v1/population/social-needs`);
const res = await fetch(url, {
method: "GET",
headers: {
Authorization: `Bearer ${process.env.TOKEN}`,
},
});
if (!res.ok) throw new Error(`${res.status} ${await res.text()}`);
console.log(await res.json());Try it in your sandbox
HRSA UDS tables Norvya can contribute to (UDS-aligned, not validated), small cells suppressed
Tables 3A, 3B, 4, 6A and the 6B / 7 measures Norvya computes, with completeness and what is out of scope, from uds_reporting. Labelled "UDS-aligned, not validated in the EHBs/UDS+ test environment". PRIMARY small-cell suppression only (the staff screen's rule; `suppression` says why); true counts only through /population/uds/export.
Parameters
Calendar year (default: last year).
All responses
200Successful Response401Unauthorized403Forbidden404Not Found409Conflict422Unprocessable Entity429Too Many Requests503Service UnavailableCodes every call can return are in Errors & limits.
curl -s "https://norvya.fly.dev/v1/population/uds" \
-H "Authorization: Bearer $TOKEN"import os
import requests
BASE = "https://norvya.fly.dev"
TOKEN = os.environ["TOKEN"]
resp = requests.get(
BASE + "/v1/population/uds",
headers={"Authorization": f"Bearer {TOKEN}"},
timeout=30,
)
resp.raise_for_status()
print(resp.json())// Node.js 18+ (ES module). Keep production credentials on your server.
const BASE = "https://norvya.fly.dev";
const url = new URL(`${BASE}/v1/population/uds`);
const res = await fetch(url, {
method: "GET",
headers: {
Authorization: `Bearer ${process.env.TOKEN}`,
},
});
if (!res.ok) throw new Error(`${res.status} ${await res.text()}`);
console.log(await res.json());Try it in your sandbox
UDS tables with true counts (health centres; audited, fails closed)
The staff export: TRUE counts (a UDS submission cannot carry suppressed cells). 409 uds_not_health_center unless your UDS settings declare a health centre. A chained PHI_EXPORT row first; 503 when the audit log is down.
Parameters
json | csv
Errors specific to this call
409uds_not_health_center503whenAll responses
200UDS tables, TRUE counts (UDS-aligned, not validated).401Unauthorized403Forbidden404Not Found409Conflict422Unprocessable Entity429Too Many Requests503Service UnavailableCodes every call can return are in Errors & limits.
curl -s "https://norvya.fly.dev/v1/population/uds/export" \
-H "Authorization: Bearer $TOKEN"import os
import requests
BASE = "https://norvya.fly.dev"
TOKEN = os.environ["TOKEN"]
resp = requests.get(
BASE + "/v1/population/uds/export",
headers={"Authorization": f"Bearer {TOKEN}"},
timeout=30,
)
resp.raise_for_status()
print(resp.json())// Node.js 18+ (ES module). Keep production credentials on your server.
const BASE = "https://norvya.fly.dev";
const url = new URL(`${BASE}/v1/population/uds/export`);
const res = await fetch(url, {
method: "GET",
headers: {
Authorization: `Bearer ${process.env.TOKEN}`,
},
});
if (!res.ok) throw new Error(`${res.status} ${await res.text()}`);
console.log(await res.json());Try it in your sandbox
UDS+ patient-level FHIR export (health centres; audited, fails closed)
fhir_bulk.uds_plus_export (the one FHIR builder): one Patient per UDS patient under a per-clinic token, the patient's clinical resources within their sharing choices, 42 CFR Part 2 resources always withheld, the identifier scan before release. Shaped to HRSA UDS+ FHIR IG 2.0.0 but NOT validated in HRSA's UDS+ test receiver (`profile_claimed` false). A chained PHI_EXPORT row first; 503 when the audit log is down; 500 export_identifier_detected if a direct identifier is found.
Parameters
none (tokenised UDS+ shape: pseudonymous patient ids, coded demographics) | safe_harbor (additionally HIPAA Safe Harbor)
Errors specific to this call
503whenAll responses
200UDS+ shaped FHIR NDJSON files + manifest (zip).401Unauthorized403Forbidden404Not Found409Conflict422Unprocessable Entity429Too Many Requests503Service UnavailableCodes every call can return are in Errors & limits.
curl -s "https://norvya.fly.dev/v1/population/uds-plus" \
-H "Authorization: Bearer $TOKEN"import os
import requests
BASE = "https://norvya.fly.dev"
TOKEN = os.environ["TOKEN"]
resp = requests.get(
BASE + "/v1/population/uds-plus",
headers={"Authorization": f"Bearer {TOKEN}"},
timeout=30,
)
resp.raise_for_status()
print(resp.json())// Node.js 18+ (ES module). Keep production credentials on your server.
const BASE = "https://norvya.fly.dev";
const url = new URL(`${BASE}/v1/population/uds-plus`);
const res = await fetch(url, {
method: "GET",
headers: {
Authorization: `Bearer ${process.env.TOKEN}`,
},
});
if (!res.ok) throw new Error(`${res.status} ${await res.text()}`);
console.log(await res.json());Try it in your sandbox
EPSDT components due now for the children of your panel (not a CMS-416), suppressed
Children your practice holds (guardian-linked child profiles), how many share their record with you, and per EPSDT component how many have it due now on Norvya's schedule (epsdt.py). NOT a CMS-416: no eligibility months, no claims. Vision, hearing and oral health carry periodicity_asserted false (Norvya does not assert those ages).
All responses
200Successful Response401Unauthorized403Forbidden404Not Found409Conflict422Unprocessable Entity429Too Many Requests503Service UnavailableCodes every call can return are in Errors & limits.
curl -s "https://norvya.fly.dev/v1/population/epsdt" \
-H "Authorization: Bearer $TOKEN"import os
import requests
BASE = "https://norvya.fly.dev"
TOKEN = os.environ["TOKEN"]
resp = requests.get(
BASE + "/v1/population/epsdt",
headers={"Authorization": f"Bearer {TOKEN}"},
timeout=30,
)
resp.raise_for_status()
print(resp.json())// Node.js 18+ (ES module). Keep production credentials on your server.
const BASE = "https://norvya.fly.dev";
const url = new URL(`${BASE}/v1/population/epsdt`);
const res = await fetch(url, {
method: "GET",
headers: {
Authorization: `Bearer ${process.env.TOKEN}`,
},
});
if (!res.ok) throw new Error(`${res.status} ${await res.text()}`);
console.log(await res.json());Try it in your sandbox
HEDIS measures for NCQA licensees only (409 hedis_not_licensed otherwise)
No HEDIS specification logic is in Norvya (NCQA requires a licence for every use). A deployment that holds an NCQA licence (HEDIS_LICENSED) and uploaded its own measure definitions gets each one computed by the Norvya computation it binds to, as suppressed cells; otherwise 409 hedis_not_licensed (or hedis_no_definitions). Never certified.
Parameters
All responses
200Successful Response401Unauthorized403Forbidden404Not Found409Conflict422Unprocessable Entity429Too Many Requests503Service UnavailableCodes every call can return are in Errors & limits.
curl -s "https://norvya.fly.dev/v1/population/hedis" \
-H "Authorization: Bearer $TOKEN"import os
import requests
BASE = "https://norvya.fly.dev"
TOKEN = os.environ["TOKEN"]
resp = requests.get(
BASE + "/v1/population/hedis",
headers={"Authorization": f"Bearer {TOKEN}"},
timeout=30,
)
resp.raise_for_status()
print(resp.json())// Node.js 18+ (ES module). Keep production credentials on your server.
const BASE = "https://norvya.fly.dev";
const url = new URL(`${BASE}/v1/population/hedis`);
const res = await fetch(url, {
method: "GET",
headers: {
Authorization: `Bearer ${process.env.TOKEN}`,
},
});
if (!res.ok) throw new Error(`${res.status} ${await res.text()}`);
console.log(await res.json());Try it in your sandbox
Webhook events
Payloads carry no health data, only a reference to fetch with your token. Each event needs its scope as well as webhooks.manage. Signing and retries
| Event | Scope | When |
|---|---|---|
population.export_completed | population.export | A FHIR Bulk export you started finished (sent to that client only). |
Generated from the Partner API router and developers_catalog.py. The router docstring is the source of each description.