Skip to main content
Prior-authorization evidence

CRD, DTR and PAS are one workflow.

Each stage hands the next one its input: a questionnaire canonical the payer chose, a completed response, an authorization number. And when a decision comes back A4, a status code is not the answer — a structured, correlated, retrievable documentation request is.

PAS-01 … PAS-08 Da Vinci CRD / DTR / PAS STU 2.2.x CDex solicited attachment Synthetic data

CMS-0057-F is the federal rule that requires Medicare Advantage, Medicaid, CHIP, and some exchange plans to offer FHIR APIs for patient access, provider access, payer-to-payer exchange, and prior authorization by January 1, 2027.

The chain

CRD, DTR and PAS are one workflow, not three endpoints

The three Da Vinci prior-authorization specifications are usually described separately, which makes them sound like three independent APIs a payer has to stand up. They are not. Each one hands the next its input, and an implementation that cannot pass that input along has built three demos rather than a workflow.

A four-stage chain. CRD answers whether prior authorization is required and names a questionnaire canonical, delivering its determination in the CDS Hooks system action. DTR follows that canonical into the questionnaire-package operation. PAS submit creates one authorization record carrying a preAuthRef. PAS inquire reads that same record as a projection with no store of its own. Below, the pended branch: an A4 review action that names required documentation raises a CDex Task Attachment Request, the provider answers with submit-attachment, and the authorization returns to In Review.
The hand-offs are the workflow: a questionnaire canonical from CRD to DTR, a completed response from DTR to PAS, and an authorization number from PAS $submit to PAS $inquire.

CRD — is prior authorization required, and on what basis

A provider signs an order. A CDS Hooks service answers with a coverage determination carrying covered, pa-needed, doc-needed and, where documentation is wanted, a questionnaire canonical.

One implementation detail matters more than it sounds: a CRD determination can arrive in the system action rather than in a card. A client that inspects only cards will read a fully answered request as though nothing happened. An absent field must also be parsed as absent, never defaulted — a missing pa-needed means the payer said nothing about prior authorization, which is materially different from saying none is required.

DTR — the payer chooses the questionnaire; the requester follows it

The questionnaire canonical named by the coverage determination is requested from Questionnaire/$questionnaire-package, and what comes back is a package containing that questionnaire and the dependencies it declares.

Package completeness is checked as declared, not as assumed: the questionnaire is walked — library extension, answer value-set bindings, sub-questionnaire extensions, through nested items — and every canonical found must resolve inside the package. Demanding a Library or ValueSet that the questionnaire never asked for would fail a conformant server. Canonical versions are never normalised away either: a dependency present at a different version is reported as a version mismatch, not as missing, because calling it missing sends a reader looking for something that is sitting in the package.

PAS $submit — one authorization record

The completed documentation is submitted as a PAS Bundle carrying a Claim with use = preauthorization. The response is a ClaimResponse on the PAS profile carrying the authorization number as preAuthRef, an X12 278 review action, and — on a denial — a coded reason rather than a bare "not medically necessary".

Status

$inquire is a read projection, and it is enforced as one

An inquiry adds no store and no status field of its own. It reads the state $submit wrote and the rest of the platform updates, through one controller and one response builder.

Read-only by contract, not by convention

The store interface exposes a single lookup method and no write method at all, and a structural test asserts it. An inquiry therefore cannot create a record, move a status, restart a decision clock, emit a duplicate transaction or cause a payer submission — however many times it is repeated. Status derives from the stored adjudication record rather than a live re-query, so an inquiry never turns into an outbound X12 transaction.

The authorization number alone is never enough

Authorization numbers are structured, and therefore guessable at the margins. An inquiry must also carry a corroborating key — the member, or the requesting provider NPI — and that key must match the stored record. A supplied key that does not match refuses even when another one does: naming the wrong member for a real authorization is guessing, and guessing must not get a different answer than a miss.

Deterministic status mapping, total over the status enum

Authorization statusX12 278outcomedisposition
Submitted—queuedpending
InReview—queuedpending
PendedA4queuedpended-additional-information
ApprovedA1completeapproved
ModifiedA2partialmodified
DeniedA3completedenied
Expired—completeexpired
Cancelled—completecancelled

outcome carries the coarse machine answer — still working, decided, partially decided — and disposition the specific one, so a caller can distinguish pending from pended for additional information from approved from denied. An unrecognised status reads as still in progress rather than as an approval that cannot be vouched for.

Refusals do not leak which authorizations exist

Unknown authorization, wrong tenant and not-your-authorization all return one identical 404 OperationOutcome, so the identifier space cannot be probed. A malformed request is a different matter and is described plainly — collapsing the two would tell a caller who forgot an identifier that their authorization does not exist. The distinguishing category is kept in the audit record instead, where an operator can act on it.

The pended branch

What actually has to happen after a payer answers A4

"Pended — additional information required" is the point where most prior-authorization integrations stop being a protocol exercise. A status code tells the provider that something is wanted. It does not tell them what, it does not correlate to anything they can retrieve, and it gives them nowhere to send an answer.

