The Smile CDR Prior Auth solution is mainly offered as part of three modules :
V2026.02+ is recommended. If you're using an older version, please reach out to our support team for further guidance.| Operation | Description |
|---|---|
<cds-hooks-endpoint>/cds-services | Discovery endpoint of the CDS hooks module |
<cds-hooks-endpoint>/cds-services/<service-id> | Hook invocation endpoint |
# CDS Hooks Endpoint
module.cds_hooks_endpoint.type=ENDPOINT_CDS_HOOKS
# security module
module.cds_hooks_endpoint.requires.SECURITY_IN_UP=local_security
module.cds_hooks_endpoint.requires.ENDPOINT_FHIR=fhir_endpoint
# CRD Module
module.prior_auth_crd.type=PRIOR_AUTH_CRD
module.prior_auth_crd.requires.ENDPOINT_CDS_HOOKS=cds_hooks_endpoint
module.prior_auth_crd.config.cds_hook.file=classpath:/config/cds-hooks.json
module.prior_auth_crd.config.routes.script.file=classpath:/config/crd-routes.xml
module.prior_auth_crd.config.functions.script.file=classpath:/config/crd-functions.js
Define which hooks CRD responds to: An optional extension block can be included in each hook definition to advertise capabilities in the CDS service discovery response (/cds-services). The extension properties are passed through as-is — include any DaVinci-standard or implementation-specific keys EHR clients require.
Note: The
davinci-crd.versionextension is a required extension for CRD. Each registered CDS Hook instance must declare a single version. Currently valid versions are 2.1 and 2.2.
Note: Starting
v2026.05.R01, thedavinci-crd.configuration-optionsextension is no longer injected automatically. If you want to advertise CRD configuration options (e.g.,coverage-info,max-cards), you must include them explicitly in theextensionblock as shown below.
[
{
"hook": "order-sign",
"title": "Order Sign CRD",
"description": "Evaluates orders for prior auth requirements",
"prefetch": {
"patient": "Patient/{{context.patientId}}",
"coverageBundle": "Coverage?patient={{context.patientId}}&status=active&_include=Coverage:payor"
},
"extension": {
"davinci-crd.version": ["2.1"],
"davinci-crd.configuration-options": [
{
"code": "coverage-info",
"type": "boolean",
"name": "Coverage Information",
"description": "Indicates whether coverage information should be returned",
"default": true
},
{
"code": "max-cards",
"type": "integer",
"name": "Maximum cards",
"description": "Indicates the maximum number of cards to be returned from the service",
"default": 10
}
]
}
},
{
"hook": "appointment-book",
"title": "Appointment Book CRD",
"prefetch": {
"patient": "Patient/{{context.patientId}}",
"coverageBundle": "Coverage?patient={{context.patientId}}&status=active"
},
"extension": {
"davinci-crd.version": ["2.1"],
"com.example.cdshooks.request.cds-hooks-specification-version": "2.1",
"com.example.cdshooks.request.fhir-version": "R4"
}
}
]
This is an example CRD Camel route to generate a static response using JS:
<routes>
<route>
<from uri="direct:start-crd"/>
<to uri="smile:camel/script?function=makeCustomResponse&includeExchange=true"/>
</route>
</routes>
JavaScript function which will be invoked by camel route to get a static response:
function makeCustomResponse(theRequest, theExchange) {
let response = {
"cards": [
{
"summary": "This response is coming from " + theRequest.hook,
"indicator": "info",
"source": {
"label": "Test label from " + theRequest.hook
}
}
]
};
return JSON.stringify(response);
}
GET request on <cds-hooks-endpoint>/cds-services. You should see 2 sample services registered like below :{
"services": [
{
"extension": {
"davinci-crd.version": ["2.1"],
"davinci-crd.configuration-options": [
{
"code": "coverage-info",
"type": "boolean",
"name": "Coverage Information",
"description": "Indicates whether coverage information should be returned",
"default": true
},
{
"code": "max-cards",
"type": "integer",
"name": "Maximum cards",
"description": "Indicates the maximum number of cards to be returned from the service",
"default": 10
}
]
},
"hook": "order-sign",
"title": "Order Sign CRD",
"description": "Evaluates orders for prior auth requirements",
"id": "prior_auth_crd_order_sign",
"prefetch": {
"patient": "Patient/{{context.patientId}}",
"coverageBundle": "Coverage?patient={{context.patientId}}&status=active&_include=Coverage:payor"
}
},
{
"extension": {
"com.example.cdshooks.request.cds-hooks-specification-version": "2.1",
"com.example.cdshooks.request.fhir-version": "R4"
},
"hook": "appointment-book",
"title": "Appointment Book CRD",
"id": "prior_auth_crd_appointment_book",
"prefetch": {
"patient": "Patient/{{context.patientId}}",
"coverageBundle": "Coverage?patient={{context.patientId}}&status=active"
}
}
]
}
id for each service, it is essentially <module_id_for_crd>_<hook_id_with_underscores>. This is on purpose to avoid conflicts in case multiple PriorAuth CRD modules end up registering same hooks against a single CDS hook endpoint.POST request on <cds-hooks-endpoint>/cds-services/prior_auth_crd_order_sign with content type Content-Type: application/json & the request body below :INVOKE_CDS_HOOKS.{
"hookInstance": "698dda66-9a2f-464a-8edb-58dfca80aa07",
"hook": "order-sign",
"context": {
"patientId": "provider-patient-carol"
},
"prefetch": {
"coverageBundle": {
"resourceType": "Bundle",
"id": "f86f42d2-3067-4693-b8ab-78a61153138d",
"meta": {
"lastUpdated": "2024-09-06T13:48:41.747-04:00"
},
"type": "searchset",
"total": 1,
"link": [
{
"relation": "self",
"url": "http://localhost:8005/Coverage?patient=provider-patient-carol&status=active&_include=Coverage:payor"
}
],
"entry": [
{
"fullUrl": "http://localhost:8005/Coverage/provider-coverage-carol",
"resource": {
"resourceType": "Coverage",
"id": "provider-coverage-carol",
"meta": {
"versionId": "1",
"lastUpdated": "2024-09-09T04:16:10.665-04:00",
"source": "#wUvugjq2zCvGu4fE"
},
"identifier": [
{
"system": "http://acme.org/fhir-ns/payer-coverage-identifier-system",
"value": "1234-COVERAGE-IDENTIFIER"
}
],
"status": "active",
"type": {
"coding": [
{
"system": "http://terminology.hl7.org/CodeSystem/v3-ActCode",
"code": "EHCPOL",
"display": "extended healthcare"
}
]
},
"policyHolder": {
"reference": "Organization/payor-organization-acme"
},
"subscriber": {
"reference": "Patient/provider-patient-carol"
},
"beneficiary": {
"reference": "Patient/provider-patient-carol"
},
"dependent": "0",
"relationship": {
"coding": [
{
"system": "http://terminology.hl7.org/CodeSystem/subscriber-relationship",
"code": "self"
}
]
},
"period": {
"start": "2011-05-23",
"end": "2025-05-23"
},
"payor": [
{
"reference": "Organization/payor-organization",
"display": "Payor"
}
],
"class": [
{
"type": {
"coding": [
{
"system": "http://terminology.hl7.org/CodeSystem/coverage-class",
"code": "group"
}
]
},
"value": "CB135",
"name": "Corporate Baker's Inc. Local #35"
}
]
},
"search": {
"mode": "match"
}
}
]
},
"patient": {
"resourceType": "Patient",
"id": "provider-patient-carol",
"meta": {
"versionId": "1",
"lastUpdated": "2024-09-09T04:16:10.665-04:00",
"source": "#wUvugjq2zCvGu4fE",
"profile": [
"http://hl7.org/fhir/us/carin-bb/StructureDefinition/C4BB-Patient|2.0.0"
]
},
"language": "en-US",
"identifier": [
{
"type": {
"coding": [
{
"system": "http://terminology.hl7.org/CodeSystem/v2-0203",
"code": "MB",
"display": "Member Number"
}
],
"text": "An identifier for the insured of an insurance policy (this insured always has a subscriber), usually assigned by the insurance carrier."
},
"system": "https://www.upmchealthplan.com/fhir/memberidentifier",
"value": "1234-TEST-MB"
},
{
"type": {
"coding": [
{
"system": "http://terminology.hl7.org/CodeSystem/v2-0203",
"code": "MR",
"display": "Medical Record number"
}
],
"text": "Medical Record Number"
},
"system": "https://www.some-system.com",
"value": "1234-TEST-MRN"
}
],
"active": true,
"name": [
{
"family": "Johnson",
"given": [
"Carol"
]
}
],
"telecom": [
{
"system": "phone",
"value": "5555555551",
"rank": 1
}
],
"gender": "female",
"birthDate": "1943-01-01",
"address": [
{
"type": "physical",
"line": [
"123 Murray Avenue"
],
"city": "PITTSBURGH",
"state": "PA",
"postalCode": "15217"
}
],
"maritalStatus": {
"coding": [
{
"system": "http://terminology.hl7.org/CodeSystem/v3-MaritalStatus",
"code": "M"
}
]
},
"communication": [
{
"language": {
"coding": [
{
"system": "urn:ietf:bcp:47",
"code": "en"
}
],
"text": "English"
},
"preferred": true
}
],
"managingOrganization": {
"reference": "Organization/payor-organization"
}
}
}
}
You should see the static response below, which is returned from camel routes:
{
"cards": [
{
"summary": "This response is coming from order-sign",
"indicator": "info",
"source": {
"label": "Test label from order-sign"
}
}
]
}
The Prior Auth PAS module registers the DTR operations $questionnaire-package and $next-question. It can be connected to any proprietary rules engine interface using Camel processors.
| Operation | Description |
|---|---|
Questionnaire/$questionnaire-package | Retrieve questionnaire with dependencies |
Questionnaire/$next-question | Adaptive questionnaire support |
Questionnaire/$log-questionnaire-errors | Allows submission of issues encountered when working with DTR artifacts |
# CQL Module (optional)
module.cql.type=CQL
module.cql.requires.ENDPOINT_FHIR=fhir_endpoint
# DTR Module (optional)
module.dtr.type=PRIOR_AUTH_DTR
module.dtr.requires.CQL=cql
module.dtr.requires.ENDPOINT_FHIR=fhir_endpoint
module.dtr.config.enable_questionnaire_package=true
# PAS Module
module.prior_auth_pas.type=PRIOR_AUTH_PAS
module.prior_auth_pas.requires.ENDPOINT_FHIR=fhir_endpoint_payer
module.prior_auth_pas.config.routes.script.file=classpath:/config_seeding/pas-routes.xml
module.prior_auth_pas.config.functions.script.file=classpath:/config_seeding/pas-functions.js
module.prior_auth_pas.config.definitions.spring_context_config.class=cdr.prior.auth.adjudication.AdjudicationAppCtx
Example showing simple $submit and $log-questionnaire-errors routes.
<routes>
<route>
<from uri="direct:start-pas-submit"/>
<log message="----------------------- default processor triggered from PAS"/>
<to uri="bean:pasRequestBundleValidator"/>
<to uri="bean:createPendedPASResponseProcessor"/>
<to uri="bean:pasResponseBundleValidator"/>
</route>
<route id="log-questionnaire-errors-route">
<from uri="direct:log-questionnaire-errors"/>
<!-- Forward to your downstream processing here -->
<to uri="stub:nowhere"/>
</route>
</routes>
The PAS module registers the PAS operations for adjudication. PAS Camel routes can be configured to handle the Claim adjudication response synchronously or asynchronously. In the case of asynchronous response the Camel route will need to be configured to return a Pended ClaimResponse.
| Operation | Description |
|---|---|
Claim/$submit | Submit prior auth request |
Claim/$inquire | Check status of existing request |
ClaimResponse/$sdh.pa.submit | ClaimResponse submission for payers to asynchronously send ClaimResponse updates |
# PAS Module
module.prior_auth_pas.type=PRIOR_AUTH_PAS
module.prior_auth_pas.requires.ENDPOINT_FHIR=fhir_endpoint
module.prior_auth_pas.config.identifier_code_system=https://example.com/pas-identifier
module.prior_auth_pas.config.payer_system_item_trn=http://sdh-mockpayer.org/ITEM_TRACE_NUMBER
module.prior_auth_pas.config.routes.script.file=classpath:/config/pas-routes.xml
To invoke the PlanDefinition there are 2 helper Camel processors available:
pasToCqlRequestProcessor to generate the PlanDef requestcqlToPasResponseProcessor to parse the PlanDef response and generate a PASResponseBundleNote: The above processors are part of a customized JAR deliverable and can be obtained from Smile Support or your Technical Account Manager.
There are also 2 optional Camel Processors available via the PAS module of Smile.
pasRequestBundleValidator to validate the incoming PAS bundle to spec.pasResponseBundleValidator to validate the outgoing response bundle to spec.Note: Both validators read the message body without consuming it, so they can be placed anywhere in the route.
Do not set disableStreamCache=true on an HTTP endpoint whose response feeds pasResponseBundleValidator - that with produce a single-read stream, and any step after the validator will see an empty body.
<routes>
<route>
<from uri="direct:start-pas-submit"/>
<!-- Optional Request Validation -->
<to uri="bean:pasRequestBundleValidator"/>
<!-- CQL-based adjudication -->
<to uri="bean:pasToCqlRequestProcessor"/>
<to uri="http://localhost:8002/fhir/PlanDefinition/$r5.apply?bridgeEndpoint=true"/>
<to uri="bean:cqlToPasResponseProcessor"/>
<!-- Optional Response Validation -->
<to uri="bean:pasResponseBundleValidator"/>
</route>
</routes>
Claim/$inquire has its own route, direct:start-pas-inquire. Two Camel processors are available via the PAS module of Smile:
pasInquiryRequestBundleValidator to validate the incoming PAS inquiry request bundle to spec.createInquireResponseProcessor to retrieve the latest adjudication response from the local repository and generate the inquiry response.Replace createInquireResponseProcessor with a call to your own payer or adjudication system to answer inquiries from that system instead.
<routes>
<route>
<from uri="direct:start-pas-inquire"/>
<!-- Optional Request Validation -->
<to uri="bean:pasInquiryRequestBundleValidator"/>
<!-- Default adjudication status lookup -->
<to uri="bean:createInquireResponseProcessor"/>
</route>
</routes>
The below set of SearchParameters are required for PAS. These SearchParameters are used when searching for PASRequestBundle with matching Claim/identifier.
{
"resourceType": "Bundle",
"type": "transaction",
"entry": [
{
"resource": {
"id": "sp-bundle-claim",
"resourceType": "SearchParameter",
"url": "http://hl7.org/fhir/SearchParameter/bundle-claim",
"name": "Bundle-claim",
"status": "active",
"description": "This parameter, of type reference, specifies the Claim resource instance in the Bundle.",
"code": "claim",
"base": [
"Bundle"
],
"type": "reference",
"expression": "Bundle.entry.select(resource as Claim)",
"target": [
"Claim"
]
},
"request": {
"method": "POST",
"url": "SearchParameter",
"ifNoneExist": "?code=claim&base=Bundle"
}
},
{
"resource": {
"id": "sp-bundle-claim-identifier",
"resourceType": "SearchParameter",
"url": "http://example.org/SearchParameter/bundle-claim-identifier",
"name": "claim.identifier",
"status": "active",
"description": "This parameter, of type token, specifies the identifier of the Claim.",
"code": "claim.identifier",
"base": [
"Bundle"
],
"type": "token",
"expression": "Bundle.entry.select(resource as Claim).identifier"
},
"request": {
"method": "POST",
"url": "SearchParameter",
"ifNoneExist": "code=claim.identifier&base=Bundle"
}
},
{
"resource": {
"id": "sp-bundle-claim-profile",
"resourceType": "SearchParameter",
"url": "http://example.org/SearchParameter/bundle-claim-profile",
"name": "claim.profile",
"status": "active",
"description": "This parameter, of type uri, specifies the profile of the Claim.",
"code": "claim.profile",
"base": [
"Bundle"
],
"type": "uri",
"expression": "Bundle.entry.select(resource as Claim).meta.profile"
},
"request": {
"method": "POST",
"url": "SearchParameter",
"ifNoneExist": "code=claim.profile&base=Bundle"
}
},
{
"resource": {
"id": "sp-bundle-claim-response",
"resourceType": "SearchParameter",
"url": "http://hl7.org/fhir/SearchParameter/bundle-claimresponse",
"name": "Bundle-claimresponse",
"status": "active",
"description": "This parameter, of type reference, specifies the ClaimResponse resource instance in the Bundle.",
"code": "claimresponse",
"base": [
"Bundle"
],
"type": "reference",
"expression": "Bundle.entry.select(resource as ClaimResponse)",
"target": [
"ClaimResponse"
]
},
"request": {
"method": "POST",
"url": "SearchParameter",
"ifNoneExist": "code=claimresponse&base=Bundle"
}
},
{
"resource": {
"id": "sp-bundle-claim-response-identifier",
"resourceType": "SearchParameter",
"url": "http://example.org/SearchParameter/bundle-claimresponse-identifier",
"name": "claimresponse.identifier",
"status": "active",
"description": "This parameter, of type token, specifies the identifier of the ClaimResponse.",
"code": "claimresponse.identifier",
"base": [
"Bundle"
],
"type": "token",
"expression": "Bundle.entry.select(resource as ClaimResponse).identifier"
},
"request": {
"method": "POST",
"url": "SearchParameter",
"ifNoneExist": "code=claimresponse.identifier&base=Bundle"
}
},
{
"resource": {
"id": "sp-bundle-claim-response-profile",
"resourceType": "SearchParameter",
"url": "http://example.org/SearchParameter/bundle-claimresponse-profile",
"name": "claimresponse.profile",
"status": "active",
"description": "This parameter, of type uri, specifies the profile of the ClaimResponse.",
"code": "claimresponse.profile",
"base": [
"Bundle"
],
"type": "uri",
"expression": "Bundle.entry.select(resource as ClaimResponse).meta.profile"
},
"request": {
"method": "POST",
"url": "SearchParameter",
"ifNoneExist": "code=claimresponse.profile&base=Bundle"
}
}
]
}
In case the provider wants to subscribe to get ClaimResponse updates a Subscription module has to be configured on the same persistence that PAS (FHIR Endpoint) depends on.
Example Subscription:
{
"resourceType": "Bundle",
"type": "transaction",
"entry": [
{
"resource": {
"resourceType": "Basic",
"id": "r4-backport-basic-resource",
"extension": [
{
"url": "http://hl7.org/fhir/5.0/StructureDefinition/extension-SubscriptionTopic.url",
"valueUri": "http://example.org/SubTopics/claim-response-update"
},
{
"url": "http://hl7.org/fhir/4.3/StructureDefinition/extension-SubscriptionTopic.resourceTrigger",
"extension": [
{
"url": "description",
"valueString": "Trigger on update of ClaimResponse resources"
},
{
"url": "resource",
"valueUri": "ClaimResponse"
},
{
"url": "supportedInteraction",
"valueCode": "update"
}
]
}
],
"modifierExtension": [
{
"url": "http://hl7.org/fhir/5.0/StructureDefinition/extension-SubscriptionTopic.status",
"valueString": "active"
}
],
"code": {
"coding": [
{
"system": "http://hl7.org/fhir/fhir-types",
"code": "SubscriptionTopic"
}
]
}
},
"request": {
"method": "PUT",
"url": "Basic/r4-backport-basic-resource"
}
},
{
"resource": {
"resourceType": "Subscription",
"id": "r4-backport-subscription",
"meta": {
"profile": [
"http://hl7.org/fhir/uv/subscriptions-backport/StructureDefinition/backport-subscription"
],
"tag": [
{
"system": "http://hapifhir.io/fhir/StructureDefinition/subscription-matching-strategy",
"code": "TOPIC",
"display": "SubscriptionTopic"
}
]
},
"status": "requested",
"reason": "Monitor update of Claim Response resources",
"criteria": "http://example.org/SubTopics/claim-response-update",
"_criteria": {
"extension": [
{
"url": "http://hl7.org/fhir/uv/subscriptions-backport/StructureDefinition/backport-filter-criteria",
"valueString": "ClaimResponse?"
}
]
},
"channel": {
"type": "rest-hook",
"endpoint": "https://hapi.requestcatcher.com/test",
"payload": "application/fhir+json"
}
},
"request": {
"method": "PUT",
"url": "Subscription/r4-backport-subscription"
}
}
]
}