https://sandbox.haau3.com, where
Example Health Plan, a test insurer, answers the
CARIN Consumer Real-Time Pharmacy Benefit Check
(STU2 ballot, 2.0.0-ballot) as a payer would, so a client written for a payer runs against it with
only its base URL changed. It answers for a small cast of test members, and each medication in its
formulary table always gets the same answer, so every outcome can be rehearsed on demand: a price
with a copay, an alternative drug, not covered, prior authorization, a quantity limit and two errors.
Every organization can call it on every plan, with no key or with a test key (see
the Sandbox). A test key’s requests count toward a minute of their own, at your plan’s
number and apart from your production requests, and never toward the plan’s month.
The open-source SDKs for TypeScript, Python and Go call every operation of this service,
and each operation in the API reference has a sample in all three and in cURL.
Service base
https://api.haau3.com/v1/fhir/r4, on the Sandbox’s own
host. It takes calls with no key or a test key, and a live key gets
403 live-key-in-sandbox. It answers application/fhir+json; fhirVersion=4.0, and every error on
it is a FHIR OperationOutcome.
The Sandbox’s first address, https://api.haau3.com/v1/sandbox/fhir/r4, also answers this check
with a test key. It is deprecated: call the Sandbox’s own host instead (see
the first address).
What is served
metadata returns the Sandbox’s CapabilityStatement, which names CARIN’s responder statement in
instantiates and CARIN’s two request messages, the member’s request (rtpbc-request) and the
request without patient details (rtpbc-request-non-phi), as the messages it receives. It also lists
every resource and operation the Sandbox answers; the Sandbox lists the
other services’ examples.
$process-message takes a member’s request and answers it in the same exchange, at the same path
as Pharmacy Benefits in production. It reads, routes and answers a request
as Pharmacy Benefits does, with two of its checks left out: every organization may call it, and it
needs no business associate agreement and no HTEST label, since only its test insurer can answer.
Pharmacy Benefits needs both for a member’s request (see Patient data), so a
request the Sandbox answers may still be refused there. It accepts POST only, with
Content-Type: application/fhir+json, and takes no parameters.
Test members
Send a test member’s member ID in any of the places CARIN carries one:
Coverage.subscriberId;- the Coverage’s
rxidclass, the member ID on a pharmacy benefit card (http://terminology.hl7.org/CodeSystem/coverage-class); - a
Patient.identifierwhosesystemishttps://example-health-plan.test/member-id.
SANDBOX-EHP, and the examples name the payer by it, in a
Coverage.payor.identifier whose type is payerid from
http://hl7.org/fhir/us/carin-bb/CodeSystem/C4BBIdentifierType. A member’s request is routed by
that Payer ID, as the platform’s Pharmacy Benefits finds a member’s insurer: SANDBOX-EHP, or the
guide’s example payer EXAMPLE-PAYER, reaches Example Health Plan, and any other Payer ID, or a
payer named without one, is answered no-responder-for-coverage, with no one asked.
Formulary table
A medication is matched by its RxNorm code or its NDC, in the Claim’s
item.productOrService.coding. The codes and displays are from RxNorm; the two drugs of CARIN’s
own examples, Prozac and Zepatier, keep CARIN’s amounts. The amounts are fixed whatever the quantity
you ask about.
What the test data does not cover
Example Health Plan lets you rehearse the shape of a member’s answer and each outcome above. It is not a model of a real plan, and it does not have:- a deductible, coinsurance tiers, or a running total of what a member has paid this year;
- step therapy, or any restriction beyond the ones in the table;
- prices that differ by pharmacy, network or mail order: the pharmacy you name changes nothing;
- amounts that follow the quantity or the days’ supply;
- a price for the request without patient details, which price sources give: it is answered
no-price-source, since the Sandbox connects none; - a member’s own sign-in: you send your platform API key, where a payer takes the member’s access token.
Send a request
The member’s request is the same message the Pharmacy Benefits page documents: aBundle of type message whose first entry is a MessageHeader with the event
rtpbc-request, then the Claim, the member’s Patient and Coverage, the prescription
(MedicationRequest), its prescriber and the pharmacy. That page’s member example answers here as
it is, since its member is Yuk Sample and its payer the guide’s EXAMPLE-PAYER.
-H "Authorization: Bearer $HAAU3_API_KEY" for your plan’s requests a minute.
Yuk Sample's request for lisinopril, and the answer
Yuk Sample's request for lisinopril, and the answer
The request, The answer:
request.json:request.json
answer.json
MedicationRequest, to another row of the tables above.
Reading the answer
The answer is aBundle of type message: a MessageHeader answering yours, one ClaimResponse,
and your Patient as you sent it. The examples label every resource HTEST
(http://terminology.hl7.org/CodeSystem/v3-ActReason), so their answers’ Patient keeps the label
and a copy you keep stays marked as test data. Example Health Plan’s ClaimResponse names the
insurer by its Payer ID, SANDBOX-EHP, and carries either an answer in item or an error in
error, never both.
itemis the medication you asked about. Its restriction is thertpbc-benefitRestrictionextension (covered,prior-auth,quantity-limitornot-covered), and what the member pays is inadjudication, each amount coded by CARIN’s pay type (copay,coinsurance,eligibleortotal).addItemis an alternative drug, where the row has one: markedrtpbc-isAlternative, with its own restrictions and amounts and the quantity you asked about.processNotealways starts with one note saying the answer is synthetic, which test member it is for and which row answered. A limit’s words, such asQuantity limit: 9 tablets per 30 days, are a further note that the item points to withnoteNumber. The last note names Example Health Plan and when it answered, as Pharmacy Benefits names a member’s insurer.errorcarries one code fromhttps://haau3.com/fhir/CodeSystem/sandbox-error:no-test-member(no test member matched) orinsurer-declined(the insurer declined the request), withoutcomeerror.
https://haau3.com/fhir/CodeSystem/pharmacy-benefits-processing-code, with outcome error:
no-responder-for-coverage for a member’s request naming another payer, and no-price-source for
the request without patient details (rtpbc-request-non-phi), since the Sandbox connects no price
source.
What is refused
A request is read by the same rules as Pharmacy Benefits’, so a request this base reads, the platform’s FHIR base reads too, though production also needs an agreement orHTEST labels for a
member’s request (above). A request it refuses is answered 400 with an OperationOutcome
that names the element by its FHIRPath, never a value you sent: a body that is not a message
Bundle, an event other than the two above, a list over its cap, an element the CARIN profiles
require that is missing, a reference that names no entry in the Bundle, a product with no NDC or
RxNorm code, or a member’s request with no Coverage or no payer identifier.
It takes Pharmacy Benefits’ Payer-Authorization header too. Example Health Plan needs no
member’s authorization, so the header is sent nowhere, but it is checked as Pharmacy Benefits
checks it: one that is not Bearer and a token is refused 400, and so is one sent with the
request without patient details.
Errors
The statuses every service shares, among them
401, 405, 406, 415, 429 and 500, are on
Errors, limits and request ids.
Data handling
Example Health Plan answers with synthetic data, for its test members only, and is not an operation for patient data. It is stateless all the same: nothing a request carries is stored, cached or logged, apart from a request ID you choose to send. The log records whether the request was answered and what became of it, as counts and fixed words, never a member or a medication, and every answer of$process-message carries Cache-Control: no-store.
See Patient data.
Specification
- CARIN Consumer Real-Time Pharmacy Benefit Check, STU2 ballot,
whose responder statement Example Health Plan’s
CapabilityStatementinstantiates. - The Sandbox’s error codes, in haau3’s FHIR Implementation Guide.
- The operation in the API reference.