ERAs
Match a payment to a claim
POST/api/v1/eras/{id}/claims/{era_claim_id}/match
Matches an unmatched payment of the ERA to one of your claims (sent, in the key's mode, and able to take a payment now: not while it is being corrected, rejected or voided) by hand, and applies it: the claim's figures become the sum of its payments, and it is paid or denied. The payer is your call: a claim of another payer than the ERA's (when the ERA's payer is known; a payment left unmatched with unmatched_reason payer_differs, say) is matched only with confirm_payer true, else 422 on confirm_payer. A reversal and its corrected payment can both be matched to one claim. A payment matched already is a conflict. Needs a key with both read and submit. An ERA posted already can still be matched: its claim is not reconciled by the post, so reconcile it on its own (POST /v1/claims/{id}/reconcile). Needs an Idempotency-Key header and a key with the submit permission.
Needs a key with submit permission.
Request
Headers
| Name | Type | Required | Description |
|---|---|---|---|
| Idempotency-Key | string | required | Makes the request safe to repeat: a request with the same key and body returns the first answer (the reply has an idempotent-replayed header), and the same key with a different request is refused. 1 to 255 printable characters; a UUID is a good choice.At least 1 character.At most 255 characters.Matches `^[\x21-\x7e]{1,255}$`. |
Path parameters
| Name | Type | Required | Description |
|---|---|---|---|
| id | string | required | An ERA ID (era_...). |
| era_claim_id | string | required | A payment of the ERA (erc_...). |
Body
| Name | Type | Required | Description |
|---|---|---|---|
| claim_id | string | required | The claim this payment is for (clm_...). |
| confirm_payer | boolean | optional | true: you checked that the payment is for this claim although its payer is not the ERA's. Needed only then. |
Response
The payment as it is now. Status 200.
| Name | Type | Description |
|---|---|---|
| id | string | An ID that starts with erc_. |
| object | string | Always `era_claim`. |
| claim_id | string or null | The claim this payment is for; null while it is unmatched. |
| match | string | matched: by the patient control number or the payer claim number; manual: matched by hand; unmatched: no claim with certainty (match it by hand).One of: `matched`, `unmatched`, `manual`. |
| unmatched_reason | string or null | Why a payment naming one of your claims was left unmatched: payer_differs (the ERA's payer is not the claim's), claim_not_payable (the claim could not take a payment in its state, such as while it is being corrected), estimate_for_claim (an estimate naming a claim), payment_for_predetermination (a payment naming a predetermination). Match it by hand once you have checked. Null otherwise.One of: `payer_differs`, `claim_not_payable`, `estimate_for_claim`, `payment_for_predetermination`. |
| patient_control_number | string | The patient control number as the payer echoed it. |
| payer_claim_number | string | |
| status | object | |
| status.code | string | The payer's claim status (CLP02). |
| status.description | string | |
| outcome | string | What the payment does to the claim: paid, denied, reversal (an earlier payment taken back), estimate (the answer to a predetermination, never a payment), or status (reported only).One of: `paid`, `denied`, `reversal`, `status`, `estimate`. |
| charge | string | An amount in dollars, as a decimal string with two places (such as "113.60").Matches `^-?\d+\.\d{2}$`. |
| paid | string | An amount in dollars, as a decimal string with two places (such as "113.60").Matches `^-?\d+\.\d{2}$`. |
| allowed | string or null | An amount in dollars, as a decimal string with two places (such as "113.60").Matches `^-?\d+\.\d{2}$`. |
| patient_responsibility | string | An amount in dollars, as a decimal string with two places (such as "113.60").Matches `^-?\d+\.\d{2}$`. |
| adjustments | array of object | Adjustments at claim level (each line has its own). |
| adjustments[].group | string | The adjustment group: CO (contractual), PR (patient responsibility), OA (other), PI (payer initiated) or CR (correction). |
| adjustments[].group_description | string | The group in plain words. |
| adjustments[].reason | string | The claim adjustment reason code, as sent (such as 45, 2 or 119). |
| adjustments[].description | string | The reason in our own plain words, for the common codes; the code itself for any other. |
| adjustments[].amount | string | An amount in dollars, as a decimal string with two places (such as "113.60").Matches `^-?\d+\.\d{2}$`. |
| patient_name | value | The patient as the payer wrote it, shown only while the payment is unmatched, to find its claim; null once matched. |
| balanced | boolean | Whether its charge less its payment is its adjustments: one that is not was not applied to its claim. |
| applied | boolean | Whether it moved its claim (paid, denied or reversed). |
| postable | boolean | Whether posting the ERA marks its claim reconciled: applied, the ERA not posted yet, and the claim paid or denied with this ERA's payment as its current one. |
| lines | array of object | |
| lines[].procedure_code | string | The CDT code the payer paid. |
| lines[].modifiers | array of string | |
| lines[].service_date | string (date) or null | |
| lines[].charge | string | An amount in dollars, as a decimal string with two places (such as "113.60").Matches `^-?\d+\.\d{2}$`. |
| lines[].paid | string | An amount in dollars, as a decimal string with two places (such as "113.60").Matches `^-?\d+\.\d{2}$`. |
| lines[].allowed | string or null | An amount in dollars, as a decimal string with two places (such as "113.60").Matches `^-?\d+\.\d{2}$`. |
| lines[].units | value | |
| lines[].adjustments | array of object | |
| lines[].adjustments[].group | string | The adjustment group: CO (contractual), PR (patient responsibility), OA (other), PI (payer initiated) or CR (correction). |
| lines[].adjustments[].group_description | string | The group in plain words. |
| lines[].adjustments[].reason | string | The claim adjustment reason code, as sent (such as 45, 2 or 119). |
| lines[].adjustments[].description | string | The reason in our own plain words, for the common codes; the code itself for any other. |
| lines[].adjustments[].amount | string | An amount in dollars, as a decimal string with two places (such as "113.60").Matches `^-?\d+\.\d{2}$`. |
| lines[].remarks | array of string | Remark codes, as sent. |
| lines[].line_control_number | value | The line control number the payer returned (ours is <patient control number>-<line>). |
| lines[].claim_line_number | integer or null | The line of the matched claim this pays; null when no line matched with certainty.At least -9007199254740991. |
Errors
| HTTP status | Code | What it means |
|---|---|---|
| 401 | UNAUTHORIZED | A valid API key is required. Send it as "Authorization: Bearer <key>". |
| 403 | PERMISSION_DENIED | This API key is not allowed to do that. |
| 404 | NOT_FOUND | Not found. |
| 422 | INVALID_REQUEST | The request is not valid. |
| 400 | IDEMPOTENCY_KEY_REQUIRED | POST and PATCH requests need an Idempotency-Key header. |
| 422 | IDEMPOTENCY_KEY_REUSED | That Idempotency-Key was already used with a different request. |
| 409 | IDEMPOTENCY_KEY_IN_USE | A request with that Idempotency-Key is still running. Retry shortly. |
| 413 | PAYLOAD_TOO_LARGE | The request body is larger than 1 MB. |
| 504 | TIMEOUT | The request took too long to finish. It may still have taken effect: look it up before sending it again with a new Idempotency-Key. What it made is found with GET /api/v1/eligibility?request_id=<this request_id>, and the same filter on /api/v1/claims and /api/v1/attachments (a key with read permission). |
| 409 | CONFLICT | The resource is not in a state that allows this, or it changed while the request was handled. Read it, then decide whether to send the request again. |
| 500 | INTERNAL | Something went wrong on our side. Quote the request ID if you contact us. |
Example
Example request
curl -X POST "https://sandbox.myclaimhouse.com/api/v1/eras/era_01JM000000E00800000000003G/claims/erc_01JM000000E00800000000003J/match" \
-H "Authorization: Bearer $CLAIMHOUSE_KEY" \
-H "Idempotency-Key: $(uuidgen)" \
-H "Content-Type: application/json" \
-d '{
"claim_id": "clm_01JM000000E00800000000002J"
}'Example response: 200
{
"id": "erc_01JM000000E00800000000003J",
"object": "era_claim",
"claim_id": "clm_01JM000000E00800000000002J",
"match": "manual",
"unmatched_reason": null,
"patient_control_number": "PMS-77812",
"payer_claim_number": "990000001077",
"status": {
"code": "4",
"description": "Denied."
},
"outcome": "denied",
"charge": "310.00",
"paid": "0.00",
"allowed": null,
"patient_responsibility": "0.00",
"adjustments": [],
"patient_name": null,
"balanced": true,
"applied": true,
"postable": false,
"lines": [
{
"procedure_code": "D4341",
"modifiers": [],
"service_date": "2026-09-24",
"charge": "310.00",
"paid": "0.00",
"allowed": null,
"units": 1,
"adjustments": [
{
"group": "CO",
"group_description": "The provider writes this off under its contract with the payer. The patient is not billed.",
"reason": "119",
"description": "The benefit maximum for the period has been reached.",
"amount": "310.00"
}
],
"remarks": [
"N130"
],
"line_control_number": "1",
"claim_line_number": 1
}
]
}A claim of another payer, not confirmed: 422
{
"error": "INVALID_REQUEST",
"message": "The request is not valid.",
"errors": [
{
"field": "confirm_payer",
"code": "required",
"message": "This claim is to another payer than the ERA's. Check the payment is for it, then match it again with confirm_payer true."
}
],
"request_id": "req_01JM000000E008000000000010"
}