A working implementation needs all of the following, and Cloud Health Office implements the solicited CDex exchange to provide them:

A structured request, or none at all

A documentation request is raised only when the decision is Pended with review action A4 and the decision names what documentation is wanted. A pended state alone is not enough: manufacturing a request from it would put a question to the provider that no reviewer posed. Each requested item carries an X12 PWK attachment-type code, a LOINC document-type code, the service line it is about and whether it is mandatory — description supplements the codes, never replaces them. A request with no items is refused at creation.

Something the provider can retrieve

The request is served as a FHIR Task on the CDex Task Attachment Request profile, at GET Task/{id} and by search — by tracking id, or by code and focus to list every cycle on one authorization. It is a projection computed on read from the one additional-information record; nothing keeps a second copy.

Correlation that a caller cannot derive

The authorization number links the Task to the prior authorization the submitter already holds. The provider-facing tracking id is random rather than derived — it is one of the keys an intake must match, so deriving it from facts a caller already knows would hand it to anyone who knows them. A later cycle is a new record with its own sequence number.

A way back in, with controls

The provider answers with POST fhir/r4/$submit-attachment. Intake applies payload controls, provider binding and idempotency, and an invalid submission is refused without consuming the provider's one chance to answer — the request stays open. There is deliberately no "invalid response" state.

A status transition that is honest

Documentation received returns the authorization to In Review — never directly to approved. A cycle closed without the information reads as failed, not completed: reporting both the same way would tell a provider their unanswered request had been satisfied. Expiry is derived from the due date rather than stored, because nothing in this repository sweeps due dates and a stored state nothing ever sets would be a lie in the data.

Repeatable inquiry behaviour

$inquire reports the resulting status without knowing anything about the exchange, and every inquiry reads live committed state — no submission-time snapshot, no cache. A status changed after submission is the status the next inquiry returns.

Retention, and why no sync job is needed

Retention is an explicit rule rather than an operational habit: retain until the last status change plus a configured period, with the CMS-0057-F one-year minimum enforced as a floor configuration cannot go under. The anchor is the last status change — never a read — so an inquiry cannot extend retention. Only terminal, past-boundary records are purgeable: Submitted, InReview and Pended records are never purged however old. Purge is a conditional delete, so a record that reopens mid-sweep survives and repeat runs are no-ops, and the sweep is disabled by default with a dry run available.

The freshness obligation needs no synchronisation job, because there is nothing to synchronise: prior-auth state is projected from the authoritative record at read time, the read seam exposes no write, and no replicated projection exists to drift. Pharmacy prior authorization is enforced as outside the CMS-0057-F medical scope rather than left as a documentation note, so drug items are excluded from the workflow and from what Patient Access serves.

Traceability

What proves the above

Implementation evidence

Scenarios
PAS-01 CRD · PAS-02 DTR · PAS-03 submit · PAS-04 inquiry · PAS-05 coded denial · PAS-06 decision timeframe · PAS-07 CDex additional information · PAS-08 drug exclusion · PAT-03 prior-auth data retention
IG family
Da Vinci CRD / DTR / PAS STU 2.2.x · CDex solicited attachment
Test data
Synthetic. Decisions come from the Cloud Health Office rule store, not from a payer's production rules.
Architecture docs
prior-authorization.md · cdex-additional-information.md
Pull requests
#1147 drug exclusion · #1154 PAS $inquire · #1155 prior-authorization retention · #1156 CDex additional-information round trip
Also exercised externally
CRD, DTR and PAS $submit are exercised against an independently developed HL7 Da Vinci implementation — see that evidence, which is kept separate from the acceptance status above

Prior-authorization scenarios from the latest published acceptance evidence, generated from the suite rather than typed into this page.

Loading the latest published CMS-0057-F acceptance evidence. It is generated in CI from the acceptance suite at a named source revision and committed to this repository, so the status shown here is the tested status rather than a claim typed into a page.

What is not proven here

  • Acceptance evidence is not CMS certification, and a Passable status does not establish production readiness for a particular payer deployment.
  • Synthetic data throughout. The coverage decisions exercised are Cloud Health Office's own rule content, not a plan's production medical policy.
  • CQL is not executed. Where a DTR package carries a Library its structure is validated; its CQL is not run. This is package exchange, not rule evaluation.
  • The CDex request is made available for retrieval, not pushed. There is no provider FHIR endpoint registry in this repository to POST a Task into.
  • The CDex Task Data Request profile is deliberately not implemented — a payer querying a provider's clinical record is a different transaction from a pended prior authorization.
  • Prior-authorization decisions in Augment mode depend on an external core adapter, and those adapters are documented stubs in this repository. See Replace vs Augment.

For the regulatory requirement rather than the implementation, the CRD, DTR and PAS guide on our sister reference site covers what the rule asks for.

Bring your own pended-authorization scenario.

The interesting question is rarely $submit. It is what your reviewers ask for, how it is coded, and who is allowed to answer.