SmileCDR Prior-Auth Module Configuration Guide

 

The Smile CDR Prior Auth solution is mainly offered as part of three modules :

  • Prior Auth CRD
  • Prior Auth PAS
  • DTR (required only if using Smile CDR's CQL/CPG for decision support)

Prerequisites

  • SmileCDR V2026.02+ is recommended. If you're using an older version, please reach out to our support team for further guidance.
  • Valid SmileCDR license with Prior Auth modules enabled.

1: CRD (Coverage Requirements Discovery)

  • CRD evaluates Provider orders against Payer rules via CDS Hooks. The below example configuration will help you set up CRD with a static response.

1.1 Key Operations

OperationDescription
<cds-hooks-endpoint>/cds-servicesDiscovery endpoint of the CDS hooks module
<cds-hooks-endpoint>/cds-services/<service-id>Hook invocation endpoint

1.2 Module Dependencies

  • CDS Hooks endpoint module
  • FHIR R4 Endpoint (through CDS Hooks module)
  • CQL module (optional - only required if the CQL evaluation engine is used for evaluating CRD)

1.3 Configuration example

  • Authentication & Authorization is not included as part of this quick setup.
# 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

1.4 CDS Hook Definitions (cds-hooks.json)

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.version extension 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, the davinci-crd.configuration-options extension 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 the extension block 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"
    }
  }
]

1.5 Camel Routes (crd-routes.xml)

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&amp;includeExchange=true"/>
	</route>
</routes>

1.6 JavaScript Functions (crd-functions.js)

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);
}

1.7 Test out CRD !

  • Perform a 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"
			}
		}
	]
}
{
	"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"
			}
		}
	]
}

2: DTR (Documentation Templates and Rules)

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.

2.1 Key Operations

OperationDescription
Questionnaire/$questionnaire-packageRetrieve questionnaire with dependencies
Questionnaire/$next-questionAdaptive questionnaire support
Questionnaire/$log-questionnaire-errorsAllows submission of issues encountered when working with DTR artifacts

2.2 Module dependencies

  • FHIR R4 endpoint
  • CQL module (optional)
  • DTR module (optional)

2.3 Configuration Properties

# 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

2.4 Route Configuration

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>

3: PAS (Prior Authorization Support)

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.

3.1 Key Operations

OperationDescription
Claim/$submitSubmit prior auth request
Claim/$inquireCheck status of existing request
ClaimResponse/$sdh.pa.submitClaimResponse submission for payers to asynchronously send ClaimResponse updates

3.2 Module Dependencies

  • FHIR endpoint
  • CQL module (optional)

3.3 Configuration Properties

# 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

3.4 Camel Routes (pas-routes.xml)

To invoke the PlanDefinition there are 2 helper Camel processors available:

  • pasToCqlRequestProcessor to generate the PlanDef request
  • cqlToPasResponseProcessor to parse the PlanDef response and generate a PASResponseBundle

Note: 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>

3.5 SearchParameter requirements

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"
      }
    }
  ]
}

3.6 Configure Subscriptions for Providers

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"
      }
    }
  ]
}