# Claim status

> Ask where a claim stands, read the payer’s answer as a next step, and know when to ask again.

Page: https://payerworks.com/docs/claim-status · Markdown: https://payerworks.com/docs/claim-status.md

> Payerworks writes and explains files; it sends nothing to a payer. Every file a route writes says `transmitted: false`, and is yours to send on your own connection. A test key is for invented data only, never a real patient.

Write the claim status question as a 276 from JSON (POST /v1/claim-status/276), send it on your own connection, and give Payerworks the 277 that comes back (POST /v1/claim-status/explain). Each question is answered with where the claim stands, whether money is coming and how much, the next step, and when to ask again.

POST /v1/claims/follow-up works the other way round: send your open claims with the day each was sent, and your own history of when each payer paid, and each claim comes back with when its remittance is expected and whether it is late. Each payer’s days to pay are learned from your history alone, with how many paid claims they rest on, and only from five up.

## Routes

- [POST /v1/claim-status/276](#post-v1-claim-status-276): Write a 276
- [POST /v1/claim-status/explain](#post-v1-claim-status-explain): Explain a claim status answer
- [POST /v1/sandbox/claim-status](#post-v1-sandbox-claim-status): Run the claim status sandbox
- [GET /v1/codes/claim-status/{category}](#get-v1-codes-claim-status-category): A claim status category
- [GET /v1/codes/claim-status-code/{code}](#get-v1-codes-claim-status-code-code): A claim status code
- [POST /v1/claims/follow-up](#post-v1-claims-follow-up): Follow up on open claims

Each route shows its call with curl and with the two clients, then its real answer, shortened, and the fields it holds. The client calls assume one client made once, `const pw = new Payerworks()` in JavaScript or `pw = payerworks.Payerworks()` in Python, each reading PAYERWORKS_API_KEY and PAYERWORKS_BASE_URL, and `body` is the request.json shown.

### POST /v1/claim-status/276

**Write a 276.** Up to one hundred claim status questions, from the JSON shape most clearinghouse APIs take, written as one 005010X212 interchange for you to send on your own connection. Each question is checked field by field first, and nothing is written if any would be refused. A test key writes test files only.

Request

```bash
curl -sS -X POST "$PAYERWORKS_BASE_URL/v1/claim-status/276" \
  -H "Authorization: Bearer $PAYERWORKS_API_KEY" \
  -H "Content-Type: application/json" \
  -d @request.json
```

With the JavaScript client

```js
const answer = await pw.postClaimStatus276(body);
```

With the Python client

```python
answer = pw.post_claim_status_276(body)
```

request.json

```json
{
  "sender_id": "SAMPLEBILLER",
  "receiver_id": "99999",
  "control_number": 21,
  "payer_name": "SAMPLE HEALTH PLAN",
  "inquiry": {
    "tradingPartnerServiceId": "99999",
    "providers": [
      {
        "providerType": "BillingProvider",
        "npi": "1234567893",
        "organizationName": "SAMPLE FAMILY MEDICINE"
      }
    ],
    "subscriber": {
      "memberId": "W123456789",
      "firstName": "SAMPLE",
      "lastName": "PATIENT",
      "dateOfBirth": "19800214"
    },
    "encounter": {
      "trackingNumber": "STATUS-0001",
      "beginningDateOfService": "20261001",
      "endDateOfService": "20261001",
      "submittedAmount": "215.00",
      "patientControlNumber": "PW-2001"
    }
  }
}
```

The answer (200)

```json
{
  "version": "005010X212",
  "usage": "T",
  "x12": "ISA*00*          *00*          *ZZ*SAMPLEBILLER   *ZZ*99999          *261019*1500*^*00501*000000021*0*T*:~GS*HR*SAMPLEBILLER*99999*20261019*1500*21*X*005010X212~ST*276*0001*005010X212~BHT*0010*13*STATUS-0001*20261019*1500~HL*1**20*1~NM1*PR*…",
  "interchange_control_number": "000000021",
  "group_control_number": "21",
  "transaction_set_control_numbers": [
    "0001"
  ],
  "inquiries": [
    {
      "index": 0,
      "trace": "STATUS-0001",
      "transaction_set_control_number": "0001",
      "warnings": []
    }
  ],
  "transmitted": false
}
```

Shortened here: lists show their first two items and long strings are cut. The whole answer is this route’s example in [/openapi.json](https://payerworks.com/openapi.json).

| Field | Type | What it is |
| --- | --- | --- |
| `version` | string | The implementation guide written. |
| `usage` | one of "T", "P" | T or P. |
| `x12` | string | The whole interchange. |
| `interchange_control_number` | string |  |
| `group_control_number` | string |  |
| `transaction_set_control_numbers` | list of string |  |
| `segments` | integer |  |
| `transmitted` | the value false | Payerworks wrote the file and sent it nowhere. |
| `inquiries` | list of object |  |

### POST /v1/claim-status/explain

**Explain a claim status answer.** A 277 claim status answer, as X12 or as the JSON most clearinghouse APIs return, said per question: where the claim stands, whether money is coming and how much, what to do next and when to ask again. A claim the payer cannot find yet is never called a rejection, and a question the payer refused because of its own data is never asked again unchanged. A claim the payer’s search did not find comes back with the next questions to ask, in order, each built from the question you sent (asked.request) and what you hold (asked.known), never from a value you did not give; a payer whose system did not answer, with a retry schedule for the same day.

Request

```bash
curl -sS -X POST "$PAYERWORKS_BASE_URL/v1/claim-status/explain" \
  -H "Authorization: Bearer $PAYERWORKS_API_KEY" \
  -H "Content-Type: application/json" \
  -d @request.json
```

With the JavaScript client

```js
const answer = await pw.postClaimStatusExplain(body);
```

With the Python client

```python
answer = pw.post_claim_status_explain(body)
```

request.json

```json
{
  "x12": "ISA*00*          *00*          *ZZ*SAMPLEPAYER    *ZZ*SAMPLEBILLER   *261018*0900*^*00501*000000092*0*T*:~\nGS*HN*SAMPLEPAYER*SAMPLEBILLER*20261018*0900*92*X*005010X212~\nST*277*0001*005010X212~\nBHT*0010*08*STATUS-0001*20261018*0900*DG~\nHL*1**20*1~\nNM1*PR*2*SAMPLE HEALTH PLAN*****PI*99999~\nHL*2*1*21*1~\nNM1*41*2*SAMPLE FAMILY MEDICINE*****46*SAMPLEBILLER~\nHL*3*2*19*1~\nNM1*1P*2*SAMPLE FAMILY MEDICINE*****XX*1234567893~\nHL*4*3*22*0~\nNM1*IL*1*PATIENT*SAMPLE****MI*W123456789~\nTRN*2*STATUS-0001~\nSTC*F1:65*20261015**215*103.2*20261015*CHK*20261016*CHK10021~\nREF*1K*PAYER-CN-21~\nREF*EJ*PW-2001~\nDTP*472*RD8*20261001-20261001~\nHL*5*3*22*0~\nNM1*IL*1*PATIENT*SECOND****MI*W987654321~\nTRN*2*STATUS-0002~\nSTC*P3:123:1P*20261015**350*0*****P3:297:1P~\nREF*1K*PAYER-CN-22~\nREF*EJ*PW-2002~\nDTP*472*RD8*20261002-20261002~\nSE*23*0001~\nGE*1*92~\nIEA*1*000000092~",
  "asked": {
    "submitted_on": "2026-10-05",
    "today": "2026-10-19"
  }
}
```

The answer (200)

```json
{
  "kind": "277",
  "label_source": "paraphrase",
  "business_days": "Business days are Monday to Friday. Holidays are not counted, so a payer closed on a holiday may need one day more.",
  "today": "2026-10-19",
  "inquiries": [
    {
      "trace": "STATUS-0001",
      "claims": [
        0
      ],
      "answered_by": 0,
      "state": "paid",
      "meaning": "The claim was finalized and paid: the claim or line has been paid (STC F1:65).",
      "money": {
        "coming": "yes",
        "amount": 103.2,
        "check_number": "CHK10021",
        "check_date": "2026-10-16",
        "adjudicated_on": "2026-10-15",
        "why": "The payer reports $103.20 paid on check or payment CHK10021 dated 10/16/2026. The remittance (835) carries the allowed amount, the adjustments and the patient's share; this answer does not."
      },
      "next_step": {
        "action": "post_remittance",
        "words": "Nothing to send again. Post the remittance (835) when it arrives: it says what was allowed and what the patient owes."
      },
      "ask_again": {
        "after_business_days": null,
        "not_before": null,
        "never": true,
        "why": "The payer has paid it: the remittance (835) is the rest of the answer, and asking again returns the same."
      },
      "asks": [],
      "next_inquiries": [],
      "retry_schedule": null
    },
    {
      "trace": "STATUS-0002",
      "claims": [
        1
      ],
      "answered_by": 1,
      "state": "info_requested",
      "meaning": "The claim was pending for provider information: more information was asked of the provider (STC P3:123:1P).",
      "money": {
        "coming": "not_yet",
        "amount": 0,
        "check_number": "",
        "check_date": "",
        "adjudicated_on": "",
        "why": "Nothing is paid until the payer receives what it asked for."
      },
      "next_step": {
        "action": "send_records",
        "words": "Send the payer the records it asked for: medical notes or a report. The claim does not move until they arrive."
      },
      "ask_again": {
        "after_business_days": 5,
        "not_before": "2026-10-26",
        "never": false,
        "why": "After what was asked is sent. The usual schedule: 3, 5 and 7 business days apart, then every 10, counted from this answer."
      },
      "asks": [
        {
          "status_code": "297",
          "procedure_code": "",
          "words": "medical notes or a report"
        }
      ],
      "next_inquiries": [],
      "retry_schedule": null
    }
  ],
  "claims": [
    {
      "index": 0,
      "trace": "STATUS-0001",
      "payer_claim_number": "PAYER-CN-21",
      "clearinghouse_claim_number": "",
      "patient_control_number": "PW-2001",
      "service_date": {
        "from": "2026-10-01",
        "to": "2026-10-01"
      },
      "charge": 215,
      "status": {
        "category_code": "F1",
        "status_code": "65",
        "entity_code": ""
      },
      "state": "paid",
      "meaning": "The claim was finalized and paid: the claim or line has been paid (STC F1:65).",
      "money": {
        "coming": "yes",
        "amount": 103.2,
        "check_number": "CHK10021",
        "check_date": "2026-10-16",
        "adjudicated_on": "2026-10-15",
        "why": "The payer reports $103.20 paid on check or payment CHK10021 dated 10/16/2026. The remittance (835) carries the allowed amount, the adjustments and the patient's share; this answer does not."
      },
      "next_step": {
        "action": "post_remittance",
        "words": "Nothing to send again. Post the remittance (835) when it arrives: it says what was allowed and what the patient owes."
      },
      "ask_again": {
        "after_business_days": null,
        "not_before": null,
        "never": true,
        "why": "The payer has paid it: the remittance (835) is the rest of the answer, and asking again returns the same."
      },
      "asks": [],
      "next_inquiries": [],
      "retry_schedule": null,
      "lines": [],
      "matches_requested": null,
      "describes_replaced_claim": false
    },
    {
      "index": 1,
      "trace": "STATUS-0002",
      "payer_claim_number": "PAYER-CN-22",
      "clearinghouse_claim_number": "",
      "patient_control_number": "PW-2002",
      "service_date": {
        "from": "2026-10-02",
        "to": "2026-10-02"
      },
      "charge": 350,
      "status": {
        "category_code": "P3",
        "status_code": "123",
        "entity_code": "1P"
      },
      "state": "info_requested",
      "meaning": "The claim was pending for provider information: more information was asked of the provider (STC P3:123:1P).",
      "money": {
        "coming": "not_yet",
        "amount": 0,
        "check_number": "",
        "check_date": "",
        "adjudicated_on": "",
        "why": "Nothing is paid until the payer receives what it asked for."
      },
      "next_step": {
        "action": "send_records",
        "words": "Send the payer the records it asked for: medical notes or a report. The claim does not move until they arrive."
      },
      "ask_again": {
        "after_business_days": 5,
        "not_before": "2026-10-26",
        "never": false,
        "why": "After what was asked is sent. The usual schedule: 3, 5 and 7 business days apart, then every 10, counted from this answer."
      },
      "asks": [
        {
          "status_code": "297",
          "procedure_code": "",
          "words": "medical notes or a report"
        }
      ],
      "next_inquiries": [],
      "retry_schedule": null,
      "lines": [],
      "matches_requested": null,
      "describes_replaced_claim": false
    }
  ],
  "notices": [],
  "errors": []
}
```

| Field | Type | What it is |
| --- | --- | --- |
| `kind` | one of "277", "json" |  |
| `label_source` | the value "paraphrase" |  |
| `business_days` | string |  |
| `today` | string |  |
| `inquiries` | list of ClaimStatusReading |  |
| `claims` | list of ClaimStatusClaim |  |
| `notices` | list of object |  |
| `errors` | list of object |  |

### POST /v1/sandbox/claim-status

**Run the claim status sandbox.** Your claim status questions, as JSON or a 276, answered by the sandbox payer with a 277 in the same call and explained. It agrees with the claims sandbox: the same payer claim number and, for each claim, the same paid amount. How the member ID ends decides the answer.

Request

```bash
curl -sS -X POST "$PAYERWORKS_BASE_URL/v1/sandbox/claim-status" \
  -H "Authorization: Bearer $PAYERWORKS_API_KEY" \
  -H "Content-Type: application/json" \
  -d @request.json
```

With the JavaScript client

```js
const answer = await pw.postSandboxClaimStatus(body);
```

With the Python client

```python
answer = pw.post_sandbox_claim_status(body)
```

request.json

```json
{
  "inquiry": {
    "tradingPartnerServiceId": "99999",
    "providers": [
      {
        "providerType": "BillingProvider",
        "npi": "1234567893",
        "organizationName": "SAMPLE FAMILY MEDICINE"
      }
    ],
    "subscriber": {
      "memberId": "W12345INFO",
      "firstName": "SAMPLE",
      "lastName": "PATIENT",
      "dateOfBirth": "19800214"
    },
    "encounter": {
      "trackingNumber": "STATUS-0001",
      "beginningDateOfService": "20261001",
      "endDateOfService": "20261001",
      "submittedAmount": "215.00",
      "patientControlNumber": "PW-2001"
    }
  }
}
```

The answer (200)

```json
{
  "usage": "T",
  "transmitted": false,
  "control": {
    "inquiry": "000000001",
    "answer": "000000002"
  },
  "files": {
    "claim_status_inquiry_276": "ISA*00*          *00*          *ZZ*SUBMITTER      *ZZ*PWSANDBOX      *261019*1500*^*00501*000000001*0*T*:~GS*HR*SUBMITTER*PWSANDBOX*20261019*1500*1*X*005010X212~ST*276*0001*005010X212~BHT*0010*13*STATUS-0001*20261019*1500~HL*1**20*1~NM1*PR*…",
    "claim_status_277": "ISA*00*          *00*          *ZZ*PWSANDBOX      *ZZ*SUBMITTER      *261019*1500*^*00501*000000002*0*T*:~GS*HN*PWSANDBOX*SUBMITTER*20261019*1500*2*X*005010X212~ST*277*0001*005010X212~BHT*0010*08*STATUS-0001*20261019*1500*DG~HL*1**20*1~NM1*…"
  },
  "outcomes": [
    {
      "trace": "STATUS-0001",
      "reference": "PW-2001",
      "rule": "INFO",
      "outcome": "info_requested",
      "category": "P3",
      "status": "123",
      "entity": "1P",
      "payer_claim_number": "PWS0120638906",
      "charge": 215,
      "paid": 0
    }
  ],
  "explained": {
    "label_source": "paraphrase",
    "business_days": "Business days are Monday to Friday. Holidays are not counted, so a payer closed on a holiday may need one day more.",
    "today": "2026-10-19",
    "inquiries": [
      {
        "trace": "STATUS-0001",
        "claims": [
          0
        ],
        "answered_by": 0,
        "state": "info_requested",
        "meaning": "The claim was pending for provider information: more information was asked of the provider (STC P3:123:1P).",
        "money": {
          "coming": "not_yet",
          "amount": 0,
          "check_number": "",
          "check_date": "",
          "adjudicated_on": "",
          "why": "Nothing is paid until the payer receives what it asked for."
        },
        "next_step": {
          "action": "send_records",
          "words": "Send the payer the records it asked for: medical notes or a report. The claim does not move until they arrive."
        },
        "ask_again": {
          "after_business_days": 5,
          "not_before": "2026-10-26",
          "never": false,
          "why": "After what was asked is sent. The usual schedule: 3, 5 and 7 business days apart, then every 10, counted from this answer."
        },
        "asks": [
          {
            "status_code": "297",
            "procedure_code": "",
            "words": "medical notes or a report"
          }
        ],
        "next_inquiries": [],
        "retry_schedule": null
      }
    ],
    "claims": [
      {
        "index": 0,
        "trace": "STATUS-0001",
        "payer_claim_number": "PWS0120638906",
        "clearinghouse_claim_number": "",
        "patient_control_number": "PW-2001",
        "service_date": {
          "from": "2026-10-01",
          "to": "2026-10-01"
        },
        "charge": 215,
        "status": {
          "category_code": "P3",
          "status_code": "123",
          "entity_code": "1P"
        },
        "state": "info_requested",
        "meaning": "The claim was pending for provider information: more information was asked of the provider (STC P3:123:1P).",
        "money": {
          "coming": "not_yet",
          "amount": 0,
          "check_number": "",
          "check_date": "",
          "adjudicated_on": "",
          "why": "Nothing is paid until the payer receives what it asked for."
        },
        "next_step": {
          "action": "send_records",
          "words": "Send the payer the records it asked for: medical notes or a report. The claim does not move until they arrive."
        },
        "ask_again": {
          "after_business_days": 5,
          "not_before": "2026-10-26",
          "never": false,
          "why": "After what was asked is sent. The usual schedule: 3, 5 and 7 business days apart, then every 10, counted from this answer."
        },
        "asks": [
          {
            "status_code": "297",
            "procedure_code": "",
            "words": "medical notes or a report"
          }
        ],
        "next_inquiries": [],
        "retry_schedule": null,
        "lines": [],
        "matches_requested": null,
        "describes_replaced_claim": false
      }
    ],
    "notices": [],
    "errors": []
  }
}
```

Shortened here: lists show their first two items and long strings are cut. The whole answer is this route’s example in [/openapi.json](https://payerworks.com/openapi.json).

| Field | Type | What it is |
| --- | --- | --- |
| `usage` | the value "T" |  |
| `transmitted` | the value false |  |
| `control` | object |  |
| `files` | object |  |
| `outcomes` | list of object |  |
| `explained` | ClaimStatusAnswer |  |

### GET /v1/codes/claim-status/{category}

**A claim status category.** A claim status category code in words, read both ways: on a claim acknowledgment (277CA), whether it means accepted, rejected or denied, and in a claim status answer, the state the explainer gives it.

Request

```bash
curl -sS -X GET "$PAYERWORKS_BASE_URL/v1/codes/claim-status/P3" \
  -H "Authorization: Bearer $PAYERWORKS_API_KEY"
```

With the JavaScript client

```js
const answer = await pw.getCodesClaimStatusByCategory("P3");
```

With the Python client

```python
answer = pw.get_codes_claim_status_by_category("P3")
```

The answer (200)

```json
{
  "category": "P3",
  "words": "pending for provider information",
  "verdict": "A",
  "known": true,
  "acknowledgment_verdict": {
    "verdict": "A",
    "words": "Not a refusal: read on a claim acknowledgment (277CA), the claim was received, accepted, pended or finalized without a denial."
  },
  "status_answer": {
    "state": "info_requested",
    "meaning": "Pending for provider information."
  }
}
```

| Field | Type | What it is |
| --- | --- | --- |
| `category` | string |  |
| `words` | string |  |
| `verdict` | string | As read on a 277CA: A, R, D or empty. |
| `known` | boolean |  |
| `acknowledgment_verdict` | object |  |
| `status_answer` | object |  |

### GET /v1/codes/claim-status-code/{code}

**A claim status code.** A claim status code in words, and whether it names an entity.

Request

```bash
curl -sS -X GET "$PAYERWORKS_BASE_URL/v1/codes/claim-status-code/297" \
  -H "Authorization: Bearer $PAYERWORKS_API_KEY"
```

With the JavaScript client

```js
const answer = await pw.getCodesClaimStatusCodeByCode("297");
```

With the Python client

```python
answer = pw.get_codes_claim_status_code_by_code("297")
```

The answer (200)

```json
{
  "code": "297",
  "words": "medical notes or a report",
  "names_an_entity": false,
  "known": true,
  "label_source": "paraphrase"
}
```

| Field | Type | What it is |
| --- | --- | --- |
| `code` | string |  |
| `words` | string |  |
| `names_an_entity` | boolean |  |
| `known` | boolean |  |
| `label_source` | the value "paraphrase" |  |

### POST /v1/claims/follow-up

**Follow up on open claims.** Your open claims (up to 200) with the day each was sent, and your history of when each payer paid (up to 20,000 rows), or the 837Ps, 277CAs and 835s themselves. Each payer’s days to pay are learned from your history alone, with how many paid claims they rest on, and only from five up; below that the answer says there is not enough history. Each claim comes back with when its remittance is expected, whether it is late, and the next step: ask its status now, wait until a day, the next questions after a not found, or retries for a payer whose system did not answer. Your own follow-up codes come back as you sent them, never read. Nothing is stored, nothing is sent, and no payer is asked.

Request

```bash
curl -sS -X POST "$PAYERWORKS_BASE_URL/v1/claims/follow-up" \
  -H "Authorization: Bearer $PAYERWORKS_API_KEY" \
  -H "Content-Type: application/json" \
  -d @request.json
```

With the JavaScript client

```js
const answer = await pw.postClaimsFollowUp(body);
```

With the Python client

```python
answer = pw.post_claims_follow_up(body)
```

request.json

```json
{
  "claims": [
    {
      "reference": "PW-3001",
      "payer_id": "99999",
      "sent_on": "2026-10-01",
      "service_date": "2026-09-29",
      "charge_amount": 215
    },
    {
      "reference": "PW-3002",
      "payer_id": "99999",
      "sent_on": "2026-08-31",
      "service_date": "2026-08-27",
      "charge_amount": 150,
      "last_status": {
        "state": "not_found",
        "asked_on": "2026-10-02",
        "checks_made": 1
      }
    }
  ],
  "history": [
    {
      "payer_id": "99999",
      "sent_on": "2026-06-01",
      "remitted_on": "2026-06-19"
    },
    {
      "payer_id": "99999",
      "sent_on": "2026-06-15",
      "remitted_on": "2026-07-08"
    },
    {
      "payer_id": "99999",
      "sent_on": "2026-07-01",
      "remitted_on": "2026-07-17"
    },
    {
      "payer_id": "99999",
      "sent_on": "2026-07-20",
      "remitted_on": "2026-08-14"
    },
    {
      "payer_id": "99999",
      "sent_on": "2026-08-03",
      "remitted_on": "2026-08-21"
    },
    {
      "payer_id": "99999",
      "sent_on": "2026-08-17",
      "remitted_on": "2026-09-11"
    }
  ],
  "today": "2026-10-19"
}
```

The answer (200)

```json
{
  "today": "2026-10-19",
  "business_days": "Business days are Monday to Friday. Holidays are not counted, so a payer closed on a holiday may need one day more.",
  "floor": 5,
  "method": "Days to pay are calendar days from the day a claim was sent to the day its remittance (835) came, learned per payer from the history you sent. A payer's window runs from the 25th to the 90th percentile of its own days, with the median as th…",
  "payers": [
    {
      "payer_id": "99999",
      "history": {
        "n": 6,
        "median_days": 20.5,
        "p25_days": 18,
        "p90_days": 25,
        "min_days": 16,
        "max_days": 25,
        "remitted_from": "2026-06-19",
        "remitted_to": "2026-09-11"
      },
      "basis": "your_history",
      "words": "Your history: 6 paid claims from this payer, paid in 20.5 days at the median, and in 18 to 25 days from the 25th to the 90th percentile."
    }
  ],
  "claims": [
    {
      "index": 0,
      "reference": "PW-3001",
      "payer_id": "99999",
      "sent_on": "2026-10-01",
      "disposition": null,
      "open": true,
      "expected_by": {
        "from": "2026-10-19",
        "likely": "2026-10-22",
        "to": "2026-10-26",
        "basis": "your_history",
        "n": 6
      },
      "overdue": false,
      "days_since_sent": 18,
      "next_step": {
        "action": "wait_until",
        "on": "2026-10-27",
        "words": "Nothing to do yet: the remittance is expected by 10/26/2026, most likely around 10/22/2026. If none has come by then, ask the payer's status on 10/27/2026."
      },
      "inquiry_window": null,
      "next_inquiries": [],
      "retry_schedule": null
    },
    {
      "index": 1,
      "reference": "PW-3002",
      "payer_id": "99999",
      "sent_on": "2026-08-31",
      "disposition": null,
      "open": true,
      "expected_by": {
        "from": "2026-09-18",
        "likely": "2026-09-21",
        "to": "2026-09-25",
        "basis": "your_history",
        "n": 6
      },
      "overdue": true,
      "days_since_sent": 49,
      "next_step": {
        "action": "follow_not_found_plan",
        "on": "2026-10-19",
        "words": "The payer's search found no claim. A search can miss a claim the payer has: ask again with the next questions, in order (next_inquiries), before sending the claim again, since a claim the payer has, sent again, is a duplicate."
      },
      "inquiry_window": null,
      "next_inquiries": [
        {
          "step": 1,
          "kind": "add_charge_amount",
          "route": "POST /v1/claim-status/276",
          "builds_on": null,
          "status": "needs_value",
          "changes": [],
          "inquiry": null,
          "warnings": [],
          "errors": [],
          "needs": [
            "the question that found nothing (asked.request)"
          ],
          "why": "Add the claim's total charge: some payers search by it, and a question without it can miss the claim."
        },
        {
          "step": 2,
          "kind": "add_payer_claim_number",
          "route": "POST /v1/claim-status/276",
          "builds_on": null,
          "status": "needs_value",
          "changes": [],
          "inquiry": null,
          "warnings": [],
          "errors": [],
          "needs": [
            "the question that found nothing (asked.request)",
            "known.payer_claim_number"
          ],
          "why": "Add the payer's own claim number, from its claim acknowledgment (the 277CA's REF*1K): a payer finds its own number first. With no 277CA from the payer, there is no number to add: the payer may never have accepted the claim."
        }
      ],
      "retry_schedule": null
    }
  ],
  "counts": {
    "claims": 2,
    "open": 2,
    "overdue": 1,
    "not_overdue": 1,
    "cannot_say": 0
  },
  "history_used": {
    "rows": 6,
    "from_files": 0
  },
  "reads": "Reads only what you send. Nothing is stored, nothing is sent, and no payer is asked."
}
```

Shortened here: lists show their first two items and long strings are cut. The whole answer is this route’s example in [/openapi.json](https://payerworks.com/openapi.json).

| Field | Type | What it is |
| --- | --- | --- |
| `today` | string |  |
| `business_days` | string |  |
| `floor` | integer | The fewest paid claims a payer’s days to pay are read from. |
| `method` | string |  |
| `payers` | list of object |  |
| `claims` | list of object |  |
| `counts` | object |  |
| `history_used` | object |  |
| `reads` | string |  |

## Reading the answer

- A claim the payer cannot find (A4 or D0) is `not_found`, never a rejection. The answer gives the next questions to ask, in order, built only from what you sent.
- E1, E2 and 689 are the payer’s own system: ask again later, with the retry schedule the answer gives. E0, E3 and E4 are the question’s own error: correct it before asking again.
- Only F1 says paid. F0, F3, F3F and F3N wait for the amount, and a figure the payer did not state is `null`.
- The claims sandbox and the status sandbox agree: a status question about a sandbox claim answers the same payer claim number and paid amount as that claim’s 277CA and 835.

## Troubleshooting

- `invalid_inquiries` (422): One question would be refused, so nothing was written. Each question’s errors are listed with the field.
- `not_a_claim_status_answer` (422): The explain route reads a 277 claim status answer (005010X212). A 277CA is an acknowledgment: send it to POST /v1/acknowledgments/explain.
- `ambiguous_answer` (400): Send the answer once, as `x12` or as `json`, never both.
- A claim the payer did not find yet is often a claim it has not loaded: the answer says when to ask again rather than calling it lost.

Every refusal these routes may answer, with its status. Any route may also answer the codes every route shares, on [Every error](https://payerworks.com/docs/errors).

| Code | Status | What it means |
| --- | --- | --- |
| `ambiguous_answer` | 400 | Send the answer once: as `x12` or as `json`, not both. |
| `ambiguous_follow_up` | 400 | Send the claims once: as `claims` or as `files`, not both. |
| `ambiguous_question` | 400 | Send the claim status questions once: as `inquiry` or `inquiries`, or as `x12` (a 276), not both. |
| `invalid_category` | 400 | A claim status category is a letter and up to two letters or digits, such as A1 or F2. |
| `invalid_claim_status_json` | 400 | `json` is the JSON claim status answer, an object with its `claims` list (or its errors). |
| `invalid_follow_up_request` | 400 | A field of the request is not in the shape it takes; each problem is listed with its field. |
| `invalid_payer_name` | 400 | `payer_name` is the payer's name as the 276 writes it (2100A NM103): text of at most 60 characters. |
| `invalid_status_asked` | 400 | `asked` describes the question you asked; one of its fields is not in the form it takes. |
| `invalid_status_code` | 400 | A claim status code is one to five digits, such as 65 or 689. |
| `invalid_submitter_name` | 400 | `submitter_name` is your organization's name as the 276 writes it (2100B NM103): text of at most 60 characters. |
| `no_claim_status_answer` | 400 | Send the payer's claim status answer as `x12` (a 277) or `json` (the JSON answer). |
| `no_claims_to_follow` | 400 | Send the open claims as `claims` (each with its reference, payer_id and sent_on), or the files as `files` (x12_837, acknowledgments, remittances). |
| `no_inquiry` | 400 | Send the claim status question as `inquiry` (or `inquiries`), in the JSON claim status shape. |
| `too_many_inquiries` | 400 | At most 100 claim status questions a call. |
| `test_key_production_file` | 403 | A test key writes test interchanges only (ISA15 = T). Use a live key for a production file. |
| `answer_too_large` | 413 | This answer is larger than one response can carry: send less in each call (split the file, or send fewer claims or requests). |
| `file_too_large` | 413 | This file holds more than one call can read: the error names what was counted (`unit`) and the most one call reads (`limit`). Split it and send each part in its own call. |
| `too_much_to_follow` | 413 | More was sent than one call takes: the error names what was counted (`unit`) and the most one call takes (`limit`). |
| `duplicate_inquiry_trace` | 422 | Two questions in one file carry the same trace (encounter.trackingNumber); each must be unique so its answer matches back. |
| `invalid_inquiries` | 422 | One or more claim status questions would be refused; nothing was written. Each question's errors are listed. |
| `not_a_claim_status_answer` | 422 | This is not a claim status answer Payerworks reads: send a 277 (005010X212) or the JSON answer. |
| `not_a_claim_status_question` | 422 | This is not a claim status question: send a 276 (005010X212) as `x12`, or the questions as `inquiry` or `inquiries`. |

## Code lists

Any one code in words: [GET /v1/codes/claim-status/{category}](#get-v1-codes-claim-status-category), [GET /v1/codes/claim-status-code/{code}](#get-v1-codes-claim-status-code-code).

### The claim status sandbox’s member ID endings

A claim status question follows the claims list, so it agrees with that claim’s 277CA and 835: the same payer claim number and the same paid amount. These endings are the status sandbox’s own, the answers a status question alone can get:

| Ending | Outcome | What it answers |
| --- | --- | --- |
| `NOFILE` | `not_found` | A member ID ending in NOFILE is not found: the payer has no claim on file for the question (A4:35). It is never a rejection. |
| `SLOW` | `payer_error` | A member ID ending in SLOW gets no answer in time: the payer’s system did not respond (E2:689:PR), so there is nothing to record and the question is asked again on the next business day. |
| `INFO` | `info_requested` | A member ID ending in INFO is pended for information the payer already asked the provider for (P3:123:1P), and the answer names it: medical notes or a report (P3:297:1P). |
| `NOPAY` | `no_payment` | A member ID ending in NOPAY is finalized with no further payment forthcoming (F4:1). The claims sandbox pays the same claim, and the answer states what it paid: nothing more is coming. |

One exception: when a claim’s payment depends on its service lines (member IDs ending in D97), the status answer says the claim is finalized and leaves what was paid to the remittance, because a status question carries no lines.

### Where a claim stands (state)

`paid`, `denied`, `rejected`, `pending`, `info_requested`, `not_found`, `member_not_found`, `no_payment`, `finalized_unpaid`, `payer_error`, `request_error`, `review`

### The next step (action)

`post_remittance`, `work_denial`, `correct_and_resubmit`, `wait`, `confirm_receipt`, `check_coverage`, `ask_again`, `fix_request`, `send_records`, `send_information`, `read_remittance`, `read_answer`, `ask_other_entity`

## Example

[claim-status.mjs](https://payerworks.com/docs/examples/claim-status.mjs) runs every step below against the API with a test key. It needs [payerworks.mjs](https://payerworks.com/sdk/payerworks.mjs) and [sample-data.mjs](https://payerworks.com/docs/examples/sample-data.mjs) beside it.

claim-status.mjs

```js
// Payerworks example: claim status, a 276 written and a 277 explained. Docs: https://payerworks.com/docs/claim-status
//
// Run it with Node 18 or later, with the JavaScript client (https://payerworks.com/sdk/payerworks.mjs)
// and sample-data.mjs beside this file:
//   PAYERWORKS_API_KEY=pw_test_... PAYERWORKS_BASE_URL=<the base URL shown with your key> node claim-status.mjs
// A test key and invented data only. Payerworks sends nothing to a payer: every file it writes is yours.
import { pathToFileURL } from 'node:url';
import { Payerworks, PayerworksError } from './payerworks.mjs';
import { STATUS_QUESTION, SENDER_ID, PAYER_ID, copy, endingIn, refusalOf } from './sample-data.mjs';

/** @param {Payerworks} pw */
export async function run(pw) {
  // 1. Write the question as a 276, to send on your own connection.
  const written = await pw.postClaimStatus276({ sender_id: SENDER_ID, receiver_id: PAYER_ID, control_number: 21, payer_name: 'SAMPLE HEALTH PLAN', inquiry: copy(STATUS_QUESTION) });

  // 2. The status sandbox answers it as a 277, already explained.
  const sandbox = await pw.postSandboxClaimStatus({ inquiry: copy(STATUS_QUESTION) });

  // 3. Explain a 277 you hold: the same reading, from the file alone.
  const explained = await pw.postClaimStatusExplain({ x12: sandbox.files.claim_status_277 });
  const claim = explained.claims[0];

  // 4. A member ID ending in NOFILE: the payer has no claim on file. That is not found, never rejected.
  const notFound = await pw.postSandboxClaimStatus({ inquiry: endingIn(STATUS_QUESTION, 'NOFILE') });

  // 5. The failure path: the answer sent twice, as X12 and as JSON, is refused.
  const refused = await refusalOf(() => pw.postClaimStatusExplain({ x12: sandbox.files.claim_status_277, json: { claims: [] } }), { PayerworksError });

  return {
    written: { transmitted: written.transmitted },
    state: claim.state,
    next_step: Boolean(claim.next_step),
    not_found: notFound.explained.claims[0]?.state ?? notFound.explained.inquiries[0]?.state,
    refused,
  };
}

// Run as a script: node <this file>, with PAYERWORKS_API_KEY and PAYERWORKS_BASE_URL set.
if (process.argv[1] && import.meta.url === pathToFileURL(process.argv[1]).href) {
  console.log(JSON.stringify(await run(new Payerworks()), null, 2));
}
```

What it answered, run against the API in Payerworks’ own tests (your request ids will differ)

```json
{
  "written": {
    "transmitted": false
  },
  "state": "paid",
  "next_step": true,
  "not_found": "not_found",
  "refused": {
    "status": 400,
    "code": "ambiguous_answer",
    "request_id": "req_5"
  }
}
```
