Spec notes: Telecom responses + B2/B3/E1
These notes record exactly what the @cosyte/ncpdp/telecom response reader decodes, where the
structural facts come from, and what it deliberately does not do. No NCPDP-copyrighted prose
is reproduced here. Field/segment labels below are our own short paraphrases; the codes and
field-number designators are factual identifiers from the NCPDP Telecommunication Standard vD.0 and
the NCPDP Data Dictionary (paywalled), recorded against our own paraphrased names.
What the response reader decodes
Reads a vD.0 Telecommunication response transmission: the fixed Response Transaction Header and the control-character-framed response segments, and lifts an adjudication view (status + disposition, pricing, DUR alerts). The same reader serves a B1 billing-claim response, a B2 reversal, a B3 rebill, and an E1 eligibility response. The response shape is identical; only the echoed Transaction Code differs. Liberal on parse; only structurally unrecoverable input throws a typed fatal.
Detecting a response vs a request
A request header leads with the routing BIN (101-A1) at offset 0 and carries the Version/Release
("D0") at offset 6. A response header leads with the Version/Release at offset 0. The two are told
apart by where "D0" sits. The request shape is checked first so a request is never mistaken for a
response. The fixed header region is then sliced up to the first structural framing char (GS/RS); the
Field Separator (FS) is excluded because it appears within a segment and never marks the
header→body boundary.
Fixed Response Transaction Header (D.0)
Positional, leading fields only. The safety-critical adjudication data lives in the framed segments,
not the header, so a mis-sized trailing field can never misread a paid/rejected outcome. Offsets
[name, offset, length]:
| Field | Designator | Offset | Length |
|---|---|---|---|
| Version/Release | 102-A2 | 0 | 2 |
| Transaction Code | 103-A3 | 2 | 2 |
| Transaction Count | 109-A9 | 4 | 1 |
| Header Response Status | 501-F1 | 5 | 1 |
| Service Provider ID Qualifier | 202-B2 | 6 | 2 |
| Service Provider ID | 201-B1 | 8 | 15 |
Header Response Status (501-F1) is the transmission-level accept/reject flag (A/R), distinct
from the per-claim Transaction Response Status (112-AN) in the Response Status segment.
Response segments + fields modeled
Segment Identification (111-AM) codes paraphrased, every response code this package names: 20
Response Message, 21 Response Status, 22 Response Claim, 23 Response Pricing, 24 Response
DUR/PPS, 25 Response Insurance, 26 Response Patient, 28 Response Coordination of Benefits. A
code outside this set is preserved verbatim and warned (NCPDP_TELECOM_UNKNOWN_SEGMENT).
The response range this package declares runs wider than the codes it names, and which codes inside it carry no name, and why, is recorded once for both sides under Telecom foundation and B1.
- Response Status (21):
ANTransaction Response Status (112-AN),FAReject Count (510-FA),FBReject Code (511-FB, repeating),F3Authorization Number (503-F3),FQAdditional Message Information (526-FQ). - Response Pricing (23):
F5Patient Pay Amount (505-F5),F9Total Amount Paid (509-F9),F6Ingredient Cost Paid (506-F6),F7Dispensing Fee Paid (507-F7),FMBasis of Reimbursement Determination (522-FM). - Response DUR/PPS (24):
J6DUR/PPS Response Code Counter (567-J6),E4Reason For Service Code (439-E4),FSClinical Significance Code (528-FS),FUPrevious Date Of Fill (530-FU),FVQuantity Of Previous Fill (531-FV),FYDUR Free Text Message (544-FY).
Safety-critical handling
-
A reject always wins. The disposition is a total function over the Transaction Response Status (112-AN) and the reject codes. Any reject present ⇒
"rejected", even when the status field claims paid; the conflict is surfaced (NCPDP_TELECOM_STATUS_CONFLICT,statusConflict: true). An unrecognized status reads"unknown", never paid (NCPDP_TELECOM_UNKNOWN_RESPONSE_STATUS). A declared positive Reject Count with no codes still resolves to rejected. -
Money is never a float. Dollar fields carry an implied 2-place decimal (cents) and an optional zoned-decimal overpunch sign on the final character (the EBCDIC-derived convention NCPDP inherits:
{,A–I = +0–9;},J–R = −0–9). Both are interpreted string-wise with the verbatim source kept; a signed zero normalizes to a non-negative0.00. Unrecognized input is preserved withisValid: falseand no interpreted amount. Money is never guessed or recomputed. -
No DUR alert is dropped. The DUR/PPS segment repeats its fields once per returned alert; the reader splits at each counter (567-J6) and at each new Reason For Service (439-E4) so two alerts are never collapsed into one. An unrecognized reject or reason code is preserved verbatim with
known: false. -
A label ships only where a public artifact establishes it. Reject Codes (511-FB) and Transaction Response Status values (112-AN) carry no label table, so the reject code comes back as the bare wire code with
known: falseand nodescription, and the status carries itsdispositionand nostatusDescription. What the one carried payer manual does and does not establish for each field, and why a partial table was withdrawn rather than shipped, is recorded in source beside each declaration. Reason For Service codes (439-E4) do carry short labels, from one cited and dated public payer manual, and that citation lives in source beside the table along with the single-source caveat that travels with it. Field by field:KNOWN-LIMITATIONS.md. -
Withdrawing a label changes nothing else on the path. The code is still verbatim, still in wire order, still never dropped, and still carries its recognition flag. The disposition is derived from the status and the rejects, never from a label, so the fail-safe above is unaffected.
What the response reader does NOT do
- No serializer/builder (emit), parse only.
- No COB/Other-Payer adjudication detail beyond preserving the segment verbatim.
- The DUR/PPS "other pharmacy / database / other prescriber" indicator fields (
FT/FW/FX) are tokenized and preserved verbatim on the raw segment but are not lifted onto theTelecomDurAlertview. Read them fromsegment.fieldsif needed. Nothing is dropped at the parse layer. - No multi-transaction emit. A response transmission carrying an answer per submitted claim is
decoded whole, and these views take a transaction index (
adjudication(t, 1), defaulting to the first), so a later claim's disposition is never read as the first one's.serializeTelecomstill writes one transaction per transmission and refuses a model carrying more. - DUR free text (544-FY) may be operationally PHI-adjacent; it is surfaced verbatim but never logged.
PHI
All fixtures are synthetic. Warnings and fatal errors carry only a stable code, a registry message selected by that code, and a position (byte offset + optional 2-char field id), never a field value.
Next
- Telecom foundation and B1: the request side these responses answer.
- Compound, COB and DUR depth: the response COB blocks and the DUR depth this page introduces.
- Guides: the adjudication read as a recipe.
- Troubleshooting and known limitations: every warning code named above, with what the reader did when it raised one.