Skip to the page
Chapters

Getting started

Sandbox and scenarios

Test eligibility checks with scripted payers chosen by member ID, including rejections and a payer that is down, and claims with a sandbox clearinghouse that answers on a compressed clock.

A test key is answered by a sandbox network that behaves like a payer, without the waiting and without a patient. Nothing reaches a real payer, nothing is billed, and every check says so: billing.reason is test_mode.

Choose a scenario with the member ID#

In test mode the subscriber's member_id picks what the payer does. The names, dates of birth and payer can be anything that passes validation: use made-up people.

Member IDThe payerWhat you get
CH-ACTIVE-FULLansweredActive coverage, full benefits returned, with 18 procedure rows
CH-MAX-NEARLY-USEDanswered$120 of the annual maximum remaining
CH-MISSING-TOOTHansweredMissing tooth clause applies to implant codes (D6xxx)
CH-INACTIVEansweredCoverage ended: inactive, with its dates and little else
CH-NOT-FOUNDrejectedAAA 75: subscriber not found
CH-DEPENDENTrejectedAAA 75: a dependent sent as the subscriber, with two fixes (the plan holder, the member ID format)
CH-DOB-MISMATCHrejectedAAA 71: date of birth does not match
CH-PAYER-DOWNpayer_unavailableAAA 42: the payer is unavailable, nothing to change
CH-GENERAL-ONLYansweredActive, a general answer with most detail not returned

Any other member ID gets CH-ACTIVE-FULL, so a first check with an invented ID works. Member IDs are not case sensitive.

The same list is available from the API, so a tool can read it: List sandbox scenarios.

Shell
curl "https://sandbox.myclaimhouse.com/api/v1/sandbox/scenarios" -H "Authorization: Bearer $CLAIMHOUSE_KEY"

Claim scenarios#

A test claim goes to a sandbox clearinghouse that answers each claim file with a 997 after 30 seconds and a 277 after 60 seconds, as real files. The subscriber's member_id on the claim picks what happens:

Member IDWhat happens
CH-REJECT-A7Accepted in the 997, then rejected by the payer in the 277 with A7:33 (subscriber not found)
CH-REJECT-A3Accepted in the 997, then returned by the payer as unprocessable in the 277 with A3:21
CH-997-REJECTThe whole file is rejected in the 997: its claims return to the queue, go out in the next batch and are accepted
CH-ATTACH-REQUIREDA claim fails validation with an attachment-required error until a closed attachment (an X-ray) is on it; then it is accepted
CH-SOLICITEDThe payer accepts the claim, then asks for a narrative and an X-ray 1 minute later (a payer request)
CH-PAID-ERAAccepted by the payer, then paid in an 835 2 minutes later: 80% of an allowed amount below the charge on each line (a contractual adjustment and coinsurance)
CH-DENIEDAccepted by the payer, then denied in an 835 2 minutes later: the benefit maximum was reached

Any other member ID is accepted by the clearinghouse (997 after 30 seconds) and by the payer (277 after 60 seconds, A1:20). See Claims for the states and the timeline.

The claims of CH-PAID-ERA and CH-DENIED are then answered with a remittance (an 835), 2 minutes after the payer accepts them: see ERAs and posting. The sandbox works out shares in whole cents, rounding down to the cent (the patient's share takes what is left, so every remittance adds up). It answers a correction as a payer does: a replacement of a claim it paid is answered with the reversal of that payment and the new payment in one remittance, and an accepted void of a claim it paid with the reversal only (nothing when it paid nothing).

A predetermination the payer accepts, whatever its member ID, is answered 2 minutes later with its estimate: a pricing-only remittance (status 25) in which, on each line, the payer would pay 80% of an allowed amount below the fee and the patient the rest. The scenarios that reject a claim reject a predetermination too. See Predeterminations.

The test payer#

CHTEST is a payer of the directory that test keys see (live keys and the public payer list do not): The Claim House test payer: accepts every claim and pays it in full in an 835 2 minutes after accepting it. Send a claim to it, with any member ID, to see a payment in full.

What each kind of scenario shows you#

  • answered scenarios return a check with outcome: "answered" and a coverage status of active or inactive. They differ in how much the payer returns: CH-GENERAL-ONLY shows a payer that leaves most detail out, so you can see how your code handles values that are null and listed in not_returned.
  • rejected scenarios answer 422 PAYER_REJECTED. The check carries a rejection with a kind and the reasons to fix. Every rejected scenario today is kind: "fix_and_resend" (CH-NOT-FOUND, CH-DEPENDENT and CH-DOB-MISMATCH): it can be fixed and resent; see Eligibility for how. No scenario gives kind: "rejected" (a rejection that resending will not change) yet, so handle that branch from its description.
  • payer_unavailable is CH-PAYER-DOWN: the payer is not answering and there is nothing to change. The reply is 502 PAYER_UNAVAILABLE, and the check is not billed.

What the sandbox does and does not do#

  • It does validate your request the way the real API does: a bad date or a missing member ID is a 422 INVALID_REQUEST with every problem listed, and nothing is recorded.
  • It does reuse a recent identical answer, as live mode will. Send Cache-Control: no-cache to get a fresh one.
  • It does send events and webhooks for test checks.
  • It does not return real payer data, and a test key cannot reach a live office or a live check.
  • Reset test data on the dashboard's Sandbox page deletes the organization's test-mode checks and claims (with their lines and timelines), its test ERAs, its test claim files, its test attachments (with their images) and payer requests, its test patient records, the sandbox network's copies of them and answers still due, their usage records and events, the test webhook deliveries and the test idempotency records. API keys, their events, offices, providers and endpoints are kept. A check still running at that moment is deleted too, and its request fails.