---
title: "Raf Delta"
method: POST
path: "/api/v1/risk-scores/delta"
tags: ["risk-scores"]
---

# Raf Delta

`POST /api/v1/risk-scores/delta`

## Request

- Base URL: `https://api.accurecord.io` (the document declares no server; this is the origin it was published from)
- URL: `https://api.accurecord.io/api/v1/risk-scores/delta`
- Auth: none declared

Score the baseline and the scenario, then explain the difference.

## Headers

- `x-api-key` string, nullable

## Request body

- RafDeltaRequest
  - `baseline_codes` string[]: Codes already accepted for the member
  - `scenario_codes` string[], required: Baseline plus the candidate(s) under consideration
  - `model_family` string
  - `model_version` string
  - `payment_year` integer
  - `segment` string: Scoring segment, e.g. COMMUNITY_NA
  - `demographics` Demographics: ⚠ EVERY FIELD IS OPTIONAL HERE AND REQUIRED BY THE SCORER, NOT BY THIS MODEL. Which ones a request must carry is a property of the model family, so it is read from ``scorer.required_demographics()`` rather than fixed here. The five Medicare fields used to be hardcoded, and a request for a family that has no OREC — every HHS-HCC request — was rejected for missing one before ``get_scorer`` was ever consulted. What is NOT negotiable is that nothing is defaulted. The RA pipeline used to substitute ``dob=1950-01-01, sex=2, orec=0``, which scored a member with no date of birth as a 76-year-old female and reported success.
    - `dob` string, date, nullable: Date of birth. No default — see the module docs.
    - `sex` integer, nullable: 1 = male, 2 = female (CMS coding)
    - `orec` integer, nullable: Original reason for entitlement
    - `ltimcaid` integer, nullable: Medicaid dummy, long-term inst.
    - `nemcaid` integer, nullable: Medicaid dummy, new enrollee
    - `age_last` integer, nullable: HHS-HCC: age on the last day of enrolment in the benefit year. Selects the Adult / Child / Infant model. Never derived from dob.
    - `metal` string, nullable: HHS-HCC: plan metal level (P/G/S/B/C, or the full name). Selects which of the five scored columns is the member's own score; all five are returned regardless.
    - `csr_indicator` integer, nullable: HHS-HCC: person-level cost-sharing-reduction indicator. Absent means no CSR-adjusted score is reported — it is never defaulted to 1.
    - `enrolduration` integer, nullable: HHS-HCC adult model: months enrolled in the benefit year.
  - `demographics_override_reason` string, nullable
  - `service_date` string, date, nullable: Date of service. If given, the loaded pack's ICD fiscal-year mapping must cover it; otherwise 422 blocked_mapping_window_pending (never a number from the wrong year).
  - `ndc_codes` string[], nullable: HHS-HCC: dispensed National Drug Codes. Omit if unknown (the score then reports which factors it could not evaluate); send [] to assert there were none.
  - `hcpcs_codes` string[], nullable: HHS-HCC: administered HCPCS codes. Omit if unknown; send [] to assert none.

## Response `200`

Successful Response

- object

## Other responses

- `400`: Malformed or out-of-bounds request — a batch over 50 codes, a file over the upload limit, an unparseable identifier, or a surface that is switched off in this environment (the `cpt_*_disabled` gates are 400, not 403). ⚠ Not interchangeable with 422: 400 is raised BY the handler, 422 by request validation.
- `401`: Missing, malformed, revoked or expired credential. Send the key as `X-API-Key` or `Authorization: Bearer`. `detail` is a string, except the MFA challenge on `/auth/login`, which is `{code: 'mfa_required', message}`.
- `403`: Authenticated but not permitted: the tier does not include the feature, the role is insufficient, or the free tier is paused. Gate-specific bodies use the `{code, message}` shape (`tier_required`, `insufficient_role`). ⚠ The free-tier pause is the ONE error in the service that does not use `detail` at all — its body is `{error: 'free_tier_paused', message}` at the top level. ⚠ Preconditions the caller CAN satisfy (no org, no BAA, PHI mode off) are 412, not 403 — see below.
- `404`: Resource, code, or org-scoped record not found. Note that a record belonging to ANOTHER organization is also a 404, never a 403 — existence is not disclosed across tenants.
- `412`: A precondition on the calling principal is unmet and the caller can fix it: no organization linked to the key (`org_required`), no signed BAA (`baa_required`), PHI mode not activated (`phi_not_activated`), reviewer mode off (`review_mode_disabled`), or the session was never second-factored (`mfa_required`). All use the `{code, message}` shape.
- `422`: Request body or query failed validation. FastAPI's own failures are a LIST of `{loc, msg, type}`; semantic refusals raised by the service are an object (the risk-adjustment endpoints use `{status, ...}`).
- `429`: Rate limit, quota or concurrency cap exceeded. The tier limiter, the per-key chart-review job cap, the anonymous demo cap and the auth/signup limiters all land here; only the tier limiter sets the `X-RateLimit-*` headers.
- `500`: Unhandled server error. The body is `{detail: 'Internal server error', request_id: <id>}` and the same id is on the `X-Request-ID` response header.
- `503`: A dependency this request needed is unavailable — the database, an upstream model provider, or reference data that is present but not READY. Retry is reasonable, except for the risk-adjustment `blocked_pack_not_ready` refusals, which stay 503 until the coefficient pack is actually loaded.

---

[API](https://skmtc.dev/accurecord/apis/icd-10-coding-api.md) · [All operations](https://skmtc.dev/accurecord/apis/icd-10-coding-api/llms.txt) · [OpenAPI document](https://skmtc.dev/accurecord/apis/icd-10-coding-api/revisions/b1e12ce06ba5?raw)
