Receivables (835) workspace operator playbook
Outcome
ERA files are uploaded, claims auto-match where the parser is confident, low-confidence and unmatched rows are reviewed and confirmed, exceptions are triaged, and line-level data is exportable for downstream reporting.
Prerequisites
remittances.createfor upload,remittances.readfor review,remittances.updatefor manual matching.- An ERA file (raw X12 835) on hand.
Upload an ERA
Open
Receivablesin the rcm-app. Click Upload ERA.Provide the ERA:
- Paste raw X12 835 into the textarea, or use the
.835/.txtfile picker. - The dialog refuses anything that doesn't start with
ISA. - Enter the canonical Payer ID (UUID).
- Optionally enter a Billing Entity ID to scope the resulting remittance row.
- Paste raw X12 835 into the textarea, or use the
Click Upload & Match. A toast reports
<matched>/<total> claims matched; you're auto-redirected to the new remittance detail page.
The route is POST /api/v1/remittances/parse. Server-side it runs
parse835 → processRemittance, which writes the remittance + claims +
lines + adjustments into billing.remittance* in a single transaction and
emits a REMITTANCE_EVENTS.MATCHED event.
Match-review tabs
The detail page splits matched claims by match_confidence:
| Tab | Filter | Operator action |
|---|---|---|
| Auto-matched | HIGH or MEDIUM and claim_id set | Audit only — read |
| Review queue | LOW and claim_id set | Accept (single click) or Re-match |
| Unmatched | claim_id IS NULL | Run Manual Match |
| Exceptions | Variance / duplicate / orphan signals | Triage (see below) |
| Adjustments | All CO/PR/OA/PI/CR rows | Reference |
| Trace | Check / EFT trace rows | Reference |
The Review-queue accept calls POST /api/v1/remittances/claims/:id/confirm,
writing a fresh MANUAL audit row in billing.remittance_match and
bumping match_confidence to HIGH. Re-match uses the manual-match
endpoint with force: true.
Manual matching
Open the Unmatched tab, click Match on a row.
Run the search — the dialog seeds the input with the PCN. Press Enter to fire
/api/v1/claims?q=….Pick a candidate. Each carries Member ID, DOS-from / DOS-to, charged amount, status.
Confirm the match. If
totalChargeAmountCentsdiffers from the remittance charged amount by more than $0.01, an amber banner warns — confirm only after eyeballing both rows.
Exceptions triage
GET /api/v1/remittances/:id/variances returns four exception classes:
| Category | Trigger | Triage |
|---|---|---|
OVERPAYMENT | actual paid > expected by > $1.00 | Recoupment risk — file a return-of-overpayment with the payer. |
UNDERPAYMENT | actual paid < expected by > $1.00 | Hand off to appeals via Denials and appeals; CARCs on the Adjustments tab tell the why. |
DUPLICATE_TRN | another remittance for the same payer carries the same TRN | Inspect the listed peer remittance IDs. If it was a payer reissue, mark remittance_type=REISSUE. Otherwise hold posting on one until resolved. |
ORPHAN_PAYMENT | unmatched remit_claim with total_paid_cents > 0 | Run Manual Match — cash is sitting in suspense. |
Tolerance is governed by EXCEPTION_TOLERANCE_CENTS (= 100¢). The
detector intentionally ignores zero-paid orphans (e.g. CO-only denial
remits) so the queue stays focused on cash-at-risk rows.
Line-level CSV export
The detail page Export Lines button hits
GET /api/v1/remittances/:id/lines/export and downloads a flattened-per-line
CSV with columns:
PCN · Remit Claim ID · Matched Claim ID · Line # · Procedure · Revenue · Units · DOS From · DOS To · Charged ($) · Paid ($) · PR ($) · CO ($) · Match Confidence · Match Method
Claim-level adjustments are reported on the first line of each claim so
column totals tie out on a SUM(...) pivot.
Audit + observability
- Every mutating route emits a
REMITTANCE_EVENTS.*envelope throughevent-bus.MATCHEDfires once perprocessRemittancecall. - The
billing.remittance_matchaudit table preserves every match decision;superseded_bychains expose the full re-match history. - Logs are tagged
service: "remittance-service"—journalctl -u rcm-core | grep remittance-serviceis the standard starting point for incident triage.
Validation
| Check | Expected |
|---|---|
| Upload returns 200 with match count | Yes |
| Auto-matched rows | Sane match confidence |
| Exceptions tab | Empty or fully triaged before close |
remittance_match audit chain | Complete history of decisions |
Troubleshooting
| Symptom | Cause | Fix |
|---|---|---|
| "Refused: not an X12 envelope" | File doesn't start with ISA | Ensure raw 835 (not unwrapped CSV/PDF). |
| All claims unmatched | Wrong payer ID, or PCN format mismatch | Confirm payer; check billing.claim.pcn format vs ERA. |
| Variance flagged but real | Payer applied unexpected adjustment | Open Adjustments tab; route to appeal. |
| Manual match candidate list empty | PCN search yields zero | Search by Member ID + DOS instead. |
Cross-references
- COB adjustment snapshot — primary 835 posting feeds the snapshot writer.
- Tertiary waterfall — auto-fires after every successful 835 post.
- Auto-correction operator playbook — for denials this workspace surfaces.