The DRG Grouper API provides programmatic access to Medicare Severity-Diagnosis Related Group (MS-DRG) calculation based on patient demographics and ICD-10 codes.
Our API accepts patient information including diagnoses, procedures, age, sex, and discharge status, then returns the calculated MS-DRG along with validation results and Hospital-Acquired Condition (HAC) logic.
Base URL: https://api.revenuecycle.works/api/drg
Skip the docs. Copy a prompt with everything your agent needs to start grouping DRGs for you.
## DRG Grouper API Reference
POST https://api.revenuecycle.works/api/drg/group
Content-Type: application/json
X-API-Key: (optional — omit for 10 req/min free tier)
### Grouper version selection
Match the version to the patient's discharge date fiscal year:
"431" — FY2026 mid-year (Apr 1 2026+), 80 new PCS codes
"430" — FY2026 (Oct 1 2025 – Mar 31 2026)
"421" — FY2025 mid-year | "420" — FY2025
"411" — FY2024 mid-year | "410" — FY2024
"401" — FY2023 mid-year | "400" — FY2023
Use "431" if unsure or for prospective analysis.
x.1 versions add new codes mid-year but share DRG definitions/weights with x.0.
### Request body (JSON)
{
"grouperVersion": "431", // required — see version table above
"principalDiagnosis": { // required
"code": "I213", // ICD-10-CM, no periods
"poa": "Y" // see POA values below
},
"admissionDiagnosis": "I213", // optional — plain ICD-10-CM string
"secondaryDiagnoses": [ // optional — same shape as principalDiagnosis
{"code": "J9601", "poa": "Y"}
],
"procedures": ["0271356"], // optional — ICD-10-PCS strings (always 7 chars)
"ageInYears": 68, // required — integer 0-120
"sex": "MALE", // required — "MALE"|"FEMALE"|"UNKNOWN"
"dischargeStatus": "HOME_SELFCARE_ROUTINE" // required — see values below
}
### POA (Present on Admission) indicators
"Y" = present on admission "N" = not present on admission
"W" = clinically undetermined "U" = documentation insufficient
"ONE" = unreported/exempt "BLANK" = exempt (default if omitted)
POA affects HAC logic — use "BLANK" when POA is not applicable.
### Common dischargeStatus values (UB-04 code → enum)
01 → "HOME_SELFCARE_ROUTINE" 02 → "SHORT_TERM_HOSPITAL"
03 → "SNF" 06 → "HOME_HEALTH_SERVICE"
07 → "LEFT_AGAINST_MEDICAL_ADVICE" 20 → "DIED"
50 → "HOSPICE_HOME" 62 → "REHAB_FACILITY_REHAB_UNIT"
63 → "LONG_TERM_CARE_HOSPITAL" 65 → "PSYCH_HOSP_UNIT"
Planned-readmission variants: append _W_PLANNED_READMISSION (e.g., 81 → "HOME_SELF_CARE_W_PLANNED_READMISSION").
Full list: 01-07, 20-21, 30, 43, 50-51, 61-66, 69-70, 81-95.
### Response (200 OK)
{
"finalDrg": "359", // MS-DRG code (3-digit string)
"finalBaseDrg": "359", // base DRG before severity split
"finalMdc": "5", // Major Diagnostic Category (0-25)
"finalSeverity": "MCC", // "MCC"|"CC"|"No CC/MCC"
"finalMedSurgType": "SURGICAL", // "MEDICAL"|"SURGICAL"
"finalGrouperReturnCode": "OK", // see error codes below
"initialDrg": "359", // initial* fields = before HAC/transfer logic
"diagnosisValidation": {...}, // code → bool (false = invalid)
"diagnosisSeverityFlags": {...}, // code → "MCC"|"CC"|"NEITHER"
"diagnosisAffectsDrg": {...}, // code → bool (did this code influence DRG?)
"procedureValidation": {...}, // code → bool
"procedureAffectsDrg": {...}, // code → bool
"procedureIsOperatingRoom": {...}, // code → bool
"hacStatus": "NOT_APPLICABLE", // HAC impact on payment
"numHacCategoriesSatisfied": 0
}
### Error handling
finalGrouperReturnCode values:
"OK" — successful grouping
"INVALID_PDX" — principal diagnosis code not recognized
"DX_CANNOT_BE_PDX" — code cannot be principal (e.g., manifestation code)
"INVALID_SEX" — sex conflicts with a diagnosis or procedure
"INVALID_DISCHARGE_STATUS" — unrecognized discharge status
HAC_* codes — Hospital-Acquired Condition POA issues
On HTTP error (non-200), the response body contains an error message string.
### Quick-start workflow
1. Pick grouperVersion by discharge date fiscal year
2. Strip periods from ICD-10 codes (I25.10 → I2510)
3. POST payload → check finalGrouperReturnCode for "OK"
4. Read finalDrg + finalMdc for the assignment
5. Use diagnosisAffectsDrg / procedureAffectsDrg to see which codes drove the result
API authentication is optional but recommended. Include your API key in the request header:
X-API-Key: your_api_key_here
💡 Try before you buy! Test the API without a key (10 requests/min limit) before requesting API access.
Without API key: 10 requests per minute
With API key: Custom rate limits based on your needs - contact us to discuss.
curl https://api.revenuecycle.works/api/drg/group \
-H "X-API-Key: your_api_key_here" \
-H "Content-Type: application/json"
The primary endpoint for calculating MS-DRG assignments. Submit patient demographics, diagnoses, and procedures to receive the appropriate DRG classification, severity level, and detailed validation results.
POST https://api.revenuecycle.works/api/drg/group
Content-Type: application/json
This endpoint processes inpatient hospital claims and returns:
| Parameter | Description |
|---|---|
| X-API-Key optional | Your API key for authentication (omit for testing with 10 req/min limit) |
| Content-Type | application/json |
| Parameter | Description |
|---|---|
|
grouperVersion
required
string
|
MS-DRG version: "400", "401", "410", "411", "420", "421", "430", or "431" (latest, FY2026)See effective dates in Enum Reference → |
|
principalDiagnosis
required
object
|
Primary diagnosis object with two properties: • code - ICD-10-CM code without periods (e.g., "I2510" not "I25.10")• poa - Present on Admission indicator
|
|
ageInYears
required
integer
|
Patient age in years (0-120) |
|
sex
required
string
|
Sex enum value: "MALE", "FEMALE", or "UNKNOWN" |
|
dischargeStatus
required
string
|
Discharge status enum value. Common values: "HOME_SELFCARE_ROUTINE", "SNF", "HOME_HEALTH_SERVICE", "DIED", "HOSPICE_HOME"See all 43 codes in Enum Reference below |
|
admissionDiagnosis
optional
string
|
Admission diagnosis ICD-10-CM code without periods (e.g., "C022"). Unlike principalDiagnosis, this is just a string, not an object. |
|
secondaryDiagnoses
optional
array
|
Array of diagnosis objects, each with: • code - ICD-10-CM code without periods (e.g., "I2510" not "I25.10")• poa - Present on Admission indicator
|
|
procedures
optional
array
|
Array of ICD-10-PCS procedure code strings (7 characters) (e.g., "0CYS0Z0") |
| Version | Effective Dates | API Value |
|---|---|---|
| V40.0 | 10/01/2022 - 03/31/2023 | "400" |
| V40.1 | 04/01/2023 - 09/30/2023 | "401" |
| V41.0 | 10/01/2023 - 03/31/2024 | "410" |
| V41.1 | 04/01/2024 - 09/30/2024 | "411" |
| V42.0 | 10/01/2024 - 03/31/2025 | "420" |
| V42.1 | 04/01/2025 - 09/30/2025 | "421" |
| V43.0 | 10/01/2025 - 03/31/2026 | "430" |
| V43.1 | 04/01/2026 - 09/30/2026 | "431" ← latest |
| Code | API Enum Value | Description |
|---|---|---|
| Y | "Y" |
Yes, condition was present at admission |
| N | "N" |
No, condition was not present at admission |
| U | "U" |
Unknown/documentation insufficient |
| W | "W" |
Clinically undetermined |
| 1 | "ONE" |
Exempt from POA reporting |
| empty string "" | "BLANK" |
Exempt from POA reporting (omitted/not provided) |
| API Enum Value | Description |
|---|---|
"MALE" |
Male patient |
"FEMALE" |
Female patient |
"UNKNOWN" |
Unknown or unspecified sex |
| Code | API Enum Value |
|---|---|
| 01 | "HOME_SELFCARE_ROUTINE" |
| 02 | "SHORT_TERM_HOSPITAL" |
| 03 | "SNF" |
| 04 | "CUST_SUPP_CARE" |
| 05 | "CANC_CHILD_HOSP" |
| 06 | "HOME_HEALTH_SERVICE" |
| 07 | "LEFT_AGAINST_MEDICAL_ADVICE" |
| 20 | "DIED" |
| 21 | "COURT_LAW_ENFRC" |
| 30 | "STILL_A_PATIENT" |
| 43 | "FEDERAL_HOSPITAL" |
| 50 | "HOSPICE_HOME" |
| 51 | "HOSPICE_MEDICAL_FACILITY" |
| 61 | "SWING_BED" |
| 62 | "REHAB_FACILITY_REHAB_UNIT" |
| 63 | "LONG_TERM_CARE_HOSPITAL" |
| 64 | "NURSING_FACILITY_MEDICAID_CERTIFIED" |
| 65 | "PSYCH_HOSP_UNIT" |
| 66 | "CRIT_ACC_HOSP" |
| 69 | "DESIGNATED_DISASTER_ALTERNATIVE_CARE_SITE" |
| 70 | "OTH_INSTITUTION" |
| 81 | "HOME_SELF_CARE_W_PLANNED_READMISSION" |
| 82 | "SHORT_TERM_HOSPITAL_W_PLANNED_READMISSION" |
| 83 | "SNF_W_PLANNED_READMISSION" |
| 84 | "CUST_SUPP_CARE_W_PLANNED_READMISSION" |
| 85 | "CANC_CHILD_HOSP_W_PLANNED_READMISSION" |
| 86 | "HOME_HEALTH_SERVICE_W_PLANNED_READMISSION" |
| 87 | "COURT_LAW_ENFRC_W_PLANNED_READMISSION" |
| 88 | "FEDERAL_HOSPITAL_W_PLANNED_READMISSION" |
| 89 | "SWING_BED_W_PLANNED_READMISSION" |
| 90 | "REHAB_FACILITY_UNIT_W_PLANNED_READMISSION" |
| 91 | "LTCH_W_PLANNED_READMISSION" |
| 92 | "NURSG_FAC_MEDICAID_CERT_W_PLANNED_READMISSION" |
| 93 | "PSYCH_HOSP_UNIT_W_PLANNED_READMISSION" |
| 94 | "CRIT_ACC_HOSP_W_PLANNED_READMISSION" |
| 95 | "OTH_INSTITUTION_W_PLANNED_READMISSION" |
⚠️ Code Formatting: All ICD-10 codes must be submitted without periods. For example, use "I2510" instead of "I25.10".
curl -X POST https://api.revenuecycle.works/api/drg/group \
-H "X-API-Key: your_api_key_here" \
-H "Content-Type: application/json" \
-d '{
"grouperVersion": "431",
"admissionDiagnosis": "I213",
"principalDiagnosis": {
"code": "I213",
"poa": "Y"
},
"secondaryDiagnoses": [
{"code": "J9601", "poa": "Y"},
{"code": "I5021", "poa": "Y"},
{"code": "J9811", "poa": "Y"},
{"code": "I255", "poa": "Y"},
{"code": "F17210", "poa": "Y"},
{"code": "I959", "poa": "Y"},
{"code": "R739", "poa": "Y"}
],
"procedures": ["0271356", "02C03Z6", "B2151ZZ", "B2111ZZ", "4A023N7", "3E073PZ"],
"ageInYears": 68,
"sex": "MALE",
"dischargeStatus": "HOME_SELFCARE_ROUTINE"
}'
Returns a JSON object with the calculated DRG and validation information.
💡 Severity Levels: MCC (Major Complication/Comorbidity), CC (Complication/Comorbidity), and No CC/MCC represent the severity of secondary diagnoses that can affect DRG assignment and reimbursement rates.
| Field | Description |
|---|---|
| Final Results | |
| finalDrg | Final assigned MS-DRG code |
| finalBaseDrg | Base DRG before severity split |
| finalMdc | Major Diagnostic Category |
| finalSeverity | Severity level: "MCC", "CC", or "No CC/MCC" |
| finalDrgSdxSeverity | Highest severity contributed by secondary diagnoses |
| finalMedSurgType | "MEDICAL" or "SURGICAL" |
| finalGrouperReturnCode | Validation status: "OK" or error code |
| Initial Results (before HAC/transfer logic) | |
| initialDrg | DRG before HAC/transfer adjustments |
| initialBaseDrg | Base DRG before HAC/transfer adjustments |
| initialMdc | MDC before HAC/transfer adjustments |
| initialSeverity | Severity before HAC/transfer adjustments |
| initialDrgSdxSeverity | SDX severity before HAC/transfer adjustments |
| initialMedSurgType | "MEDICAL" or "SURGICAL" |
| initialGrouperReturnCode | Return code before HAC/transfer adjustments |
| Diagnosis Details | |
| diagnosisValidation | Map of diagnosis codes to validation boolean. false indicates invalid code. Invalid codes are excluded from DRG calculation. |
| diagnosisSeverityFlags | Severity per diagnosis: "MCC", "CC", or "NEITHER" |
| diagnosisAffectsDrg | Map of diagnosis codes to boolean indicating whether the diagnosis affected the final DRG assignment |
| diagnosisAffectsDrgDetail | Map of diagnosis codes to detailed impact: "NONE", "DRG", "SEVERITY", or "BOTH" |
| diagnosisPoaStatus | Map of diagnosis codes to their POA status as evaluated by the grouper |
| Procedure Details | |
| procedureValidation | Map of procedure codes to validation boolean. false indicates invalid code. Invalid procedures are excluded from DRG calculation. |
| procedureAffectsDrg | Map of procedure codes to boolean indicating whether the procedure affected the final DRG assignment |
| procedureAffectsDrgDetail | Map of procedure codes to detailed impact: "NONE", "DRG", "SEVERITY", or "BOTH" |
| procedureIsOperatingRoom | Map of procedure codes to boolean indicating whether the procedure is classified as an operating room procedure |
| HAC (Hospital-Acquired Conditions) | |
| hacStatus | HAC impact status (e.g., "NOT_APPLICABLE") |
| numHacCategoriesSatisfied | Number of HAC categories triggered |
| diagnosisHacCategories | Map of diagnosis codes to HAC category assignments (empty if no HACs) |
{
"finalDrg": "359",
"finalBaseDrg": "359",
"finalMdc": "5",
"finalSeverity": "MCC",
"finalDrgSdxSeverity": "MCC",
"finalMedSurgType": "SURGICAL",
"initialDrg": "359",
"initialBaseDrg": "359",
"initialMdc": "5",
"initialSeverity": "MCC",
"initialDrgSdxSeverity": "MCC",
"initialMedSurgType": "SURGICAL",
"finalGrouperReturnCode": "OK",
"initialGrouperReturnCode": "OK",
"hacStatus": "NOT_APPLICABLE",
"numHacCategoriesSatisfied": 0,
"diagnosisValidation": {
"J9811": true,
"J9601": true,
"I959": true,
"I255": true,
"I213": true,
"F17210": true,
"R739": true,
"I5021": true
},
"procedureValidation": {
"0271356": true,
"02C03Z6": true,
"B2151ZZ": true,
"B2111ZZ": true,
"4A023N7": true,
"3E073PZ": true
},
"diagnosisSeverityFlags": {
"J9811": "CC",
"J9601": "MCC",
"I959": "NEITHER",
"I255": "NEITHER",
"I213": "NEITHER",
"F17210": "NEITHER",
"R739": "NEITHER",
"I5021": "MCC"
},
"diagnosisAffectsDrg": {
"J9811": false,
"J9601": false,
"I959": false,
"I255": false,
"I213": true,
"F17210": false,
"R739": false,
"I5021": true
},
"diagnosisAffectsDrgDetail": {
"J9811": "NONE",
"J9601": "NONE",
"I959": "NONE",
"I255": "NONE",
"I213": "BOTH",
"F17210": "NONE",
"R739": "NONE",
"I5021": "BOTH"
},
"diagnosisPoaStatus": {
"J9811": "POA_NOT_CHECKED",
"J9601": "POA_NOT_CHECKED",
"I959": "POA_NOT_CHECKED",
"I255": "POA_NOT_CHECKED",
"I213": "POA_NOT_CHECKED",
"F17210": "POA_NOT_CHECKED",
"R739": "POA_NOT_CHECKED",
"I5021": "POA_NOT_CHECKED"
},
"procedureAffectsDrg": {
"0271356": true,
"02C03Z6": true,
"B2151ZZ": false,
"B2111ZZ": false,
"4A023N7": false,
"3E073PZ": false
},
"procedureAffectsDrgDetail": {
"0271356": "BOTH",
"02C03Z6": "BOTH",
"B2151ZZ": "NONE",
"B2111ZZ": "NONE",
"4A023N7": "NONE",
"3E073PZ": "NONE"
},
"procedureIsOperatingRoom": {
"0271356": true,
"02C03Z6": true,
"B2151ZZ": false,
"B2111ZZ": false,
"4A023N7": false,
"3E073PZ": false
},
"diagnosisHacCategories": {}
}
Here's how to make a request in Python and JavaScript:
import requests
response = requests.post(
"https://api.revenuecycle.works/api/drg/group",
headers={
"X-API-Key": "your_api_key_here",
"Content-Type": "application/json"
},
json={
"grouperVersion": "431",
"admissionDiagnosis": "I213",
"principalDiagnosis": {"code": "I213", "poa": "Y"},
"secondaryDiagnoses": [
{"code": "J9601", "poa": "Y"},
{"code": "I5021", "poa": "Y"},
{"code": "J9811", "poa": "Y"},
{"code": "I255", "poa": "Y"},
{"code": "F17210", "poa": "Y"},
{"code": "I959", "poa": "Y"},
{"code": "R739", "poa": "Y"}
],
"procedures": ["0271356", "02C03Z6", "B2151ZZ", "B2111ZZ", "4A023N7", "3E073PZ"],
"ageInYears": 68,
"sex": "MALE",
"dischargeStatus": "HOME_SELFCARE_ROUTINE"
}
)
result = response.json()
print(f"DRG: {result['finalDrg']}")
print(f"MDC: {result['finalMdc']}")
print(f"Severity: {result['finalSeverity']}")
const response = await fetch(
"https://api.revenuecycle.works/api/drg/group",
{
method: "POST",
headers: {
"X-API-Key": "your_api_key_here",
"Content-Type": "application/json"
},
body: JSON.stringify({
grouperVersion: "431",
admissionDiagnosis: "I213",
principalDiagnosis: { code: "I213", poa: "Y" },
secondaryDiagnoses: [
{ code: "J9601", poa: "Y" },
{ code: "I5021", poa: "Y" },
{ code: "J9811", poa: "Y" },
{ code: "I255", poa: "Y" },
{ code: "F17210", poa: "Y" },
{ code: "I959", poa: "Y" },
{ code: "R739", poa: "Y" }
],
procedures: ["0271356", "02C03Z6", "B2151ZZ", "B2111ZZ", "4A023N7", "3E073PZ"],
ageInYears: 68,
sex: "MALE",
dischargeStatus: "HOME_SELFCARE_ROUTINE"
})
}
);
const data = await response.json();
console.log("DRG:", data.finalDrg);
console.log("MDC:", data.finalMdc);
console.log("Severity:", data.finalSeverity);
| 200 | Success - DRG calculated successfully |
| 400 | Bad Request - Invalid input data |
| 401 | Unauthorized - Invalid API key (only when a key is provided) |
| 429 | Too Many Requests - Rate limit exceeded |
| 500 | Server Error - Contact support |
The finalGrouperReturnCode field indicates validation status:
| Return Code | Description |
|---|---|
"OK" |
Success, DRG assigned without errors |
"INVALID_PDX" |
Principal diagnosis code is invalid |
"DX_CANNOT_BE_PDX" |
Code cannot be used as principal diagnosis |
"INVALID_SEX" |
Sex conflicts with diagnosis/procedure |
"HAC_MISSING_ONE_POA" |
HAC condition missing POA indicator |
{
"finalGrouperReturnCode": "INVALID_PDX",
"finalDrg": "999",
"error": "Principal diagnosis code is invalid or cannot be used as primary diagnosis"
}
Questions about integration? Contact our support team or try the free web tool.