Getting started
Quickstart
Get a test key, find a payer, run a sandbox eligibility check, read the answer, then trigger a rejection and fix it.
Seven steps, all in test mode, about five minutes. Nothing here reaches a real payer or costs anything. You need curl and a terminal.
This quickstart is about eligibility, the fastest thing to try. Claims, attachments, remittances (ERAs) and predeterminations follow the same key, headers and conventions: see the Claims, Attachments, ERAs and Predeterminations guides once this works.
1. Get a test key#
Sign in to the dashboard (or create a sandbox account), open Developers, and under Create an API key choose mode Test with both Read and Submit permissions. Copy the key: it is shown once. Then keep it in a variable:
export CLAIMHOUSE_KEY="ch_test_<key id>.<secret>"Check that it works:
curl "https://sandbox.myclaimhouse.com/api/v1/me" -H "Authorization: Bearer $CLAIMHOUSE_KEY"The answer names the key, shows "mode": "test" and lists its permissions:
{
"id": "key_...",
"object": "api_key",
"name": "Quickstart",
"mode": "test",
"permissions": ["read", "submit"],
"organization": { "id": "org_...", "object": "organization", "name": "..." }
}2. Find your test office#
A check is made for an office. Every new organization starts with a test-mode sample office, so you can use it as it is. List your offices and keep the first ID:
curl "https://sandbox.myclaimhouse.com/api/v1/offices" -H "Authorization: Bearer $CLAIMHOUSE_KEY"export OFFICE_ID="off_..." # the id of the first office in the answer3. Find a payer#
Search the payer directory for a payer that answers eligibility checks:
curl "https://sandbox.myclaimhouse.com/api/v1/payers/search?q=delta&supports=eligibility" -H "Authorization: Bearer $CLAIMHOUSE_KEY"Each payer has a Claim House ID (pyr_...) that never changes. Keep one:
export PAYER_ID="pyr_..." # the id of a payer in the answerThe directory is also public, without a key, on the payer network page.
4. Run a sandbox eligibility check#
A POST needs an Idempotency-Key: a value you make up, once for each new attempt. In test mode the subscriber's member_id picks the scenario, and CH-ACTIVE-FULL is an active plan with full benefits. The people here are made up: use made-up people too.
curl "https://sandbox.myclaimhouse.com/api/v1/eligibility" \
-H "Authorization: Bearer $CLAIMHOUSE_KEY" \
-H "Idempotency-Key: $(uuidgen)" \
-H "Content-Type: application/json" \
-d @- <<EOF
{
"office_id": "$OFFICE_ID",
"payer_id": "$PAYER_ID",
"subscriber": {
"first_name": "Sam",
"last_name": "Sample",
"date_of_birth": "1990-01-01",
"member_id": "CH-ACTIVE-FULL"
},
"procedure_codes": ["D0120", "D2740"]
}
EOFThe service date is left out, so it defaults to today in the office's time zone.
5. Read the answer#
The reply is the check. These are the parts you will use first (the real answer has more):
{
"id": "elg_...",
"object": "eligibility_check",
"outcome": "answered",
"status": "active",
"billing": { "charged": false, "state": "not_billable", "reason": "test_mode", "label": "Not billed: test mode" },
"plan": { "name": "...", "type": "PPO", "group_number": "...", "benefit_period": "Calendar year" },
"maximums": [{ "level": "individual", "period": "calendar_year", "amount": "2000.00", "used": "0.00", "remaining": "2000.00", "applies_to": null }],
"deductibles": [{ "level": "individual", "period": "calendar_year", "amount": "50.00", "used": "0.00", "remaining": "50.00", "applies_to": "..." }],
"coverage": [{ "category": "preventive", "percent_paid": 100, "covered": true, "frequency": null, "notes": "..." }],
"procedures": [{ "code": "D0120", "percent_paid": 100, "covered": true, "status": "covered_now" }],
"not_returned": []
}statussays whether the patient has coverage:active,inactiveorunknown.maximumsanddeductiblesgiveamount,usedandremainingas decimal strings, so no floating point rounds your money.coverageis by category (preventive, basic, major and so on);procedureshas one row for each code you asked about, with the percent paid, how often it is covered and whether it is covered now.- A value the payer did not return is
null, and its name is innot_returned.
Run the same check again within 60 minutes and you get the saved answer instead of a new call: cache.state is hit and billing.reason is cache_hit. Send Cache-Control: no-cache to ask the payer again.
Eligibility explains every part.
6. Trigger a rejection#
Run the same request with the member ID CH-NOT-FOUND. The payer cannot find the subscriber, so the reply is an error that carries the check, and the reasons to fix are in check.rejection:
curl "https://sandbox.myclaimhouse.com/api/v1/eligibility" \
-H "Authorization: Bearer $CLAIMHOUSE_KEY" \
-H "Idempotency-Key: $(uuidgen)" \
-H "Content-Type: application/json" \
-d @- <<EOF
{
"office_id": "$OFFICE_ID",
"payer_id": "$PAYER_ID",
"subscriber": {
"first_name": "Sam",
"last_name": "Sample",
"date_of_birth": "1990-01-01",
"member_id": "CH-NOT-FOUND"
}
}
EOF{
"error": "PAYER_REJECTED",
"message": "The payer rejected the check. The check object says what to change, and whether resending can help.",
"errors": [],
"request_id": "req_...",
"check": {
"id": "elg_...",
"outcome": "rejected",
"rejection": {
"kind": "fix_and_resend",
"payer_code": "75",
"reasons": [
{
"code": "MEMBER_NOT_FOUND",
"about": "subscriber",
"field": "subscriber.member_id",
"message": "... could not find this subscriber.",
"fix": "Check the member ID, name and date of birth against the insurance card, then send the check again."
}
]
}
}
}kind tells you what to do. fix_and_resend means change something and send again; field names what to change. Keep the check's id:
export CHECK_ID="elg_..." # check.id in the answer7. Fix it and resend with parent_id#
Send the corrected request with parent_id set to the rejected check. Here the member ID is corrected (in the sandbox, any other member ID gets the default scenario), and a new Idempotency-Key marks the new attempt:
curl "https://sandbox.myclaimhouse.com/api/v1/eligibility" \
-H "Authorization: Bearer $CLAIMHOUSE_KEY" \
-H "Idempotency-Key: $(uuidgen)" \
-H "Content-Type: application/json" \
-d @- <<EOF
{
"office_id": "$OFFICE_ID",
"payer_id": "$PAYER_ID",
"parent_id": "$CHECK_ID",
"subscriber": {
"first_name": "Sam",
"last_name": "Sample",
"date_of_birth": "1990-01-01",
"member_id": "W100200300"
}
}
EOFThe new check answers with parent_id set to the check it corrects, so you can follow the chain. To list the corrections of a check, use GET /eligibility?parent_id=<id>.
Next#
- Errors, retries and idempotency: what to do when a request times out.
- Events and webhooks: get a signed webhook when a check completes.
- Sandbox and scenarios: every scripted payer.
- Going live: what changes with a live key.