@cosyte/x12
Classes
AckBuildError
Thrown by build999 / buildTA1 when the caller asks the library to
fabricate an inconsistent acknowledgment (most notably an accept paired
with errors). Carries a stable code for programmatic narrowing.
Throwing here is the documented contract for the cosyte ack archetype: the library mechanically builds the disposition it is told; if the disposition is internally inconsistent it refuses, surfacing the bug at the call site rather than silently lying to the inbound sender.
AckBuildError deliberately does NOT extend X12ParseError - the
parser-vs-builder distinction matters at the type level (a parser catch
should never catch a builder bug, and vice versa).
Example
import { AckBuildError, ACK_BUILD_ERROR_CODES } from "@cosyte/x12";
try {
build999({ ... ack: { ..., functional: { disposition: "A", ... } }, ... });
} catch (err) {
if (err instanceof AckBuildError) {
// err.code is one of ACK_BUILD_ERROR_CODES
}
}
Extends
Error
Constructors
Constructor
new AckBuildError(
code,message):AckBuildError
Internal
Construct a new AckBuildError. Both fields required so every thrower
pins a stable code.
Parameters
code
message
string
Returns
Overrides
Error.constructor
Properties
code
readonlycode:AckBuildErrorCode
Claim837BuildError
Thrown by "./build-837.js".build837P / build837I / build837D
when the supplied claim spec cannot be emitted as a conformant,
self-consistent 837 - most importantly when the HL hierarchy spine is
structurally impossible. Carries a stable code for programmatic
narrowing. Messages are PHI-clean: they name structural positions
(indices, level codes) and counts, never patient names or member ids.
Example
import { Claim837BuildError } from "@cosyte/x12";
try {
build837P(spec);
} catch (err) {
if (err instanceof Claim837BuildError) {
// err.code is one of CLAIM_837_BUILD_ERROR_CODES
}
}
Extends
Error
Constructors
Constructor
new Claim837BuildError(
code,message):Claim837BuildError
Internal
Parameters
code
message
string
Returns
Overrides
Error.constructor
Properties
code
readonlycode:Claim837BuildErrorCode
ClaimStatus277BuildError
Thrown by "./build-277.js".build277 / "./build-277.js".build277CA when the supplied claim-status spec cannot be
emitted as a conformant, self-consistent 277 - most importantly when its
nested tree cannot form a valid HL hierarchy. Carries a stable code for
programmatic narrowing. Deliberately does NOT extend X12ParseError or
X12BuildError - the domain-refusal distinction matters at the type
level.
Example
import { ClaimStatus277BuildError } from "@cosyte/x12";
try {
build277(spec);
} catch (err) {
if (err instanceof ClaimStatus277BuildError) {
// err.code is one of CLAIM_STATUS_277_BUILD_ERROR_CODES
}
}
Extends
Error
Constructors
Constructor
new ClaimStatus277BuildError(
code,message):ClaimStatus277BuildError
Internal
Parameters
code
message
string
Returns
Overrides
Error.constructor
Properties
code
readonlycode:ClaimStatus277BuildErrorCode
Eligibility271BuildError
Thrown by "./build-271.js".build271 when the supplied eligibility
spec cannot be emitted as a conformant, self-consistent 271 - most
importantly when its nested tree cannot form a valid HL hierarchy. Carries
a stable code for programmatic narrowing. Deliberately does NOT extend
X12ParseError or X12BuildError - the domain-refusal distinction
matters at the type level.
Example
import { Eligibility271BuildError } from "@cosyte/x12";
try {
build271(spec);
} catch (err) {
if (err instanceof Eligibility271BuildError) {
// err.code is one of ELIGIBILITY_271_BUILD_ERROR_CODES
}
}
Extends
Error
Constructors
Constructor
new Eligibility271BuildError(
code,message):Eligibility271BuildError
Internal
Parameters
code
message
string
Returns
Overrides
Error.constructor
Properties
code
readonlycode:Eligibility271BuildErrorCode
Enrollment834BuildError
Thrown by "./build-834.js".build834 when the supplied enrollment
spec cannot be emitted as a conformant, self-consistent 834 - most
importantly when a maintenance type code is outside the validated X12 875
subset. Carries a stable code for programmatic narrowing. Deliberately
does NOT extend X12ParseError or X12BuildError - the domain-refusal
distinction matters at the type level.
Example
import { Enrollment834BuildError } from "@cosyte/x12";
try {
build834(spec);
} catch (err) {
if (err instanceof Enrollment834BuildError) {
// err.code is one of ENROLLMENT_834_BUILD_ERROR_CODES
}
}
Extends
Error
Constructors
Constructor
new Enrollment834BuildError(
code,message):Enrollment834BuildError
Internal
Parameters
code
message
string
Returns
Overrides
Error.constructor
Properties
code
readonlycode:Enrollment834BuildErrorCode
LoopSpecDefinitionError
Thrown by defineLoopSpec when the supplied spec is structurally
invalid. Carries the offending path so a consumer fixing a typo doesn't
have to hunt: e.g. "segments[3].id" or "children[0].trigger".
Example
import { defineLoopSpec, LoopSpecDefinitionError } from "@cosyte/x12";
try {
defineLoopSpec({
id: "2300",
trigger: "clm",
segments: [{ id: "clm", usage: "required", max: 1 }],
});
} catch (err) {
if (err instanceof LoopSpecDefinitionError) {
// err.path === "trigger"
}
}
Extends
Error
Constructors
Constructor
new LoopSpecDefinitionError(
path,message):LoopSpecDefinitionError
Internal
Construct a new LoopSpecDefinitionError with the offending path.
Parameters
path
string
message
string
Returns
Overrides
Error.constructor
Properties
path
readonlypath:string
Premium820BuildError
Thrown by "./build-820.js".build820 when the supplied premium
spec cannot be emitted as a conformant, self-consistent 820. Carries a
stable code for programmatic narrowing. Deliberately does NOT extend
X12ParseError or X12BuildError - the domain-refusal distinction
matters at the type level.
Example
import { Premium820BuildError } from "@cosyte/x12";
try {
build820(spec);
} catch (err) {
if (err instanceof Premium820BuildError) {
// err.code is one of PREMIUM_820_BUILD_ERROR_CODES
}
}
Extends
Error
Constructors
Constructor
new Premium820BuildError(
code,message):Premium820BuildError
Internal
Parameters
code
"X12_820_BUILD_INVALID_SPEC"
message
string
Returns
Overrides
Error.constructor
Properties
code
readonlycode:"X12_820_BUILD_INVALID_SPEC"
Remit835BuildError
Thrown by "./build-835.js".build835 when the supplied remittance
spec cannot be emitted as a conformant, self-consistent 835 - most
importantly when it fails a §1.10.2 balance invariant. Carries a stable
code for programmatic narrowing. Deliberately does NOT extend
X12ParseError or X12BuildError - the domain-refusal distinction
matters at the type level.
Example
import { Remit835BuildError } from "@cosyte/x12";
try {
build835(spec);
} catch (err) {
if (err instanceof Remit835BuildError) {
// err.code is one of REMIT_835_BUILD_ERROR_CODES
}
}
Extends
Error
Constructors
Constructor
new Remit835BuildError(
code,message):Remit835BuildError
Internal
Parameters
code
message
string
Returns
Overrides
Error.constructor
Properties
code
readonlycode:Remit835BuildErrorCode
ServicesReview278BuildError
Thrown by "./build-278.js".build278Request / "./build-278.js".build278Response when the supplied services-review spec
cannot be emitted as a conformant, self-consistent 278 - most importantly
when its nested tree cannot form a valid HL hierarchy, or when a response's
HCR certification action is missing the verbatim actionCode the builder
is forbidden to infer. Carries a stable code for programmatic narrowing.
Deliberately does NOT extend X12ParseError or X12BuildError - the
domain-refusal distinction matters at the type level.
Example
import { ServicesReview278BuildError } from "@cosyte/x12";
try {
build278Request(spec);
} catch (err) {
if (err instanceof ServicesReview278BuildError) {
// err.code is one of AUTH_278_BUILD_ERROR_CODES
}
}
Extends
Error
Constructors
Constructor
new ServicesReview278BuildError(
code,message):ServicesReview278BuildError
Internal
Parameters
code
ServicesReview278BuildErrorCode
message
string
Returns
Overrides
Error.constructor
Properties
code
readonlycode:ServicesReview278BuildErrorCode
X12BuildError
Thrown by "./build-interchange.js".buildInterchange when the
supplied envelope spec is structurally impossible. Carries a stable code
for programmatic narrowing. Deliberately does NOT extend X12ParseError
- the parser-vs-builder distinction matters at the type level.
Example
import { X12BuildError } from "@cosyte/x12";
try {
buildInterchange({ ...spec, interchangeControlNumber: "0123456789" });
} catch (err) {
if (err instanceof X12BuildError) {
// err.code is one of X12_BUILD_ERROR_CODES
}
}
Extends
Error
Constructors
Constructor
new X12BuildError(
code,message):X12BuildError
Internal
Parameters
code
"X12_BUILD_INVALID_SPEC"
message
string
Returns
Overrides
Error.constructor
Properties
code
readonlycode:"X12_BUILD_INVALID_SPEC"
X12Decimal
String-backed decimal for X12 R-type elements. Immutable; arithmetic
returns a new X12Decimal. Equality is mathematical ("0.00"
equals "0"), not lexical - use toString() for byte-exact comparison.
Example
import { X12Decimal } from "@cosyte/x12";
const charge = X12Decimal.fromString("500.00");
const paid = X12Decimal.fromString("450.00");
const due = charge?.subtract(paid!);
due?.toString(); // "50.00"
due?.isZero(); // false
Properties
ZERO
readonlystaticZERO:X12Decimal
Canonical zero with scale: 0 - "0". Used as the additive identity
for balance reductions. Use X12Decimal.fromBigInt(0n, n) for a zero
at a specific scale.
Example
import { X12Decimal } from "@cosyte/x12";
X12Decimal.ZERO.toString(); // "0"
X12Decimal.ZERO.isZero(); // true
Methods
abs()
abs():
X12Decimal
Absolute value. Scale and lexical form may change (canonical rendering
drops the leading -).
Returns
Example
import { X12Decimal } from "@cosyte/x12";
X12Decimal.fromString("-50.00")?.abs().toString(); // "50.00"
add()
add(
other):X12Decimal
Add two X12Decimal values exactly. Result scale is
max(this.scale, other.scale); result lexical form is canonical.
Parameters
other
Returns
Example
import { X12Decimal } from "@cosyte/x12";
const a = X12Decimal.fromString("0.1")!;
const b = X12Decimal.fromString("0.2")!;
a.add(b).toString(); // "0.3" - exact, never 0.30000000000000004
compareTo()
compareTo(
other):-1|0|1
Three-way compare: -1 if this < other, 0 if equal, 1 if
this > other. Mathematical compare across scales.
Parameters
other
Returns
-1 | 0 | 1
Example
import { X12Decimal } from "@cosyte/x12";
X12Decimal.fromString("10")!.compareTo(X12Decimal.fromString("9.99")!); // 1
equals()
equals(
other):boolean
Mathematical equality across scales ("0.00" equals "0"). For
byte-exact comparison use a.toString() === b.toString().
Parameters
other
Returns
boolean
Example
import { X12Decimal } from "@cosyte/x12";
const a = X12Decimal.fromString("0.00")!;
const b = X12Decimal.fromString("0")!;
a.equals(b); // true
a.toString() === b.toString();// false ("0.00" vs "0")
isZero()
isZero():
boolean
True when this value is exactly zero (any scale).
Returns
boolean
Example
import { X12Decimal } from "@cosyte/x12";
X12Decimal.fromString("0.00")?.isZero(); // true
X12Decimal.fromString("-50")?.isZero(); // false
negate()
negate():
X12Decimal
Arithmetic negation. abs() === negate() for negative values; for
positive values flips sign; zero is its own negation.
Returns
Example
import { X12Decimal } from "@cosyte/x12";
X12Decimal.fromString("50.00")?.negate().toString(); // "-50.00"
X12Decimal.fromString("-50.00")?.negate().toString(); // "50.00"
signum()
signum():
-1|0|1
-1 / 0 / 1 indicating the sign of the value. Zero values
(including "0.00" and "-0.00") always return 0.
Returns
-1 | 0 | 1
Example
import { X12Decimal } from "@cosyte/x12";
X12Decimal.fromString("-50")?.signum(); // -1
X12Decimal.fromString("0.00")?.signum(); // 0
X12Decimal.fromString("0.01")?.signum(); // 1
subtract()
subtract(
other):X12Decimal
Subtract other from this exactly. Result scale is
max(this.scale, other.scale).
Parameters
other
Returns
Example
import { X12Decimal } from "@cosyte/x12";
X12Decimal.fromString("500.00")!.subtract(X12Decimal.fromString("50")!).toString();
// "450.00"
toNumber()
toNumber():
number
Lossy conversion to JS number. JSDoc warns: number cannot
represent every X12 monetary value exactly (0.1 + 0.2 !== 0.3).
Helpers return X12Decimal, not number; use this only for display
or when the loss is acceptable. Magnitudes large enough to lose
precision (> Number.MAX_SAFE_INTEGER after scaling) still convert
without throwing - silently lossy.
Returns
number
Example
import { X12Decimal } from "@cosyte/x12";
X12Decimal.fromString("1234.56")?.toNumber(); // 1234.56 (typically exact)
X12Decimal.fromString("0.1")?.toNumber(); // 0.1 (lossy at higher precision)
toString()
toString():
string
Return the verbatim lexical form (for X12Decimal.fromString)
or the canonical rendering (for arithmetic results / fromBigInt).
Round-trip is byte-exact when the value was produced by fromString.
Returns
string
Example
import { X12Decimal } from "@cosyte/x12";
X12Decimal.fromString("0050.00")?.toString(); // "0050.00" (verbatim)
X12Decimal.fromBigInt(5000n, 2).toString(); // "50.00" (canonical)
fromBigInt()
staticfromBigInt(value,scale):X12Decimal
Construct an X12Decimal from a BigInt magnitude + scale (decimal
places). Useful when arithmetic produces a result whose lexical form
the caller wants to control. raw is rendered canonically (sign +
integer + optional .fraction).
Parameters
value
bigint
scale
number
Returns
Example
import { X12Decimal } from "@cosyte/x12";
X12Decimal.fromBigInt(123456n, 2).toString(); // "1234.56"
X12Decimal.fromBigInt(-50n, 0).toString(); // "-50"
X12Decimal.fromBigInt(0n, 2).toString(); // "0.00"
fromString()
staticfromString(raw):X12Decimal|undefined
Decode an X12 R-type decimal element into an X12Decimal, or
undefined when the input is empty or does not match the shape
[+-]?digits(.digits?)?. Empty string returns undefined, never
zero - "not supplied" and "zero" are spec-distinct.
Parameters
raw
string
Returns
X12Decimal | undefined
Example
import { X12Decimal } from "@cosyte/x12";
X12Decimal.fromString("1234.56")?.toString(); // "1234.56"
X12Decimal.fromString("-50")?.signum(); // -1
X12Decimal.fromString(""); // undefined
X12Decimal.fromString("1,234.56"); // undefined (X12 forbids thousands sep)
X12ParseError
Thrown by parseX12 when the input violates one of the 4 unrecoverable
Tier-3 structural rules (missing ISA, truncated ISA, invalid ISA
delimiters, or empty input). Carries positional context plus a short
snippet of the offending input so consumers can log actionable errors.
Remarks
snippet is the library's ONE deliberate PHI exception, and it exists for
the four Tier-3 structural fatals only. Those are raised before the
envelope is readable and are undebuggable without a few bytes of context.
It may contain PHI/PII when parsing real interchanges (member IDs appear in
ISA-06/08 only as trading-partner IDs, not patient identity, but a real
claim / eligibility body elsewhere in the input can carry PHI). Redact at
the call site if required by your compliance posture; the library does not
redact snippets itself.
A strict-mode escalation of a Tier-2 warning carries snippet: "". That
error's message is the same frozen-registry entry the warning carried and
position locates it, so there is nothing to attach and nothing to
redact.
Example
import { parseX12, X12ParseError } from "@cosyte/x12";
try {
parseX12("");
} catch (err) {
if (err instanceof X12ParseError && err.code === "X12_EMPTY_INPUT") {
// handle empty input - err.position, err.snippet available
}
}
Extends
Error
Constructors
Constructor
new X12ParseError(
code,message,position,snippetText):X12ParseError
Internal
Construct a new X12ParseError. All four fields are required so every
thrower populates full positional context.
Parameters
code
message
string
position
snippetText
string
Returns
Overrides
Error.constructor
Properties
code
readonlycode:X12FatalCode
position
readonlyposition:X12Position
snippet
readonlysnippet:string
X12ProfileError
Thrown by defineProfile() and profile-validation code when a profile
definition is structurally invalid. Carries the offending profile name
(when known) so consumers can pinpoint which definition failed.
Example
import { defineProfile, X12ProfileError } from "@cosyte/x12";
try {
defineProfile({ name: "" });
} catch (err) {
if (err instanceof X12ProfileError) {
console.error(err.message, err.profileName);
}
}
Extends
Error
Constructors
Constructor
new X12ProfileError(
message,profileName?):X12ProfileError
Internal
Construct a new X12ProfileError. profileName is optional so the
name validator can throw before a usable name is available.
Parameters
message
string
profileName?
string
Returns
Overrides
Error.constructor
Properties
profileName
readonlyprofileName:string|undefined
Interfaces
Build271AddressSpec
A postal address (N3 + N4) attached to a subscriber / dependent name. Mirrors "./types.js".X12EligibilityAddress.
Example
import type { Build271AddressSpec } from "@cosyte/x12";
const a: Build271AddressSpec = {
lines: ["123 MAIN ST"], city: "ANYTOWN", state: "CA", postalCode: "90001",
};
Properties
city?
readonlyoptionalcity?:string
N4-01 - city.
countryCode?
readonlyoptionalcountryCode?:string
N4-04 - country code.
lines
readonlylines: readonlystring[]
N3 address lines (1-2).
postalCode?
readonlyoptionalpostalCode?:string
N4-03 - postal code.
state?
readonlyoptionalstate?:string
N4-02 - state / province.
Build271BenefitSpec
One eligibility-or-benefit line (EB, Loop 2110C/2110D). EB-01 is the
eligibility code; EB-03 carries one-or-more Service Type Codes (emitted
as a repeating simple element). Monetary + percent + quantity are
X12Decimal. Mirrors "./types.js".X12EligibilityBenefit
minus each service type's derived description.
Example
import type { Build271BenefitSpec } from "@cosyte/x12";
import { X12Decimal } from "@cosyte/x12";
const b: Build271BenefitSpec = {
eligibilityCode: "1", coverageLevelCode: "IND",
serviceTypeCodes: [{ code: "30" }], inPlanNetwork: "Y",
monetaryAmount: X12Decimal.fromString("1000.00")!,
};
Properties
authorizationRequired?
readonlyoptionalauthorizationRequired?:string
EB-11 - authorization / certification indicator.
coverageLevelCode?
readonlyoptionalcoverageLevelCode?:string
EB-02 - coverage level code (IND, FAM, …).
dates?
readonlyoptionaldates?: readonlyBuild271DateSpec[]
Loop 2120 benefit-related DTP dates.
eligibilityCode
readonlyeligibilityCode:string
EB-01 - eligibility or benefit information code.
inPlanNetwork?
readonlyoptionalinPlanNetwork?:string
EB-12 - in-plan-network indicator (Y / N / U / W).
insuranceTypeCode?
readonlyoptionalinsuranceTypeCode?:string
EB-04 - insurance type code.
messages?
readonlyoptionalmessages?: readonlystring[]
MSG free-form benefit messages.
monetaryAmount?
readonlyoptionalmonetaryAmount?:X12Decimal
EB-07 - monetary amount.
percent?
readonlyoptionalpercent?:X12Decimal
EB-08 - percent.
planCoverageDescription?
readonlyoptionalplanCoverageDescription?:string
EB-05 - plan coverage description.
quantity?
readonlyoptionalquantity?:X12Decimal
EB-10 - quantity.
quantityQualifier?
readonlyoptionalquantityQualifier?:string
EB-09 - quantity qualifier.
references?
readonlyoptionalreferences?: readonlyBuild271ReferenceSpec[]
Loop 2120 benefit-related REF identifiers.
relatedEntities?
readonlyoptionalrelatedEntities?: readonlyBuild271EntitySpec[]
Loop 2120C/D benefit-related entities (NM1).
serviceTypeCodes?
readonlyoptionalserviceTypeCodes?: readonlyBuild271ServiceTypeSpec[]
EB-03 - one-or-more Service Type Codes (emitted as a repeating element).
timePeriodQualifier?
readonlyoptionaltimePeriodQualifier?:string
EB-06 - time period qualifier.
Build271DateSpec
A DTP date / date-range on a subscriber, dependent, or benefit line. Mirrors "./types.js".X12EligibilityDate.
Example
import type { Build271DateSpec } from "@cosyte/x12";
const d: Build271DateSpec = { qualifier: "307", formatQualifier: "D8", value: "20260101" };
Properties
formatQualifier
readonlyformatQualifier:string
DTP-02 - date/time format qualifier (D8 / RD8).
qualifier
readonlyqualifier:string
DTP-01 - date/time qualifier.
value
readonlyvalue:string
DTP-03 - date/time value.
Build271DependentSpec
One dependent (Loop 2000D / 2100D) - a patient who is not the subscriber. Same benefit-bearing shape as a subscriber minus the nested dependents. Mirrors "./types.js".X12EligibilityDependent.
Example
import type { Build271DependentSpec } from "@cosyte/x12";
const d: Build271DependentSpec = {
name: { entityIdentifierCode: "03", entityTypeQualifier: "1", lastName: "DOE", firstName: "JUNIOR" },
benefits: [{ eligibilityCode: "1", coverageLevelCode: "IND" }],
};
Properties
benefits?
readonlyoptionalbenefits?: readonlyBuild271BenefitSpec[]
Loop 2110D eligibility / benefit lines.
dates?
readonlyoptionaldates?: readonlyBuild271DateSpec[]
Loop 2100D DTP dates.
name?
readonlyoptionalname?:Build271MemberSpec
Loop 2100D dependent name (NM1 + DMG + N3/N4).
references?
readonlyoptionalreferences?: readonlyBuild271ReferenceSpec[]
Loop 2100D REF identifiers.
traces?
readonlyoptionaltraces?: readonlyBuild271TraceSpec[]
Loop 2000D TRN reassociation traces.
Build271EntitySpec
A non-person entity (NM1) - the information-source payer (Loop 2100A) or information-receiver provider (Loop 2100B), or a benefit-related entity (Loop 2120C). Mirrors "./types.js".X12EligibilityEntity.
Example
import type { Build271EntitySpec } from "@cosyte/x12";
const payer: Build271EntitySpec = {
entityIdentifierCode: "PR", entityTypeQualifier: "2",
name: "MEDPAY INSURANCE", idQualifier: "PI", idCode: "00123",
};
Properties
entityIdentifierCode
readonlyentityIdentifierCode:string
NM1-01 - entity identifier code (PR payer, 1P provider, …).
entityTypeQualifier
readonlyentityTypeQualifier:string
NM1-02 - entity type qualifier (1 person, 2 non-person).
idCode?
readonlyoptionalidCode?:string
NM1-09 - identification code.
idQualifier?
readonlyoptionalidQualifier?:string
NM1-08 - identification code qualifier.
name
readonlyname:string
NM1-03 - organization / last name.
Build271EnvelopeSpec
Interchange + group + transaction identity for the built 271. Mirrors the
"../remit/build-835-types.js".Build835EnvelopeSpec; the builder
fixes GS-01 to "HB" and the version/release to "005010X279A1" (the
271 functional group + TR3) so the caller never hand-codes them.
Example
import type { Build271EnvelopeSpec } from "@cosyte/x12";
const env: Build271EnvelopeSpec = {
senderId: "MEDPAY", receiverId: "PROVIDER",
interchangeDate: "260601", interchangeTime: "1200",
interchangeControlNumber: "000000001",
groupControlNumber: "1", transactionSetControlNumber: "0001",
};
Properties
applicationReceiverCode?
readonlyoptionalapplicationReceiverCode?:string
GS-03 - application receiver code. Default: the interchange receiver id.
applicationSenderCode?
readonlyoptionalapplicationSenderCode?:string
GS-02 - application sender code. Default: the interchange sender id.
componentSeparator?
readonlyoptionalcomponentSeparator?:string
Component (sub-element) separator (ISA-16). Default ":".
elementSeparator?
readonlyoptionalelementSeparator?:string
Element separator (ISA byte 4). Default "*".
groupControlNumber
readonlygroupControlNumber:string
GS-06 / GE-02 - group control number.
groupDate?
readonlyoptionalgroupDate?:string
GS-04 - group date CCYYMMDD. Default: century-expanded ISA-09.
groupTime?
readonlyoptionalgroupTime?:string
GS-05 - group time HHMM. Default: the interchange time.
interchangeControlNumber
readonlyinterchangeControlNumber:string
ISA-13 / IEA-02 - interchange control number (zero-padded to 9 on emit).
interchangeDate
readonlyinterchangeDate:string
ISA-09 - interchange date YYMMDD.
interchangeTime
readonlyinterchangeTime:string
ISA-10 - interchange time HHMM.
receiverId
readonlyreceiverId:string
ISA-08 - interchange receiver id (padded to 15 on emit).
receiverQualifier?
readonlyoptionalreceiverQualifier?:string
ISA-07 - interchange receiver qualifier. Default "ZZ".
repetitionSeparator?
readonlyoptionalrepetitionSeparator?:string
Repetition separator (ISA-11). Default "^".
segmentTerminator?
readonlyoptionalsegmentTerminator?:string
Segment terminator (ISA byte 106). Default "~".
senderId
readonlysenderId:string
ISA-06 - interchange sender id (padded to 15 on emit).
senderQualifier?
readonlyoptionalsenderQualifier?:string
ISA-05 - interchange sender qualifier. Default "ZZ".
transactionSetControlNumber
readonlytransactionSetControlNumber:string
ST-02 / SE-02 - transaction set control number.
usageIndicator?
readonlyoptionalusageIndicator?:string
ISA-15 - usage indicator (P production, T test). Default "P".
Build271InformationReceiverSpec
One information receiver (Loop 2000B / 2100B) - the provider that requested eligibility. Carries the provider entity (NM1) and its subscribers.
Example
import type { Build271InformationReceiverSpec } from "@cosyte/x12";
const r: Build271InformationReceiverSpec = {
entity: { entityIdentifierCode: "1P", entityTypeQualifier: "2", name: "ANYTOWN CLINIC", idQualifier: "XX", idCode: "1234567890" },
subscribers: [],
};
Properties
entity
readonlyentity:Build271EntitySpec
Loop 2100B information-receiver provider entity (NM1).
subscribers
readonlysubscribers: readonlyBuild271SubscriberSpec[]
Loop 2000C subscribers (at least one required - a receiver with none is refused).
Build271InformationSourceSpec
One information source (Loop 2000A / 2100A) - the payer answering the eligibility request. Carries the payer entity (NM1) and its receivers.
Example
import type { Build271InformationSourceSpec } from "@cosyte/x12";
const src: Build271InformationSourceSpec = {
entity: { entityIdentifierCode: "PR", entityTypeQualifier: "2", name: "MEDPAY INSURANCE", idQualifier: "PI", idCode: "00123" },
receivers: [],
};
Properties
entity
readonlyentity:Build271EntitySpec
Loop 2100A information-source payer entity (NM1).
receivers
readonlyreceivers: readonlyBuild271InformationReceiverSpec[]
Loop 2000B receivers (at least one required - a source with none is refused).
Build271MemberSpec
A person (subscriber Loop 2100C / dependent Loop 2100D) decoded from
NM1 + the optional DMG demographics + N3/N4 address. idCode is the
member identifier (NM1-09) - synthetic-only in fixtures. Mirrors "./types.js".X12EligibilityMember.
Example
import type { Build271MemberSpec } from "@cosyte/x12";
const m: Build271MemberSpec = {
entityIdentifierCode: "IL", entityTypeQualifier: "1",
lastName: "DOE", firstName: "JANE", idQualifier: "MI", idCode: "MBR0001",
dateOfBirth: "19800101", genderCode: "F",
};
Properties
address?
readonlyoptionaladdress?:Build271AddressSpec
N3 + N4 postal address.
dateOfBirth?
readonlyoptionaldateOfBirth?:string
DMG-02 - date of birth (CCYYMMDD; emitted with DMG-01 = D8).
entityIdentifierCode
readonlyentityIdentifierCode:string
NM1-01 - entity identifier code (IL insured / subscriber, 03 dependent).
entityTypeQualifier
readonlyentityTypeQualifier:string
NM1-02 - entity type qualifier (1 person).
firstName?
readonlyoptionalfirstName?:string
NM1-04 - first name.
genderCode?
readonlyoptionalgenderCode?:string
DMG-03 - gender code (M / F / U).
idCode?
readonlyoptionalidCode?:string
NM1-09 - identification code (the member id).
idQualifier?
readonlyoptionalidQualifier?:string
NM1-08 - identification code qualifier (MI member id).
lastName?
readonlyoptionallastName?:string
NM1-03 - last name.
middleName?
readonlyoptionalmiddleName?:string
NM1-05 - middle name.
suffix?
readonlyoptionalsuffix?:string
NM1-07 - name suffix.
Build271ReferenceSpec
A REF supplemental identifier on a subscriber, dependent, or benefit line. Mirrors "./types.js".X12EligibilityReference.
Example
import type { Build271ReferenceSpec } from "@cosyte/x12";
const r: Build271ReferenceSpec = { qualifier: "6P", value: "GRP0001" };
Properties
description?
readonlyoptionaldescription?:string
REF-03 - description.
qualifier
readonlyqualifier:string
REF-01 - reference identification qualifier.
value
readonlyvalue:string
REF-02 - reference identification.
Build271ServiceTypeSpec
One Service Type Code (EB-03, X12 external code source 1365). Only the
verbatim code is supplied - the read side looks up its description
from the bundled snapshot, so the spec deliberately omits it.
Example
import type { Build271ServiceTypeSpec } from "@cosyte/x12";
const st: Build271ServiceTypeSpec = { code: "30" };
Properties
code
readonlycode:string
EB-03 - a single Service Type Code.
Build271Spec
The complete spec for "./build-271.js".build271: the envelope plus the nested informationSources → receivers → subscribers → (dependents) tree the builder walks depth-first to compute the HL spine.
Example
import { build271, X12Decimal, type Build271Spec } from "@cosyte/x12";
const spec: Build271Spec = {
envelope: {
senderId: "MEDPAY", receiverId: "PROVIDER",
interchangeDate: "260601", interchangeTime: "1200",
interchangeControlNumber: "000000001",
groupControlNumber: "1", transactionSetControlNumber: "0001",
},
informationSources: [{
entity: { entityIdentifierCode: "PR", entityTypeQualifier: "2", name: "MEDPAY INSURANCE", idQualifier: "PI", idCode: "00123" },
receivers: [{
entity: { entityIdentifierCode: "1P", entityTypeQualifier: "2", name: "ANYTOWN CLINIC", idQualifier: "XX", idCode: "1234567890" },
subscribers: [{
traces: [{ traceTypeCode: "2", referenceId: "ELIG001" }],
name: { entityIdentifierCode: "IL", entityTypeQualifier: "1", lastName: "DOE", firstName: "JANE", idQualifier: "MI", idCode: "MBR0001" },
benefits: [{ eligibilityCode: "1", coverageLevelCode: "IND", serviceTypeCodes: [{ code: "30" }], monetaryAmount: X12Decimal.fromString("1000.00")! }],
}],
}],
}],
};
const ix = build271(spec);
Properties
envelope
readonlyenvelope:Build271EnvelopeSpec
Interchange + group + transaction identity.
informationSources
readonlyinformationSources: readonlyBuild271InformationSourceSpec[]
Loop 2000A information sources (at least one required).
Build271SubscriberSpec
One subscriber (Loop 2000C / 2100C). Holds the echoed TRN traces, the subscriber name + demographics, the eligibility/benefit lines, and any non-subscriber dependents. Mirrors "./types.js".X12EligibilitySubscriber.
Example
import type { Build271SubscriberSpec } from "@cosyte/x12";
const s: Build271SubscriberSpec = {
traces: [{ traceTypeCode: "2", referenceId: "ELIG001" }],
name: { entityIdentifierCode: "IL", entityTypeQualifier: "1", lastName: "DOE", firstName: "JANE" },
benefits: [{ eligibilityCode: "1", coverageLevelCode: "IND" }],
};
Properties
benefits?
readonlyoptionalbenefits?: readonlyBuild271BenefitSpec[]
Loop 2110C eligibility / benefit lines.
dates?
readonlyoptionaldates?: readonlyBuild271DateSpec[]
Loop 2100C DTP dates.
dependents?
readonlyoptionaldependents?: readonlyBuild271DependentSpec[]
Loop 2000D dependents (a non-empty list sets the subscriber HL-04 to "1").
name?
readonlyoptionalname?:Build271MemberSpec
Loop 2100C subscriber name (NM1 + DMG + N3/N4).
references?
readonlyoptionalreferences?: readonlyBuild271ReferenceSpec[]
Loop 2100C REF identifiers.
traces?
readonlyoptionaltraces?: readonlyBuild271TraceSpec[]
Loop 2000C TRN reassociation traces.
Build271TraceSpec
A reassociation trace (TRN). The verbatim echo of the requesting 270's
trace number - referenceId (TRN-02) is the value a provider matches
against the trace it sent. Mirrors "./types.js".X12EligibilityTrace.
Example
import type { Build271TraceSpec } from "@cosyte/x12";
const t: Build271TraceSpec = { traceTypeCode: "2", referenceId: "ELIG20260627001" };
Properties
originatingCompanyId?
readonlyoptionaloriginatingCompanyId?:string
TRN-03 - originating company identifier.
referenceId
readonlyreferenceId:string
TRN-02 - reference identification (echoed verbatim from the 270).
supplementalReferenceId?
readonlyoptionalsupplementalReferenceId?:string
TRN-04 - supplemental reference identifier.
traceTypeCode
readonlytraceTypeCode:string
TRN-01 - trace type code (2 referenced - added by the payer in the 271).
Build277ClaimSpec
One claim status-tracking loop (Loop 2200). A claim opens on a TRN (claim-level reassociation trace) or - in a 277CA provider-level batch acknowledgment - on a standalone STC. Carries at most one trace, the claim-level STC statuses, supplemental REF / DTP, and any service-line statuses (Loop 2220). Mirrors "./types.js".X12ClaimStatus.
Example
import type { Build277ClaimSpec } from "@cosyte/x12";
const c: Build277ClaimSpec = {
trace: { traceTypeCode: "2", referenceId: "CLAIM001" },
statuses: [{ statuses: [{ categoryCode: "A2", statusCode: "20" }] }],
};
Properties
dates?
readonlyoptionaldates?: readonlyBuild277DateSpec[]
Claim-level DTP dates.
references?
readonlyoptionalreferences?: readonlyBuild277ReferenceSpec[]
Claim-level REF identifiers.
serviceLines?
readonlyoptionalserviceLines?: readonlyBuild277ServiceLineSpec[]
Loop 2220 service lines.
statuses?
readonlyoptionalstatuses?: readonlyBuild277StatusSpec[]
Claim-level STC statuses.
trace?
readonlyoptionaltrace?:Build277TraceSpec
Loop 2200 TRN reassociation trace (opens the claim; at most one).
Build277DateSpec
A DTP date / date-range on a claim or service-line status. Mirrors "./types.js".X12StatusDate.
Example
import type { Build277DateSpec } from "@cosyte/x12";
const d: Build277DateSpec = { qualifier: "472", formatQualifier: "RD8", value: "20260601-20260601" };
Properties
formatQualifier
readonlyformatQualifier:string
DTP-02 - date/time format qualifier (D8 / RD8).
qualifier
readonlyqualifier:string
DTP-01 - date/time qualifier.
value
readonlyvalue:string
DTP-03 - date/time value.
Build277DependentSpec
One dependent (Loop 2000E / 2100E) - a patient who is not the subscriber. Carries the optional member NM1 and the claims tracked for that dependent.
Example
import type { Build277DependentSpec } from "@cosyte/x12";
const d: Build277DependentSpec = {
member: { entityIdentifierCode: "QC", entityTypeQualifier: "1", lastName: "DOE", firstName: "JUNIOR" },
claims: [{ trace: { traceTypeCode: "2", referenceId: "CLAIM002" } }],
};
Properties
claims
readonlyclaims: readonlyBuild277ClaimSpec[]
Loop 2200 claims tracked for the dependent (at least one required).
member?
readonlyoptionalmember?:Build277MemberSpec
Loop 2100E dependent member (NM1).
Build277EntitySpec
A non-person entity (NM1) - the information-source payer (Loop 2100A), information receiver (2100B), or service provider (2100C). Mirrors "./types.js".X12StatusEntity.
Example
import type { Build277EntitySpec } from "@cosyte/x12";
const payer: Build277EntitySpec = {
entityIdentifierCode: "PR", entityTypeQualifier: "2",
name: "MEDPAY INSURANCE", idQualifier: "PI", idCode: "00123",
};
Properties
entityIdentifierCode
readonlyentityIdentifierCode:string
NM1-01 - entity identifier code (PR payer, 41 receiver, 1P provider).
entityTypeQualifier
readonlyentityTypeQualifier:string
NM1-02 - entity type qualifier (1 person, 2 non-person).
idCode?
readonlyoptionalidCode?:string
NM1-09 - identification code.
idQualifier?
readonlyoptionalidQualifier?:string
NM1-08 - identification code qualifier.
name
readonlyname:string
NM1-03 - organization name.
Build277EnvelopeSpec
Interchange + group + transaction identity for the built 277 / 277CA.
Mirrors the "../remit/build-835-types.js".Build835EnvelopeSpec;
the builder fixes GS-01 to "HN" and ST-01 to "277". ST-03 / GS-08 are
the version supplied by the builder entry point (005010X212 for
"./build-277.js".build277, 005010X214 for
"./build-277.js".build277CA) so the caller never hand-codes them.
Example
import type { Build277EnvelopeSpec } from "@cosyte/x12";
const env: Build277EnvelopeSpec = {
senderId: "MEDPAY", receiverId: "PROVIDER",
interchangeDate: "260601", interchangeTime: "1200",
interchangeControlNumber: "000000001",
groupControlNumber: "1", transactionSetControlNumber: "0001",
};
Properties
applicationReceiverCode?
readonlyoptionalapplicationReceiverCode?:string
GS-03 - application receiver code. Default: the interchange receiver id.
applicationSenderCode?
readonlyoptionalapplicationSenderCode?:string
GS-02 - application sender code. Default: the interchange sender id.
componentSeparator?
readonlyoptionalcomponentSeparator?:string
Component (sub-element) separator (ISA-16). Default ":".
elementSeparator?
readonlyoptionalelementSeparator?:string
Element separator (ISA byte 4). Default "*".
groupControlNumber
readonlygroupControlNumber:string
GS-06 / GE-02 - group control number.
groupDate?
readonlyoptionalgroupDate?:string
GS-04 - group date CCYYMMDD. Default: century-expanded ISA-09.
groupTime?
readonlyoptionalgroupTime?:string
GS-05 - group time HHMM. Default: the interchange time.
interchangeControlNumber
readonlyinterchangeControlNumber:string
ISA-13 / IEA-02 - interchange control number (zero-padded to 9 on emit).
interchangeDate
readonlyinterchangeDate:string
ISA-09 - interchange date YYMMDD.
interchangeTime
readonlyinterchangeTime:string
ISA-10 - interchange time HHMM.
receiverId
readonlyreceiverId:string
ISA-08 - interchange receiver id (padded to 15 on emit).
receiverQualifier?
readonlyoptionalreceiverQualifier?:string
ISA-07 - interchange receiver qualifier. Default "ZZ".
repetitionSeparator?
readonlyoptionalrepetitionSeparator?:string
Repetition separator (ISA-11). Default "^".
segmentTerminator?
readonlyoptionalsegmentTerminator?:string
Segment terminator (ISA byte 106). Default "~".
senderId
readonlysenderId:string
ISA-06 - interchange sender id (padded to 15 on emit).
senderQualifier?
readonlyoptionalsenderQualifier?:string
ISA-05 - interchange sender qualifier. Default "ZZ".
transactionSetControlNumber
readonlytransactionSetControlNumber:string
ST-02 / SE-02 - transaction set control number.
usageIndicator?
readonlyoptionalusageIndicator?:string
ISA-15 - usage indicator (P production, T test). Default "P".
Build277InformationReceiverSpec
One information receiver (Loop 2000B / 2100B). Carries the receiver entity (NM1) and its service providers.
Example
import type { Build277InformationReceiverSpec } from "@cosyte/x12";
const r: Build277InformationReceiverSpec = {
entity: { entityIdentifierCode: "41", entityTypeQualifier: "2", name: "CLEARINGHOUSE", idQualifier: "46", idCode: "CH001" },
providers: [],
};
Properties
entity
readonlyentity:Build277EntitySpec
Loop 2100B information-receiver entity (NM1).
providers
readonlyproviders: readonlyBuild277ProviderSpec[]
Loop 2000C service providers (at least one required - a receiver with none is refused).
Build277InformationSourceSpec
One information source (Loop 2000A / 2100A) - the payer answering the claim-status request. Carries the payer entity (NM1) and its receivers.
Example
import type { Build277InformationSourceSpec } from "@cosyte/x12";
const src: Build277InformationSourceSpec = {
entity: { entityIdentifierCode: "PR", entityTypeQualifier: "2", name: "MEDPAY INSURANCE", idQualifier: "PI", idCode: "00123" },
receivers: [],
};
Properties
entity
readonlyentity:Build277EntitySpec
Loop 2100A information-source payer entity (NM1).
receivers
readonlyreceivers: readonlyBuild277InformationReceiverSpec[]
Loop 2000B receivers (at least one required - a source with none is refused).
Build277MemberSpec
A person (subscriber Loop 2100D / dependent Loop 2100E) decoded from an
NM1. idCode is the member identifier (NM1-09) - synthetic-only in
fixtures. Mirrors "./types.js".X12StatusMember.
Example
import type { Build277MemberSpec } from "@cosyte/x12";
const m: Build277MemberSpec = {
entityIdentifierCode: "QC", entityTypeQualifier: "1",
lastName: "DOE", firstName: "JANE", idQualifier: "MI", idCode: "MBR0001",
};
Properties
entityIdentifierCode
readonlyentityIdentifierCode:string
NM1-01 - entity identifier code (QC patient, IL insured).
entityTypeQualifier
readonlyentityTypeQualifier:string
NM1-02 - entity type qualifier (1 person).
firstName?
readonlyoptionalfirstName?:string
NM1-04 - first name.
idCode?
readonlyoptionalidCode?:string
NM1-09 - identification code (the member id).
idQualifier?
readonlyoptionalidQualifier?:string
NM1-08 - identification code qualifier (MI member id).
lastName?
readonlyoptionallastName?:string
NM1-03 - last name.
middleName?
readonlyoptionalmiddleName?:string
NM1-05 - middle name.
suffix?
readonlyoptionalsuffix?:string
NM1-07 - name suffix.
Build277ProviderSpec
One service provider (Loop 2000C / 2100C - HL level 19). Carries the provider entity (NM1) and its subscribers.
Example
import type { Build277ProviderSpec } from "@cosyte/x12";
const p: Build277ProviderSpec = {
entity: { entityIdentifierCode: "1P", entityTypeQualifier: "2", name: "ANYTOWN CLINIC", idQualifier: "XX", idCode: "1234567890" },
subscribers: [],
};
Properties
entity
readonlyentity:Build277EntitySpec
Loop 2100C service-provider entity (NM1).
subscribers
readonlysubscribers: readonlyBuild277SubscriberSpec[]
Loop 2000D subscribers (at least one required - a provider with none is refused).
Build277ReferenceSpec
A REF supplemental identifier on a claim or service-line status. Mirrors "./types.js".X12StatusReference.
Example
import type { Build277ReferenceSpec } from "@cosyte/x12";
const r: Build277ReferenceSpec = { qualifier: "1K", value: "PCN0001" };
Properties
description?
readonlyoptionaldescription?:string
REF-03 - description.
qualifier
readonlyqualifier:string
REF-01 - reference identification qualifier.
value
readonlyvalue:string
REF-02 - reference identification.
Build277ServiceLineSpec
One service-line status (Loop 2220). Triggered by an SVC; carries the procedure / revenue identification, line amounts, and its own STC statuses + REF / DTP. Mirrors "./types.js".X12ServiceLineStatus.
Example
import type { Build277ServiceLineSpec } from "@cosyte/x12";
import { X12Decimal } from "@cosyte/x12";
const l: Build277ServiceLineSpec = {
serviceIdQualifier: "HC", procedureCode: "99213", modifiers: ["25"],
lineChargeAmount: X12Decimal.fromString("150.00")!,
// SVC-07 is required in 005010X212, so `build277` refuses a line without it.
unitsOfService: X12Decimal.fromString("1")!,
statuses: [{ statuses: [{ categoryCode: "F2", statusCode: "65" }] }],
};
Properties
dates?
readonlyoptionaldates?: readonlyBuild277DateSpec[]
Loop 2220 DTP dates.
lineChargeAmount?
readonlyoptionallineChargeAmount?:X12Decimal
SVC-02 - line charge amount.
linePaymentAmount?
readonlyoptionallinePaymentAmount?:X12Decimal
SVC-03 - line payment amount.
modifiers?
readonlyoptionalmodifiers?: readonlystring[]
SVC-01 components 3..6 - procedure modifiers.
procedureCode?
readonlyoptionalprocedureCode?:string
SVC-01 component 2 - procedure code.
references?
readonlyoptionalreferences?: readonlyBuild277ReferenceSpec[]
Loop 2220 REF identifiers.
revenueCode?
readonlyoptionalrevenueCode?:string
SVC-04 - revenue code.
serviceIdQualifier?
readonlyoptionalserviceIdQualifier?:string
SVC-01 component 1 - product/service id qualifier (HC, NU, …).
statuses?
readonlyoptionalstatuses?: readonlyBuild277StatusSpec[]
Loop 2220 STC statuses.
unitsOfService?
readonlyoptionalunitsOfService?:X12Decimal
SVC-07 - units of service count (data element 380).
Usage differs by TR3 and so does the builder. In 005010X212 the
element is REQUIRED, so "./build-277.js".build277 REFUSES a
service line that omits it rather than emit a document short a required
element. In 005010X214 it is SITUATIONAL, so
"./build-277.js".build277CA emits it when supplied and omits it
otherwise. Nothing is ever defaulted: a count the caller did not supply
is a count nobody sent, and inventing one would put a quantity on the
wire that no submitter stands behind.
Build277Spec
The complete spec for "./build-277.js".build277 / "./build-277.js".build277CA: the envelope plus the nested informationSources → receivers → providers → subscribers → (dependents) tree the builder walks depth-first to compute the HL spine.
Example
import { build277, X12Decimal, type Build277Spec } from "@cosyte/x12";
const spec: Build277Spec = {
envelope: {
senderId: "MEDPAY", receiverId: "PROVIDER",
interchangeDate: "260601", interchangeTime: "1200",
interchangeControlNumber: "000000001",
groupControlNumber: "1", transactionSetControlNumber: "0001",
},
informationSources: [{
entity: { entityIdentifierCode: "PR", entityTypeQualifier: "2", name: "MEDPAY INSURANCE", idQualifier: "PI", idCode: "00123" },
receivers: [{
entity: { entityIdentifierCode: "41", entityTypeQualifier: "2", name: "CLEARINGHOUSE", idQualifier: "46", idCode: "CH001" },
providers: [{
entity: { entityIdentifierCode: "1P", entityTypeQualifier: "2", name: "ANYTOWN CLINIC", idQualifier: "XX", idCode: "1234567890" },
subscribers: [{
member: { entityIdentifierCode: "QC", entityTypeQualifier: "1", lastName: "DOE", firstName: "JANE" },
claims: [{
trace: { traceTypeCode: "2", referenceId: "CLAIM001" },
statuses: [{ statuses: [{ categoryCode: "A2", statusCode: "20" }], totalChargeAmount: X12Decimal.fromString("150.00")! }],
}],
}],
}],
}],
}],
};
const ix = build277(spec);
Properties
envelope
readonlyenvelope:Build277EnvelopeSpec
Interchange + group + transaction identity.
informationSources
readonlyinformationSources: readonlyBuild277InformationSourceSpec[]
Loop 2000A information sources (at least one required).
Build277StatusCodeSpec
One Health Care Claim Status composite (C043 - STC-01 / STC-10 / STC-11). Pairs a CSCC (category, source 507) with a CSC (status, source 508) and the responsible entity. Only the verbatim codes are supplied - the read side resolves the descriptions. Mirrors "./types.js".X12StatusCode minus the derived descriptions.
Example
import type { Build277StatusCodeSpec } from "@cosyte/x12";
const c: Build277StatusCodeSpec = { categoryCode: "A2", statusCode: "20", entityCode: "PR" };
Properties
categoryCode
readonlycategoryCode:string
C043-01 - Claim Status Category Code (CSCC). Required on the first composite.
entityCode?
readonlyoptionalentityCode?:string
C043-03 - responsible entity code.
statusCode?
readonlyoptionalstatusCode?:string
C043-02 - Claim Status Code (CSC).
Build277StatusSpec
One decoded STC segment - the headline status fields plus the up-to-three Build277StatusCodeSpec composites (STC-01, STC-10, STC-11). The first composite (STC-01) is required and must carry a category code. Mirrors "./types.js".X12StatusInfo.
Example
import type { Build277StatusSpec } from "@cosyte/x12";
import { X12Decimal } from "@cosyte/x12";
const s: Build277StatusSpec = {
statuses: [{ categoryCode: "A2", statusCode: "20" }],
statusEffectiveDate: "20260627",
totalChargeAmount: X12Decimal.fromString("150.00")!,
};
Properties
actionCode?
readonlyoptionalactionCode?:string
STC-03 - action code.
adjudicationDate?
readonlyoptionaladjudicationDate?:string
STC-06 - adjudication / payment date.
message?
readonlyoptionalmessage?:string
STC-12 - free-form message.
paymentAmount?
readonlyoptionalpaymentAmount?:X12Decimal
STC-05 - claim payment amount.
statusEffectiveDate?
readonlyoptionalstatusEffectiveDate?:string
STC-02 - status information effective date.
statuses
readonlystatuses: readonlyBuild277StatusCodeSpec[]
STC-01 / STC-10 / STC-11 - 1..3 status composites (first is required).
totalChargeAmount?
readonlyoptionaltotalChargeAmount?:X12Decimal
STC-04 - total claim charge amount.
Build277SubscriberSpec
One subscriber (Loop 2000D / 2100D). Carries the optional member NM1, the subscriber-level claims, and any non-subscriber dependents.
Example
import type { Build277SubscriberSpec } from "@cosyte/x12";
const s: Build277SubscriberSpec = {
member: { entityIdentifierCode: "QC", entityTypeQualifier: "1", lastName: "DOE", firstName: "JANE" },
claims: [{ trace: { traceTypeCode: "2", referenceId: "CLAIM001" } }],
};
Properties
claims?
readonlyoptionalclaims?: readonlyBuild277ClaimSpec[]
Loop 2200 subscriber-level claims.
dependents?
readonlyoptionaldependents?: readonlyBuild277DependentSpec[]
Loop 2000E dependents (a non-empty list sets the subscriber HL-04 to "1").
member?
readonlyoptionalmember?:Build277MemberSpec
Loop 2100D subscriber member (NM1).
Build277TraceSpec
A reassociation trace (TRN). For a 277 claim status, referenceId
(TRN-02) echoes the requesting 276's trace number verbatim. A claim
opens on its trace, so a claim carries at most one trace. Mirrors "./types.js".X12StatusTrace.
Example
import type { Build277TraceSpec } from "@cosyte/x12";
const t: Build277TraceSpec = { traceTypeCode: "2", referenceId: "CLAIM20260627001" };
Properties
originatingCompanyId?
readonlyoptionaloriginatingCompanyId?:string
TRN-03 - originating company identifier.
referenceId
readonlyreferenceId:string
TRN-02 - reference identification (echoed verbatim from the 276).
supplementalReferenceId?
readonlyoptionalsupplementalReferenceId?:string
TRN-04 - supplemental reference identifier.
traceTypeCode
readonlytraceTypeCode:string
TRN-01 - trace type code.
Build278DateSpec
A DTP date / date-range on a review. Mirrors "./types.js".X12AuthDate.
Example
import type { Build278DateSpec } from "@cosyte/x12";
const d: Build278DateSpec = { qualifier: "472", formatQualifier: "RD8", value: "20260601-20260605" };
Properties
formatQualifier
readonlyformatQualifier:string
DTP-02 - date/time format qualifier (D8 / RD8).
qualifier
readonlyqualifier:string
DTP-01 - date/time qualifier (435 admission, 472 service).
value
readonlyvalue:string
DTP-03 - date/time value.
Build278DecisionSpec
The HCR Health Care Services Review decision (RESPONSE ONLY). actionCode
(HCR-01) is the certification outcome and is emitted VERBATIM - the
builder never infers or upgrades it, so the response round-trips the exact
decision the caller supplied. A request spec carrying a decision is
REFUSED. Mirrors "./types.js".X12ReviewDecision.
Example
import type { Build278DecisionSpec } from "@cosyte/x12";
const d: Build278DecisionSpec = { actionCode: "A1", reviewIdentificationNumber: "AUTH123456" };
Properties
actionCode
readonlyactionCode:string
HCR-01 - action code (A1 certified, A3 not certified, A4 pended, A6 modified).
reasonCode?
readonlyoptionalreasonCode?:string
HCR-03 - reason code.
reviewIdentificationNumber?
readonlyoptionalreviewIdentificationNumber?:string
HCR-02 - review / authorization identification number.
secondSurgicalOpinionCode?
readonlyoptionalsecondSurgicalOpinionCode?:string
HCR-04 - second surgical opinion code.
Build278DependentSpec
One dependent (Loop 2000D / 2010D - HL level 23) - a patient who is not the subscriber. Carries the optional member NM1 + DMG and the reviews tracked for that dependent (at least one required).
Example
import type { Build278DependentSpec } from "@cosyte/x12";
const d: Build278DependentSpec = {
member: { entityIdentifierCode: "QC", entityTypeQualifier: "1", lastName: "DOE", firstName: "JUNIOR" },
reviews: [{ requestCategoryCode: "HS", certificationTypeCode: "I" }],
};
Properties
member?
readonlyoptionalmember?:Build278MemberSpec
Loop 2010D dependent member (NM1 + DMG).
reviews
readonlyreviews: readonlyBuild278ReviewSpec[]
Loop 2000E/2000F reviews tracked for the dependent (at least one required).
Build278DiagnosisSpec
One diagnosis composite emitted into the review's HI segment. Only the
verbatim qualifier (HI-0x-01) + code (HI-0x-02) are supplied - the read
side resolves the codeSystem. Mirrors "./types.js".X12AuthDiagnosis minus the derived codeSystem.
Example
import type { Build278DiagnosisSpec } from "@cosyte/x12";
const dx: Build278DiagnosisSpec = { qualifier: "ABK", code: "E1165" };
Properties
code
readonlycode:string
HI-0x-02 - diagnosis code.
qualifier
readonlyqualifier:string
HI-0x-01 - diagnosis code-source qualifier (ABK ICD-10-CM principal).
Build278EntitySpec
A non-person entity (NM1) - the UMO (Loop 2010A), the requester (Loop 2010B), or a provider attached to a review. Mirrors "./types.js".X12AuthEntity.
Example
import type { Build278EntitySpec } from "@cosyte/x12";
const umo: Build278EntitySpec = {
entityIdentifierCode: "X3", entityTypeQualifier: "2",
name: "UTILIZATION REVIEW CO", idQualifier: "PI", idCode: "UMO001",
};
Properties
entityIdentifierCode
readonlyentityIdentifierCode:string
NM1-01 - entity identifier code (X3 UMO, 1P requester, 71 attending).
entityTypeQualifier
readonlyentityTypeQualifier:string
NM1-02 - entity type qualifier (1 person, 2 non-person).
idCode?
readonlyoptionalidCode?:string
NM1-09 - identification code.
idQualifier?
readonlyoptionalidQualifier?:string
NM1-08 - identification code qualifier.
name
readonlyname:string
NM1-03 - name (organization or last name).
Build278EnvelopeSpec
Interchange + group + transaction identity for the built 278. The builder
fixes GS-01 to "HI" and ST-01 to "278"; ST-03 / GS-08 is the version
supplied by the entry point (005010X217 for "./build-278.js".build278Request, 005010X216 for "./build-278.js".build278Response) so the caller never hand-codes them.
Example
import type { Build278EnvelopeSpec } from "@cosyte/x12";
const env: Build278EnvelopeSpec = {
senderId: "SUBMITTER", receiverId: "UMOPAYER",
interchangeDate: "260601", interchangeTime: "1200",
interchangeControlNumber: "000000001",
groupControlNumber: "1", transactionSetControlNumber: "0001",
};
Properties
applicationReceiverCode?
readonlyoptionalapplicationReceiverCode?:string
GS-03 - application receiver code. Default: the interchange receiver id.
applicationSenderCode?
readonlyoptionalapplicationSenderCode?:string
GS-02 - application sender code. Default: the interchange sender id.
componentSeparator?
readonlyoptionalcomponentSeparator?:string
Component (sub-element) separator (ISA-16). Default ":".
elementSeparator?
readonlyoptionalelementSeparator?:string
Element separator (ISA byte 4). Default "*".
groupControlNumber
readonlygroupControlNumber:string
GS-06 / GE-02 - group control number.
groupDate?
readonlyoptionalgroupDate?:string
GS-04 - group date CCYYMMDD. Default: century-expanded ISA-09.
groupTime?
readonlyoptionalgroupTime?:string
GS-05 - group time HHMM. Default: the interchange time.
interchangeControlNumber
readonlyinterchangeControlNumber:string
ISA-13 / IEA-02 - interchange control number (zero-padded to 9 on emit).
interchangeDate
readonlyinterchangeDate:string
ISA-09 - interchange date YYMMDD.
interchangeTime
readonlyinterchangeTime:string
ISA-10 - interchange time HHMM.
receiverId
readonlyreceiverId:string
ISA-08 - interchange receiver id (padded to 15 on emit).
receiverQualifier?
readonlyoptionalreceiverQualifier?:string
ISA-07 - interchange receiver qualifier. Default "ZZ".
repetitionSeparator?
readonlyoptionalrepetitionSeparator?:string
Repetition separator (ISA-11). Default "^".
segmentTerminator?
readonlyoptionalsegmentTerminator?:string
Segment terminator (ISA byte 106). Default "~".
senderId
readonlysenderId:string
ISA-06 - interchange sender id (padded to 15 on emit).
senderQualifier?
readonlyoptionalsenderQualifier?:string
ISA-05 - interchange sender qualifier. Default "ZZ".
transactionSetControlNumber
readonlytransactionSetControlNumber:string
ST-02 / SE-02 - transaction set control number.
usageIndicator?
readonlyoptionalusageIndicator?:string
ISA-15 - usage indicator (P production, T test). Default "P".
Build278HeaderSpec
The BHT beginning-of-hierarchical-transaction header. Mirrors "./types.js".X12AuthHeader; structurePurposeCode (BHT-01, "0078" for
a 278) is required.
Example
import type { Build278HeaderSpec } from "@cosyte/x12";
const h: Build278HeaderSpec = {
structurePurposeCode: "0078", purposeCode: "13",
referenceId: "AUTHREQ-202606", date: "20260601", time: "1200",
};
Properties
date?
readonlyoptionaldate?:string
BHT-04 - transaction set creation date (CCYYMMDD).
purposeCode?
readonlyoptionalpurposeCode?:string
BHT-02 - transaction set purpose code (13 request / 11 response).
referenceId?
readonlyoptionalreferenceId?:string
BHT-03 - submitter transaction reference (re-association key).
structurePurposeCode
readonlystructurePurposeCode:string
BHT-01 - hierarchical structure code (0078 services review).
time?
readonlyoptionaltime?:string
BHT-05 - transaction set creation time (HHMM).
transactionTypeCode?
readonlyoptionaltransactionTypeCode?:string
BHT-06 - transaction type code.
Build278MemberSpec
A person (subscriber Loop 2010C / dependent Loop 2010D) - NM1 plus the
optional DMG demographics. idCode (NM1-09) is the member identifier -
synthetic-only in fixtures. Mirrors "./types.js".X12AuthMember.
Example
import type { Build278MemberSpec } from "@cosyte/x12";
const m: Build278MemberSpec = {
entityIdentifierCode: "IL", entityTypeQualifier: "1",
lastName: "DOE", firstName: "JANE", idQualifier: "MI", idCode: "MBR0001",
dateOfBirth: "19850515", genderCode: "F",
};
Properties
dateOfBirth?
readonlyoptionaldateOfBirth?:string
DMG-02 - date of birth (CCYYMMDD). A DMG is emitted only when this or genderCode is set.
entityIdentifierCode
readonlyentityIdentifierCode:string
NM1-01 - entity identifier code (IL insured, QC patient).
entityTypeQualifier
readonlyentityTypeQualifier:string
NM1-02 - entity type qualifier (1 person).
firstName?
readonlyoptionalfirstName?:string
NM1-04 - first name.
genderCode?
readonlyoptionalgenderCode?:string
DMG-03 - gender code (M / F / U).
idCode?
readonlyoptionalidCode?:string
NM1-09 - identification code (the member id).
idQualifier?
readonlyoptionalidQualifier?:string
NM1-08 - identification code qualifier (MI member id).
lastName?
readonlyoptionallastName?:string
NM1-03 - last name.
middleName?
readonlyoptionalmiddleName?:string
NM1-05 - middle name.
suffix?
readonlyoptionalsuffix?:string
NM1-07 - name suffix.
Build278ReferenceSpec
A REF supplemental identifier on a review. Mirrors "./types.js".X12AuthReference.
Example
import type { Build278ReferenceSpec } from "@cosyte/x12";
const r: Build278ReferenceSpec = { qualifier: "BB", value: "PRIORAUTH-1" };
Properties
description?
readonlyoptionaldescription?:string
REF-03 - description.
qualifier
readonlyqualifier:string
REF-01 - reference identification qualifier.
value
readonlyvalue:string
REF-02 - reference identification.
Build278ReviewSpec
One services-review item - a patient-event (EV, Loop 2000E) or service
(SS, Loop 2000F) HL. Carries the UM review information, the optional HCR
decision (response only), echoed TRN traces, HI diagnoses, attached
provider NM1s, and the supplemental REF / DTP / MSG. Nested reviews become
child HLs (an SS service under an EV event) parented to this review.
Mirrors "./types.js".X12ServiceReview.
Example
import type { Build278ReviewSpec } from "@cosyte/x12";
const r: Build278ReviewSpec = {
levelCode: "EV", requestCategoryCode: "HS", certificationTypeCode: "I", serviceTypeCode: "1",
traces: [{ traceTypeCode: "1", referenceId: "AUTHREQ-202606-0001" }],
diagnoses: [{ qualifier: "ABK", code: "E1165" }],
dates: [{ qualifier: "472", formatQualifier: "RD8", value: "20260601-20260605" }],
};
Properties
certificationTypeCode?
readonlyoptionalcertificationTypeCode?:string
UM-02 - certification type code (I initial / R renewal).
dates?
readonlyoptionaldates?: readonlyBuild278DateSpec[]
Supplemental DTP dates.
decision?
readonlyoptionaldecision?:Build278DecisionSpec
HCR decision - RESPONSE ONLY (a request review carrying one is refused).
diagnoses?
readonlyoptionaldiagnoses?: readonlyBuild278DiagnosisSpec[]
HI diagnosis composites (emitted as one HI segment).
levelCode?
readonlyoptionallevelCode?:"EV"|"SS"
HL-03 - review level code (EV patient event / SS service). Default
"EV".
The only caller-supplied HL-03 in the library; every other level on every
builder's spine is a module constant selected by tree position. A value
outside EV / SS is refused (X12_278_BUILD_INVALID_SPEC) rather
than emitted: it produces a well-formed document whose review loop no
reader opens, so the review and its HCR-01 certification decision would
fail to decode. An absent value still defaults to EV.
levelOfServiceCode?
readonlyoptionallevelOfServiceCode?:string
UM-06 - level of service code.
messages?
readonlyoptionalmessages?: readonlystring[]
MSG free-form messages.
providers?
readonlyoptionalproviders?: readonlyBuild278EntitySpec[]
Attached provider NM1s (rendering / attending / operating).
references?
readonlyoptionalreferences?: readonlyBuild278ReferenceSpec[]
Supplemental REF identifiers.
requestCategoryCode
readonlyrequestCategoryCode:string
UM-01 - request category code (required; a review with none is refused).
reviews?
readonlyoptionalreviews?: readonlyBuild278ReviewSpec[]
Nested service (SS) reviews parented to this review.
serviceTypeCode?
readonlyoptionalserviceTypeCode?:string
UM-03 - service type code.
traces?
readonlyoptionaltraces?: readonlyBuild278TraceSpec[]
Loop 2000E/2000F TRN traces.
Build278Spec
The complete spec for "./build-278.js".build278Request / "./build-278.js".build278Response: the envelope + BHT header plus the UMO → requester → subscriber → (dependent) → reviews tree the builder walks depth-first to compute the HL spine.
Example
import { build278Request, type Build278Spec } from "@cosyte/x12";
const spec: Build278Spec = {
envelope: {
senderId: "SUBMITTER", receiverId: "UMOPAYER",
interchangeDate: "260601", interchangeTime: "1200",
interchangeControlNumber: "000000001",
groupControlNumber: "1", transactionSetControlNumber: "0001",
},
header: { structurePurposeCode: "0078", purposeCode: "13", referenceId: "AUTHREQ-202606" },
utilizationManagementOrganization: { entityIdentifierCode: "X3", entityTypeQualifier: "2", name: "UTILIZATION REVIEW CO", idQualifier: "PI", idCode: "UMO001" },
requester: { entityIdentifierCode: "1P", entityTypeQualifier: "2", name: "RENDERING CLINIC", idQualifier: "XX", idCode: "1234567893" },
subscriber: {
member: { entityIdentifierCode: "IL", entityTypeQualifier: "1", lastName: "DOE", firstName: "JANE", idQualifier: "MI", idCode: "MBR0001" },
reviews: [{
requestCategoryCode: "HS", certificationTypeCode: "I", serviceTypeCode: "1",
traces: [{ traceTypeCode: "1", referenceId: "AUTHREQ-202606-0001" }],
diagnoses: [{ qualifier: "ABK", code: "E1165" }],
}],
},
};
const ix = build278Request(spec);
Properties
envelope
readonlyenvelope:Build278EnvelopeSpec
Interchange + group + transaction identity.
header
readonlyheader:Build278HeaderSpec
BHT header.
requester
readonlyrequester:Build278EntitySpec
Loop 2010B requester (HL level 21).
subscriber
readonlysubscriber:Build278SubscriberSpec
Loop 2000C subscriber (HL level 22).
utilizationManagementOrganization
readonlyutilizationManagementOrganization:Build278EntitySpec
Loop 2010A utilization management organization (HL level 20).
Build278SubscriberSpec
One subscriber (Loop 2000C / 2010C - HL level 22). Carries the optional member NM1 + DMG, the subscriber-level reviews, and an optional dependent. A subscriber with neither a review nor a dependent is REFUSED.
Example
import type { Build278SubscriberSpec } from "@cosyte/x12";
const s: Build278SubscriberSpec = {
member: { entityIdentifierCode: "IL", entityTypeQualifier: "1", lastName: "DOE", firstName: "JANE" },
reviews: [{ requestCategoryCode: "HS", certificationTypeCode: "I", serviceTypeCode: "1" }],
};
Properties
dependent?
readonlyoptionaldependent?:Build278DependentSpec
Loop 2000D dependent (sets the subscriber HL-04 to "1").
member?
readonlyoptionalmember?:Build278MemberSpec
Loop 2010C subscriber member (NM1 + DMG).
reviews?
readonlyoptionalreviews?: readonlyBuild278ReviewSpec[]
Loop 2000E/2000F subscriber-level reviews.
Build278TraceSpec
A reassociation trace (TRN) on a review. A 278 request carries a trace the response echoes VERBATIM so the requester can re-associate the certification outcome. Mirrors "./types.js".X12AuthTrace.
Example
import type { Build278TraceSpec } from "@cosyte/x12";
const t: Build278TraceSpec = { traceTypeCode: "1", referenceId: "AUTHREQ-202606-0001" };
Properties
originatingCompanyId?
readonlyoptionaloriginatingCompanyId?:string
TRN-03 - originating company identifier.
referenceId
readonlyreferenceId:string
TRN-02 - reference identification (echoed verbatim between request/response).
supplementalReferenceId?
readonlyoptionalsupplementalReferenceId?:string
TRN-04 - supplemental reference identifier.
traceTypeCode
readonlytraceTypeCode:string
TRN-01 - trace type code.
Build820AddressSpec
N3 + N4 address block on a party. Mirrors "./types.js".X12PremiumAddress.
Example
import type { Build820AddressSpec } from "@cosyte/x12";
const a: Build820AddressSpec = {
lines: ["500 CORPORATE BLVD"], city: "COLUMBUS", state: "OH", postalCode: "43004",
};
Properties
city?
readonlyoptionalcity?:string
N4-01 - city.
countryCode?
readonlyoptionalcountryCode?:string
N4-04 - country code.
lines
readonlylines: readonlystring[]
N3 address lines (1-2).
postalCode?
readonlyoptionalpostalCode?:string
N4-03 - postal code.
state?
readonlyoptionalstate?:string
N4-02 - state / province.
Build820AdjustmentSpec
ADX adjustment to a premium remittance. Mirrors "./types.js".X12PremiumAdjustment.
Example
import type { Build820AdjustmentSpec } from "@cosyte/x12";
import { X12Decimal } from "@cosyte/x12";
const a: Build820AdjustmentSpec = {
amount: X12Decimal.fromString("-25.00")!, reasonCode: "53",
};
Properties
amount
readonlyamount:X12Decimal
ADX-01 - signed monetary adjustment.
reasonCode
readonlyreasonCode:string
ADX-02 - adjustment reason code (52 credit memo, 53 debit memo, …).
referenceId?
readonlyoptionalreferenceId?:string
ADX-04 - reference id (situational).
referenceQualifier?
readonlyoptionalreferenceQualifier?:string
ADX-03 - reference qualifier (situational).
Build820DateSpec
DTM date attached to a remittance loop. Mirrors "./types.js".X12PremiumDate. The 820 carries dates only inside a remittance loop - a header-level DTM is not part of the typed surface.
Example
import type { Build820DateSpec } from "@cosyte/x12";
const d: Build820DateSpec = { qualifier: "582", value: "20260601" };
Properties
qualifier
readonlyqualifier:string
DTM-01 - date/time qualifier.
value
readonlyvalue:string
DTM-02 - verbatim CCYYMMDD date.
Build820EntitySpec
ENT entity - opens an organization-summary remittance loop (Loop 2000A). Mirrors "./types.js".X12PremiumEntity. All elements optional; the ENT's role is to open the loop.
Example
import type { Build820EntitySpec } from "@cosyte/x12";
const e: Build820EntitySpec = {
assignedNumber: "1", entityIdentifierCode: "2J", idQualifier: "94", idCode: "GRP-0001",
};
Properties
assignedNumber?
readonlyoptionalassignedNumber?:string
ENT-01 - assigned number.
entityIdentifierCode?
readonlyoptionalentityIdentifierCode?:string
ENT-02 - entity identifier code.
idCode?
readonlyoptionalidCode?:string
ENT-04 - identification code.
idQualifier?
readonlyoptionalidQualifier?:string
ENT-03 - identification code qualifier.
Build820EnvelopeSpec
Interchange + group + transaction identity for the built 820. The builder
fixes GS-01 to "RA" (Payment Order / Remittance Advice) and the
version/release to "005010X218" (the 820 functional group + TR3) so the
caller never hand-codes them.
Example
import type { Build820EnvelopeSpec } from "@cosyte/x12";
const env: Build820EnvelopeSpec = {
senderId: "EMPLOYERCO", receiverId: "MEDPAY",
interchangeDate: "260601", interchangeTime: "1200",
interchangeControlNumber: "000000001",
groupControlNumber: "1", transactionSetControlNumber: "0001",
};
Properties
applicationReceiverCode?
readonlyoptionalapplicationReceiverCode?:string
GS-03 - application receiver code. Default: the interchange receiver id.
applicationSenderCode?
readonlyoptionalapplicationSenderCode?:string
GS-02 - application sender code. Default: the interchange sender id.
componentSeparator?
readonlyoptionalcomponentSeparator?:string
Component (sub-element) separator (ISA-16). Default ":".
elementSeparator?
readonlyoptionalelementSeparator?:string
Element separator (ISA byte 4). Default "*".
groupControlNumber
readonlygroupControlNumber:string
GS-06 / GE-02 - group control number.
groupDate?
readonlyoptionalgroupDate?:string
GS-04 - group date CCYYMMDD. Default: century-expanded ISA-09.
groupTime?
readonlyoptionalgroupTime?:string
GS-05 - group time HHMM. Default: the interchange time.
interchangeControlNumber
readonlyinterchangeControlNumber:string
ISA-13 / IEA-02 - interchange control number (zero-padded to 9 on emit).
interchangeDate
readonlyinterchangeDate:string
ISA-09 - interchange date YYMMDD.
interchangeTime
readonlyinterchangeTime:string
ISA-10 - interchange time HHMM.
receiverId
readonlyreceiverId:string
ISA-08 - interchange receiver id (padded to 15 on emit).
receiverQualifier?
readonlyoptionalreceiverQualifier?:string
ISA-07 - interchange receiver qualifier. Default "ZZ".
repetitionSeparator?
readonlyoptionalrepetitionSeparator?:string
Repetition separator (ISA-11). Default "^".
segmentTerminator?
readonlyoptionalsegmentTerminator?:string
Segment terminator (ISA byte 106). Default "~".
senderId
readonlysenderId:string
ISA-06 - interchange sender id (padded to 15 on emit).
senderQualifier?
readonlyoptionalsenderQualifier?:string
ISA-05 - interchange sender qualifier. Default "ZZ".
transactionSetControlNumber
readonlytransactionSetControlNumber:string
ST-02 / SE-02 - transaction set control number.
usageIndicator?
readonlyoptionalusageIndicator?:string
ISA-15 - usage indicator (P production, T test). Default "P".
Build820OpenItemSpec
RMR open item - the premium line unit: a policy / invoice reference plus
the amount paid and (optionally) the amount due. Mirrors "./types.js".X12PremiumOpenItem. At least one of qualifier /
referenceId must be non-empty (an RMR with no identity is dropped on the
read side, so the builder refuses it).
Example
import type { Build820OpenItemSpec } from "@cosyte/x12";
import { X12Decimal } from "@cosyte/x12";
const o: Build820OpenItemSpec = {
qualifier: "AZ", referenceId: "POL-0001", amountPaid: X12Decimal.fromString("250.00")!,
};
Properties
amountDue?
readonlyoptionalamountDue?:X12Decimal
RMR-05 - amount due / original (situational).
amountPaid
readonlyamountPaid:X12Decimal
RMR-04 - amount paid.
paymentActionCode?
readonlyoptionalpaymentActionCode?:string
RMR-03 - payment action code (situational).
qualifier
readonlyqualifier:string
RMR-01 - reference id qualifier (11, IK, AZ, …).
referenceId
readonlyreferenceId:string
RMR-02 - reference id (policy / invoice number).
Build820PartySpec
Loop 1000A premium receiver (N1*PE) or Loop 1000B premium payer /
remitter (N1*PR / N1*RM). Mirrors "./types.js".X12PremiumParty.
Example
import type { Build820PartySpec } from "@cosyte/x12";
const remitter: Build820PartySpec = {
entityIdentifierCode: "PR", name: "EMPLOYER CO", idQualifier: "FI", idCode: "FEIN123",
};
Properties
address?
readonlyoptionaladdress?:Build820AddressSpec
N3 + N4 address block.
entityIdentifierCode
readonlyentityIdentifierCode:string
N1-01 - entity identifier code (PE receiver / PR / RM remitter).
idCode?
readonlyoptionalidCode?:string
N1-04 - identification code.
idQualifier?
readonlyoptionalidQualifier?:string
N1-03 - identification code qualifier.
name
readonlyname:string
N1-02 - party name.
references?
readonlyoptionalreferences?: readonlyBuild820ReferenceSpec[]
REF supplemental identifiers.
Build820PaymentSpec
BPR financial-information / payment header. totalPremiumAmount is the
aggregate premium the bank moved (BPR-02). Identical segment shape to the
835 - but the 820 carries no balance equation, so this total is emitted
verbatim, never reconciled against the remittance open items.
Example
import type { Build820PaymentSpec } from "@cosyte/x12";
import { X12Decimal } from "@cosyte/x12";
const bpr: Build820PaymentSpec = {
transactionHandlingCode: "I",
totalPremiumAmount: X12Decimal.fromString("12500.00")!,
creditDebitFlag: "C", method: "ACH", paymentDate: "20260601",
};
Properties
creditDebitFlag
readonlycreditDebitFlag:string
BPR-03 - credit/debit flag (C credit, D debit).
method
readonlymethod:string
BPR-04 - payment method (ACH, CHK, NON, …).
paymentDate
readonlypaymentDate:string
BPR-16 - payment effective date (CCYYMMDD).
paymentFormatCode?
readonlyoptionalpaymentFormatCode?:string
BPR-05 - payment format code (situational).
totalPremiumAmount
readonlytotalPremiumAmount:X12Decimal
BPR-02 - total premium amount the bank moved.
transactionHandlingCode
readonlytransactionHandlingCode:string
BPR-01 - transaction handling code (I remittance + payment, H notification, …).
Build820PersonSpec
NM1 individual (member) inside a remittance loop. Mirrors "./types.js".X12PremiumPerson. PHI surface: every field carries PHI. The
builder emits NM1-02 (entity type qualifier) as "1" (person); the read
side does not interpret it.
Example
import type { Build820PersonSpec } from "@cosyte/x12";
const p: Build820PersonSpec = {
entityIdentifierCode: "IL", lastName: "DOE", firstName: "JANE",
idQualifier: "34", idCode: "MBR0001",
};
Properties
entityIdentifierCode
readonlyentityIdentifierCode:string
NM1-01 - entity identifier code (IL insured, …).
firstName?
readonlyoptionalfirstName?:string
NM1-04 - first name.
idCode?
readonlyoptionalidCode?:string
NM1-09 - identification code (verbatim member id).
idQualifier?
readonlyoptionalidQualifier?:string
NM1-08 - identification code qualifier (34 SSN, ZZ mutually defined, …).
lastName?
readonlyoptionallastName?:string
NM1-03 - last name.
middleName?
readonlyoptionalmiddleName?:string
NM1-05 - middle name.
suffix?
readonlyoptionalsuffix?:string
NM1-07 - name suffix.
Build820ReferenceSpec
REF supplemental identifier on a party or remittance loop. Mirrors "./types.js".X12PremiumReference. description (REF-03) is emitted only
when supplied.
Example
import type { Build820ReferenceSpec } from "@cosyte/x12";
const ref: Build820ReferenceSpec = { qualifier: "38", value: "POL-0001" };
Properties
description?
readonlyoptionaldescription?:string
REF-03 - description (situational).
qualifier
readonlyqualifier:string
REF-01 - reference identification qualifier.
value
readonlyvalue:string
REF-02 - reference identification value.
Build820RemittanceSpec
One Loop 2000 remittance - an organization summary (entity), an
individual (individual), or both. Mirrors "./types.js".X12PremiumRemittance. Structural preconditions the builder
enforces so the loop round-trips through get820Payments:
- at least one of
entity/individualmust be present (a remittance needs anENTorNM1to open its loop), and - at least one
openItemsentry must be present (a premium remittance always carries anRMRline; an item-less loop would also merge into a following individual remittance on the read side).
Example
import type { Build820RemittanceSpec } from "@cosyte/x12";
import { X12Decimal } from "@cosyte/x12";
const r: Build820RemittanceSpec = {
individual: { entityIdentifierCode: "IL", lastName: "DOE", idQualifier: "34", idCode: "MBR0001" },
openItems: [{ qualifier: "AZ", referenceId: "POL-0001", amountPaid: X12Decimal.fromString("250.00")! }],
};
Properties
adjustments?
readonlyoptionaladjustments?: readonlyBuild820AdjustmentSpec[]
ADX adjustments for the loop.
dates?
readonlyoptionaldates?: readonlyBuild820DateSpec[]
DTM dates for the loop.
entity?
readonlyoptionalentity?:Build820EntitySpec
ENT entity (Loop 2000A organization summary).
individual?
readonlyoptionalindividual?:Build820PersonSpec
NM1 individual (member).
openItems
readonlyopenItems: readonlyBuild820OpenItemSpec[]
RMR open items (≥ 1 required).
references?
readonlyoptionalreferences?: readonlyBuild820ReferenceSpec[]
REF supplemental identifiers for the loop.
Build820Spec
The full input to "./build-820.js".build820: the envelope, the
payment header, ≥ 1 trace, optional receiver / remitter parties, and ≥ 1
remittance loop. A well-formed spec round-trips through get820Payments
field-for-field; a structurally impossible one is REFUSED with a "./build-errors.js".Premium820BuildError.
Example
import { build820, X12Decimal, type Build820Spec } from "@cosyte/x12";
const spec: Build820Spec = {
envelope: {
senderId: "EMPLOYERCO", receiverId: "MEDPAY",
interchangeDate: "260601", interchangeTime: "1200",
interchangeControlNumber: "000000001",
groupControlNumber: "1", transactionSetControlNumber: "0001",
},
payment: {
transactionHandlingCode: "I",
totalPremiumAmount: X12Decimal.fromString("250.00")!,
creditDebitFlag: "C", method: "ACH", paymentDate: "20260601",
},
traces: [{ traceTypeCode: "1", referenceId: "PREM-202606" }],
remitter: { entityIdentifierCode: "PR", name: "EMPLOYER CO" },
receiver: { entityIdentifierCode: "PE", name: "MEDPAY INSURANCE" },
remittances: [
{
individual: { entityIdentifierCode: "IL", lastName: "DOE", idQualifier: "34", idCode: "MBR0001" },
openItems: [{ qualifier: "AZ", referenceId: "POL-0001", amountPaid: X12Decimal.fromString("250.00")! }],
},
],
};
const ix = build820(spec);
Properties
envelope
readonlyenvelope:Build820EnvelopeSpec
Interchange / group / transaction identity.
payment
readonlypayment:Build820PaymentSpec
BPR payment header.
receiver?
readonlyoptionalreceiver?:Build820PartySpec
Loop 1000A premium receiver (N1*PE).
remittances
readonlyremittances: readonlyBuild820RemittanceSpec[]
Loop 2000 remittance detail (≥ 1 required).
remitter?
readonlyoptionalremitter?:Build820PartySpec
Loop 1000B premium payer / remitter (N1PR / N1RM).
traces
readonlytraces: readonlyBuild820TraceSpec[]
TRN traces (≥ 1 required).
Build820TraceSpec
TRN reassociation trace - pairs the 820 to the originating ACH / check so the receiver can reconcile the premium deposit. At least one is required (TR3 005010X218 mandates the header TRN).
Example
import type { Build820TraceSpec } from "@cosyte/x12";
const trn: Build820TraceSpec = {
traceTypeCode: "1", referenceId: "PREM-202606", originatingCompanyId: "1512345678",
};
Properties
originatingCompanyId?
readonlyoptionaloriginatingCompanyId?:string
TRN-03 - originating company identifier.
originatingCompanySupplementalCode?
readonlyoptionaloriginatingCompanySupplementalCode?:string
TRN-04 - originating company supplemental code.
referenceId
readonlyreferenceId:string
TRN-02 - reference identification (the trace / check number).
traceTypeCode
readonlytraceTypeCode:string
TRN-01 - trace type code (1 current transaction trace numbers).
Build834AddressSpec
N3 + N4 address block on a member. Mirrors "./types.js".X12EnrollmentAddress.
Example
import type { Build834AddressSpec } from "@cosyte/x12";
const a: Build834AddressSpec = {
lines: ["100 MAIN ST"], city: "COLUMBUS", state: "OH", postalCode: "43004",
};
Properties
city?
readonlyoptionalcity?:string
N4-01 - city.
countryCode?
readonlyoptionalcountryCode?:string
N4-04 - country code.
lines
readonlylines: readonlystring[]
N3 address lines (1-2).
postalCode?
readonlyoptionalpostalCode?:string
N4-03 - postal code.
state?
readonlyoptionalstate?:string
N4-02 - state / province.
Build834AmountSpec
AMT amount on a health-coverage loop. Mirrors "./types.js".X12EnrollmentAmount.
Example
import type { Build834AmountSpec } from "@cosyte/x12";
import { X12Decimal } from "@cosyte/x12";
const a: Build834AmountSpec = { qualifier: "P3", amount: X12Decimal.fromString("125.00")! };
Properties
amount
readonlyamount:X12Decimal
AMT-02 - monetary amount.
qualifier
readonlyqualifier:string
AMT-01 - amount qualifier code (P3 premium, B9 co-insurance, …).
Build834CoordinationOfBenefitsSpec
Loop 2320 coordination of benefits (COB). Mirrors "./types.js".X12CoordinationOfBenefits.
Example
import type { Build834CoordinationOfBenefitsSpec } from "@cosyte/x12";
const c: Build834CoordinationOfBenefitsSpec = {
payerResponsibility: "P", referenceId: "OTHERGRP-1", coordinationOfBenefitsCode: "1",
};
Properties
coordinationOfBenefitsCode?
readonlyoptionalcoordinationOfBenefitsCode?:string
COB-03 - coordination of benefits code.
payerResponsibility?
readonlyoptionalpayerResponsibility?:string
COB-01 - payer responsibility (P primary, S secondary, T tertiary).
referenceId?
readonlyoptionalreferenceId?:string
COB-02 - the other payer's group / policy number.
Build834CoverageSpec
Loop 2300 health coverage (HD) plus its dates (DTP) and amounts
(AMT). Mirrors "./types.js".X12HealthCoverage.
maintenanceTypeCode (HD-01, X12 875) is validated when present - an
unknown code is REFUSED.
Example
import type { Build834CoverageSpec } from "@cosyte/x12";
const c: Build834CoverageSpec = {
maintenanceTypeCode: "021", insuranceLineCode: "HLT",
planCoverageDescription: "GOLD PPO", coverageLevelCode: "FAM",
dates: [{ qualifier: "348", value: "20260101" }],
};
Properties
amounts?
readonlyoptionalamounts?: readonlyBuild834AmountSpec[]
AMT coverage amounts.
coverageLevelCode?
readonlyoptionalcoverageLevelCode?:string
HD-05 - coverage level code (IND, FAM, EMP, …).
dates?
readonlyoptionaldates?: readonlyBuild834DateSpec[]
DTP coverage dates.
insuranceLineCode?
readonlyoptionalinsuranceLineCode?:string
HD-03 - insurance line code (HLT, DEN, VIS, …).
maintenanceTypeCode?
readonlyoptionalmaintenanceTypeCode?:string
HD-01 - maintenance type code (X12 875; validated when present).
planCoverageDescription?
readonlyoptionalplanCoverageDescription?:string
HD-04 - plan coverage description.
Build834DateSpec
DTP date on a member or a health-coverage loop. Mirrors "./types.js".X12EnrollmentDate. value (DTP-03) is the verbatim
CCYYMMDD or range; formatQualifier (DTP-02) defaults to "D8" (single
date) - pass "RD8" for a range. The read model surfaces only the
qualifier + value, so the format qualifier does not affect a round-trip.
Example
import type { Build834DateSpec } from "@cosyte/x12";
const d: Build834DateSpec = { qualifier: "356", value: "20260101" };
Properties
formatQualifier?
readonlyoptionalformatQualifier?:string
DTP-02 - date/time format qualifier. Default "D8".
qualifier
readonlyqualifier:string
DTP-01 - date/time qualifier (356 eligibility begin, 357 end, …).
value
readonlyvalue:string
DTP-03 - verbatim CCYYMMDD or range.
Build834EnvelopeSpec
Interchange + group + transaction identity for the built 834. The builder
fixes GS-01 to "BE" (Benefit Enrollment and Maintenance) and the
version/release to "005010X220A1" (the 834 functional group + TR3) so
the caller never hand-codes them.
Example
import type { Build834EnvelopeSpec } from "@cosyte/x12";
const env: Build834EnvelopeSpec = {
senderId: "EMPLOYERCO", receiverId: "MEDPAY",
interchangeDate: "260601", interchangeTime: "1200",
interchangeControlNumber: "000000001",
groupControlNumber: "1", transactionSetControlNumber: "0001",
};
Properties
applicationReceiverCode?
readonlyoptionalapplicationReceiverCode?:string
GS-03 - application receiver code. Default: the interchange receiver id.
applicationSenderCode?
readonlyoptionalapplicationSenderCode?:string
GS-02 - application sender code. Default: the interchange sender id.
componentSeparator?
readonlyoptionalcomponentSeparator?:string
Component (sub-element) separator (ISA-16). Default ":".
elementSeparator?
readonlyoptionalelementSeparator?:string
Element separator (ISA byte 4). Default "*".
groupControlNumber
readonlygroupControlNumber:string
GS-06 / GE-02 - group control number.
groupDate?
readonlyoptionalgroupDate?:string
GS-04 - group date CCYYMMDD. Default: century-expanded ISA-09.
groupTime?
readonlyoptionalgroupTime?:string
GS-05 - group time HHMM. Default: the interchange time.
interchangeControlNumber
readonlyinterchangeControlNumber:string
ISA-13 / IEA-02 - interchange control number (zero-padded to 9 on emit).
interchangeDate
readonlyinterchangeDate:string
ISA-09 - interchange date YYMMDD.
interchangeTime
readonlyinterchangeTime:string
ISA-10 - interchange time HHMM.
receiverId
readonlyreceiverId:string
ISA-08 - interchange receiver id (padded to 15 on emit).
receiverQualifier?
readonlyoptionalreceiverQualifier?:string
ISA-07 - interchange receiver qualifier. Default "ZZ".
repetitionSeparator?
readonlyoptionalrepetitionSeparator?:string
Repetition separator (ISA-11). Default "^".
segmentTerminator?
readonlyoptionalsegmentTerminator?:string
Segment terminator (ISA byte 106). Default "~".
senderId
readonlysenderId:string
ISA-06 - interchange sender id (padded to 15 on emit).
senderQualifier?
readonlyoptionalsenderQualifier?:string
ISA-05 - interchange sender qualifier. Default "ZZ".
transactionSetControlNumber
readonlytransactionSetControlNumber:string
ST-02 / SE-02 - transaction set control number.
usageIndicator?
readonlyoptionalusageIndicator?:string
ISA-15 - usage indicator (P production, T test). Default "P".
Build834HeaderSpec
The 834 header - BGN beginning segment + sponsor (N1*P5) + payer
(N1*IN) + header REF / DTP. Mirrors "./types.js".X12EnrollmentHeader minus the read-only warnings.
Example
import type { Build834HeaderSpec } from "@cosyte/x12";
const header: Build834HeaderSpec = {
transactionSetPurposeCode: "00", referenceId: "FILE-202606", date: "20260601",
sponsor: { entityIdentifierCode: "P5", name: "EMPLOYER CO" },
payer: { entityIdentifierCode: "IN", name: "MEDPAY INSURANCE" },
};
Properties
actionCode?
readonlyoptionalactionCode?:string
BGN-08 - action code (2 change / 4 verify / RX replace, …).
date?
readonlyoptionaldate?:string
BGN-03 - transaction set creation date (CCYYMMDD).
dates?
readonlyoptionaldates?: readonlyBuild834DateSpec[]
Header DTP dates.
payer?
readonlyoptionalpayer?:Build834PartySpec
Loop 1000B payer (N1*IN).
referenceId?
readonlyoptionalreferenceId?:string
BGN-02 - reference identification (the file / batch id).
references?
readonlyoptionalreferences?: readonlyBuild834ReferenceSpec[]
Header REF identifiers.
sponsor?
readonlyoptionalsponsor?:Build834PartySpec
Loop 1000A sponsor (N1*P5).
time?
readonlyoptionaltime?:string
BGN-04 - transaction set creation time (HHMM).
transactionSetPurposeCode
readonlytransactionSetPurposeCode:string
BGN-01 - transaction set purpose code (00 original, 15 re-submission, …).
Build834MemberNameSpec
Loop 2100A member name (NM1*IL) + demographics (DMG) + address
(N3/N4). Mirrors "./types.js".X12EnrollmentMember. PHI
surface: every field carries PHI. entityIdentifierCode defaults to
"IL" (insured) - the read side captures only the IL member name, so a
different qualifier would not round-trip.
Example
import type { Build834MemberNameSpec } from "@cosyte/x12";
const m: Build834MemberNameSpec = {
lastName: "DOE", firstName: "JANE", idQualifier: "34", idCode: "MBR0001",
dateOfBirth: "19850515", genderCode: "F",
};
Properties
address?
readonlyoptionaladdress?:Build834AddressSpec
N3 + N4 address block.
dateOfBirth?
readonlyoptionaldateOfBirth?:string
DMG-02 - date of birth (CCYYMMDD).
entityIdentifierCode?
readonlyoptionalentityIdentifierCode?:string
NM1-01 - entity identifier code. Default "IL" (insured).
firstName?
readonlyoptionalfirstName?:string
NM1-04 - first name.
genderCode?
readonlyoptionalgenderCode?:string
DMG-03 - gender code (M / F / U).
idCode?
readonlyoptionalidCode?:string
NM1-09 - identification code (verbatim member id).
idQualifier?
readonlyoptionalidQualifier?:string
NM1-08 - identification code qualifier (34 SSN, ZZ mutually defined, …).
lastName?
readonlyoptionallastName?:string
NM1-03 - last name.
middleName?
readonlyoptionalmiddleName?:string
NM1-05 - middle name.
suffix?
readonlyoptionalsuffix?:string
NM1-07 - name suffix.
Build834MemberSpec
One Loop 2000 member-level detail (INS) - a single member's enrollment
action. Mirrors "./types.js".X12Enrollment minus the looked-up
maintenanceTypeDescription. maintenanceTypeCode (INS-03, X12 875) is
REQUIRED and safety-critical - it is emitted verbatim and an unknown code
is REFUSED.
Example
import type { Build834MemberSpec } from "@cosyte/x12";
const member: Build834MemberSpec = {
subscriberIndicator: "Y", relationshipCode: "18", maintenanceTypeCode: "021",
member: { lastName: "DOE", firstName: "JANE", idQualifier: "34", idCode: "MBR0001" },
healthCoverages: [{ maintenanceTypeCode: "021", insuranceLineCode: "HLT" }],
};
Properties
benefitStatusCode?
readonlyoptionalbenefitStatusCode?:string
INS-05 - benefit status code (A active, C COBRA, …).
coordinationOfBenefits?
readonlyoptionalcoordinationOfBenefits?: readonlyBuild834CoordinationOfBenefitsSpec[]
Loop 2320 coordination of benefits.
dates?
readonlyoptionaldates?: readonlyBuild834DateSpec[]
DTP member-level dates (eligibility begin / end).
employmentStatusCode?
readonlyoptionalemploymentStatusCode?:string
INS-08 - employment status code (FT, PT, …).
healthCoverages?
readonlyoptionalhealthCoverages?: readonlyBuild834CoverageSpec[]
Loop 2300 health coverages.
maintenanceReasonCode?
readonlyoptionalmaintenanceReasonCode?:string
INS-04 - maintenance reason code.
maintenanceTypeCode
readonlymaintenanceTypeCode:string
INS-03 - maintenance type code (X12 875; required, validated).
member?
readonlyoptionalmember?:Build834MemberNameSpec
Loop 2100A member name + DMG + address.
references?
readonlyoptionalreferences?: readonlyBuild834ReferenceSpec[]
REF supplemental identifiers (subscriber id, group/policy).
relationshipCode?
readonlyoptionalrelationshipCode?:string
INS-02 - relationship code (18 self, 01 spouse, 19 child, …).
subscriberIndicator?
readonlyoptionalsubscriberIndicator?:string
INS-01 - subscriber indicator (Y subscriber / N dependent).
Build834PartySpec
N1 party - sponsor (Loop 1000A, N1*P5) or payer (Loop 1000B, N1*IN).
Mirrors "./types.js".X12EnrollmentParty.
Example
import type { Build834PartySpec } from "@cosyte/x12";
const sponsor: Build834PartySpec = {
entityIdentifierCode: "P5", name: "EMPLOYER CO", idQualifier: "FI", idCode: "FEIN123",
};
Properties
entityIdentifierCode
readonlyentityIdentifierCode:string
N1-01 - entity identifier code (P5 sponsor / IN payer).
idCode?
readonlyoptionalidCode?:string
N1-04 - identification code.
idQualifier?
readonlyoptionalidQualifier?:string
N1-03 - identification code qualifier.
name
readonlyname:string
N1-02 - party name.
Build834ReferenceSpec
REF supplemental identifier on the header or a member. Mirrors "./types.js".X12EnrollmentReference. description (REF-03) is emitted
only when supplied.
Example
import type { Build834ReferenceSpec } from "@cosyte/x12";
const ref: Build834ReferenceSpec = { qualifier: "0F", value: "MBR0001" };
Properties
description?
readonlyoptionaldescription?:string
REF-03 - description (situational).
qualifier
readonlyqualifier:string
REF-01 - reference identification qualifier.
value
readonlyvalue:string
REF-02 - reference identification value.
Build834Spec
The full input to "./build-834.js".build834: the envelope, the
header, and ≥ 1 member loop. A well-formed spec round-trips through
get834Header / get834Enrollments field-for-field; a spec with an
unknown maintenance type or a missing member loop is REFUSED with an
"./build-errors.js".Enrollment834BuildError.
Example
import { build834, type Build834Spec } from "@cosyte/x12";
const spec: Build834Spec = {
envelope: {
senderId: "EMPLOYERCO", receiverId: "MEDPAY",
interchangeDate: "260601", interchangeTime: "1200",
interchangeControlNumber: "000000001",
groupControlNumber: "1", transactionSetControlNumber: "0001",
},
header: {
transactionSetPurposeCode: "00", referenceId: "FILE-202606", date: "20260601",
sponsor: { entityIdentifierCode: "P5", name: "EMPLOYER CO" },
payer: { entityIdentifierCode: "IN", name: "MEDPAY INSURANCE" },
},
members: [
{
subscriberIndicator: "Y", relationshipCode: "18", maintenanceTypeCode: "021",
member: { lastName: "DOE", firstName: "JANE", idQualifier: "34", idCode: "MBR0001" },
healthCoverages: [{ maintenanceTypeCode: "021", insuranceLineCode: "HLT" }],
},
],
};
const ix = build834(spec);
Properties
envelope
readonlyenvelope:Build834EnvelopeSpec
Interchange / group / transaction identity.
header
readonlyheader:Build834HeaderSpec
BGN header + sponsor / payer parties.
members
readonlymembers: readonlyBuild834MemberSpec[]
Loop 2000 member-level detail (≥ 1 required).
Build835AddressSpec
N3 + N4 address block on a party. Mirrors "./types.js".X12RemitAddress.
Example
import type { Build835AddressSpec } from "@cosyte/x12";
const a: Build835AddressSpec = {
lines: ["123 PAYER WAY"], city: "BALTIMORE", state: "MD", postalCode: "21244",
};
Properties
city?
readonlyoptionalcity?:string
N4-01 - city.
countryCode?
readonlyoptionalcountryCode?:string
N4-04 - country code.
lines
readonlylines: readonlystring[]
N3 address lines (1-2).
postalCode?
readonlyoptionalpostalCode?:string
N4-03 - postal code.
state?
readonlyoptionalstate?:string
N4-02 - state / province.
Build835AdjustmentSpec
One CAS adjustment (one reason / amount / quantity triple under a group
code). Mirrors "./types.js".X12RemitAdjustment minus the
looked-up reasonDescription. The builder re-chunks adjustments that
share a groupCode into CAS segments (≤ 6 triples each).
Example
import type { Build835AdjustmentSpec } from "@cosyte/x12";
import { X12Decimal } from "@cosyte/x12";
const cas: Build835AdjustmentSpec = {
groupCode: "PR", reasonCode: "1", amount: X12Decimal.fromString("50.00")!,
};
Properties
amount
readonlyamount:X12Decimal
Adjustment amount.
groupCode
readonlygroupCode:string
CAS-01 - claim adjustment group code (CO, PR, OA, PI).
quantity?
readonlyoptionalquantity?:X12Decimal
Adjustment quantity (situational).
reasonCode
readonlyreasonCode:string
Adjustment reason code (CARC).
Build835AmountSpec
AMT supplemental amount on a claim / service line. Mirrors "./types.js".X12RemitAmount.
Example
import type { Build835AmountSpec } from "@cosyte/x12";
import { X12Decimal } from "@cosyte/x12";
const amt: Build835AmountSpec = { qualifier: "B6", amount: X12Decimal.fromString("450.00")! };
Properties
amount
readonlyamount:X12Decimal
AMT-02 - monetary amount.
qualifier
readonlyqualifier:string
AMT-01 - amount qualifier code (AU, B6, …).
Build835ClaimSpec
Loop 2100 claim-payment spec. Subject to the claim balance invariant
CLP-03 == CLP-04 + Σ(claim CAS + line CAS) - the builder REFUSES an
out-of-balance claim. Mirrors "./types.js".X12RemitClaim minus
the looked-up claimStatusDescription.
Example
import type { Build835ClaimSpec } from "@cosyte/x12";
import { X12Decimal } from "@cosyte/x12";
const claim: Build835ClaimSpec = {
patientControlNumber: "PT-ACCT-001", claimStatusCode: "1",
totalChargeAmount: X12Decimal.fromString("500.00")!,
totalPaymentAmount: X12Decimal.fromString("450.00")!,
patientResponsibilityAmount: X12Decimal.fromString("50.00")!,
};
Properties
adjustments?
readonlyoptionaladjustments?: readonlyBuild835AdjustmentSpec[]
Claim-level CAS adjustments.
amounts?
readonlyoptionalamounts?: readonlyBuild835AmountSpec[]
Claim-level AMT amounts.
claimFilingIndicatorCode?
readonlyoptionalclaimFilingIndicatorCode?:string
CLP-06 - claim filing indicator code.
claimFrequencyCode?
readonlyoptionalclaimFrequencyCode?:string
CLP-08-3 - claim frequency code.
claimStatusCode
readonlyclaimStatusCode:string
CLP-02 - claim status code.
correctedPatient?
readonlyoptionalcorrectedPatient?:Build835PersonSpec
NM1*74 corrected patient.
facilityTypeCode?
readonlyoptionalfacilityTypeCode?:string
CLP-08-1 - facility type code.
patient?
readonlyoptionalpatient?:Build835PersonSpec
NM1*QC patient.
patientControlNumber
readonlypatientControlNumber:string
CLP-01 - patient control number.
patientResponsibilityAmount
readonlypatientResponsibilityAmount:X12Decimal
CLP-05 - patient responsibility amount (informational, not balanced).
payerClaimControlNumber?
readonlyoptionalpayerClaimControlNumber?:string
CLP-07 - payer claim control number.
references?
readonlyoptionalreferences?: readonlyBuild835ReferenceSpec[]
Claim-level REF identifiers.
remarks?
readonlyoptionalremarks?: readonlyBuild835RemarkSpec[]
Claim-level LQ remarks.
renderingProvider?
readonlyoptionalrenderingProvider?:Build835ProviderSpec
A second NM1*82 (rendering provider).
serviceLines?
readonlyoptionalserviceLines?: readonlyBuild835ServiceLineSpec[]
Loop 2110 service lines.
servicePeriodEnd?
readonlyoptionalservicePeriodEnd?:string
DTM*233 statement-to date.
servicePeriodStart?
readonlyoptionalservicePeriodStart?:string
DTM*232 statement-from date.
serviceProvider?
readonlyoptionalserviceProvider?:Build835ProviderSpec
NM1*82 service provider.
subscriber?
readonlyoptionalsubscriber?:Build835PersonSpec
NM1*IL subscriber.
totalChargeAmount
readonlytotalChargeAmount:X12Decimal
CLP-03 - total submitted charge amount.
totalPaymentAmount
readonlytotalPaymentAmount:X12Decimal
CLP-04 - total claim payment amount.
Build835ContactSpec
PER contact on a party (Loop 1000A/1000B). Each contact may carry up to three communication channels. Mirrors "./types.js".X12RemitContact.
Example
import type { Build835ContactSpec } from "@cosyte/x12";
const per: Build835ContactSpec = {
contactFunctionCode: "BL",
name: "JANE COORDINATOR",
communications: [{ qualifier: "TE", value: "5551234567" }],
};
Properties
communications?
readonlyoptionalcommunications?: readonlyobject[]
Up to 3 communication channels (PER-03/04, 05/06, 07/08).
contactFunctionCode
readonlycontactFunctionCode:string
PER-01 - contact function code (BL technical, CX claim office, …).
name?
readonlyoptionalname?:string
PER-02 - contact name.
Build835EnvelopeSpec
Interchange + group + transaction identity for the built 835. Mirrors
the build999 envelope spec; the builder fixes GS-01 to "HP" and the
version/release to "005010X221A1" (the 835 functional group + TR3) so
the caller never hand-codes them.
Example
import type { Build835EnvelopeSpec } from "@cosyte/x12";
const env: Build835EnvelopeSpec = {
senderId: "MEDICARE", receiverId: "SUBMITTER",
interchangeDate: "260601", interchangeTime: "1200",
interchangeControlNumber: "000000001",
groupControlNumber: "1", transactionSetControlNumber: "0001",
};
Properties
applicationReceiverCode?
readonlyoptionalapplicationReceiverCode?:string
GS-03 - application receiver code. Default: the interchange receiver id.
applicationSenderCode?
readonlyoptionalapplicationSenderCode?:string
GS-02 - application sender code. Default: the interchange sender id.
componentSeparator?
readonlyoptionalcomponentSeparator?:string
Component (sub-element) separator (ISA-16). Default ":".
elementSeparator?
readonlyoptionalelementSeparator?:string
Element separator (ISA byte 4). Default "*".
groupControlNumber
readonlygroupControlNumber:string
GS-06 / GE-02 - group control number.
groupDate?
readonlyoptionalgroupDate?:string
GS-04 - group date CCYYMMDD. Default: century-expanded ISA-09.
groupTime?
readonlyoptionalgroupTime?:string
GS-05 - group time HHMM. Default: the interchange time.
interchangeControlNumber
readonlyinterchangeControlNumber:string
ISA-13 / IEA-02 - interchange control number (zero-padded to 9 on emit).
interchangeDate
readonlyinterchangeDate:string
ISA-09 - interchange date YYMMDD.
interchangeTime
readonlyinterchangeTime:string
ISA-10 - interchange time HHMM.
receiverId
readonlyreceiverId:string
ISA-08 - interchange receiver id (padded to 15 on emit).
receiverQualifier?
readonlyoptionalreceiverQualifier?:string
ISA-07 - interchange receiver qualifier. Default "ZZ".
repetitionSeparator?
readonlyoptionalrepetitionSeparator?:string
Repetition separator (ISA-11). Default "^".
segmentTerminator?
readonlyoptionalsegmentTerminator?:string
Segment terminator (ISA byte 106). Default "~".
senderId
readonlysenderId:string
ISA-06 - interchange sender id (padded to 15 on emit).
senderQualifier?
readonlyoptionalsenderQualifier?:string
ISA-05 - interchange sender qualifier. Default "ZZ".
transactionSetControlNumber
readonlytransactionSetControlNumber:string
ST-02 / SE-02 - transaction set control number.
usageIndicator?
readonlyoptionalusageIndicator?:string
ISA-15 - usage indicator (P production, T test). Default "P".
Build835PartySpec
N1 party - payer (Loop 1000A, entityIdentifierCode: "PR") or payee
(Loop 1000B, "PE"). Mirrors "./types.js".X12RemitParty.
Example
import type { Build835PartySpec } from "@cosyte/x12";
const payer: Build835PartySpec = {
entityIdentifierCode: "PR", name: "MEDICARE PART A",
address: { lines: ["123 PAYER WAY"], city: "BALTIMORE", state: "MD", postalCode: "21244" },
};
Properties
additionalIdentifiers?
readonlyoptionaladditionalIdentifiers?: readonlyBuild835ReferenceSpec[]
REF additional identifiers.
address?
readonlyoptionaladdress?:Build835AddressSpec
N3 + N4 address block.
contacts?
readonlyoptionalcontacts?: readonlyBuild835ContactSpec[]
PER contacts.
entityIdentifierCode
readonlyentityIdentifierCode:string
N1-01 - entity identifier code (PR payer / PE payee).
idCode?
readonlyoptionalidCode?:string
N1-04 - identification code.
idQualifier?
readonlyoptionalidQualifier?:string
N1-03 - identification code qualifier.
name
readonlyname:string
N1-02 - party name.
Build835PaymentSpec
BPR financial-information / payment header. totalActualPayment is the
sum the bank moved - it is the right-hand side of the top-of-remit
balance invariant BPR-02 == Σ(CLP-04) − Σ(PLB) the builder enforces.
Example
import type { Build835PaymentSpec } from "@cosyte/x12";
import { X12Decimal } from "@cosyte/x12";
const bpr: Build835PaymentSpec = {
transactionHandlingCode: "I",
totalActualPayment: X12Decimal.fromString("450.00")!,
creditDebitFlag: "C",
method: "ACH",
paymentDate: "20260601",
};
Properties
creditDebitFlag
readonlycreditDebitFlag:string
BPR-03 - credit/debit flag (C credit, D debit).
method
readonlymethod:string
BPR-04 - payment method (ACH, CHK, NON, BOP, FWT).
paymentDate
readonlypaymentDate:string
BPR-16 - payment effective date (CCYYMMDD).
paymentFormatCode?
readonlyoptionalpaymentFormatCode?:string
BPR-05 - payment format code (situational).
totalActualPayment
readonlytotalActualPayment:X12Decimal
BPR-02 - total actual provider payment amount.
transactionHandlingCode
readonlytransactionHandlingCode:string
BPR-01 - transaction handling code (I remittance + payment, H notification, …).
Build835PersonSpec
NM1 person on a claim - patient (QC), subscriber (IL), or corrected
patient (74). Mirrors "./types.js".X12RemitPerson. NM1-02
(entity type qualifier) is emitted as "1" (person).
Example
import type { Build835PersonSpec } from "@cosyte/x12";
const patient: Build835PersonSpec = {
entityIdentifierCode: "QC", lastName: "PATIENT", firstName: "TEST",
idQualifier: "MI", idCode: "MEMBER001",
};
Properties
entityIdentifierCode
readonlyentityIdentifierCode:string
NM1-01 - entity identifier code (QC patient / IL insured / 74 corrected).
firstName?
readonlyoptionalfirstName?:string
NM1-04 - first name.
idCode?
readonlyoptionalidCode?:string
NM1-09 - identification code.
idQualifier?
readonlyoptionalidQualifier?:string
NM1-08 - identification code qualifier (MI, 34, …).
lastName?
readonlyoptionallastName?:string
NM1-03 - last name / organization name.
middleName?
readonlyoptionalmiddleName?:string
NM1-05 - middle name.
suffix?
readonlyoptionalsuffix?:string
NM1-07 - name suffix.
Build835ProviderAdjustmentSpec
PLB provider-level adjustment. Sign convention (raw EDI): a POSITIVE
amount REDUCES the provider payment (take-back / recoupment); a NEGATIVE
amount ADDS to it (interest / advance). The top-of-remit invariant
BPR-02 == Σ(CLP-04) − Σ(PLB) relies on this sign. Mirrors "./types.js".X12RemitProviderAdjustment.
Example
import type { Build835ProviderAdjustmentSpec } from "@cosyte/x12";
import { X12Decimal } from "@cosyte/x12";
const plb: Build835ProviderAdjustmentSpec = {
providerId: "1234567890", fiscalPeriodDate: "20261231",
reasonCode: "WO", subCode: "PRIOR-CLAIM-X", amount: X12Decimal.fromString("50.00")!,
};
Properties
amount
readonlyamount:X12Decimal
Adjustment amount (raw EDI sign).
fiscalPeriodDate
readonlyfiscalPeriodDate:string
PLB-02 - fiscal period date (CCYYMMDD).
providerId
readonlyproviderId:string
PLB-01 - provider identifier.
reasonCode
readonlyreasonCode:string
Adjustment reason code (PLB composite component 1).
subCode?
readonlyoptionalsubCode?:string
Adjustment reference / sub code (PLB composite component 2).
Build835ProviderSpec
NM1 provider on a claim - service provider (82). Mirrors "./types.js".X12RemitProvider. NM1-02 is emitted as "2"
(non-person / organization).
Example
import type { Build835ProviderSpec } from "@cosyte/x12";
const prov: Build835ProviderSpec = {
entityIdentifierCode: "82", name: "RENDERING PROVIDER INC",
idQualifier: "XX", idCode: "1234567890",
};
Properties
entityIdentifierCode
readonlyentityIdentifierCode:string
NM1-01 - entity identifier code (82 service provider).
idCode?
readonlyoptionalidCode?:string
NM1-09 - identification code.
idQualifier?
readonlyoptionalidQualifier?:string
NM1-08 - identification code qualifier (XX NPI).
name?
readonlyoptionalname?:string
NM1-03 - organization name.
Build835ReferenceSpec
REF additional identifier on a party / claim / service line. Mirrors
"./types.js".X12RemitReference. description (REF-03) is
emitted only when supplied.
Example
import type { Build835ReferenceSpec } from "@cosyte/x12";
const ref: Build835ReferenceSpec = { qualifier: "TJ", value: "123456789" };
Properties
description?
readonlyoptionaldescription?:string
REF-03 - description (situational).
qualifier
readonlyqualifier:string
REF-01 - reference identification qualifier.
value
readonlyvalue:string
REF-02 - reference identification value.
Build835RemarkSpec
One remark (LQ). Mirrors "./types.js".X12RemitRemark minus the
looked-up description. Emitted as LQ*{system}*{code}. Note: the read
side also surfaces MIA/MOA remark codes as system: "HE" remarks - the
builder emits all remarks via LQ, so a round-trip reproduces the
{ system, code } pair (the equivalent model), not the original
MIA/MOA segment.
Example
import type { Build835RemarkSpec } from "@cosyte/x12";
const lq: Build835RemarkSpec = { system: "HE", code: "N4" };
Properties
code
readonlycode:string
LQ-02 - industry code value.
system
readonlysystem:string
LQ-01 - code list qualifier code (HE healthcare remark / RARC, …).
Build835ServiceLineSpec
Loop 2110 service-line spec. Subject to the per-line balance invariant
SVC-02 == SVC-03 + Σ(line CAS) - the builder REFUSES an out-of-balance
line. Mirrors "./types.js".X12RemitServiceLine.
Example
import type { Build835ServiceLineSpec } from "@cosyte/x12";
import { X12Decimal } from "@cosyte/x12";
const line: Build835ServiceLineSpec = {
productServiceIdQualifier: "HC", productServiceId: "99213",
chargeAmount: X12Decimal.fromString("500.00")!,
paymentAmount: X12Decimal.fromString("450.00")!,
adjustments: [{ groupCode: "PR", reasonCode: "1", amount: X12Decimal.fromString("50.00")! }],
};
Properties
adjustments?
readonlyoptionaladjustments?: readonlyBuild835AdjustmentSpec[]
Line-level CAS adjustments.
amounts?
readonlyoptionalamounts?: readonlyBuild835AmountSpec[]
Line-level AMT amounts.
chargeAmount
readonlychargeAmount:X12Decimal
SVC-02 - line item charge amount.
modifiers?
readonlyoptionalmodifiers?: readonlystring[]
SVC-01-3..6 - procedure modifiers.
originalServiceId?
readonlyoptionaloriginalServiceId?:string
SVC-06-2 - original (submitted) product/service ID.
originalServiceIdQualifier?
readonlyoptionaloriginalServiceIdQualifier?:string
SVC-06-1 - original product/service ID qualifier.
originalUnitsOfService?
readonlyoptionaloriginalUnitsOfService?:X12Decimal
SVC-07 - Original Units of Service Count: the units as SUBMITTED, sent only when they differ from the paid count in SVC-05.
paidUnitsOfService?
readonlyoptionalpaidUnitsOfService?:X12Decimal
SVC-05 - Units of Service Paid Count. The count the payer actually adjudicated. Distinct from Build835ServiceLineSpec.originalUnitsOfService, which is what was submitted.
paymentAmount
readonlypaymentAmount:X12Decimal
SVC-03 - line item provider payment amount.
productServiceId
readonlyproductServiceId:string
SVC-01-2 - product/service ID (the procedure code).
productServiceIdQualifier
readonlyproductServiceIdQualifier:string
SVC-01-1 - product/service ID qualifier (HC, AD, N4, WK, IV).
references?
readonlyoptionalreferences?: readonlyBuild835ReferenceSpec[]
Line-level REF identifiers.
remarks?
readonlyoptionalremarks?: readonlyBuild835RemarkSpec[]
Line-level LQ remarks.
revenueCode?
readonlyoptionalrevenueCode?:string
SVC-04 - NUBC revenue code (institutional).
serviceDateEnd?
readonlyoptionalserviceDateEnd?:string
Service date end (DTM*151).
serviceDateStart?
readonlyoptionalserviceDateStart?:string
Service date start (DTM150, or single DTM472 when start == end).
Build835Spec
The full input to "./build-835.js".build835: the envelope, the
payment header, ≥ 1 trace, optional payer/payee parties, the claims, and
optional provider-level adjustments. A balanced spec round-trips through
get835 field-for-field; an imbalanced one is REFUSED with a "./build-errors.js".Remit835BuildError.
Example
import { build835, X12Decimal, type Build835Spec } from "@cosyte/x12";
const spec: Build835Spec = {
envelope: {
senderId: "MEDICARE", receiverId: "SUBMITTER",
interchangeDate: "260601", interchangeTime: "1200",
interchangeControlNumber: "000000001",
groupControlNumber: "1", transactionSetControlNumber: "0001",
},
payment: {
transactionHandlingCode: "I",
totalActualPayment: X12Decimal.fromString("450.00")!,
creditDebitFlag: "C", method: "ACH", paymentDate: "20260601",
},
traces: [{ traceTypeCode: "1", referenceId: "0012345", originatingCompanyId: "1512345678" }],
claims: [
{
patientControlNumber: "PT-ACCT-001", claimStatusCode: "1",
totalChargeAmount: X12Decimal.fromString("500.00")!,
totalPaymentAmount: X12Decimal.fromString("450.00")!,
patientResponsibilityAmount: X12Decimal.fromString("50.00")!,
adjustments: [{ groupCode: "PR", reasonCode: "1", amount: X12Decimal.fromString("50.00")! }],
},
],
};
const ix = build835(spec);
Properties
claims
readonlyclaims: readonlyBuild835ClaimSpec[]
Loop 2100 claim payments.
envelope
readonlyenvelope:Build835EnvelopeSpec
Interchange / group / transaction identity.
payee?
readonlyoptionalpayee?:Build835PartySpec
Loop 1000B payee party (N1*PE).
payer?
readonlyoptionalpayer?:Build835PartySpec
Loop 1000A payer party (N1*PR).
payment
readonlypayment:Build835PaymentSpec
BPR payment header.
providerAdjustments?
readonlyoptionalproviderAdjustments?: readonlyBuild835ProviderAdjustmentSpec[]
PLB provider-level adjustments.
traces
readonlytraces: readonlyBuild835TraceSpec[]
TRN traces (≥ 1 required).
Build835TraceSpec
TRN reassociation trace. At least one is required by the TR3 (it pairs the 835 to the payment artifact a cash-poster reconciles against).
Example
import type { Build835TraceSpec } from "@cosyte/x12";
const trn: Build835TraceSpec = {
traceTypeCode: "1", referenceId: "0012345", originatingCompanyId: "1512345678",
};
Properties
originatingCompanyId?
readonlyoptionaloriginatingCompanyId?:string
TRN-03 - originating company identifier.
originatingCompanySupplementalCode?
readonlyoptionaloriginatingCompanySupplementalCode?:string
TRN-04 - originating company supplemental code.
referenceId
readonlyreferenceId:string
TRN-02 - reference identification (the trace / check number).
traceTypeCode
readonlytraceTypeCode:string
TRN-01 - trace type code (1 current transaction trace numbers).
Build837AddressSpec
N3 + N4 address block on an entity. Mirrors "./types.js".X12ClaimAddress.
Example
import type { Build837AddressSpec } from "@cosyte/x12";
const a: Build837AddressSpec = {
lines: ["123 BILLING WAY"], city: "CLEVELAND", state: "OH", postalCode: "44113",
};
Properties
city?
readonlyoptionalcity?:string
N4-01 - city.
countryCode?
readonlyoptionalcountryCode?:string
N4-04 - country code.
lines
readonlylines: readonlystring[]
N3 address lines (1-2).
postalCode?
readonlyoptionalpostalCode?:string
N4-03 - postal code.
state?
readonlyoptionalstate?:string
N4-02 - state / province.
Build837AdjudicationSpec
SVD + adjacent CAS / DTP - Loop 2430 Line Adjudication Information (a prior payer's adjudication of this line, for COB). Mirrors "./types.js".X12LineAdjudication.
Example
import type { Build837AdjudicationSpec } from "@cosyte/x12";
import { X12Decimal } from "@cosyte/x12";
const svd: Build837AdjudicationSpec = {
otherPayerId: "PAYER02", amountPaid: X12Decimal.fromString("50.00")!,
procedureQualifier: "HC", procedureCode: "99213",
adjustments: [{ groupCode: "CO", reasonCode: "45", amount: X12Decimal.fromString("20.00")! }],
dateAdjudicated: "20260520",
};
Properties
adjustments?
readonlyoptionaladjustments?: readonlyBuild837AdjustmentSpec[]
CAS adjustments under this adjudication.
amountPaid
readonlyamountPaid:X12Decimal
SVD-02 - amount the other payer paid for this line.
dateAdjudicated?
readonlyoptionaldateAdjudicated?:string
DTP*573 - adjudication / payment date (CCYYMMDD).
otherPayerId
readonlyotherPayerId:string
SVD-01 - other payer identifier.
paidUnits?
readonlyoptionalpaidUnits?:X12Decimal
SVD-05 - paid units of service.
procedureCode?
readonlyoptionalprocedureCode?:string
SVD-03-2 - adjudicated procedure code.
procedureQualifier?
readonlyoptionalprocedureQualifier?:string
SVD-03-1 - adjudicated procedure qualifier.
Build837AdjustmentSpec
One CAS adjustment triple inside a Loop 2430 line adjudication. Mirrors
the remit X12RemitAdjustment shape (CAS semantics are identical).
Example
import type { Build837AdjustmentSpec } from "@cosyte/x12";
import { X12Decimal } from "@cosyte/x12";
const cas: Build837AdjustmentSpec = { groupCode: "CO", reasonCode: "45", amount: X12Decimal.fromString("20.00")! };
Properties
amount
readonlyamount:X12Decimal
Adjustment amount.
groupCode
readonlygroupCode:string
CAS-01 - claim adjustment group code (CO, PR, OA, PI).
quantity?
readonlyoptionalquantity?:X12Decimal
Adjustment quantity (situational).
reasonCode
readonlyreasonCode:string
Adjustment reason code (CARC).
Build837AmountSpec
AMT supplemental amount on a claim / service line. Mirrors "./types.js".X12ClaimAmount.
Example
import type { Build837AmountSpec } from "@cosyte/x12";
import { X12Decimal } from "@cosyte/x12";
const amt: Build837AmountSpec = { qualifier: "F5", amount: X12Decimal.fromString("25.00")! };
Properties
amount
readonlyamount:X12Decimal
AMT-02 - monetary amount.
qualifier
readonlyqualifier:string
AMT-01 - amount qualifier code.
Build837BillingProviderSpec
Loop 2000A billing provider. Emits an HL level-20 top-of-tree node, computed by the builder. Requires ≥ 1 subscriber.
Example
import type { Build837BillingProviderSpec } from "@cosyte/x12";
declare const sub: import("@cosyte/x12").Build837SubscriberSpec;
const bp: Build837BillingProviderSpec = {
provider: {
entityIdentifierCode: "85", entityTypeQualifier: "2", name: "BILLING CLINIC INC",
idQualifier: "XX", idCode: "1234567890",
address: { lines: ["123 BILLING WAY"], city: "CLEVELAND", state: "OH", postalCode: "44113" },
references: [{ qualifier: "EI", value: "987654321" }],
},
subscribers: [sub],
};
Properties
payToAddress?
readonlyoptionalpayToAddress?:Build837AddressSpec
NM1*87 - pay-to address (N3/N4 round-trip; the name is not re-surfaced).
payToPlan?
readonlyoptionalpayToPlan?:Build837EntitySpec
NM1*PE - pay-to plan (837I only).
provider
readonlyprovider:Build837EntitySpec
NM1*85 - the billing provider.
subscribers
readonlysubscribers: readonlyBuild837SubscriberSpec[]
Loop 2000B subscribers (≥ 1 required).
Build837ClaimSpec
Loop 2300 claim. The builder REFUSES a claim with an empty claimId or no
service lines (a CLM requires ≥ 1 LX/SVx loop). Mirrors "./types.js".X12Claim minus the HL-resolved context the spine supplies.
Example
import type { Build837ClaimSpec } from "@cosyte/x12";
import { X12Decimal } from "@cosyte/x12";
const claim: Build837ClaimSpec = {
claimId: "PT-ACCT-001", totalCharge: X12Decimal.fromString("150.00")!,
placeOfServiceCode: "11", facilityCodeQualifier: "B", claimFrequencyCode: "1",
providerSignatureOnFile: "Y", providerAcceptAssignment: "A",
benefitsAssignment: "Y", releaseOfInformationCode: "Y",
diagnoses: [{ qualifier: "ABK", code: "J20.9" }],
serviceLines: [{
variant: "P", procedureQualifier: "HC", procedureCode: "99213",
charge: X12Decimal.fromString("150.00")!, unitOfMeasure: "UN",
units: X12Decimal.fromString("1")!, diagnosisPointers: ["1"],
}],
};
Properties
amounts?
readonlyoptionalamounts?: readonlyBuild837AmountSpec[]
AMT claim-level amounts.
benefitsAssignment?
readonlyoptionalbenefitsAssignment?:string
CLM-08 - benefits assignment certification indicator.
claimFrequencyCode?
readonlyoptionalclaimFrequencyCode?:string
CLM-05-3 - claim frequency type code.
claimId
readonlyclaimId:string
CLM-01 - patient account / claim id.
dates?
readonlyoptionaldates?: readonlyBuild837DateSpec[]
DTP claim-level dates.
diagnoses?
readonlyoptionaldiagnoses?: readonlyBuild837HiCodeSpec[]
HI diagnoses.
facilityCodeQualifier?
readonlyoptionalfacilityCodeQualifier?:string
CLM-05-2 - facility code qualifier.
notes?
readonlyoptionalnotes?: readonlyBuild837NoteSpec[]
NTE claim-level notes.
otherHi?
readonlyoptionalotherHi?: readonlyBuild837HiCodeSpec[]
HI other code-set entries (value information, condition, occurrence, …).
otherSubscribers?
readonlyoptionalotherSubscribers?: readonlyBuild837OtherSubscriberSpec[]
Loop 2320 other subscribers.
placeOfServiceCode?
readonlyoptionalplaceOfServiceCode?:string
CLM-05-1 - place of service code.
procedures?
readonlyoptionalprocedures?: readonlyBuild837HiCodeSpec[]
HI procedures.
providerAcceptAssignment?
readonlyoptionalproviderAcceptAssignment?:string
CLM-07 - provider accept assignment code.
providers?
readonlyoptionalproviders?: readonlyBuild837EntitySpec[]
Loop 2310x claim provider names (NM1 fields round-trip).
providerSignatureOnFile?
readonlyoptionalproviderSignatureOnFile?:string
CLM-06 - provider/supplier signature on file.
references?
readonlyoptionalreferences?: readonlyBuild837ReferenceSpec[]
REF claim-level identifiers.
releaseOfInformationCode?
readonlyoptionalreleaseOfInformationCode?:string
CLM-09 - release of information code.
serviceLines
readonlyserviceLines: readonlyBuild837ServiceLineSpec[]
Loop 2400 service lines (≥ 1 required).
totalCharge
readonlytotalCharge:X12Decimal
CLM-02 - total claim charge amount.
Build837ContactSpec
PER contact on an entity (Loop 1000A submitter, etc.). Each contact may carry up to three communication channels. Mirrors "./types.js".X12ClaimContact.
Example
import type { Build837ContactSpec } from "@cosyte/x12";
const per: Build837ContactSpec = {
contactFunctionCode: "IC",
name: "JANE SUBMITTER",
communications: [{ qualifier: "TE", value: "5551234567" }],
};
Properties
communications?
readonlyoptionalcommunications?: readonlyobject[]
Up to 3 communication channels (PER-03/04, 05/06, 07/08).
contactFunctionCode
readonlycontactFunctionCode:string
PER-01 - contact function code (IC information contact, …).
name?
readonlyoptionalname?:string
PER-02 - contact name.
Build837DateSpec
DTP date - claim-level or service-line-level. Mirrors "./types.js".X12ClaimDate.
Example
import type { Build837DateSpec } from "@cosyte/x12";
const d: Build837DateSpec = { qualifier: "472", formatQualifier: "D8", value: "20260601" };
Properties
formatQualifier
readonlyformatQualifier:string
DTP-02 - date/time format qualifier (D8 CCYYMMDD, RD8 range).
qualifier
readonlyqualifier:string
DTP-01 - date/time qualifier (472 service, 431 onset, …).
value
readonlyvalue:string
DTP-03 - the date value verbatim.
Build837DrugSpec
LIN + CTP - Loop 2410 Drug Identification (837P). Mirrors "./types.js".X12LineDrug.
Example
import type { Build837DrugSpec } from "@cosyte/x12";
import { X12Decimal } from "@cosyte/x12";
const drug: Build837DrugSpec = {
qualifier: "N4", code: "00093721410",
quantity: X12Decimal.fromString("1.5")!, unitOfMeasure: "ML",
};
Properties
code
readonlycode:string
LIN-03 - the drug code (NDC).
qualifier
readonlyqualifier:string
LIN-02 - product id qualifier (N4 NDC, …).
quantity?
readonlyoptionalquantity?:X12Decimal
CTP-04 - dispensed quantity (situational).
unitOfMeasure?
readonlyoptionalunitOfMeasure?:string
CTP-05-1 - UCUM unit of measure (situational).
Build837EntitySpec
NM1 entity used throughout the 837 - submitter (41), receiver (40),
billing provider (85), subscriber (IL), payer (PR), patient (QC),
and the 2310x / 2420x provider roles. Mirrors "./types.js".X12ClaimEntity.
Note: when used as a claim-level (2310x) or service-line (2420x) provider,
only the NM1 fields round-trip through get837Claims; an attached
address / contacts / references is emitted but the read side does
not re-surface it on the provider (a documented Phase 5 read limitation).
Example
import type { Build837EntitySpec } from "@cosyte/x12";
const billing: Build837EntitySpec = {
entityIdentifierCode: "85", entityTypeQualifier: "2",
name: "BILLING CLINIC INC", idQualifier: "XX", idCode: "1234567890",
address: { lines: ["123 BILLING WAY"], city: "CLEVELAND", state: "OH", postalCode: "44113" },
references: [{ qualifier: "EI", value: "987654321" }],
};
Properties
address?
readonlyoptionaladdress?:Build837AddressSpec
N3 + N4 address block.
contacts?
readonlyoptionalcontacts?: readonlyBuild837ContactSpec[]
PER contacts.
entityIdentifierCode
readonlyentityIdentifierCode:string
NM1-01 - entity identifier code.
entityTypeQualifier
readonlyentityTypeQualifier:string
NM1-02 - entity type qualifier (1 person, 2 non-person).
firstName?
readonlyoptionalfirstName?:string
NM1-04 - first name (person).
idCode?
readonlyoptionalidCode?:string
NM1-09 - identification code.
idQualifier?
readonlyoptionalidQualifier?:string
NM1-08 - identification code qualifier (XX NPI, MI member id, …).
middleName?
readonlyoptionalmiddleName?:string
NM1-05 - middle name (person).
name
readonlyname:string
NM1-03 - last name / organization name.
references?
readonlyoptionalreferences?: readonlyBuild837ReferenceSpec[]
REF additional identifiers.
suffix?
readonlyoptionalsuffix?:string
NM1-07 - name suffix (person).
Build837EnvelopeSpec
Interchange + group + transaction identity for the built 837. The builder
fixes GS-01 to "HC", and defaults the ST-03 / GS-08 reference to the
variant's TR3 (005010X222A2 / X223A3 / X224A2) so the caller never
has to hand-code it.
🩺 That default is not what every trading partner accepts, so
Build837EnvelopeSpec.implementationConventionReference overrides
it. The three defaults are published errata guides, but they are
neither the identifiers HIPAA adopts at 45 CFR 162.1102 nor the ones
payer companion guides commonly require in ST-03 / GS-08 (CMS and several
state Medicaid guides state 005010X222A1 for Professional and
005010X223A2 for Institutional). A partner that requires one of those
will reject a Professional or Institutional 837 built on the default,
and the override is how you send what your partner asked for. The default
itself was deliberately NOT re-stamped: which published guide identifier
a partner accepts is a partner fact rather than a spec fact, and changing
bytes this library already emitted would break the partners it works with
today. The READ side is unaffected - get837Claims recognises all of
these references.
Example
import type { Build837EnvelopeSpec } from "@cosyte/x12";
const env: Build837EnvelopeSpec = {
senderId: "SUBMITTER", receiverId: "RECEIVER",
interchangeDate: "260601", interchangeTime: "1200",
interchangeControlNumber: "000000001",
groupControlNumber: "1", transactionSetControlNumber: "0001",
};
Properties
applicationReceiverCode?
readonlyoptionalapplicationReceiverCode?:string
GS-03 - application receiver code. Default: the interchange receiver id.
applicationSenderCode?
readonlyoptionalapplicationSenderCode?:string
GS-02 - application sender code. Default: the interchange sender id.
claimOrEncounterIndicator?
readonlyoptionalclaimOrEncounterIndicator?:string
BHT-06 - claim/encounter indicator (CH chargeable, RP reporting). Default "CH".
componentSeparator?
readonlyoptionalcomponentSeparator?:string
Component (sub-element) separator (ISA-16). Default ":".
elementSeparator?
readonlyoptionalelementSeparator?:string
Element separator (ISA byte 4). Default "*".
groupControlNumber
readonlygroupControlNumber:string
GS-06 / GE-02 - group control number.
groupDate?
readonlyoptionalgroupDate?:string
GS-04 - group date CCYYMMDD. Default: century-expanded ISA-09.
groupTime?
readonlyoptionalgroupTime?:string
GS-05 - group time HHMM. Default: the interchange time.
implementationConventionReference?
readonlyoptionalimplementationConventionReference?:string
🩺 ST-03 and GS-08 - the implementation convention reference this
837 declares. Default: the variant's TR3 (005010X222A2 Professional,
005010X223A3 Institutional, 005010X224A2 Dental).
Set it to whatever your trading partner's companion guide requires,
for example 005010X222A1 on a professional claim to a payer that asks
for it. Which published identifier a partner accepts is a partner fact,
so this library will not choose for you: it defaults to a real published
guide and gets out of the way. One value is written to both elements,
because this builder has always written the same reference to ST-03 and
GS-08 and nothing grounds a caller making them differ. That is a statement
about the bytes this field emits, not about what each element may legally
hold: GS-08 is data element 480 (AN 1/12) and ST-03 is element 1705
(AN 1/35), and nothing here bounds the length.
Refused, all X12_837_BUILD_INVALID_SPEC. An empty string, because a
trailing empty element is dropped on emit, so it would delete ST-03 and
GS-08 rather than send them empty. One carrying an active delimiter or
the release character, because these two elements cannot carry it even
escaped: the ST and GS segments are read by a splitter that is not
release-aware, so the declaration would silently become two elements. And
one this library's own reader resolves to a different variant
(005010X223A2 handed to build837P): the file would declare one variant
and carry another's service segments, and get837Claims would then decode
none of its service lines. Those are what this field adds, on top of the
element-type guard every string slot already has, which refuses a
non-string with the same code - no total is published. Anything else is
emitted as given - the set of published errata is not provably
exhaustive, so an identifier this library does not carry is the caller's
call, not an error.
🩺 A guard on this element cannot make the element trustworthy. An active
delimiter in a DIFFERENT envelope field splits its own segment and shifts
every element after it, so ST-03 / GS-08 are then read out of a
neighbour's slot. KNOWN-LIMITATIONS.md carries the measurement.
interchangeControlNumber
readonlyinterchangeControlNumber:string
ISA-13 / IEA-02 - interchange control number (zero-padded to 9 on emit).
interchangeDate
readonlyinterchangeDate:string
ISA-09 - interchange date YYMMDD.
interchangeTime
readonlyinterchangeTime:string
ISA-10 - interchange time HHMM.
receiverId
readonlyreceiverId:string
ISA-08 - interchange receiver id (padded to 15 on emit).
receiverQualifier?
readonlyoptionalreceiverQualifier?:string
ISA-07 - interchange receiver qualifier. Default "ZZ".
repetitionSeparator?
readonlyoptionalrepetitionSeparator?:string
Repetition separator (ISA-11). Default "^".
segmentTerminator?
readonlyoptionalsegmentTerminator?:string
Segment terminator (ISA byte 106). Default "~".
senderId
readonlysenderId:string
ISA-06 - interchange sender id (padded to 15 on emit).
senderQualifier?
readonlyoptionalsenderQualifier?:string
ISA-05 - interchange sender qualifier. Default "ZZ".
transactionDate?
readonlyoptionaltransactionDate?:string
BHT-04 - transaction creation date CCYYMMDD. Default: the group date.
transactionReferenceId?
readonlyoptionaltransactionReferenceId?:string
BHT-03 - originator application reference id. Default: the transaction set control number.
transactionSetControlNumber
readonlytransactionSetControlNumber:string
ST-02 / SE-02 - transaction set control number.
transactionTime?
readonlyoptionaltransactionTime?:string
BHT-05 - transaction creation time HHMM. Default: the group time.
usageIndicator?
readonlyoptionalusageIndicator?:string
ISA-15 - usage indicator (P production, T test). Default "P".
Build837HiCodeSpec
One HI diagnosis / procedure composite. Mirrors "./types.js".X12ClaimHiCode minus the looked-up codeSystem / category
(the builder emits the qualifier; the read side resolves the system).
Example
import type { Build837HiCodeSpec } from "@cosyte/x12";
const dx: Build837HiCodeSpec = { qualifier: "ABK", code: "J20.9" };
Properties
code
readonlycode:string
Composite component 2 - the diagnosis / procedure code.
date?
readonlyoptionaldate?:string
Composite component 4 - date value (situational).
dateQualifier?
readonlyoptionaldateQualifier?:string
Composite component 3 - date/time format qualifier (situational).
monetaryAmount?
readonlyoptionalmonetaryAmount?:X12Decimal
Composite component 5 - monetary amount (situational).
poaIndicator?
readonlyoptionalpoaIndicator?:string
Composite component 9 - present-on-admission indicator (837I).
qualifier
readonlyqualifier:string
Composite component 1 - code-list qualifier (ABK, ABF, BBR, …).
quantity?
readonlyoptionalquantity?:X12Decimal
Composite component 6 - quantity (situational).
versionId?
readonlyoptionalversionId?:string
Composite component 7 - version id (situational).
Build837NoteSpec
NTE free-text note. Mirrors "./types.js".X12ClaimNote. NTE-02 may carry incidental PHI - synthetic-only fixtures.
Example
import type { Build837NoteSpec } from "@cosyte/x12";
const n: Build837NoteSpec = { noteReferenceCode: "ADD", description: "SUPPLEMENTAL INFO" };
Properties
description
readonlydescription:string
NTE-02 - free text.
noteReferenceCode
readonlynoteReferenceCode:string
NTE-01 - note reference code (ADD, CER, …).
Build837OtherSubscriberSpec
Loop 2320 Other Subscriber Information (COB surface). Mirrors "./types.js".X12OtherSubscriber.
Example
import type { Build837OtherSubscriberSpec } from "@cosyte/x12";
const oth: Build837OtherSubscriberSpec = {
payerResponsibilityCode: "S", individualRelationshipCode: "01",
otherSubscriber: { entityIdentifierCode: "IL", entityTypeQualifier: "1", name: "SPOUSE" },
otherPayer: { entityIdentifierCode: "PR", entityTypeQualifier: "2", name: "SECONDARY PLAN" },
};
Properties
claimFilingIndicator?
readonlyoptionalclaimFilingIndicator?:string
SBR-09 - claim filing indicator code.
individualRelationshipCode?
readonlyoptionalindividualRelationshipCode?:string
SBR-02 - individual relationship code.
otherPayer?
readonlyoptionalotherPayer?:Build837EntitySpec
NM1*PR - the other payer.
otherSubscriber?
readonlyoptionalotherSubscriber?:Build837EntitySpec
NM1IL / NM1QC - the other subscriber.
payerResponsibilityCode
readonlypayerResponsibilityCode:string
SBR-01 - payer responsibility code (P/S/T).
Build837PatientSpec
Loop 2000C dependent patient (patient ≠ subscriber). Emits an HL level-23 child of the enclosing subscriber HL, computed by the builder. Requires ≥ 1 claim.
Example
import type { Build837PatientSpec } from "@cosyte/x12";
declare const claim: import("@cosyte/x12").Build837ClaimSpec;
const pat: Build837PatientSpec = {
individualRelationshipCode: "19",
patient: { entityIdentifierCode: "QC", entityTypeQualifier: "1", name: "CHILD", firstName: "TEST" },
claims: [claim],
};
Properties
claims
readonlyclaims: readonlyBuild837ClaimSpec[]
Loop 2300 claims under this patient.
individualRelationshipCode?
readonlyoptionalindividualRelationshipCode?:string
PAT-01 - individual relationship code (19 child, …).
patient
readonlypatient:Build837EntitySpec
NM1*QC - the patient.
Build837ReferenceSpec
REF additional identifier on an entity / claim / service line. Mirrors
"./types.js".X12ClaimReference. description (REF-03) is emitted
only when supplied.
Example
import type { Build837ReferenceSpec } from "@cosyte/x12";
const ref: Build837ReferenceSpec = { qualifier: "EI", value: "987654321" };
Properties
description?
readonlyoptionaldescription?:string
REF-03 - description (situational).
qualifier
readonlyqualifier:string
REF-01 - reference identification qualifier.
value
readonlyvalue:string
REF-02 - reference identification value.
Build837ServiceLineBaseSpec
Fields shared across every service-line variant spec.
Extended by
Build837ServiceLineDentalSpecBuild837ServiceLineInstitutionalSpecBuild837ServiceLineProfessionalSpec
Properties
adjudications?
readonlyoptionaladjudications?: readonlyBuild837AdjudicationSpec[]
Loop 2430 line adjudications.
amounts?
readonlyoptionalamounts?: readonlyBuild837AmountSpec[]
Line-level AMT amounts.
charge
readonlycharge:X12Decimal
SVx charge amount - SV1-02 (P), SV2-03 (I) or SV3-02 (D).
dates?
readonlyoptionaldates?: readonlyBuild837DateSpec[]
DTP service-line dates.
lineNumber?
readonlyoptionallineNumber?:string
LX-01 - line number. Default: the 1-based index within the claim.
notes?
readonlyoptionalnotes?: readonlyBuild837NoteSpec[]
Line-level NTE notes.
providers?
readonlyoptionalproviders?: readonlyBuild837EntitySpec[]
Loop 2420 service-line provider names (NM1 fields round-trip).
references?
readonlyoptionalreferences?: readonlyBuild837ReferenceSpec[]
Line-level REF identifiers.
unitOfMeasure?
readonlyoptionalunitOfMeasure?:string
SVx unit/basis-of-measurement code (UN, MJ, …).
units
readonlyunits:X12Decimal
SVx units of service - SV1-04 (P), SV2-05 (I) or SV3-06 (D).
Required as of 0.0.13. Through 0.0.12 this was optional and an
omitted value was emitted as the literal "0", so the builder stated a
service unit count the caller never supplied. It now refuses with
X12_837_BUILD_INVALID_SPEC instead, the same stance build277 takes
for SVC-07: this builder will not invent a count, and will not leave the
element empty for the receiver to guess at either.
Build837ServiceLineDentalSpec
837D service line (SV3). Mirrors "./types.js".X12_837ServiceLineDental.
Example
import type { Build837ServiceLineDentalSpec } from "@cosyte/x12";
import { X12Decimal } from "@cosyte/x12";
const sl: Build837ServiceLineDentalSpec = {
variant: "D", procedureQualifier: "AD", procedureCode: "D2391",
charge: X12Decimal.fromString("180.00")!, units: X12Decimal.fromString("1")!,
placeOfServiceCode: "11", toothInformation: [{ qualifier: "JP", toothCode: "14", surfaces: ["O"] }],
};
Extends
Properties
adjudications?
readonlyoptionaladjudications?: readonlyBuild837AdjudicationSpec[]
Loop 2430 line adjudications.
Inherited from
Build837ServiceLineBaseSpec.adjudications
amounts?
readonlyoptionalamounts?: readonlyBuild837AmountSpec[]
Line-level AMT amounts.
Inherited from
Build837ServiceLineBaseSpec.amounts
charge
readonlycharge:X12Decimal
SVx charge amount - SV1-02 (P), SV2-03 (I) or SV3-02 (D).
Inherited from
Build837ServiceLineBaseSpec.charge
dates?
readonlyoptionaldates?: readonlyBuild837DateSpec[]
DTP service-line dates.
Inherited from
Build837ServiceLineBaseSpec.dates
lineNumber?
readonlyoptionallineNumber?:string
LX-01 - line number. Default: the 1-based index within the claim.
Inherited from
Build837ServiceLineBaseSpec.lineNumber
modifiers?
readonlyoptionalmodifiers?: readonlystring[]
SV3-01-3..6 - procedure modifiers.
notes?
readonlyoptionalnotes?: readonlyBuild837NoteSpec[]
Line-level NTE notes.
Inherited from
Build837ServiceLineBaseSpec.notes
oralCavityArea?
readonlyoptionaloralCavityArea?: readonlystring[]
SV3-04 - oral cavity area designation codes.
placeOfServiceCode?
readonlyoptionalplaceOfServiceCode?:string
SV3-03 - place of service.
procedureCode
readonlyprocedureCode:string
SV3-01-2 - procedure code.
procedureQualifier
readonlyprocedureQualifier:string
SV3-01-1 - procedure qualifier (AD ADA/CDT).
prosthesisCrownInlayCode?
readonlyoptionalprosthesisCrownInlayCode?:string
SV3-05 - prosthesis / crown / inlay code.
providers?
readonlyoptionalproviders?: readonlyBuild837EntitySpec[]
Loop 2420 service-line provider names (NM1 fields round-trip).
Inherited from
Build837ServiceLineBaseSpec.providers
references?
readonlyoptionalreferences?: readonlyBuild837ReferenceSpec[]
Line-level REF identifiers.
Inherited from
Build837ServiceLineBaseSpec.references
toothInformation?
readonlyoptionaltoothInformation?: readonlyBuild837ToothSpec[]
Loop 2400 TOO tooth information.
unitOfMeasure?
readonlyoptionalunitOfMeasure?:string
SVx unit/basis-of-measurement code (UN, MJ, …).
Inherited from
Build837ServiceLineBaseSpec.unitOfMeasure
units
readonlyunits:X12Decimal
SVx units of service - SV1-04 (P), SV2-05 (I) or SV3-06 (D).
Required as of 0.0.13. Through 0.0.12 this was optional and an
omitted value was emitted as the literal "0", so the builder stated a
service unit count the caller never supplied. It now refuses with
X12_837_BUILD_INVALID_SPEC instead, the same stance build277 takes
for SVC-07: this builder will not invent a count, and will not leave the
element empty for the receiver to guess at either.
Inherited from
Build837ServiceLineBaseSpec.units
variant
readonlyvariant:"D"
Build837ServiceLineInstitutionalSpec
837I service line (SV2). Mirrors "./types.js".X12_837ServiceLineInstitutional.
Example
import type { Build837ServiceLineInstitutionalSpec } from "@cosyte/x12";
import { X12Decimal } from "@cosyte/x12";
const sl: Build837ServiceLineInstitutionalSpec = {
variant: "I", revenueCode: "0120", procedureQualifier: "HC", procedureCode: "99221",
charge: X12Decimal.fromString("1500.00")!, unitOfMeasure: "UN", units: X12Decimal.fromString("1")!,
};
Extends
Properties
adjudications?
readonlyoptionaladjudications?: readonlyBuild837AdjudicationSpec[]
Loop 2430 line adjudications.
Inherited from
Build837ServiceLineBaseSpec.adjudications
amounts?
readonlyoptionalamounts?: readonlyBuild837AmountSpec[]
Line-level AMT amounts.
Inherited from
Build837ServiceLineBaseSpec.amounts
charge
readonlycharge:X12Decimal
SVx charge amount - SV1-02 (P), SV2-03 (I) or SV3-02 (D).
Inherited from
Build837ServiceLineBaseSpec.charge
dates?
readonlyoptionaldates?: readonlyBuild837DateSpec[]
DTP service-line dates.
Inherited from
Build837ServiceLineBaseSpec.dates
lineNumber?
readonlyoptionallineNumber?:string
LX-01 - line number. Default: the 1-based index within the claim.
Inherited from
Build837ServiceLineBaseSpec.lineNumber
modifiers?
readonlyoptionalmodifiers?: readonlystring[]
SV2-02-3..6 - procedure modifiers.
nonCoveredCharge?
readonlyoptionalnonCoveredCharge?:X12Decimal
SV2-07 - non-covered charge amount.
notes?
readonlyoptionalnotes?: readonlyBuild837NoteSpec[]
Line-level NTE notes.
Inherited from
Build837ServiceLineBaseSpec.notes
procedureCode?
readonlyoptionalprocedureCode?:string
SV2-02-2 - procedure code (situational).
procedureQualifier?
readonlyoptionalprocedureQualifier?:string
SV2-02-1 - procedure qualifier (situational).
providers?
readonlyoptionalproviders?: readonlyBuild837EntitySpec[]
Loop 2420 service-line provider names (NM1 fields round-trip).
Inherited from
Build837ServiceLineBaseSpec.providers
references?
readonlyoptionalreferences?: readonlyBuild837ReferenceSpec[]
Line-level REF identifiers.
Inherited from
Build837ServiceLineBaseSpec.references
revenueCode
readonlyrevenueCode:string
SV2-01 - NUBC revenue code.
serviceLineRate?
readonlyoptionalserviceLineRate?:X12Decimal
SV2-06 - line item rate.
unitOfMeasure?
readonlyoptionalunitOfMeasure?:string
SVx unit/basis-of-measurement code (UN, MJ, …).
Inherited from
Build837ServiceLineBaseSpec.unitOfMeasure
units
readonlyunits:X12Decimal
SVx units of service - SV1-04 (P), SV2-05 (I) or SV3-06 (D).
Required as of 0.0.13. Through 0.0.12 this was optional and an
omitted value was emitted as the literal "0", so the builder stated a
service unit count the caller never supplied. It now refuses with
X12_837_BUILD_INVALID_SPEC instead, the same stance build277 takes
for SVC-07: this builder will not invent a count, and will not leave the
element empty for the receiver to guess at either.
Inherited from
Build837ServiceLineBaseSpec.units
variant
readonlyvariant:"I"
Build837ServiceLineProfessionalSpec
837P service line (SV1). Mirrors "./types.js".X12_837ServiceLineProfessional.
Example
import type { Build837ServiceLineProfessionalSpec } from "@cosyte/x12";
import { X12Decimal } from "@cosyte/x12";
const sl: Build837ServiceLineProfessionalSpec = {
variant: "P", procedureQualifier: "HC", procedureCode: "99213",
modifiers: ["25"], charge: X12Decimal.fromString("150.00")!,
unitOfMeasure: "UN", units: X12Decimal.fromString("1")!,
diagnosisPointers: ["1"], dates: [{ qualifier: "472", formatQualifier: "D8", value: "20260601" }],
};
Extends
Properties
adjudications?
readonlyoptionaladjudications?: readonlyBuild837AdjudicationSpec[]
Loop 2430 line adjudications.
Inherited from
Build837ServiceLineBaseSpec.adjudications
amounts?
readonlyoptionalamounts?: readonlyBuild837AmountSpec[]
Line-level AMT amounts.
Inherited from
Build837ServiceLineBaseSpec.amounts
charge
readonlycharge:X12Decimal
SVx charge amount - SV1-02 (P), SV2-03 (I) or SV3-02 (D).
Inherited from
Build837ServiceLineBaseSpec.charge
dates?
readonlyoptionaldates?: readonlyBuild837DateSpec[]
DTP service-line dates.
Inherited from
Build837ServiceLineBaseSpec.dates
diagnosisPointers?
readonlyoptionaldiagnosisPointers?: readonlystring[]
SV1-07 - diagnosis code pointers (1-4).
drug?
readonlyoptionaldrug?:Build837DrugSpec
Loop 2410 drug identification.
emergencyIndicator?
readonlyoptionalemergencyIndicator?:string
SV1-09 - emergency indicator.
epsdtIndicator?
readonlyoptionalepsdtIndicator?:string
SV1-11 - EPSDT indicator.
familyPlanningIndicator?
readonlyoptionalfamilyPlanningIndicator?:string
SV1-12 - family planning indicator.
lineNumber?
readonlyoptionallineNumber?:string
LX-01 - line number. Default: the 1-based index within the claim.
Inherited from
Build837ServiceLineBaseSpec.lineNumber
modifiers?
readonlyoptionalmodifiers?: readonlystring[]
SV1-01-3..6 - procedure modifiers.
notes?
readonlyoptionalnotes?: readonlyBuild837NoteSpec[]
Line-level NTE notes.
Inherited from
Build837ServiceLineBaseSpec.notes
placeOfServiceCode?
readonlyoptionalplaceOfServiceCode?:string
SV1-05 - place of service (overrides claim-level).
procedureCode
readonlyprocedureCode:string
SV1-01-2 - procedure code.
procedureQualifier
readonlyprocedureQualifier:string
SV1-01-1 - procedure qualifier (HC HCPCS/CPT, …).
providers?
readonlyoptionalproviders?: readonlyBuild837EntitySpec[]
Loop 2420 service-line provider names (NM1 fields round-trip).
Inherited from
Build837ServiceLineBaseSpec.providers
references?
readonlyoptionalreferences?: readonlyBuild837ReferenceSpec[]
Line-level REF identifiers.
Inherited from
Build837ServiceLineBaseSpec.references
unitOfMeasure?
readonlyoptionalunitOfMeasure?:string
SVx unit/basis-of-measurement code (UN, MJ, …).
Inherited from
Build837ServiceLineBaseSpec.unitOfMeasure
units
readonlyunits:X12Decimal
SVx units of service - SV1-04 (P), SV2-05 (I) or SV3-06 (D).
Required as of 0.0.13. Through 0.0.12 this was optional and an
omitted value was emitted as the literal "0", so the builder stated a
service unit count the caller never supplied. It now refuses with
X12_837_BUILD_INVALID_SPEC instead, the same stance build277 takes
for SVC-07: this builder will not invent a count, and will not leave the
element empty for the receiver to guess at either.
Inherited from
Build837ServiceLineBaseSpec.units
variant
readonlyvariant:"P"
Build837Spec
The full input to "./build-837.js".build837P / build837I /
build837D: the envelope, the submitter (Loop 1000A) + receiver (Loop
1000B), and the nested billing-provider → subscriber → (claims | patient)
tree from which the builder COMPUTES the HL spine. A well-formed spec
round-trips through get837Claims field-for-field; a structurally
impossible tree is REFUSED with a "./build-errors.js".Claim837BuildError.
Example
import { build837P, X12Decimal, type Build837Spec } from "@cosyte/x12";
const spec: Build837Spec = {
envelope: {
senderId: "SUBMITTER", receiverId: "RECEIVER",
interchangeDate: "260601", interchangeTime: "1200",
interchangeControlNumber: "000000001",
groupControlNumber: "1", transactionSetControlNumber: "0001",
},
submitter: { entityIdentifierCode: "41", entityTypeQualifier: "2", name: "SUBMITTER ONE", idQualifier: "46", idCode: "SUB001" },
receiver: { entityIdentifierCode: "40", entityTypeQualifier: "2", name: "RECEIVER ONE", idQualifier: "46", idCode: "REC001" },
billingProviders: [{
provider: { entityIdentifierCode: "85", entityTypeQualifier: "2", name: "BILLING CLINIC INC", idQualifier: "XX", idCode: "1234567890" },
subscribers: [{
info: { payerResponsibilityCode: "P", individualRelationshipCode: "18", claimFilingIndicator: "MB" },
subscriber: { entityIdentifierCode: "IL", entityTypeQualifier: "1", name: "PATIENT", firstName: "TEST", idQualifier: "MI", idCode: "MEMBER001" },
payer: { entityIdentifierCode: "PR", entityTypeQualifier: "2", name: "PAYER ONE", idQualifier: "PI", idCode: "PAYER01" },
claims: [{
claimId: "PT-ACCT-001", totalCharge: X12Decimal.fromString("150.00")!,
diagnoses: [{ qualifier: "ABK", code: "J20.9" }],
serviceLines: [{ variant: "P", procedureQualifier: "HC", procedureCode: "99213", charge: X12Decimal.fromString("150.00")!, unitOfMeasure: "UN", units: X12Decimal.fromString("1")!, diagnosisPointers: ["1"] }],
}],
}],
}],
};
const ix = build837P(spec);
Properties
billingProviders
readonlybillingProviders: readonlyBuild837BillingProviderSpec[]
Loop 2000A billing providers (≥ 1 required).
envelope
readonlyenvelope:Build837EnvelopeSpec
Interchange / group / transaction identity.
receiver
readonlyreceiver:Build837EntitySpec
Loop 1000B receiver (NM1*40).
submitter
readonlysubmitter:Build837EntitySpec
Loop 1000A submitter (NM1*41).
Build837SubscriberInfoSpec
SBR - Subscriber Information for a Loop 2000B subscriber. Mirrors "./types.js".X12SubscriberInfo.
Example
import type { Build837SubscriberInfoSpec } from "@cosyte/x12";
const info: Build837SubscriberInfoSpec = {
payerResponsibilityCode: "P", individualRelationshipCode: "18",
groupNumber: "GROUP123", claimFilingIndicator: "MB",
};
Properties
claimFilingIndicator?
readonlyoptionalclaimFilingIndicator?:string
SBR-09 - claim filing indicator code.
groupName?
readonlyoptionalgroupName?:string
SBR-04 - group name.
groupNumber?
readonlyoptionalgroupNumber?:string
SBR-03 - group / policy number.
individualRelationshipCode?
readonlyoptionalindividualRelationshipCode?:string
SBR-02 - individual relationship code (18 self, …).
payerResponsibilityCode
readonlypayerResponsibilityCode:string
SBR-01 - payer responsibility code (P/S/T).
Build837SubscriberSpec
Loop 2000B subscriber. Emits an HL level-22 child of the enclosing billing
provider HL, computed by the builder. Carries either direct claims
(patient = subscriber, SBR-02 18) or dependent patients.
Example
import type { Build837SubscriberSpec } from "@cosyte/x12";
declare const claim: import("@cosyte/x12").Build837ClaimSpec;
const sub: Build837SubscriberSpec = {
info: { payerResponsibilityCode: "P", individualRelationshipCode: "18", claimFilingIndicator: "MB" },
subscriber: { entityIdentifierCode: "IL", entityTypeQualifier: "1", name: "PATIENT", firstName: "TEST", idQualifier: "MI", idCode: "MEMBER001" },
payer: { entityIdentifierCode: "PR", entityTypeQualifier: "2", name: "PAYER ONE", idQualifier: "PI", idCode: "PAYER01" },
claims: [claim],
};
Properties
claims?
readonlyoptionalclaims?: readonlyBuild837ClaimSpec[]
Loop 2300 claims directly under the subscriber (patient = subscriber).
info
readonlyinfo:Build837SubscriberInfoSpec
SBR subscriber information.
patients?
readonlyoptionalpatients?: readonlyBuild837PatientSpec[]
Loop 2000C dependent patients.
payer
readonlypayer:Build837EntitySpec
NM1*PR - the payer.
subscriber
readonlysubscriber:Build837EntitySpec
NM1*IL - the subscriber.
Build837ToothSpec
TOO - Tooth Information (837D Loop 2400). Mirrors "./types.js".X12ToothInformation.
Example
import type { Build837ToothSpec } from "@cosyte/x12";
const too: Build837ToothSpec = { qualifier: "JP", toothCode: "14", surfaces: ["O"] };
Properties
qualifier
readonlyqualifier:string
TOO-01 - tooth-numbering code list qualifier (JP ADA universal, …).
surfaces?
readonlyoptionalsurfaces?: readonlystring[]
TOO-03 - per-surface codes (M, O, D, …).
toothCode
readonlytoothCode:string
TOO-02 - tooth identifier.
Build999ElementErrorSpec
Element-level error spec - the input shape for an IK4 the library will
build. copyOfBadDataElement is OPTIONAL by design: when the offending
value is PHI (medical record number, name, date of birth), callers
SHOULD omit it. The library never auto-populates this field.
Properties
contexts?
readonlyoptionalcontexts?: readonlystring[]
Optional CTX context strings emitted between this IK4 and the next.
Each entry becomes a single CTX segment with the given value as its
first composite element. Pass [] (default) for no context.
copyOfBadDataElement?
readonlyoptionalcopyOfBadDataElement?:string
dataElementReferenceNumber?
readonlyoptionaldataElementReferenceNumber?:string
position
readonlyposition:object
component?
readonlyoptionalcomponent?:number
element
readonlyelement:number
repetition?
readonlyoptionalrepetition?:number
syntaxErrorCode
readonlysyntaxErrorCode:Ik403Code
Build999EnvelopeSpec
Envelope spec for build999 - the ISA + GS + ST + matching trailers
that wrap the 999 transaction set. Defaults are spec-conformant for a
minimal 999 envelope:
senderQualifier/receiverQualifierdefault toZZ(mutually defined).usageIndicatordefaults toP(production).repetitionSeparatordefaults to^;componentSeparatordefaults to:;segmentTerminatordefaults to~. Override for trading- partner companion-guide requirements (e.g. Medicare uses:component, BCBS some shapes use\\).interchangeControlNumberis the 9-character ISA-13 value (zero- padded if needed).groupControlNumberis the GS-06 numeric string (1–9 digits).transactionSetControlNumberis the ST-02 string (4–9 digits per X12 .5).
Properties
componentSeparator?
readonlyoptionalcomponentSeparator?:string
elementSeparator?
readonlyoptionalelementSeparator?:string
groupControlNumber
readonlygroupControlNumber:string
groupDate?
readonlyoptionalgroupDate?:string
groupResponsibleAgency?
readonlyoptionalgroupResponsibleAgency?:string
groupTime?
readonlyoptionalgroupTime?:string
interchangeControlNumber
readonlyinterchangeControlNumber:string
interchangeDate
readonlyinterchangeDate:string
interchangeTime
readonlyinterchangeTime:string
receiverId
readonlyreceiverId:string
receiverQualifier?
readonlyoptionalreceiverQualifier?:string
repetitionSeparator?
readonlyoptionalrepetitionSeparator?:string
segmentTerminator?
readonlyoptionalsegmentTerminator?:string
senderId
readonlysenderId:string
senderQualifier?
readonlyoptionalsenderQualifier?:string
transactionSetControlNumber
readonlytransactionSetControlNumber:string
usageIndicator?
readonlyoptionalusageIndicator?:"P"|"T"
Build999FunctionalGroupSpec
Functional-group response spec - input for the AK1 + AK9 pair.
Properties
disposition
readonlydisposition:X12AckDispositionCode
functionalIdCode
readonlyfunctionalIdCode:string
groupControlNumber
readonlygroupControlNumber:string
numberOfAcceptedTransactionSets
readonlynumberOfAcceptedTransactionSets:number
numberOfReceivedTransactionSets
readonlynumberOfReceivedTransactionSets:number
numberOfTransactionSets
readonlynumberOfTransactionSets:number
syntaxErrorCodes?
readonlyoptionalsyntaxErrorCodes?: readonlystring[]
transactionResponses
readonlytransactionResponses: readonlyBuild999TransactionResponseSpec[]
versionRelease
readonlyversionRelease:string
Build999SegmentErrorSpec
Segment-level error spec - input for an IK3 (with optional nested IK4s).
Properties
contexts?
readonlyoptionalcontexts?: readonlystring[]
Optional CTX context strings emitted between this IK3 and the first nested IK4 (or the next IK3 / IK5 if no IK4s). Each entry becomes a single CTX segment with the given value as its first composite element.
elementErrors?
readonlyoptionalelementErrors?: readonlyBuild999ElementErrorSpec[]
loopIdentifier?
readonlyoptionalloopIdentifier?:string
segmentIdCode
readonlysegmentIdCode:string
segmentPositionInTransactionSet
readonlysegmentPositionInTransactionSet:number
syntaxErrorCode?
readonlyoptionalsyntaxErrorCode?:Ik304Code
Build999Spec
Top-level spec for build999.
Properties
envelope
readonlyenvelope:Build999EnvelopeSpec
functionalGroup
readonlyfunctionalGroup:Build999FunctionalGroupSpec
Build999TransactionResponseSpec
Transaction-set response spec - input for one AK2..IK5 block.
Properties
disposition
readonlydisposition:X12AckDispositionCode
implementationConventionReference?
readonlyoptionalimplementationConventionReference?:string
segmentErrors?
readonlyoptionalsegmentErrors?: readonlyBuild999SegmentErrorSpec[]
syntaxErrorCodes?
readonlyoptionalsyntaxErrorCodes?: readonlystring[]
transactionSetControlNumber
readonlytransactionSetControlNumber:string
transactionSetIdCode
readonlytransactionSetIdCode:string
BuildTA1Options
Options accepted by buildTA1: the delimiter set the returned
segment will be read against. Every field is optional and defaults to the
cosyte parser archetype (* element, ^ repetition, : component, ~
segment), which is the same four build999 takes on
"./types.js".Build999EnvelopeSpec.
The three non-element fields exist for ESCAPING and nothing else.
buildTA1 still emits no segment terminator, no repetition and no
composite. It has to know them because a caller value carrying one of
them has to be released, and because escaping a byte that is NOT a
delimiter where the segment lands corrupts the value: unescapeRelease
preserves ?X verbatim for any X outside the declared set, so a value
released against a guessed delimiter comes back carrying a stray ?.
If you embed a TA1 in an envelope whose delimiters are not the
archetype, state them here - the defaults are an assumption this
function cannot verify, exactly as they were before it escaped anything.
Properties
componentSeparator?
readonlyoptionalcomponentSeparator?:string
elementSeparator?
readonlyoptionalelementSeparator?:string
repetitionSeparator?
readonlyoptionalrepetitionSeparator?:string
segmentTerminator?
readonlyoptionalsegmentTerminator?:string
BuildTA1Spec
Top-level spec for buildTA1.
Properties
ackCode
readonlyackCode:Ta1AckCode
interchangeControlNumber
readonlyinterchangeControlNumber:string
interchangeDate
readonlyinterchangeDate:string
interchangeTime
readonlyinterchangeTime:string
noteCode
readonlynoteCode:Ta1NoteCode
CodeListEntry
One entry returned from a code-list lookup(code). The inbound code
value is echoed verbatim (so a caller that branches on entry.code is
comparing exactly the bytes that came in, never a normalized form);
description is the bundled human-readable text from the snapshot.
Future fields (isObsolete, replacedBy) are tracked by the roadmap;
v0.0.x snapshots ship code + description only.
Example
import { lookupCarc } from "@cosyte/x12";
const entry = lookupCarc("45");
entry?.code; // "45"
entry?.description; // "Charge exceeds fee schedule/maximum allowable..."
Properties
code
readonlycode:string
description
readonlydescription:string
CodeListMeta
Metadata header attached to every bundled code-list snapshot. Surfaces the snapshot's identity + provenance + freshness so consumers can decide whether a stale description matters for their use case.
Example
import { CARC } from "@cosyte/x12";
CARC.meta.id; // "CARC"
CARC.meta.snapshotDate; // ISO date string this snapshot was captured
CARC.meta.publishedDate; // ISO date string of the underlying WPC publication
Properties
description
readonlydescription:string
id
readonlyid:string
note?
readonlyoptionalnote?:string
publishedDate
readonlypublishedDate:string
snapshotDate
readonlysnapshotDate:string
source
readonlysource:string
CodeListSnapshot
A complete bundled code-list snapshot. meta carries provenance;
codes is a frozen plain object so consumers can iterate or build their
own lookups without going through the helper. Internal use prefers the
per-snapshot lookup* helpers - they return a frozen CodeListEntry ergonomic for the helper APIs.
Example
import { CARC } from "@cosyte/x12";
Object.keys(CARC.codes).length; // count of bundled CARC codes
CARC.codes["45"]; // raw description string (or undefined)
Properties
codes
readonlycodes:Readonly<Record<string,string>>
meta
readonlymeta:CodeListMeta
DefineLoopSpecInput
Input shape accepted by defineLoopSpec. children is optional;
LoopSpec.children always materializes as a frozen [] when omitted
so consumer code can iterate without an ?? [] guard.
Example
import type { DefineLoopSpecInput } from "@cosyte/x12";
const input: DefineLoopSpecInput = {
id: "2110",
trigger: "SVC",
segments: [{ id: "SVC", usage: "required", max: 1 }],
};
Properties
children?
readonlyoptionalchildren?: readonlyLoopSpec[]
description?
readonlyoptionaldescription?:string
id
readonlyid:string
segments
readonlysegments: readonlyLoopSegmentSpec[]
trigger
readonlytrigger:string
Delimiters
The four X12 delimiter classes discovered from fixed byte positions inside
the ISA envelope. Phase 1 detects all four from the ISA itself - they are
NEVER assumed (in particular, component is rarely : outside Medicare).
element- ISA byte 4 (1-indexed); separates the 16 ISA elements.repetition- ISA-11 (byte 83, 1-indexed); separates repetitions inside an element. Carries the legacy Control Standards Identifier (typicallyU) for pre-005010 inputs; Phase 1 surfaces it verbatim.component- ISA-16 (byte 105, 1-indexed); separates sub-elements of a composite. Real-world senders use:,\\,^,|, and more.segment- the byte immediately after ISA-16 (byte 106, 1-indexed); terminates each segment. Typically~, often followed by optional\r\nwhich is silently tolerated.
Example
import type { Delimiters } from "@cosyte/x12";
const medicare: Delimiters = {
element: "*",
repetition: "^",
component: ":",
segment: "~",
};
Properties
component
readonlycomponent:string
element
readonlyelement:string
repetition
readonlyrepetition:string
segment
readonlysegment:string
FunctionalGroupSpec
A single GS..GE functional group. The builder emits the GS header, each
transaction set, then GE{count}{control} with GE-01 (the transaction
count) computed for you.
Example
const group: FunctionalGroupSpec = {
functionalIdCode: "HC",
groupControlNumber: "1",
versionRelease: "005010X222A2",
transactions: [tx],
};
Properties
applicationReceiverCode?
readonlyoptionalapplicationReceiverCode?:string
GS-03 - application receiver code. Defaults to the interchange receiver id.
applicationSenderCode?
readonlyoptionalapplicationSenderCode?:string
GS-02 - application sender code. Defaults to the interchange sender id.
functionalIdCode
readonlyfunctionalIdCode:string
GS-01 - functional identifier code (HC claims, HP remittance, …).
groupControlNumber
readonlygroupControlNumber:string
GS-06 / GE-02 - group control number (echoed on GE-02).
groupDate?
readonlyoptionalgroupDate?:string
GS-04 - group date CCYYMMDD. Defaults to the century-expanded ISA-09.
groupTime?
readonlyoptionalgroupTime?:string
GS-05 - group time HHMM. Defaults to the interchange time (ISA-10).
responsibleAgencyCode?
readonlyoptionalresponsibleAgencyCode?:string
GS-07 - responsible agency code. Defaults to "X" (ASC X12).
transactions
readonlytransactions: readonlyTransactionSetSpec[]
The ordered ST..SE transaction sets inside this group.
versionRelease
readonlyversionRelease:string
GS-08 - version / release / industry identifier code (e.g. "005010X222A2").
GeSegment
The decoded GE functional group trailer. GE-01 is the transaction count, which reconciles against the number of ST/SE pairs in the group, and GE-02 the group control number, which reconciles against GS-06.
elements is 1-indexed (elements[0] = "GE", elements[1] = GE-01,
elements[2] = GE-02). Element values are stored RAW,
pre-?-unescape, so an element is the framed byte text of its slot and
not necessarily the value the sender stated.
Example
import type { GeSegment } from "@cosyte/x12";
declare const ge: GeSegment;
ge.raw; // verbatim segment text
ge.elements[2]; // raw text of GE-02 (post-element-split, pre-?-unescape)
Properties
elements
readonlyelements: readonlystring[]
raw
readonlyraw:string
GsSegment
The decoded GS functional group header. GS-01 is the functional ID code
(HC for claims, HP for remittance, etc.), GS-06 the group control
number, which reconciles against GE-02, and GS-08 the version /
implementation convention reference (e.g. 005010X222A2).
elements is 1-indexed (elements[0] = "GS", elements[1] = GS-01,
..., elements[8] = GS-08). Element values are stored RAW,
pre-?-unescape, so an element is the framed byte text of its slot and
not necessarily the value the sender stated.
Example
import type { GsSegment } from "@cosyte/x12";
declare const gs: GsSegment;
gs.raw; // verbatim segment text
gs.elements[6]; // raw text of GS-06 (post-element-split, pre-?-unescape)
Properties
elements
readonlyelements: readonlystring[]
raw
readonlyraw:string
IeaSegment
The decoded IEA interchange trailer. IEA-01 is the group count and IEA-02 the interchange control number, which the envelope walker reconciles against ISA-13.
raw is the exact segment string (without the segment terminator) and
elements is 1-indexed (elements[0] = "IEA", elements[1] = IEA-01,
elements[2] = IEA-02). Element values are stored RAW,
pre-?-unescape, so an element is the framed byte text of its slot and
not necessarily the value the sender stated.
Example
import type { IeaSegment } from "@cosyte/x12";
declare const iea: IeaSegment;
iea.raw; // verbatim segment text
iea.elements[2]; // raw text of IEA-02 (post-element-split, pre-?-unescape)
Properties
elements
readonlyelements: readonlystring[]
raw
readonlyraw:string
InterchangeSpec
The top-level spec for "./build-interchange.js".buildInterchange.
The required fields name the interchange identity; everything else has a
conformant default (*^:~ delimiters, ZZ qualifiers, P usage
indicator, 00501 version).
Example
const spec: InterchangeSpec = {
senderId: "SENDER",
receiverId: "RECEIVER",
interchangeDate: "250101",
interchangeTime: "1200",
interchangeControlNumber: "000000001",
groups: [group],
};
Properties
componentSeparator?
readonlyoptionalcomponentSeparator?:string
Component (sub-element) separator (ISA-16). Default ":".
elementSeparator?
readonlyoptionalelementSeparator?:string
Element separator (ISA byte 4). Default "*".
groups
readonlygroups: readonlyFunctionalGroupSpec[]
The ordered GS..GE functional groups inside this interchange.
interchangeControlNumber
readonlyinterchangeControlNumber:string
ISA-13 / IEA-02 - interchange control number (zero-padded to 9 on emit).
interchangeDate
readonlyinterchangeDate:string
ISA-09 - interchange date YYMMDD.
interchangeTime
readonlyinterchangeTime:string
ISA-10 - interchange time HHMM.
receiverId
readonlyreceiverId:string
ISA-08 - interchange receiver id (padded to 15 on emit).
receiverQualifier?
readonlyoptionalreceiverQualifier?:string
ISA-07 - interchange receiver qualifier. Default "ZZ".
repetitionSeparator?
readonlyoptionalrepetitionSeparator?:string
Repetition separator (ISA-11). Default "^".
segmentTerminator?
readonlyoptionalsegmentTerminator?:string
Segment terminator (ISA byte 106). Default "~".
senderId
readonlysenderId:string
ISA-06 - interchange sender id (padded to 15 on emit).
senderQualifier?
readonlyoptionalsenderQualifier?:string
ISA-05 - interchange sender qualifier. Default "ZZ".
usageIndicator?
readonlyoptionalusageIndicator?:string
ISA-15 - usage indicator (P production, T test). Default "P".
version?
readonlyoptionalversion?:string
ISA-12 - interchange control version number. Default "00501".
IsaSegment
The decoded ISA interchange header. raw preserves the exact 106-byte
ISA + terminator string from input so round-trip serialization is
byte-exact regardless of any lenient normalization downstream. elements
is the 16 ISA values, 1-indexed (elements[0] is the literal "ISA"
name placeholder, elements[1] is ISA-01, ..., elements[16] is ISA-16).
Example
import type { IsaSegment } from "@cosyte/x12";
declare const isa: IsaSegment;
isa.elements[12]; // ISA-12 - version, expected "00501"
isa.elements[13]; // ISA-13 - interchange control number
Properties
elements
readonlyelements: readonlystring[]
raw
readonlyraw:string
LoopSegmentSpec
A segment slot inside a loop body. Carries the segment id, its TR3
usage + cardinality, and an optional position label (e.g. "Loop 2300 #2") used by Phase 3+ loop-walker diagnostics. Stored verbatim by
defineLoopSpec; no validation beyond the structural shape so consumers
can author payer-specific segment specs without re-deriving each rule.
Example
import type { LoopSegmentSpec } from "@cosyte/x12";
const clm: LoopSegmentSpec = { id: "CLM", usage: "required", max: 1 };
Properties
description?
readonlyoptionaldescription?:string
id
readonlyid:string
max
readonlymax:LoopMax
position?
readonlyoptionalposition?:string
usage
readonlyusage:LoopUsage
LoopSpec
A declarative loop description used by Phase 3+ transaction extractors
and consumer-authored payer profiles alike. Frozen by defineLoopSpec
so a LoopSpec is safe to share across calls.
Example
import { defineLoopSpec } from "@cosyte/x12";
const Loop2300 = defineLoopSpec({
id: "2300",
description: "837 Claim Information",
trigger: "CLM",
segments: [
{ id: "CLM", usage: "required", max: 1 },
{ id: "DTP", usage: "situational", max: ">1" },
{ id: "HI", usage: "situational", max: ">1" },
],
});
Properties
children
readonlychildren: readonlyLoopSpec[]
description?
readonlyoptionaldescription?:string
id
readonlyid:string
segments
readonlysegments: readonlyLoopSegmentSpec[]
trigger
readonlytrigger:string
SerializeOptions
Options accepted by serializeX12. Every field is optional;
serializeX12(ix) produces the byte-faithful reconstruction with no
reconciliation.
Remarks
With exactOptionalPropertyTypes: true, do not pass specClean: undefined
explicitly - omit the key instead.
Example
import { serializeX12, parseX12 } from "@cosyte/x12";
const ix = parseX12(raw);
// Spec-clean emit that fixes any stale envelope counts:
const out = serializeX12(ix, {
specClean: true,
recomputeCounts: true,
onWarning: (w) => console.warn(w.code, w.message),
});
Properties
onWarning?
readonlyoptionalonWarning?:OnWarningCallback
Invoked once per reconciliation warning (spec-clean mode only).
recomputeCounts?
readonlyoptionalrecomputeCounts?:boolean
Substitute the recomputed SE-01 / GE-01 / IEA-01 counts into the emitted
control segments (only meaningful with specClean: true). Default
false - the serializer warns on a count mismatch but emits the model's
verbatim value. Control NUMBERS are never rewritten regardless.
specClean?
readonlyoptionalspecClean?:boolean
Reconcile envelope counts + control-number pairs and surface any
mismatch via onWarning. Default false (pure byte-faithful
reconstruction, no reconciliation, no warnings).
Ta1Segment
A decoded envelope-level TA1 Interchange Acknowledgment segment. TA1 is NOT a transaction set - per the ASC X12 standard it lives at the envelope level, between ISA and the first GS, or alone inside an ISA..IEA with no GS at all (a TA1-only interchange). One interchange may carry multiple TA1 segments, each acknowledging a prior inbound interchange.
TA1-01 is the interchange control number of the acknowledged interchange
and the reassociation key. TA1-02 and TA1-03 are
its interchange date (YYMMDD) and time (HHMM). TA1-04 is the Interchange
Acknowledgment Code, code list I13 (A accepted, E accepted with
errors, R rejected), and TA1-05 the Interchange Note Code, code list
I18.
elements is 1-indexed (elements[0] = "TA1", elements[1] = TA1-01,
..., elements[5] = TA1-05). Element values are stored RAW,
pre-?-unescape, so an element is the framed byte text of its slot and
not necessarily the value the sender stated.
The Phase 3 envelope walker captures TA1 segments here verbatim; the
typed-ack model is built on top by parseTA1, whose five decoded fields
are POST-?-unescape. parseTA1 decodes the FIRST TA1 on an
interchange, so on a multi-TA1 inbound it does not necessarily describe
the segment you are holding. TA1 contains only structural control /
disposition codes - by spec it carries NO PHI.
Example
import type { Ta1Segment } from "@cosyte/x12";
declare const ta1: Ta1Segment;
ta1.raw; // verbatim segment text
ta1.elements[1]; // raw text of TA1-01 (post-element-split, pre-?-unescape)
Properties
elements
readonlyelements: readonlystring[]
raw
readonlyraw:string
TransactionSetSpec
A single ST..SE transaction set. The builder emits ST{idCode}{control},
then each body SegmentSpec, then SE{count}{control} with the
segment count (ST..SE inclusive) computed for you.
Example
const tx: TransactionSetSpec = {
transactionSetIdCode: "837",
transactionSetControlNumber: "0001",
implementationConventionReference: "005010X222A2",
segments: [["BHT", "0019", "00", "REF", "20250101", "1200", "CH"]],
};
Properties
implementationConventionReference?
readonlyoptionalimplementationConventionReference?:string
ST-03 - implementation convention reference (optional, e.g. "005010X222A2").
segments
readonlysegments: readonlySegmentSpec[]
Body segments between ST and SE (excludes ST and SE themselves).
transactionSetControlNumber
readonlytransactionSetControlNumber:string
ST-02 / SE-02 - transaction set control number (echoed on SE-02).
transactionSetIdCode
readonlytransactionSetIdCode:string
ST-01 - transaction set ID code (e.g. "837", "835", "271").
X12_837ServiceLineDental
837D service line (SV3). Dental lines carry the ADA-coded procedure
(qualifier AD, CDT code) plus optional tooth + surface detail
captured on the per-line TOO segments (Loop 2400 in X224A2).
Example
import type { X12_837ServiceLineDental } from "@cosyte/x12";
declare const sl: X12_837ServiceLineDental;
sl.procedureQualifier; // "AD"
sl.procedureCode; // "D2391" composite resin
sl.charge.toString(); // "180.00"
sl.toothInformation[0]?.toothCode; // "14"
sl.toothInformation[0]?.surfaces; // ["O"]
Extends
X12_837ServiceLineBase
Properties
adjudications
readonlyadjudications: readonlyX12LineAdjudication[]
Inherited from
X12_837ServiceLineBase.adjudications
amounts
readonlyamounts: readonlyX12ClaimAmount[]
Inherited from
X12_837ServiceLineBase.amounts
charge
readonlycharge:X12Decimal|undefined
The service line's charge - SV1-02 (professional), SV2-03
(institutional) or SV3-02 (dental). undefined where this library
decoded no value from that element: it was absent or empty, it held
bytes that do not decode as a decimal (which also emits
X12_UNPARSEABLE_DECIMAL), or no SVx for the resolved variant was
decoded onto the line at all (which emits
X12_837_SERVICE_LINE_NOT_DECODED at the LX). Through 0.0.12 all
three read X12Decimal.ZERO, and a consumer could not tell any of them
from a line the sender charged nothing for.
Inherited from
X12_837ServiceLineBase.charge
dates
readonlydates: readonlyX12ClaimDate[]
Inherited from
X12_837ServiceLineBase.dates
drug
readonlydrug:X12LineDrug|undefined
Inherited from
X12_837ServiceLineBase.drug
lineNumber
readonlylineNumber:string
Inherited from
X12_837ServiceLineBase.lineNumber
modifiers
readonlymodifiers: readonlystring[]
notes
readonlynotes: readonlyX12ClaimNote[]
Inherited from
X12_837ServiceLineBase.notes
oralCavityArea
readonlyoralCavityArea: readonlystring[]
placeOfServiceCode
readonlyplaceOfServiceCode:string|undefined
Inherited from
X12_837ServiceLineBase.placeOfServiceCode
procedureCode
readonlyprocedureCode:string
procedureQualifier
readonlyprocedureQualifier:string
prosthesisCrownInlayCode
readonlyprosthesisCrownInlayCode:string|undefined
providers
readonlyproviders: readonlyX12ClaimEntity[]
Inherited from
X12_837ServiceLineBase.providers
references
readonlyreferences: readonlyX12ClaimReference[]
Inherited from
X12_837ServiceLineBase.references
toothInformation
readonlytoothInformation: readonlyX12ToothInformation[]
unitOfMeasure
readonlyunitOfMeasure:string|undefined
Inherited from
X12_837ServiceLineBase.unitOfMeasure
units
readonlyunits:X12Decimal|undefined
The service line's unit count - SV1-04 (professional), SV2-05
(institutional) or SV3-06 (dental). undefined on the same three
conditions as X12_837ServiceLineBase.charge, and for the same
reason: a fabricated count is a count the sender never sent.
Inherited from
X12_837ServiceLineBase.units
variant
readonlyvariant:"D"
X12_837ServiceLineInstitutional
837I service line (SV2). Institutional lines lead with a revenueCode
(SV2-01, NUBC 4-digit revenue code - what kind of service this is);
the procedure code (HCPCS) and modifiers in SV2-02 are situational.
nonCoveredCharge (SV2-07) is the portion of the line the provider
has marked as not covered before the payer adjudicates.
Example
import type { X12_837ServiceLineInstitutional } from "@cosyte/x12";
declare const sl: X12_837ServiceLineInstitutional;
sl.revenueCode; // "0260" IV therapy
sl.procedureCode; // "J7030"
sl.charge.toString(); // "780.00"
sl.nonCoveredCharge?.toString();// "0.00"
Extends
X12_837ServiceLineBase
Properties
adjudications
readonlyadjudications: readonlyX12LineAdjudication[]
Inherited from
X12_837ServiceLineBase.adjudications
amounts
readonlyamounts: readonlyX12ClaimAmount[]
Inherited from
X12_837ServiceLineBase.amounts
charge
readonlycharge:X12Decimal|undefined
The service line's charge - SV1-02 (professional), SV2-03
(institutional) or SV3-02 (dental). undefined where this library
decoded no value from that element: it was absent or empty, it held
bytes that do not decode as a decimal (which also emits
X12_UNPARSEABLE_DECIMAL), or no SVx for the resolved variant was
decoded onto the line at all (which emits
X12_837_SERVICE_LINE_NOT_DECODED at the LX). Through 0.0.12 all
three read X12Decimal.ZERO, and a consumer could not tell any of them
from a line the sender charged nothing for.
Inherited from
X12_837ServiceLineBase.charge
dates
readonlydates: readonlyX12ClaimDate[]
Inherited from
X12_837ServiceLineBase.dates
drug
readonlydrug:X12LineDrug|undefined
Inherited from
X12_837ServiceLineBase.drug
lineNumber
readonlylineNumber:string
Inherited from
X12_837ServiceLineBase.lineNumber
modifiers
readonlymodifiers: readonlystring[]
nonCoveredCharge
readonlynonCoveredCharge:X12Decimal|undefined
notes
readonlynotes: readonlyX12ClaimNote[]
Inherited from
X12_837ServiceLineBase.notes
placeOfServiceCode
readonlyplaceOfServiceCode:string|undefined
Inherited from
X12_837ServiceLineBase.placeOfServiceCode
procedureCode
readonlyprocedureCode:string|undefined
procedureQualifier
readonlyprocedureQualifier:string|undefined
providers
readonlyproviders: readonlyX12ClaimEntity[]
Inherited from
X12_837ServiceLineBase.providers
references
readonlyreferences: readonlyX12ClaimReference[]
Inherited from
X12_837ServiceLineBase.references
revenueCode
readonlyrevenueCode:string
serviceLineRate
readonlyserviceLineRate:X12Decimal|undefined
unitOfMeasure
readonlyunitOfMeasure:string|undefined
Inherited from
X12_837ServiceLineBase.unitOfMeasure
units
readonlyunits:X12Decimal|undefined
The service line's unit count - SV1-04 (professional), SV2-05
(institutional) or SV3-06 (dental). undefined on the same three
conditions as X12_837ServiceLineBase.charge, and for the same
reason: a fabricated count is a count the sender never sent.
Inherited from
X12_837ServiceLineBase.units
variant
readonlyvariant:"I"
X12_837ServiceLineProfessional
837P service line (SV1). procedureQualifier is the HCPCS / CPT
qualifier (typically HC for HCPCS / CPT-4; ER jurisdiction-specific
procedure code; IV HIPPS-based rate code); procedureCode is the
verbatim code; modifiers are the 1-4 procedure modifiers from
SV1-01-3 through SV1-01-6 (e.g. 25, 59, LT, RT).
diagnosisPointers carry up to 4 pointers (SV1-07's composite of
positional indexes into the claim's HI diagnoses). The pointer "1"
refers to the first principal-diagnosis HI composite, "2" the second,
etc.; verbatim string preserved.
Example
import type { X12_837ServiceLineProfessional } from "@cosyte/x12";
declare const sl: X12_837ServiceLineProfessional;
sl.procedureQualifier; // "HC"
sl.procedureCode; // "99213"
sl.modifiers; // ["25"]
sl.diagnosisPointers; // ["1"]
sl.placeOfServiceCode; // "11" office (overrides claim-level)
sl.charge.toString(); // "150.00"
Extends
X12_837ServiceLineBase
Properties
adjudications
readonlyadjudications: readonlyX12LineAdjudication[]
Inherited from
X12_837ServiceLineBase.adjudications
amounts
readonlyamounts: readonlyX12ClaimAmount[]
Inherited from
X12_837ServiceLineBase.amounts
charge
readonlycharge:X12Decimal|undefined
The service line's charge - SV1-02 (professional), SV2-03
(institutional) or SV3-02 (dental). undefined where this library
decoded no value from that element: it was absent or empty, it held
bytes that do not decode as a decimal (which also emits
X12_UNPARSEABLE_DECIMAL), or no SVx for the resolved variant was
decoded onto the line at all (which emits
X12_837_SERVICE_LINE_NOT_DECODED at the LX). Through 0.0.12 all
three read X12Decimal.ZERO, and a consumer could not tell any of them
from a line the sender charged nothing for.
Inherited from
X12_837ServiceLineBase.charge
dates
readonlydates: readonlyX12ClaimDate[]
Inherited from
X12_837ServiceLineBase.dates
diagnosisPointers
readonlydiagnosisPointers: readonlystring[]
drug
readonlydrug:X12LineDrug|undefined
Inherited from
X12_837ServiceLineBase.drug
emergencyIndicator
readonlyemergencyIndicator:string|undefined
epsdtIndicator
readonlyepsdtIndicator:string|undefined
familyPlanningIndicator
readonlyfamilyPlanningIndicator:string|undefined
lineNumber
readonlylineNumber:string
Inherited from
X12_837ServiceLineBase.lineNumber
modifiers
readonlymodifiers: readonlystring[]
notes
readonlynotes: readonlyX12ClaimNote[]
Inherited from
X12_837ServiceLineBase.notes
placeOfServiceCode
readonlyplaceOfServiceCode:string|undefined
Inherited from
X12_837ServiceLineBase.placeOfServiceCode
procedureCode
readonlyprocedureCode:string
procedureQualifier
readonlyprocedureQualifier:string
providers
readonlyproviders: readonlyX12ClaimEntity[]
Inherited from
X12_837ServiceLineBase.providers
references
readonlyreferences: readonlyX12ClaimReference[]
Inherited from
X12_837ServiceLineBase.references
unitOfMeasure
readonlyunitOfMeasure:string|undefined
Inherited from
X12_837ServiceLineBase.unitOfMeasure
units
readonlyunits:X12Decimal|undefined
The service line's unit count - SV1-04 (professional), SV2-05
(institutional) or SV3-06 (dental). undefined on the same three
conditions as X12_837ServiceLineBase.charge, and for the same
reason: a fabricated count is a count the sender never sent.
Inherited from
X12_837ServiceLineBase.units
variant
readonlyvariant:"P"
X12_837Submission
The top-level result returned by get837Claims(). Carries the submitter
(Loop 1000A) and receiver (Loop 1000B) parties, the HL hierarchy walk
(Loops 2000A/B/C - every HL segment captured with parent-pointer
provenance), every claim payment loop (Loop 2300), and every warning
surfaced during the walk - including the safety-critical
X12_HL_PARENT_MISMATCH and X12_HL_PARENT_LEVEL_INVALID.
Example
import { parseX12, get837Claims } from "@cosyte/x12";
const ix = parseX12(raw);
const tx = ix.groups[0]?.transactions.find((t) => t.st.elements[1] === "837");
if (tx !== undefined) {
const sub = get837Claims(ix.delimiters, tx);
sub?.variant; // "P" | "I" | "D" | "unknown"
sub?.claims.length; // count of CLM segments encountered
for (const claim of sub?.claims ?? []) {
claim.totalCharge.toString();
claim.diagnoses[0]?.codeSystem; // "ICD-10-CM" etc.
}
}
Properties
claims
readonlyclaims: readonlyX12Claim[]
hierarchies
readonlyhierarchies: readonlyX12HierarchicalLevel[]
implementationConventionReference
readonlyimplementationConventionReference:string|undefined
receiver
readonlyreceiver:X12ClaimEntity|undefined
submitter
readonlysubmitter:X12ClaimEntity|undefined
variant
readonlyvariant:X12Claim837Variant
warnings
readonlywarnings: readonlyX12ParseWarning[]
X12Ack999
The decoded 999 Implementation Acknowledgment. Returned by
parse999(raw). Carries every loop the wire produced and the underlying
parsed envelope (so byte-exact round-trip is reachable through
interchange.isa.raw).
warnings collects both envelope-level warnings (from parseX12) AND
any 999-specific warnings (e.g. an unknown disposition code, an AK9
count mismatch). The set is additive - never throws on a real-world
999.
Properties
ak1
readonlyak1:X12Ack999Ak1
ak9
readonlyak9:X12Ack999Ak9
interchange
readonlyinterchange:X12Interchange
transactionResponses
readonlytransactionResponses: readonlyX12Ack999TransactionResponse[]
warnings
readonlywarnings: readonlyX12ParseWarning[]
X12Ack999Ak1
The decoded AK1 functional group response header (loop 1).
functionalIdCode- AK1-01: echoes the inbound GS-01 (e.g.HCfor a claim group).groupControlNumber- AK1-02: echoes the inbound GS-06.versionRelease- AK1-03: echoes the inbound GS-08 (e.g.005010X222A2). Situational at the standard level, ALWAYS present in X231A1; surfaced asstring | undefinedto remain lenient on parse.
Example
import type { X12Ack999Ak1 } from "@cosyte/x12";
declare const ak1: X12Ack999Ak1;
ak1.functionalIdCode; // "HC"
ak1.versionRelease; // "005010X222A2" | undefined
Properties
functionalIdCode
readonlyfunctionalIdCode:string
groupControlNumber
readonlygroupControlNumber:string
versionRelease
readonlyversionRelease:string|undefined
X12Ack999Ak2
The decoded AK2 transaction set response header (loop 2000).
transactionSetIdCode- AK2-01: echoes the inbound ST-01 (e.g.837,270).transactionSetControlNumber- AK2-02: echoes the inbound ST-02.implementationConventionReference- AK2-03: echoes the inbound ST-03 (the TR3 ID, e.g.005010X222A2); situational.
Example
import type { X12Ack999Ak2 } from "@cosyte/x12";
declare const ak2: X12Ack999Ak2;
ak2.transactionSetIdCode; // "837"
Properties
implementationConventionReference
readonlyimplementationConventionReference:string|undefined
transactionSetControlNumber
readonlytransactionSetControlNumber:string
transactionSetIdCode
readonlytransactionSetIdCode:string
X12Ack999Ak9
The decoded AK9 functional group response trailer.
disposition- AK9-01: functional-group-level disposition.numberOfTransactionSets- AK9-02: echoes the inbound GE-01.numberOfReceivedTransactionSets- AK9-03: how many ST..SE pairs actually arrived.numberOfAcceptedTransactionSets- AK9-04: how many were accepted. By construction0 <= accepted <= received <= numberOfTransactionSets.syntaxErrorCodes- AK9-05..AK9-09: situational; up to five functional-group syntax error codes (code list 716).
Properties
disposition
readonlydisposition:X12AckDispositionCode
numberOfAcceptedTransactionSets
readonlynumberOfAcceptedTransactionSets:number
numberOfReceivedTransactionSets
readonlynumberOfReceivedTransactionSets:number
numberOfTransactionSets
readonlynumberOfTransactionSets:number
syntaxErrorCodes
readonlysyntaxErrorCodes: readonlystring[]
X12Ack999ElementNote
One IK4 element-level error wrapped with its (optional) IK3-paired CTX
context strings - surfaced verbatim because CTX uses a composite syntax
the X231A1 implementer typically writes as ELEMENT*NM1*8*1. The
library does not try to over-decompose the CTX value at this phase.
Properties
contexts
readonlycontexts: readonlystring[]
ik4
readonlyik4:X12Ack999Ik4
X12Ack999Ik3
The decoded IK3 implementation data segment note (loop 2100).
segmentIdCode- IK3-01: the X12 segment identifier (e.g.NM1,CLP,HL).segmentPositionInTransactionSet- IK3-02: 1-indexed position of the offending segment inside the inbound ST..SE.loopIdentifier- IK3-03: situational; the loop identifier (e.g.2010BA) where the offending segment lives.syntaxErrorCode- IK3-04: situational; one of Ik304Code.undefinedwhen the parent IK3 is purely a context wrapper for nested IK4s (the per-element error path).
Example
import type { X12Ack999SegmentNote } from "@cosyte/x12";
declare const note: X12Ack999SegmentNote;
note.ik3.segmentIdCode; // "NM1"
note.ik3.segmentPositionInTransactionSet; // 8
Properties
loopIdentifier
readonlyloopIdentifier:string|undefined
segmentIdCode
readonlysegmentIdCode:string
segmentPositionInTransactionSet
readonlysegmentPositionInTransactionSet:number
syntaxErrorCode
readonlysyntaxErrorCode:Ik304Code|undefined
X12Ack999Ik4
The decoded IK4 implementation data element note (loop 2110).
position- IK4-01: composite carrying element / component / repetition (1-indexed).dataElementReferenceNumber- IK4-02: situational; the ASC X12 element reference number (e.g.66for NM1-08).syntaxErrorCode- IK4-03: required; one of Ik403Code.copyOfBadDataElement- IK4-04: situational; the verbatim offending element value. By spec it may be omitted entirely; callers building a 999 SHOULD omit it whenever the offending bytes are PHI (medical IDs, names, dates). The library never auto-populates this field.
Example
import type { X12Ack999ElementNote } from "@cosyte/x12";
declare const note: X12Ack999ElementNote;
note.ik4.syntaxErrorCode; // "7" (invalid code value)
Properties
copyOfBadDataElement
readonlycopyOfBadDataElement:string|undefined
dataElementReferenceNumber
readonlydataElementReferenceNumber:string|undefined
position
readonlyposition:X12Ack999Ik4Position
syntaxErrorCode
readonlysyntaxErrorCode:Ik403Code
X12Ack999Ik4Position
Position of an element/component/repetition inside a parent segment for
an IK4 element note. Element is 1-indexed (the TR3 convention);
component and repetition are surfaced exactly as encoded in IK4-01's
composite - see TR3 005010X231A1 §IK4.
Example
import type { X12Ack999Ik4Position } from "@cosyte/x12";
const pos: X12Ack999Ik4Position = { element: 1, component: 2 };
Properties
component
readonlycomponent:number|undefined
element
readonlyelement:number
repetition
readonlyrepetition:number|undefined
X12Ack999Ik5
The decoded IK5 implementation transaction set response trailer.
disposition- IK5-01: one of X12AckDispositionCode.syntaxErrorCodes- IK5-02..IK5-06: situational; up to five transaction-set syntax error codes (code list 718).
Properties
disposition
readonlydisposition:X12AckDispositionCode
syntaxErrorCodes
readonlysyntaxErrorCodes: readonlystring[]
X12Ack999SegmentNote
One IK3 segment-level error wrapped with its (optional) CTX context strings and any nested IK4 element-level errors. Lifting the IK3 / IK4 groups into nested arrays mirrors the X231A1 loop hierarchy exactly so the typed model maps 1:1 onto the wire shape.
Properties
contexts
readonlycontexts: readonlystring[]
elementNotes
readonlyelementNotes: readonlyX12Ack999ElementNote[]
ik3
readonlyik3:X12Ack999Ik3
X12Ack999TransactionResponse
One AK2..IK5 transaction-set response inside a 999.
Properties
ak2
readonlyak2:X12Ack999Ak2
ik5
readonlyik5:X12Ack999Ik5
segmentNotes
readonlysegmentNotes: readonlyX12Ack999SegmentNote[]
X12AckTA1
The decoded TA1 Interchange Acknowledgment.
interchangeControlNumber- TA1-01: echoes the inbound ISA-13.interchangeDate- TA1-02: YYMMDD (echoes inbound ISA-09).interchangeTime- TA1-03: HHMM (echoes inbound ISA-10).ackCode- TA1-04: Ta1AckCode.noteCode- TA1-05: typed when the value is a known I18 code (Ta1NoteCode);noteCodeRawcarries the un-narrowed string alongside so unknown extensions survive. A clause here said that string is preserved VERBATIM and is deleted, not reworded:X12-TA1-RESIDUALSmade it post-unescape, andraw.elements[5]is the verbatim surface.noteCodeRaw- the un-narrowed TA1-05 string. Equal tonoteCodewhen the value is a known I18 code; equal to the decoded inbound text when not.raw- the underlying envelope-level Ta1Segment, for byte-exact round-trip.
The five decoded fields are POST-?-unescape; raw is the verbatim
byte surface and is not. X12-TA1-RESIDUALS moved the decoded half:
before it, a released TA1-01 read back carrying its ? and matched no
ISA-13, while every dot-path read of the same element already unescaped.
Read raw.elements when you want the bytes.
Example
import type { X12AckTA1 } from "@cosyte/x12";
declare const ta1: X12AckTA1;
ta1.ackCode; // "A" | "E" | "R"
ta1.noteCode; // "000" | "001" | ...
Properties
ackCode
readonlyackCode:Ta1AckCode
interchangeControlNumber
readonlyinterchangeControlNumber:string
interchangeDate
readonlyinterchangeDate:string
interchangeTime
readonlyinterchangeTime:string
noteCode
readonlynoteCode:Ta1NoteCode|undefined
noteCodeRaw
readonlynoteCodeRaw:string
raw
readonlyraw:Ta1Segment
X12AuthDate
A DTP date / date-range attached to a review item. qualifier is DTP-01
(e.g. 435 admission, 472 service); value is DTP-03 in the DTP-02
format (D8 CCYYMMDD / RD8 range).
Example
import type { X12AuthDate } from "@cosyte/x12";
declare const d: X12AuthDate;
d.qualifier; // "472"
d.formatQualifier; // "D8"
d.value; // "20260601"
Properties
formatQualifier
readonlyformatQualifier:string
qualifier
readonlyqualifier:string
value
readonlyvalue:string
X12AuthDiagnosis
One diagnosis from an HI segment (Loop 2000E). qualifier (HI-0x-01) is
the X12 code-source qualifier (e.g. ABK ICD-10-CM principal); code
(HI-0x-02) is the diagnosis code. codeSystem resolves the qualifier
against the bundled HI_QUALIFIERS snapshot - "unknown" (with an
X12_UNKNOWN_HI_QUALIFIER warning) when the qualifier is outside it. The
verbatim qualifier + code are always preserved.
Example
import type { X12AuthDiagnosis } from "@cosyte/x12";
declare const dx: X12AuthDiagnosis;
dx.qualifier; // "ABK"
dx.code; // "E1165"
dx.codeSystem; // "ICD-10-CM"
Properties
code
readonlycode:string
codeSystem
readonlycodeSystem:X12HiCodeSystem
qualifier
readonlyqualifier:string
X12AuthEntity
A non-person entity (UMO in Loop 2010A, requester in Loop 2010B, or a provider attached to a review). Decoded from an NM1 - name + identifier, no demographics.
Example
import type { X12AuthEntity } from "@cosyte/x12";
declare const e: X12AuthEntity;
e.entityIdentifierCode; // "X3" (UMO) / "1P" (provider)
e.name; // "UTILIZATION REVIEW CO"
Properties
entityIdentifierCode
readonlyentityIdentifierCode:string
entityTypeQualifier
readonlyentityTypeQualifier:string
idCode
readonlyidCode:string|undefined
idQualifier
readonlyidQualifier:string|undefined
name
readonlyname:string
X12AuthHeader
The BHT beginning-of-hierarchical-transaction header. purposeCode
(BHT-02) is 00 (original) / 18 (reissue); transactionTypeCode
(BHT-06) distinguishes a request (RT / cancel) from administrative
variants.
Example
import type { X12AuthHeader } from "@cosyte/x12";
declare const h: X12AuthHeader;
h.referenceId; // "AUTH-202606"
h.date; // "20260601" (BHT-04, CCYYMMDD)
Properties
date
readonlydate:string|undefined
purposeCode
readonlypurposeCode:string|undefined
referenceId
readonlyreferenceId:string|undefined
structurePurposeCode
readonlystructurePurposeCode:string
time
readonlytime:string|undefined
transactionTypeCode
readonlytransactionTypeCode:string|undefined
X12AuthMember
A person (subscriber Loop 2010C / dependent Loop 2010D) decoded from NM1 +
the optional DMG demographics. idCode (NM1-09) is the member identifier
- synthetic-only in fixtures.
Example
import type { X12AuthMember } from "@cosyte/x12";
declare const m: X12AuthMember;
m.lastName; // "DOE"
m.dateOfBirth; // "19850515" (DMG-02, CCYYMMDD)
Properties
dateOfBirth
readonlydateOfBirth:string|undefined
entityIdentifierCode
readonlyentityIdentifierCode:string
entityTypeQualifier
readonlyentityTypeQualifier:string
firstName
readonlyfirstName:string|undefined
genderCode
readonlygenderCode:string|undefined
idCode
readonlyidCode:string|undefined
idQualifier
readonlyidQualifier:string|undefined
lastName
readonlylastName:string|undefined
middleName
readonlymiddleName:string|undefined
suffix
readonlysuffix:string|undefined
X12AuthReference
A REF supplemental identifier attached to a review item. qualifier is
REF-01; value is REF-02.
Example
import type { X12AuthReference } from "@cosyte/x12";
declare const r: X12AuthReference;
r.qualifier; // "BB" (authorization number)
r.value; // "PRIORAUTH-1"
Properties
description
readonlydescription:string|undefined
qualifier
readonlyqualifier:string
value
readonlyvalue:string
X12AuthTrace
A reassociation trace (TRN). A 278 request carries a trace the response echoes verbatim so the requester can re-associate the certification outcome with the request it sent - the walker NEVER mutates it.
Example
import type { X12AuthTrace } from "@cosyte/x12";
declare const t: X12AuthTrace;
t.traceTypeCode; // "1" (current transaction)
t.referenceId; // "AUTHREQ-202606-0001"
Properties
originatingCompanyId
readonlyoriginatingCompanyId:string|undefined
referenceId
readonlyreferenceId:string
supplementalReferenceId
readonlysupplementalReferenceId:string|undefined
traceTypeCode
readonlytraceTypeCode:string
X12Claim
Decoded CLM claim header + every claim-scoped loop. The variant
mirrors the parent submission's variant; the serviceLines discriminate
on the same variant so a consumer can do a single switch.
PHI surface: claimId (provider's patient-account number), the
subscriber/patient NM1 entities, member ID on subscriber/patient, NTE
notes. All surfaced verbatim; warnings never echo values.
Example
import type { X12Claim } from "@cosyte/x12";
declare const c: X12Claim;
c.variant; // "P" / "I" / "D" / "unknown"
c.claimId; // CLM-01 (patient account number)
c.totalCharge?.toString(); // CLM-02 as X12Decimal, or undefined if none decoded
c.diagnoses[0]?.codeSystem; // "ICD-10-CM"
c.serviceLines.length; // count of LX/SVx loops
Properties
amounts
readonlyamounts: readonlyX12ClaimAmount[]
benefitsAssignment
readonlybenefitsAssignment:string|undefined
billingProvider
readonlybillingProvider:X12ClaimEntity|undefined
claimFrequencyCode
readonlyclaimFrequencyCode:string|undefined
claimId
readonlyclaimId:string
dates
readonlydates: readonlyX12ClaimDate[]
diagnoses
readonlydiagnoses: readonlyX12ClaimHiCode[]
facilityCodeQualifier
readonlyfacilityCodeQualifier:string|undefined
hierarchy
readonlyhierarchy:X12HierarchicalLevel|undefined
notes
readonlynotes: readonlyX12ClaimNote[]
otherHi
readonlyotherHi: readonlyX12ClaimHiCode[]
otherSubscribers
readonlyotherSubscribers: readonlyX12OtherSubscriber[]
patient
readonlypatient:X12ClaimMember|undefined
payer
readonlypayer:X12ClaimEntity|undefined
payToAddress
readonlypayToAddress:X12ClaimAddress|undefined
payToPlan
readonlypayToPlan:X12ClaimEntity|undefined
placeOfServiceCode
readonlyplaceOfServiceCode:string|undefined
procedures
readonlyprocedures: readonlyX12ClaimHiCode[]
providerAcceptAssignment
readonlyproviderAcceptAssignment:string|undefined
providers
readonlyproviders: readonlyX12ClaimEntity[]
providerSignatureOnFile
readonlyproviderSignatureOnFile:string|undefined
references
readonlyreferences: readonlyX12ClaimReference[]
releaseOfInformationCode
readonlyreleaseOfInformationCode:string|undefined
serviceLines
readonlyserviceLines: readonlyX12_837ServiceLine[]
subscriber
readonlysubscriber:X12ClaimMember|undefined
totalCharge
readonlytotalCharge:X12Decimal|undefined
CLM-02, the total claim charge. undefined where this library decoded
no value from that element - it was absent or empty, or it held bytes
that do not decode as a decimal (which also emits
X12_UNPARSEABLE_DECIMAL at its elementIndex). Through 0.0.12 both
cases read X12Decimal.ZERO, indistinguishable from a claim whose
charge really is zero.
variant
readonlyvariant:X12Claim837Variant
X12ClaimAddress
Decoded N3 + N4 address block attached to an entity. Same shape as the 835's address (intentional - symmetry across helpers). All fields verbatim, no normalization.
Example
import type { X12ClaimAddress } from "@cosyte/x12";
declare const a: X12ClaimAddress;
a.lines[0]; // "123 PROVIDER WAY"
a.city; // "CLEVELAND"
a.state; // "OH"
a.postalCode; // "44113"
Properties
city
readonlycity:string|undefined
countryCode
readonlycountryCode:string|undefined
lines
readonlylines: readonlystring[]
postalCode
readonlypostalCode:string|undefined
state
readonlystate:string|undefined
X12ClaimAmount
Decoded AMT segment - supplemental claim amount (patient-paid amount,
coverage amount, etc.). qualifier from X12 522. Surfaced verbatim;
never folded into a computed total (the 837 has no on-spec balance
invariant analogous to the 835's CLP balance).
Example
import type { X12ClaimAmount } from "@cosyte/x12";
declare const a: X12ClaimAmount;
a.qualifier; // "F5" patient amount paid
a.amount.toString(); // "25.00"
Properties
amount
readonlyamount:X12Decimal
qualifier
readonlyqualifier:string
X12ClaimContact
Decoded PER contact segment. contactFunctionCode = IC (Information
Contact), BL (Technical), AP (Accounts Payable Contact); each
carries up to 3 communication channels (TE telephone, EM email,
FX fax, EX extension).
Example
import type { X12ClaimContact } from "@cosyte/x12";
declare const c: X12ClaimContact;
c.contactFunctionCode; // "IC"
c.communications[0]?.qualifier; // "TE"
c.communications[0]?.value; // "5551234567"
Properties
communications
readonlycommunications: readonlyobject[]
contactFunctionCode
readonlycontactFunctionCode:string
name
readonlyname:string|undefined
X12ClaimDate
Decoded DTP date - claim-level or service-line-level. formatQualifier
is DTP-02 (D8 single-date CCYYMMDD; RD8 date range
CCYYMMDD-CCYYMMDD). value is DTP-03 verbatim - the parser never
normalizes the literal.
Date-qualifier vocabulary on 837 (X12 374): 472 Service Date, 434
Statement Date, 435 Admission Date (837I), 096 Discharge Date
(837I), 431 Onset of Current Illness, 454 Initial Treatment Date,
297 Last Worked Date, etc.
Example
import type { X12ClaimDate } from "@cosyte/x12";
declare const d: X12ClaimDate;
d.qualifier; // "472"
d.formatQualifier; // "D8"
d.value; // "20260601"
Properties
formatQualifier
readonlyformatQualifier:string
qualifier
readonlyqualifier:string
value
readonlyvalue:string
X12ClaimEntity
Generic NM1 entity used throughout the 837. Covers billing provider
(85), pay-to address (87), submitter (41), receiver (40),
subscriber name (IL), patient name (QC), payer (PR), and the long
tail of 2310 / 2330 / 2420 provider / payer / facility roles. The
entityIdentifierCode discriminates the role; consumers branching on
roles should compare against the X12 0098 code list.
PHI surface: lastName/firstName/idCode carry PHI when the role is
a person (subscriber, patient, rendering provider as an individual).
Surfaced verbatim - the parser never echoes them in warnings.
Example
import type { X12ClaimEntity } from "@cosyte/x12";
declare const e: X12ClaimEntity;
e.entityIdentifierCode; // "85" billing provider
e.name; // verbatim NM1-03
e.idQualifier; // "XX" (NPI)
e.idCode; // verbatim NPI
Properties
address
readonlyaddress:X12ClaimAddress|undefined
contacts
readonlycontacts: readonlyX12ClaimContact[]
entityIdentifierCode
readonlyentityIdentifierCode:string
entityTypeQualifier
readonlyentityTypeQualifier:string
firstName
readonlyfirstName:string|undefined
idCode
readonlyidCode:string|undefined
idQualifier
readonlyidQualifier:string|undefined
middleName
readonlymiddleName:string|undefined
name
readonlyname:string
references
readonlyreferences: readonlyX12ClaimReference[]
suffix
readonlysuffix:string|undefined
X12ClaimHiCode
Decoded HI diagnosis or procedure composite. ONE entry per HI composite
(HI-01..HI-12); the parser surfaces the verbatim qualifier AND the
resolved X12HiCodeSystem so consumers can branch by system
without re-deriving the mapping. The category discriminates the role
(diagnosis / procedure / NUBC code-set entry).
poaIndicator (Present-on-Admission) is HI-NN-9 - 837I institutional
inpatient only. CMS-mandated values: Y Yes, N No, U Insufficient
documentation, W Clinically undetermined, 1 Exempt from POA
reporting. Verbatim - the parser preserves the value, never validates
against the spec list (Phase 9 profile may layer enforcement).
Example
import type { X12ClaimHiCode } from "@cosyte/x12";
declare const dx: X12ClaimHiCode;
dx.qualifier; // "ABK" - principal diagnosis ICD-10-CM
dx.codeSystem; // "ICD-10-CM"
dx.category; // "principal-diagnosis"
dx.code; // "J45.50"
dx.poaIndicator; // "Y" (837I only)
Properties
category
readonlycategory:X12HiCategory
code
readonlycode:string
codeSystem
readonlycodeSystem:X12HiCodeSystem
date
readonlydate:string|undefined
dateQualifier
readonlydateQualifier:string|undefined
monetaryAmount
readonlymonetaryAmount:X12Decimal|undefined
poaIndicator
readonlypoaIndicator:string|undefined
qualifier
readonlyqualifier:string
quantity
readonlyquantity:X12Decimal|undefined
versionId
readonlyversionId:string|undefined
X12ClaimMember
A claim's subscriber or patient - the NM1 entity plus the SBR/PAT metadata that wraps it.
Example
import type { X12ClaimMember } from "@cosyte/x12";
declare const m: X12ClaimMember;
m.entity.name; // verbatim subscriber name (PHI)
m.info.claimFilingIndicator; // "MB"
Properties
entity
readonlyentity:X12ClaimEntity
info
readonlyinfo:X12SubscriberInfo
X12ClaimNote
Decoded NTE note - free-text annotation. noteReferenceCode (NTE-01)
classifies the note ('ADD' Additional Information, 'CER' Certification,
'DCP' Goals/Rehabilitation/Discharge Plans, 'DGN' Diagnosis, 'DME' DME,
'MED' Medications, etc., X12 code list 363).
NOTE: NTE-02 is free text supplied by the provider - it may include incidental PHI (a patient name in a clinical note). Surfaced verbatim for fidelity; the parser flags this surface in JSDoc but never redacts. Consumers should treat NTE-02 as PHI-bearing.
Example
import type { X12ClaimNote } from "@cosyte/x12";
declare const n: X12ClaimNote;
n.noteReferenceCode; // "ADD"
n.description; // verbatim - may include incidental PHI
Properties
description
readonlydescription:string
noteReferenceCode
readonlynoteReferenceCode:string
X12ClaimReference
Decoded REF segment - additional identifier on an entity or claim.
Verbatim across the table; the qualifier vocabulary depends on the
context (EI Employer ID at the billing provider, D9 Claim Number on
an other-payer reference, G1 Prior Authorization, etc.).
Example
import type { X12ClaimReference } from "@cosyte/x12";
declare const r: X12ClaimReference;
r.qualifier; // "EI"
r.value; // "123456789"
Properties
description
readonlydescription:string|undefined
qualifier
readonlyqualifier:string
value
readonlyvalue:string
X12ClaimStatus
One claim status-tracking loop (Loop 2200). A claim opens on a TRN (claim-level reassociation trace) or - in a 277CA provider-level batch acknowledgment - on a standalone STC. Carries the resolved HL context, the echoed traces, the decoded STC statuses, supplemental REF / DTP, and any service-line statuses (Loop 2220).
Example
import type { X12ClaimStatus } from "@cosyte/x12";
declare const c: X12ClaimStatus;
c.serviceProvider?.name; // "ANYTOWN CLINIC"
c.subscriber?.lastName; // "DOE"
c.statuses[0]?.totalChargeAmount?.toString(); // "150.00"
Properties
dates
readonlydates: readonlyX12StatusDate[]
dependent
readonlydependent:X12StatusMember|undefined
informationReceiver
readonlyinformationReceiver:X12StatusEntity|undefined
informationSource
readonlyinformationSource:X12StatusEntity|undefined
references
readonlyreferences: readonlyX12StatusReference[]
serviceLines
readonlyserviceLines: readonlyX12ServiceLineStatus[]
serviceProvider
readonlyserviceProvider:X12StatusEntity|undefined
statuses
readonlystatuses: readonlyX12StatusInfo[]
subscriber
readonlysubscriber:X12StatusMember|undefined
traces
readonlytraces: readonlyX12StatusTrace[]
X12ClaimStatusResponse
Top-level result of the 277 / 277CA walker. Claims are flattened: each
X12ClaimStatus carries its enclosing information source (payer),
information receiver, service provider, and subscriber / dependent
context resolved from the HL tree, mirroring how get835 flattens claim
payment loops.
Example
import { parseX12, get277Status } from "@cosyte/x12";
const ix = parseX12(raw);
const tx = ix.groups[0]?.transactions.find((t) => t.st.elements[1] === "277");
if (tx !== undefined) {
const status = get277Status(ix.delimiters, tx);
for (const claim of status?.claims ?? []) {
claim.traces[0]?.referenceId; // echoed 276 trace
claim.statuses[0]?.statuses[0]?.categoryCode; // "A2" (acknowledgment)
}
}
Properties
claims
readonlyclaims: readonlyX12ClaimStatus[]
hierarchies
readonlyhierarchies: readonlyX12Hl[]
implementationConventionReference
readonlyimplementationConventionReference:string|undefined
transactionType
readonlytransactionType:"claim-status"|"claim-acknowledgment"
warnings
readonlywarnings: readonlyX12ParseWarning[]
X12CoordinationOfBenefits
Decoded Loop 2320 coordination of benefits (COB). payerResponsibility
is COB-01 (P primary, S secondary, T tertiary); referenceId is
COB-02 (the other payer's group/policy number); serviceTypeCode is
COB-03.
Example
import type { X12CoordinationOfBenefits } from "@cosyte/x12";
declare const c: X12CoordinationOfBenefits;
c.payerResponsibility; // "P"
c.referenceId; // "OTHERGRP-1"
Properties
coordinationOfBenefitsCode
readonlycoordinationOfBenefitsCode:string|undefined
payerResponsibility
readonlypayerResponsibility:string|undefined
referenceId
readonlyreferenceId:string|undefined
X12DecimalRead
The tri-state result of readElementDecimal: the decoded value (when there is one) alongside the reason there is not.
Example
import { readElementDecimal } from "@cosyte/x12";
const read = readElementDecimal(seg, 2, delim);
if (read.status === "unparseable") {
// the element was PRESENT and did not decode - do not read it as absent
}
Properties
status
readonlystatus:X12DecimalStatus
Which of the three spec-distinct outcomes this read hit.
value
readonlyvalue:X12Decimal|undefined
The decoded decimal, or undefined for both non-"decoded" states.
X12DecimalWarningSink
Where elementDecimal / elementDecimalOrZero put an
X12_UNPARSEABLE_DECIMAL warning, and the segment-level position it is
anchored to. The helpers add the failing elementIndex themselves, so a
caller passes the position of the SEGMENT it is decoding and never has to
remember to narrow it per element.
Example
import { elementDecimalOrZero, type X12DecimalWarningSink } from "@cosyte/x12";
const sink: X12DecimalWarningSink = { warnings, position: { segmentIndex: 3 } };
elementDecimalOrZero(seg, 2, delim, sink);
Properties
position
readonlyposition:X12Position
Position of the segment being decoded; elementIndex is supplied by the helper.
warnings
readonlywarnings:X12ParseWarning[]
The walker's warning accumulator. Appended to, never read.
X12Eligibility
Top-level result of "./get-271.js".get271Eligibility. Carries every subscriber loop (each with its enclosing information-source payer and information-receiver provider, its echoed TRN traces, name, and eligibility/benefit lines), the verbatim HL hierarchy, and every warning surfaced during the walk.
Example
import { parseX12, get271Eligibility } from "@cosyte/x12";
const ix = parseX12(raw);
const tx = ix.groups[0]?.transactions.find((t) => t.st.elements[1] === "271");
if (tx !== undefined) {
const elig = get271Eligibility(ix.delimiters, tx);
for (const sub of elig.subscribers) {
sub.traces[0]?.referenceId; // echoed 270 trace number
sub.benefits[0]?.eligibilityCode; // "1" (Active Coverage)
}
}
Properties
hierarchies
readonlyhierarchies: readonlyX12Hl[]
subscribers
readonlysubscribers: readonlyX12EligibilitySubscriber[]
warnings
readonlywarnings: readonlyX12ParseWarning[]
X12EligibilityAddress
A postal address (N3 + N4) attached to a subscriber / dependent name.
Example
import type { X12EligibilityAddress } from "@cosyte/x12";
declare const a: X12EligibilityAddress;
a.lines[0]; // "123 MAIN ST"
a.city; // "ANYTOWN"
a.state; // "CA"
a.postalCode; // "90001"
Properties
city
readonlycity:string|undefined
countryCode
readonlycountryCode:string|undefined
lines
readonlylines: readonlystring[]
postalCode
readonlypostalCode:string|undefined
state
readonlystate:string|undefined
X12EligibilityBenefit
One eligibility-or-benefit line (EB, Loop 2110C/2110D). EB-01 is the
eligibility code (1 Active Coverage, 6 Inactive, I Non-Covered,
…); EB-03 carries one-or-more Service Type Codes (each looked up against
the bundled snapshot). Monetary + percent + quantity are
X12Decimal. The walker preserves the verbatim EB-01 even when no
description resolves.
Example
import type { X12EligibilityBenefit } from "@cosyte/x12";
declare const b: X12EligibilityBenefit;
b.eligibilityCode; // "1"
b.serviceTypeCodes[0]?.code; // "30"
b.inPlanNetwork; // "Y"
b.monetaryAmount?.toString(); // "1000.00"
Properties
authorizationRequired
readonlyauthorizationRequired:string|undefined
coverageLevelCode
readonlycoverageLevelCode:string|undefined
dates
readonlydates: readonlyX12EligibilityDate[]
eligibilityCode
readonlyeligibilityCode:string
inPlanNetwork
readonlyinPlanNetwork:string|undefined
insuranceTypeCode
readonlyinsuranceTypeCode:string|undefined
messages
readonlymessages: readonlystring[]
monetaryAmount
readonlymonetaryAmount:X12Decimal|undefined
percent
readonlypercent:X12Decimal|undefined
planCoverageDescription
readonlyplanCoverageDescription:string|undefined
quantity
readonlyquantity:X12Decimal|undefined
quantityQualifier
readonlyquantityQualifier:string|undefined
references
readonlyreferences: readonlyX12EligibilityReference[]
relatedEntities
readonlyrelatedEntities: readonlyX12EligibilityEntity[]
serviceTypeCodes
readonlyserviceTypeCodes: readonlyX12EligibilityServiceType[]
timePeriodQualifier
readonlytimePeriodQualifier:string|undefined
X12EligibilityDate
A DTP date / date-range attached to a subscriber, dependent, or benefit
line. qualifier is DTP-01 (e.g. 307 Eligibility, 291 Plan); value
is DTP-03 in the DTP-02 format (D8 CCYYMMDD / RD8 range).
Example
import type { X12EligibilityDate } from "@cosyte/x12";
declare const d: X12EligibilityDate;
d.qualifier; // "307"
d.formatQualifier; // "D8"
d.value; // "20260101"
Properties
formatQualifier
readonlyformatQualifier:string
qualifier
readonlyqualifier:string
value
readonlyvalue:string
X12EligibilityDependent
One dependent (Loop 2000D / 2100D) - a patient who is not the subscriber (relationship is carried at the HL level). Same benefit-bearing shape as a subscriber minus the nested dependents.
Example
import type { X12EligibilityDependent } from "@cosyte/x12";
declare const d: X12EligibilityDependent;
d.name?.firstName; // "JUNIOR"
d.benefits[0]?.coverageLevelCode; // "IND"
Properties
benefits
readonlybenefits: readonlyX12EligibilityBenefit[]
dates
readonlydates: readonlyX12EligibilityDate[]
hierarchy
readonlyhierarchy:X12Hl|undefined
name
readonlyname:X12EligibilityMember|undefined
references
readonlyreferences: readonlyX12EligibilityReference[]
traces
readonlytraces: readonlyX12EligibilityTrace[]
X12EligibilityEntity
A non-person entity (payer in Loop 2100A, provider in Loop 2100B, or a benefit-related entity in Loop 2120C). Decoded from an NM1 - no demographics, just the organization / provider name + identifier.
Example
import type { X12EligibilityEntity } from "@cosyte/x12";
declare const e: X12EligibilityEntity;
e.entityIdentifierCode; // "PR" (payer) / "1P" (provider)
e.name; // "MEDPAY INSURANCE"
e.idCode; // "00123"
Properties
entityIdentifierCode
readonlyentityIdentifierCode:string
entityTypeQualifier
readonlyentityTypeQualifier:string
idCode
readonlyidCode:string|undefined
idQualifier
readonlyidQualifier:string|undefined
name
readonlyname:string
X12EligibilityMember
A person (subscriber / dependent) decoded from NM1 + the optional DMG
demographics + N3/N4 address. idCode is the member identifier (NM1-09)
- synthetic-only in fixtures.
Example
import type { X12EligibilityMember } from "@cosyte/x12";
declare const m: X12EligibilityMember;
m.lastName; // "DOE"
m.dateOfBirth; // "19800101" (DMG-02, CCYYMMDD)
m.genderCode; // "F"
Properties
address
readonlyaddress:X12EligibilityAddress|undefined
dateOfBirth
readonlydateOfBirth:string|undefined
entityIdentifierCode
readonlyentityIdentifierCode:string
entityTypeQualifier
readonlyentityTypeQualifier:string
firstName
readonlyfirstName:string|undefined
genderCode
readonlygenderCode:string|undefined
idCode
readonlyidCode:string|undefined
idQualifier
readonlyidQualifier:string|undefined
lastName
readonlylastName:string|undefined
middleName
readonlymiddleName:string|undefined
suffix
readonlysuffix:string|undefined
X12EligibilityReference
A REF supplemental identifier attached to a subscriber, dependent, or
benefit line. qualifier is REF-01; value is REF-02.
Example
import type { X12EligibilityReference } from "@cosyte/x12";
declare const r: X12EligibilityReference;
r.qualifier; // "6P" (group number)
r.value; // "GRP0001"
Properties
description
readonlydescription:string|undefined
qualifier
readonlyqualifier:string
value
readonlyvalue:string
X12EligibilityServiceType
A decoded Service Type Code (EB-03, X12 external code source 1365). The
verbatim code is always preserved; description resolves from the
bundled snapshot (or undefined when outside the subset).
Example
import type { X12EligibilityServiceType } from "@cosyte/x12";
declare const st: X12EligibilityServiceType;
st.code; // "30"
st.description; // "Health Benefit Plan Coverage"
Properties
code
readonlycode:string
description
readonlydescription:string|undefined
X12EligibilitySubscriber
One subscriber (Loop 2000C / 2100C). Holds the enclosing information source (Loop 2100A payer) and information receiver (Loop 2100B provider) resolved from the HL tree, the verbatim echoed TRN traces, the subscriber name + demographics, and the eligibility/benefit lines. Non-subscriber patients hang off dependents.
Example
import type { X12EligibilitySubscriber } from "@cosyte/x12";
declare const s: X12EligibilitySubscriber;
s.informationSource?.name; // "MEDPAY INSURANCE"
s.name?.lastName; // "DOE"
s.dependents.length; // 0
Properties
benefits
readonlybenefits: readonlyX12EligibilityBenefit[]
dates
readonlydates: readonlyX12EligibilityDate[]
dependents
readonlydependents: readonlyX12EligibilityDependent[]
hierarchy
readonlyhierarchy:X12Hl|undefined
informationReceiver
readonlyinformationReceiver:X12EligibilityEntity|undefined
informationSource
readonlyinformationSource:X12EligibilityEntity|undefined
name
readonlyname:X12EligibilityMember|undefined
references
readonlyreferences: readonlyX12EligibilityReference[]
traces
readonlytraces: readonlyX12EligibilityTrace[]
X12EligibilityTrace
A reassociation trace (TRN). The verbatim echo of the requesting 270's
trace number - referenceId (TRN-02) is the value a provider matches
against the trace it sent. The walker NEVER mutates it.
Example
import type { X12EligibilityTrace } from "@cosyte/x12";
declare const t: X12EligibilityTrace;
t.traceTypeCode; // "2" (referenced - added by the payer in the 271)
t.referenceId; // "ELIG20260627001" (echoed verbatim from the 270)
Properties
originatingCompanyId
readonlyoriginatingCompanyId:string|undefined
referenceId
readonlyreferenceId:string
supplementalReferenceId
readonlysupplementalReferenceId:string|undefined
traceTypeCode
readonlytraceTypeCode:string
X12Enrollment
One decoded Loop 2000 member-level detail (INS) - a single member's
enrollment action. Carries the member identity (Loop 2100A NM1 + DMG +
address), the supplemental ids (REF - subscriber id, group/policy), the
dates (DTP - eligibility begin/end), the health-coverage loops (Loop
2300 HD), and the coordination-of-benefits loops (Loop 2320 COB). Any
recoverable deviation (e.g. an unknown maintenance type) is surfaced on
warnings for THIS member only.
Example
import type { X12Enrollment } from "@cosyte/x12";
declare const e: X12Enrollment;
e.maintenanceTypeCode; // "021" addition
e.maintenanceTypeDescription; // "Addition"
e.member?.lastName; // verbatim member surname
e.healthCoverages[0]?.insuranceLineCode; // "HLT"
Properties
benefitStatusCode
readonlybenefitStatusCode:string|undefined
coordinationOfBenefits
readonlycoordinationOfBenefits: readonlyX12CoordinationOfBenefits[]
dates
readonlydates: readonlyX12EnrollmentDate[]
employmentStatusCode
readonlyemploymentStatusCode:string|undefined
healthCoverages
readonlyhealthCoverages: readonlyX12HealthCoverage[]
maintenanceReasonCode
readonlymaintenanceReasonCode:string|undefined
maintenanceTypeCode
readonlymaintenanceTypeCode:string
maintenanceTypeDescription
readonlymaintenanceTypeDescription:string|undefined
member
readonlymember:X12EnrollmentMember|undefined
references
readonlyreferences: readonlyX12EnrollmentReference[]
relationshipCode
readonlyrelationshipCode:string|undefined
subscriberIndicator
readonlysubscriberIndicator:string|undefined
warnings
readonlywarnings: readonlyX12ParseWarning[]
X12EnrollmentAddress
Decoded N3 + N4 address block attached to a member. lines is the N3
address lines (1-2 entries); city / state / postalCode come from
N4. All verbatim - no normalization.
Example
import type { X12EnrollmentAddress } from "@cosyte/x12";
declare const a: X12EnrollmentAddress;
a.lines[0]; // "100 MAIN ST"
a.city; // "COLUMBUS"
Properties
city
readonlycity:string|undefined
countryCode
readonlycountryCode:string|undefined
lines
readonlylines: readonlystring[]
postalCode
readonlypostalCode:string|undefined
state
readonlystate:string|undefined
X12EnrollmentAmount
Decoded AMT amount attached to a health-coverage loop. qualifier is the
amount qualifier (AMT-01 - "P3" premium, "B9" co-insurance, …);
amount is "../../decimal.js".X12Decimal (NEVER number).
Example
import type { X12EnrollmentAmount } from "@cosyte/x12";
declare const a: X12EnrollmentAmount;
a.qualifier; // "P3"
a.amount.toString(); // "125.00"
Properties
amount
readonlyamount:X12Decimal
qualifier
readonlyqualifier:string
X12EnrollmentDate
Decoded DTP date attached to a member or a health-coverage loop.
qualifier is the date/time qualifier (DTP-01); value is the verbatim
CCYYMMDD or range (DTP-03). No normalization.
Example
import type { X12EnrollmentDate } from "@cosyte/x12";
declare const d: X12EnrollmentDate;
d.qualifier; // "356" eligibility begin
d.value; // "20260101"
Properties
qualifier
readonlyqualifier:string
value
readonlyvalue:string
X12EnrollmentHeader
Decoded 834 header - the BGN Beginning Segment plus the sponsor
(N1*P5) and payer (N1*IN) parties. Returned by
"./get-834.js".get834Header; the per-member stream is separate
so a consumer can read the file-level context without draining the
(potentially huge) member roster.
Example
import type { X12EnrollmentHeader } from "@cosyte/x12";
declare const h: X12EnrollmentHeader;
h.transactionSetPurposeCode; // "00" original
h.sponsor?.name; // "EMPLOYER CO"
h.payer?.name; // "MEDPAY INSURANCE"
Properties
actionCode
readonlyactionCode:string|undefined
date
readonlydate:string|undefined
dates
readonlydates: readonlyX12EnrollmentDate[]
payer
readonlypayer:X12EnrollmentParty|undefined
referenceId
readonlyreferenceId:string|undefined
references
readonlyreferences: readonlyX12EnrollmentReference[]
sponsor
readonlysponsor:X12EnrollmentParty|undefined
time
readonlytime:string|undefined
transactionSetPurposeCode
readonlytransactionSetPurposeCode:string
warnings
readonlywarnings: readonlyX12ParseWarning[]
X12EnrollmentMember
Decoded Loop 2100A member name (NM1*IL) + demographic (DMG) +
address (N3/N4). PHI surface: every field carries PHI.
Example
import type { X12EnrollmentMember } from "@cosyte/x12";
declare const m: X12EnrollmentMember;
m.lastName; // verbatim
m.idCode; // verbatim member id
m.dateOfBirth; // "19850515" (CCYYMMDD, verbatim)
m.genderCode; // "F"
Properties
address
readonlyaddress:X12EnrollmentAddress|undefined
dateOfBirth
readonlydateOfBirth:string|undefined
entityIdentifierCode
readonlyentityIdentifierCode:string
firstName
readonlyfirstName:string|undefined
genderCode
readonlygenderCode:string|undefined
idCode
readonlyidCode:string|undefined
idQualifier
readonlyidQualifier:string|undefined
lastName
readonlylastName:string|undefined
middleName
readonlymiddleName:string|undefined
suffix
readonlysuffix:string|undefined
X12EnrollmentParty
Decoded Loop 1000 party (sponsor N1*P5, payer N1*IN, TPA/broker
N1*BO/N1*TV). Organizational PII, not member PHI.
Example
import type { X12EnrollmentParty } from "@cosyte/x12";
declare const p: X12EnrollmentParty;
p.entityIdentifierCode; // "P5" plan sponsor
p.name; // "EMPLOYER CO"
p.idCode; // "FEIN123" (verbatim)
Properties
entityIdentifierCode
readonlyentityIdentifierCode:string
idCode
readonlyidCode:string|undefined
idQualifier
readonlyidQualifier:string|undefined
name
readonlyname:string
X12EnrollmentReference
Decoded REF - supplemental identifier (subscriber id 0F, group/policy
1L, member id 23, …). qualifier is the X12 reference-identification
qualifier; value is the verbatim id.
Example
import type { X12EnrollmentReference } from "@cosyte/x12";
declare const r: X12EnrollmentReference;
r.qualifier; // "0F" subscriber number
r.value; // "MBR0001"
Properties
description
readonlydescription:string|undefined
qualifier
readonlyqualifier:string
value
readonlyvalue:string
X12FunctionalGroup
A single GS..GE functional group inside an interchange. transactions
is the ordered list of ST..SE transaction sets inside it (opaque bodies
at Phase 1 - see X12TransactionSet).
Example
import type { X12FunctionalGroup } from "@cosyte/x12";
declare const group: X12FunctionalGroup;
group.transactions.length;
Properties
ge
readonlyge:GeSegment|undefined
gs
readonlygs:GsSegment
transactions
readonlytransactions: readonlyX12TransactionSet[]
X12HealthCoverage
Decoded Loop 2300 health coverage (HD) plus its attached dates (DTP)
and monetary amounts (AMT). insuranceLineCode is HD-03 (HLT, DEN,
VIS, …); maintenanceTypeCode is HD-01 - the per-coverage echo of the
member action, validated against the same X12 0875 snapshot as INS-03.
Example
import type { X12HealthCoverage } from "@cosyte/x12";
declare const c: X12HealthCoverage;
c.insuranceLineCode; // "HLT"
c.planCoverageDescription; // "GOLD PPO"
c.dates[0]?.qualifier; // "348" benefit begin
Properties
amounts
readonlyamounts: readonlyX12EnrollmentAmount[]
coverageLevelCode
readonlycoverageLevelCode:string|undefined
dates
readonlydates: readonlyX12EnrollmentDate[]
insuranceLineCode
readonlyinsuranceLineCode:string|undefined
maintenanceTypeCode
readonlymaintenanceTypeCode:string|undefined
maintenanceTypeDescription
readonlymaintenanceTypeDescription:string|undefined
planCoverageDescription
readonlyplanCoverageDescription:string|undefined
X12HierarchicalLevel
One HL segment captured during the walk. The 837 HL hierarchy is the
safety primitive: HL-01 is this level's id (sequential within the
transaction); HL-02 is the parent's id (empty when this is a top-level
HL); HL-03 is the level code (20 Information Source = billing
provider, 22 Subscriber, 23 Dependent/patient); HL-04 is 1 when
any HL below it claims this as its parent, 0 otherwise.
Parent-pointer integrity is the #1 safety property. The walker
validates HL-02 references an earlier-emitted HL-01 in the same
transaction AND that the parent's HL-03 level is consistent with this
level (20 → 22; 22 → 23). Violations emit
X12_HL_PARENT_MISMATCH and X12_HL_PARENT_LEVEL_INVALID -
the parser NEVER silently re-numbers.
Example
import type { X12HierarchicalLevel } from "@cosyte/x12";
declare const hl: X12HierarchicalLevel;
hl.hlId; // "1" (sequential within the transaction)
hl.parentHlId; // undefined for billing-provider top level
hl.levelCode; // "20"
hl.hasChild; // "1"
Properties
hasChild
readonlyhasChild:string
hlId
readonlyhlId:string
levelCode
readonlylevelCode:string
parentHlId
readonlyparentHlId:string|undefined
X12Hl
One HL segment captured during an eligibility / claim-status walk. The
hierarchy is the structural safety primitive - see the module doc. The
verbatim declared parentHlId is always preserved even when it fails
validation (the parser never re-numbers).
Example
import type { X12Hl } from "@cosyte/x12";
declare const hl: X12Hl;
hl.hlId; // "3"
hl.parentHlId; // "2" (undefined at the information-source top level)
hl.levelCode; // "22" (Subscriber)
hl.hasChild; // "1"
Properties
hasChild
readonlyhasChild:string
hlId
readonlyhlId:string
levelCode
readonlylevelCode:string
parentHlId
readonlyparentHlId:string|undefined
X12Interchange
The top-level X12 interchange returned by parseX12. isa carries the
envelope header verbatim; delimiters is the four-class delimiter set
detected from fixed positions inside isa.raw; groups is the ordered
GS..GE list; orphanSegments holds any segment that fell outside every
transaction set (empty for a well-formed interchange); warnings
accumulates every Tier-2 deviation observed during the parse (lenient
mode); trailingBytes (when present) is any non-empty content after IEA -
preserved verbatim so a consumer can inspect or re-emit it.
Example
import { parseX12 } from "@cosyte/x12";
const ix = parseX12(raw);
for (const w of ix.warnings) console.warn(w.code, w.position);
Properties
delimiters
readonlydelimiters:Delimiters
groups
readonlygroups: readonlyX12FunctionalGroup[]
iea
readonlyiea:IeaSegment|undefined
isa
readonlyisa:IsaSegment
orphanSegments
readonlyorphanSegments: readonlyX12OrphanSegment[]
Segments the envelope grammar could not place, in input order - almost
always because they fell outside every ST..SE transaction set, plus the
TA1-inside-a-group case, which is lifted out of the transaction it
arrived in. Empty for a well-formed interchange. See
X12OrphanSegment.
profile?
readonlyoptionalprofile?:X12Profile
The trading-partner X12Profile in effect for this parse, if any -
either passed explicitly via options.profile or resolved from the
process-scoped default. Present only when a profile applied; used for
attribution and as the partition basis for partitionWarnings.
ta1Segments
readonlyta1Segments: readonlyTa1Segment[]
trailingBytes?
readonlyoptionaltrailingBytes?:string
warnings
readonlywarnings: readonlyX12ParseWarning[]
X12LineAdjudication
Decoded SVD + adjacent CAS / DTP - Line Adjudication Information (Loop
2430). Captures another payer's prior adjudication of THIS line so the
downstream payer has the COB context. The adjustments re-use the
remit X12RemitAdjustment shape since the CAS semantics are identical
to those on the 835.
procedureCode is SVD-03-2 (verbatim) - the adjudicated procedure
code as the other payer recorded it. May differ from the line's SV
procedure code if the other payer remapped.
Example
import type { X12LineAdjudication } from "@cosyte/x12";
declare const a: X12LineAdjudication;
a.otherPayerId; // "84320" (the other payer's id)
a.amountPaid?.toString(); // "50.00", or undefined if none decoded
a.procedureCode; // "99213"
a.adjustments[0]?.groupCode;// "CO"
a.dateAdjudicated; // "20260520" CCYYMMDD verbatim
Properties
adjustments
readonlyadjustments: readonlyX12RemitAdjustment[]
amountPaid
readonlyamountPaid:X12Decimal|undefined
SVD-02, the amount the other payer paid on this line. undefined where
this library decoded no value from that element - absent, empty, or
bytes that do not decode (which also emits X12_UNPARSEABLE_DECIMAL).
Through 0.0.12 both cases read X12Decimal.ZERO, indistinguishable
from a payer that adjudicated the line to nothing.
dateAdjudicated
readonlydateAdjudicated:string|undefined
otherPayerId
readonlyotherPayerId:string
paidUnits
readonlypaidUnits:X12Decimal|undefined
procedureCode
readonlyprocedureCode:string|undefined
procedureQualifier
readonlyprocedureQualifier:string|undefined
X12LineDrug
Decoded LIN + CTP - Drug Identification (837P Loop 2410). Surfaces the
NDC and the optional dispensed-quantity + UCUM unit. qualifier
= N4 NDC (overwhelmingly common), EN EAN/UCC-13, HI HIBC.
Example
import type { X12LineDrug } from "@cosyte/x12";
declare const d: X12LineDrug;
d.qualifier; // "N4"
d.code; // verbatim NDC
d.quantity?.toString(); // "1.50"
d.unitOfMeasure; // "ML" UCUM milliliter
Properties
code
readonlycode:string
qualifier
readonlyqualifier:string
quantity
readonlyquantity:X12Decimal|undefined
unitOfMeasure
readonlyunitOfMeasure:string|undefined
X12OrphanSegment
A segment the envelope grammar has no place for, captured verbatim rather
than discarded. Every segment recorded here also raised exactly one
X12_UNEXPECTED_SEGMENT warning whose position.segmentIndex equals
segmentIndex, and context is that warning's library-owned
discriminant, so the two surfaces can be joined without string matching.
These are structural anomalies, not a normal shape: a stray segment
between GE and IEA, a body segment between an SE and its group's
GE, a body segment between GS and the first ST, an ST with no open
group, an SE closing nothing, a GE closing nothing, or a TA1 inside
an open functional group. The parser cannot place any of them in the typed
tree, but it no longer drops them either, so a segment that used to vanish
is now readable here.
Most of these sit outside every ST..SE transaction set, but the TA1
case does not. TA1 is envelope-level by spec, so a TA1 anywhere
inside an open group is routed here even when it arrives BETWEEN an ST
and its SE - in which case it is lifted out of that transaction's
segments / rawSegments and appears only on this array. That is
long-standing behaviour (it predates this array; the segment simply used
to be discarded), and it is the one case where ix.groups is not the whole
typed model.
serializeX12 re-emits these, at anchor, so an orphan and its
X12_UNEXPECTED_SEGMENT warning both survive a round trip. Placement is by
the structural anchor and NEVER by segmentIndex: that index is an
index into the INPUT stream, and the emit is not in input order (it hoists
ta1Segments ahead of the groups and skips the zero-length segment a
doubled terminator produces), so replaying by index splices an orphan into
whatever occupies that slot - measurably, into an 835's ST..SE body,
where a re-parse reports nothing at all. Use segmentIndex to join
back to the warning, not to place the segment. See KNOWN-LIMITATIONS.md.
Two things are NOT recorded here. A doubled segment terminator delimits a
zero-length segment carrying no elements, so there is nothing to retain.
A segment whose first element is empty (*A*B~) has no id for the
envelope walker to dispatch on and is skipped without a warning; that is
long-standing behaviour this array does not change.
This is document content, so treat it as PHI. Unlike an
X12ParseWarning, whose message is a lookup into a frozen registry and
whose metadata is positional only, an orphan carries the sender's bytes
verbatim, exactly as X12TransactionSet.rawSegments and isa.raw do. A
segment outside a transaction is not required to be PHI-free, so do NOT
log this array wholesale when triaging; log context and segmentIndex,
which name the structural rule and the location without echoing content.
Example
import { parseX12 } from "@cosyte/x12";
const ix = parseX12(raw);
for (const o of ix.orphanSegments) {
console.warn(o.context, o.segmentIndex, o.segment.id);
}
Properties
anchor
readonlyanchor:X12OrphanAnchor
Where the segment sat in the typed tree - the slot serializeX12 puts it
back into. See X12OrphanAnchor for why a structural anchor and not
segmentIndex is what makes re-emission sound.
context
readonlycontext:X12UnexpectedSegmentContext
Which structural rule the segment broke.
raw
readonlyraw:string
The verbatim segment text, segment terminator stripped.
segment
readonlysegment:X12Segment
The decoded segment (id + 1-indexed elements), as for any body segment.
segmentIndex
readonlysegmentIndex:number
Global segment index in the post-ISA stream (ISA itself is index 0) -
identical to the position.segmentIndex of the segment's
X12_UNEXPECTED_SEGMENT warning.
X12OtherSubscriber
Decoded Loop 2320 - Other Subscriber Information. Captures the SBR-01 payer responsibility code and the associated other-subscriber / other- payer NM1 entities; Phase 5 records the surface so a consumer knows COB exists. Detailed CAS / OI / MOA breakdown inside Loop 2320 is deferred to Phase 9 (it tracks one payer's specific adjudication and is rarely needed for outbound claim creation).
Example
import type { X12OtherSubscriber } from "@cosyte/x12";
declare const o: X12OtherSubscriber;
o.payerResponsibilityCode; // "S" secondary
o.otherSubscriber?.name; // verbatim
o.otherPayer?.name; // verbatim
Properties
claimFilingIndicator
readonlyclaimFilingIndicator:string|undefined
individualRelationshipCode
readonlyindividualRelationshipCode:string|undefined
otherPayer
readonlyotherPayer:X12ClaimEntity|undefined
otherSubscriber
readonlyotherSubscriber:X12ClaimEntity|undefined
payerResponsibilityCode
readonlypayerResponsibilityCode:string
X12ParseOptions
Options accepted by parseX12 to tune lenient/strict behaviour. Every
field is optional; parseX12(raw, {}) is valid and produces the library
defaults.
Remarks
With exactOptionalPropertyTypes: true, callers cannot pass
{ strict: undefined } - either omit the key or pass a boolean.
Example
import { parseX12, type X12ParseOptions } from "@cosyte/x12";
const opts: X12ParseOptions = {
strict: true,
onWarning: (w) => console.warn(w.code),
};
parseX12(raw, opts);
Properties
onWarning?
readonlyoptionalonWarning?:OnWarningCallback
profile?
readonlyoptionalprofile?:X12Profile|null
A trading-partner X12Profile to attach to the result. An explicit
profile ALWAYS wins over any process-scoped default; pass null to opt
out of the default for a single call. When omitted, parseX12 consults
getDefaultProfile(). The profile is attached as ix.profile for
attribution and consumed by partitionWarnings; it does not alter the
lenient parse itself (v1 profiles are descriptive - see the profile
subsystem docs).
strict?
readonlyoptionalstrict?:boolean
X12ParseWarning
Data shape for every Tier-2 warning emitted by the parser. Warnings are
plain data (distinct from X12ParseError, which is a thrown Error
subclass) so they can be safely accumulated on X12Interchange.warnings
and passed to onWarning callbacks.
message is always a member of ALL_WARNING_MESSAGES: it names
the deviation, never the bytes that caused it. position says where to
look and the bytes stay on the model. A warning has no snippet.
Example
import type { X12ParseWarning } from "@cosyte/x12";
declare const w: X12ParseWarning;
w.code; // "X12_PRE_005010"
w.position; // { segmentIndex: 0, interchangeIndex: 0, elementIndex: 12 }
Properties
code
readonlycode:X12WarningCode
message
readonlymessage:string
position
readonlyposition:X12Position
X12Position
Positional context attached to every warning and fatal error. Fields are 1-indexed against the X12 spec convention (interchange first, then group, then transaction, then segment, then element within that segment, then component within that element).
All fields past segmentIndex are optional - for a top-level fatal like
X12_EMPTY_INPUT only segmentIndex: 0 is populated; for a per-element
warning deep inside a transaction every field may be set.
Remarks
With exactOptionalPropertyTypes: true, do not pass interchangeIndex: undefined explicitly - omit the key instead.
Example
import type { X12Position } from "@cosyte/x12";
const pos: X12Position = { segmentIndex: 0, interchangeIndex: 0 };
Properties
componentIndex?
readonlyoptionalcomponentIndex?:number
elementIndex?
readonlyoptionalelementIndex?:number
groupIndex?
readonlyoptionalgroupIndex?:number
interchangeIndex?
readonlyoptionalinterchangeIndex?:number
repetitionIndex?
readonlyoptionalrepetitionIndex?:number
segmentIndex
readonlysegmentIndex:number
transactionIndex?
readonlyoptionaltransactionIndex?:number
X12PremiumAddress
Decoded N3 + N4 address block attached to a party. lines is the N3
address lines (1-2 entries); city / state / postalCode come from
N4. All verbatim - no normalization.
Example
import type { X12PremiumAddress } from "@cosyte/x12";
declare const a: X12PremiumAddress;
a.lines[0]; // "500 CORPORATE BLVD"
a.city; // "COLUMBUS"
Properties
city
readonlycity:string|undefined
countryCode
readonlycountryCode:string|undefined
lines
readonlylines: readonlystring[]
postalCode
readonlypostalCode:string|undefined
state
readonlystate:string|undefined
X12PremiumAdjustment
Decoded ADX - Adjustment to a premium remittance. amount is ADX-01
(signed monetary adjustment); reasonCode is ADX-02 (adjustment reason -
"52" credit memo, "53" debit memo, …); the optional
referenceQualifier / referenceId (ADX-03 / ADX-04) tie the adjustment
to a prior item.
Example
import type { X12PremiumAdjustment } from "@cosyte/x12";
declare const a: X12PremiumAdjustment;
a.amount.toString(); // "-25.00"
a.reasonCode; // "53"
Properties
amount
readonlyamount:X12Decimal
reasonCode
readonlyreasonCode:string
referenceId
readonlyreferenceId:string|undefined
referenceQualifier
readonlyreferenceQualifier:string|undefined
X12PremiumDate
Decoded DTM date attached to the header or a remittance loop. qualifier
is the date/time qualifier (DTM-01); value is the verbatim CCYYMMDD
(DTM-02). No normalization.
Example
import type { X12PremiumDate } from "@cosyte/x12";
declare const d: X12PremiumDate;
d.qualifier; // "582" (report period)
d.value; // "20260601"
Properties
qualifier
readonlyqualifier:string
value
readonlyvalue:string
X12PremiumEntity
Decoded ENT - Entity (organization-summary remittance). assignedNumber
is ENT-01; the entity is identified by ENT-02 (entity id code) plus the
ENT-03 / ENT-04 qualifier + id. All verbatim.
Example
import type { X12PremiumEntity } from "@cosyte/x12";
declare const e: X12PremiumEntity;
e.assignedNumber; // "1"
e.entityIdentifierCode; // "2J" (correspondent)
e.idCode; // "GRP-0001"
Properties
assignedNumber
readonlyassignedNumber:string|undefined
entityIdentifierCode
readonlyentityIdentifierCode:string|undefined
idCode
readonlyidCode:string|undefined
idQualifier
readonlyidQualifier:string|undefined
X12PremiumOpenItem
Decoded RMR - Remittance Advice Accounts Receivable Open Item Reference.
The premium-line unit: a policy / invoice reference plus the amount paid
and (optionally) the amount due. qualifier is RMR-01 (reference id
qualifier - "11" account number, "IK" invoice, "AZ" health-insurance
policy number); referenceId is RMR-02; amountPaid is RMR-04;
amountDue is RMR-05.
Example
import type { X12PremiumOpenItem } from "@cosyte/x12";
declare const o: X12PremiumOpenItem;
o.qualifier; // "AZ"
o.referenceId; // "POL-0001"
o.amountPaid?.toString(); // "250.00", or undefined if none decoded
Properties
amountDue
readonlyamountDue:X12Decimal|undefined
amountPaid
readonlyamountPaid:X12Decimal|undefined
RMR-04, the amount paid against this open item. undefined where this library decoded no value
from that element - it was absent or empty, or it held bytes that do
not decode as a decimal (which also emits X12_UNPARSEABLE_DECIMAL at
its elementIndex). Through 0.0.12 both cases read
X12Decimal.ZERO, indistinguishable from an amount of zero the sender
did state.
paymentActionCode
readonlypaymentActionCode:string|undefined
qualifier
readonlyqualifier:string
referenceId
readonlyreferenceId:string
X12PremiumParty
Decoded Loop 1000A (Premium Receiver, N1*PE) or Loop 1000B (Premium
Payer / Remitter, N1*PR / N1*RM) party. Uniform shape so a consumer
can read both by role. Names + addresses here are PII (organizational),
not PHI in the §164.514 sense - member identity lives on the per-member
remittance detail.
Example
import type { X12PremiumParty } from "@cosyte/x12";
declare const payer: X12PremiumParty;
payer.name; // "EMPLOYER CO"
payer.idCode; // "FEIN123" (verbatim)
Properties
address
readonlyaddress:X12PremiumAddress|undefined
entityIdentifierCode
readonlyentityIdentifierCode:string
idCode
readonlyidCode:string|undefined
idQualifier
readonlyidQualifier:string|undefined
name
readonlyname:string
references
readonlyreferences: readonlyX12PremiumReference[]
X12PremiumPaymentHeader
Decoded BPR - Financial Information / payment header (identical segment
shape to the 835). totalPremiumAmount is BPR-02, the aggregate premium
the bank actually moved; method is BPR-04 (ACH / CHK / NON / …).
Example
import type { X12PremiumPaymentHeader } from "@cosyte/x12";
declare const p: X12PremiumPaymentHeader;
p.totalPremiumAmount?.toString(); // "12500.00", or undefined if none decoded
p.method; // "ACH"
p.paymentDate; // "20260601" (CCYYMMDD, verbatim)
Properties
creditDebitFlag
readonlycreditDebitFlag:string
BPR-03 credit/debit flag. Spec-defined "C" (credit) or "D" (debit);
typed string to preserve any verbatim non-spec value from a quirky
sender.
method
readonlymethod:string
paymentDate
readonlypaymentDate:string
paymentFormatCode
readonlypaymentFormatCode:string|undefined
totalPremiumAmount
readonlytotalPremiumAmount:X12Decimal|undefined
BPR-02, the aggregate premium moved. undefined where this library decoded no value
from that element - it was absent or empty, or it held bytes that do
not decode as a decimal (which also emits X12_UNPARSEABLE_DECIMAL at
its elementIndex). Through 0.0.12 both cases read
X12Decimal.ZERO, indistinguishable from an amount of zero the sender
did state.
transactionHandlingCode
readonlytransactionHandlingCode:string
X12PremiumPayments
The top-level result returned by "./get-820.js".get820Payments. Carries the payment header (BPR), reassociation traces (TRN), the premium receiver + remitter parties (Loop 1000A / 1000B), every organization / individual remittance detail loop (Loop 2000 → RMR / ADX), and every warning surfaced during the walk.
Example
import { parseX12, get820Payments } from "@cosyte/x12";
const ix = parseX12(raw);
const tx = ix.groups[0]?.transactions.find((t) => t.st.elements[1] === "820");
if (tx !== undefined) {
const prem = get820Payments(ix.delimiters, tx);
prem.payment.totalPremiumAmount.toString();
for (const r of prem.remittances) {
r.openItems[0]?.amountPaid.toString();
}
}
Properties
payment
readonlypayment:X12PremiumPaymentHeader
receiver
readonlyreceiver:X12PremiumParty|undefined
remittances
readonlyremittances: readonlyX12PremiumRemittance[]
remitter
readonlyremitter:X12PremiumParty|undefined
traces
readonlytraces: readonlyX12PremiumTrace[]
warnings
readonlywarnings: readonlyX12ParseWarning[]
X12PremiumPerson
Decoded NM1 individual (member) inside an individual remittance loop. PHI surface: every field carries PHI.
Example
import type { X12PremiumPerson } from "@cosyte/x12";
declare const p: X12PremiumPerson;
p.entityIdentifierCode; // "IL" insured
p.lastName; // verbatim
p.idQualifier; // "34" SSN / "ZZ" mutually defined
p.idCode; // verbatim member id
Properties
entityIdentifierCode
readonlyentityIdentifierCode:string
firstName
readonlyfirstName:string|undefined
idCode
readonlyidCode:string|undefined
idQualifier
readonlyidQualifier:string|undefined
lastName
readonlylastName:string|undefined
middleName
readonlymiddleName:string|undefined
suffix
readonlysuffix:string|undefined
X12PremiumReference
Decoded REF segment - supplemental identifier (master policy number, plan
id, version). qualifier is the X12 reference-identification qualifier;
value is the verbatim id.
Example
import type { X12PremiumReference } from "@cosyte/x12";
declare const r: X12PremiumReference;
r.qualifier; // "38" (master policy number)
r.value; // "POL-0001"
Properties
description
readonlydescription:string|undefined
qualifier
readonlyqualifier:string
value
readonlyvalue:string
X12PremiumRemittance
Decoded Loop 2000 remittance entry - one organization-summary (ENT) or
individual (NM1) remittance. Carries the open-item references (RMR), the
adjustments (ADX), and any REF / DTM context. The entity / individual
name fields carry PII / PHI (member name + id) - surfaced verbatim, never
echoed in a warning, never normalized.
Example
import type { X12PremiumRemittance } from "@cosyte/x12";
declare const r: X12PremiumRemittance;
r.individual?.lastName; // verbatim member surname
r.openItems[0]?.referenceId; // policy / invoice number
r.openItems[0]?.amountPaid.toString(); // "250.00"
Properties
adjustments
readonlyadjustments: readonlyX12PremiumAdjustment[]
dates
readonlydates: readonlyX12PremiumDate[]
entity
readonlyentity:X12PremiumEntity|undefined
individual
readonlyindividual:X12PremiumPerson|undefined
openItems
readonlyopenItems: readonlyX12PremiumOpenItem[]
references
readonlyreferences: readonlyX12PremiumReference[]
X12PremiumTrace
Decoded TRN - Reassociation Trace Number. Pairs the 820 to the
originating ACH / check artifact so the receiver can reconcile the
premium deposit. referenceId is the trace number a bank statement / ACH
addenda will carry.
Example
import type { X12PremiumTrace } from "@cosyte/x12";
declare const t: X12PremiumTrace;
t.traceTypeCode; // "1" - Current Transaction Trace Numbers
t.referenceId; // e.g. "PREM-202606" (verbatim)
Properties
originatingCompanyId
readonlyoriginatingCompanyId:string|undefined
originatingCompanySupplementalCode
readonlyoriginatingCompanySupplementalCode:string|undefined
referenceId
readonlyreferenceId:string
traceTypeCode
readonlytraceTypeCode:string
X12Profile
A readonly, frozen profile produced by defineProfile(). Mirrors the
locked hl7 Profile shape (name / description / lineage) plus X12's
quirks axis and a structured describe().
Example
import { parseX12, profiles } from "@cosyte/x12";
const ix = parseX12(raw, { profile: profiles.availity });
ix.profile?.name; // "availity"
ix.profile?.describe().adds.length;
Properties
describe
readonlydescribe: () =>X12ProfileDescription
Returns
description?
readonlyoptionaldescription?:string
lineage
readonlylineage: readonlystring[]
name
readonlyname:string
quirks
readonlyquirks: readonlyX12ProfileQuirk[]
X12ProfileDescription
Structured describe() output - the "what this profile relaxes / adds /
requires" record published with the package. Returned as DATA (not a
formatted string, unlike hl7) so downstream tooling - docs generators,
the pathways engine - can consume it programmatically.
Example
import { profiles } from "@cosyte/x12";
const d = profiles.availity.describe();
d.adds.map((q) => q.id); // ["payer-loop-ref-2u", "service-line-ref-f8"]
d.expectedWarnings; // readonly X12WarningCode[]
Properties
adds
readonlyadds: readonlyX12ProfileQuirk[]
description?
readonlyoptionaldescription?:string
expectedWarnings
readonlyexpectedWarnings: readonlyX12WarningCode[]
Sorted, de-duplicated union of every quirk's expectedWarnings.
lineage
readonlylineage: readonlystring[]
name
readonlyname:string
relaxes
readonlyrelaxes: readonlyX12ProfileQuirk[]
requires
readonlyrequires: readonlyX12ProfileQuirk[]
X12ProfileQuirk
A single trading-partner deviation captured by a profile. Every quirk is
fixture-grounded: fixture points at a real Tier-2 corpus file that
demonstrates the deviation, and sourceCategory records where the quirk
was observed. This is the locked hard rule - a quirk without a
demonstrating fixture is forbidden, enforced both by this required field
and by the accuracy test.
Example
import type { X12ProfileQuirk } from "@cosyte/x12";
const quirk: X12ProfileQuirk = {
id: "payer-loop-ref-2u",
effect: "adds",
summary: "Payer Loop 1000A carries a REF*2U additional payer identifier.",
fixture: "remit/835-availity-quirk.edi",
sourceCategory: "Availity 835 ERA companion guide - payer-loop REF",
};
Properties
effect
readonlyeffect:X12ProfileEffect
Which describe() bucket this quirk renders into.
expectedWarnings?
readonlyoptionalexpectedWarnings?: readonlyX12WarningCode[]
Warning codes this quirk leads a consumer to EXPECT when the deviation
is present. Drives partitionWarnings. Often empty: the lenient parser
absorbs most corpus deviations with zero warnings, and that "lossless,
no warning" outcome is itself the documented behavior.
fixture
readonlyfixture:string
Path to the Tier-2 fixture demonstrating the deviation, relative to
test/fixtures/ (e.g. "remit/835-availity-quirk.edi"). REQUIRED - the
locked hard rule. The accuracy test parses this file and asserts the
claimed deviation is present.
id
readonlyid:string
Stable, kebab-case identifier - unique within a profile's quirk set.
sourceCategory
readonlysourceCategory:string
Where the deviation was observed (companion guide / corpus category).
summary
readonlysummary:string
One-line human summary. NEVER contains PHI - describes structure only.
X12ProfileSpec
Input accepted by defineProfile(). Every field except name is
optional; extends composes parent profiles (lineage + quirks merge) the
same way hl7's extends does.
Example
import { defineProfile, profiles, type X12ProfileSpec } from "@cosyte/x12";
const spec: X12ProfileSpec = {
name: "my-bcbs-regional",
extends: profiles.bcbsCommon,
quirks: [
{
id: "service-line-ref-f8",
effect: "adds",
summary: "Service line carries a REF*F8 original-reference identifier.",
fixture: "remit/835-availity-quirk.edi",
sourceCategory: "regional BCBS 835 companion guide",
},
],
};
const profile = defineProfile(spec);
Properties
description?
readonlyoptionaldescription?:string
extends?
readonlyoptionalextends?:X12Profile| readonlyX12Profile[]
name
readonlyname:string
quirks?
readonlyoptionalquirks?: readonlyX12ProfileQuirk[]
X12RemitAddress
Decoded N3 + N4 address block attached to a party. lines is the N3
address lines (1-2 entries); city/state/postalCode come from N4.
All fields verbatim - no normalization (no proper-casing, no
postal-code canonicalization).
Example
import type { X12RemitAddress } from "@cosyte/x12";
declare const a: X12RemitAddress;
a.lines[0]; // "123 PAYER WAY"
a.city; // "ANYTOWN"
a.state; // "OH"
a.postalCode; // "44113"
Properties
city
readonlycity:string|undefined
countryCode
readonlycountryCode:string|undefined
lines
readonlylines: readonlystring[]
postalCode
readonlypostalCode:string|undefined
state
readonlystate:string|undefined
X12RemitAdjustment
Decoded CAS adjustment. One CAS segment carries up to 6 adjustment
triples (reason code + amount + optional quantity) all under the same
groupCode (CAS-01). The walker flattens these so each
X12RemitAdjustment is ONE adjustment, not one segment.
groupCode is the safety primitive - see
"../../code-lists/cagc.js".CLAIM_ADJUSTMENT_GROUP_CODES. CO
= provider write-off; PR = patient owes; OA / PI = other / payer
edit. reasonCode is the CARC value (verbatim); reasonDescription
is from the bundled snapshot or undefined if outside the subset.
Example
import type { X12RemitAdjustment } from "@cosyte/x12";
declare const a: X12RemitAdjustment;
a.groupCode; // "PR" (patient responsibility)
a.reasonCode; // "1" (deductible)
a.reasonDescription; // "Deductible Amount"
a.amount?.toString(); // "50.00", or undefined if none decoded
Properties
amount
readonlyamount:X12Decimal|undefined
The CAS adjustment amount for this triple. undefined where this library decoded no value
from that element - it was absent or empty, or it held bytes that do
not decode as a decimal (which also emits X12_UNPARSEABLE_DECIMAL at
its elementIndex). Through 0.0.12 both cases read
X12Decimal.ZERO, indistinguishable from an amount of zero the sender
did state, and the balance invariants summed that fabricated zero.
groupCode
readonlygroupCode:string
quantity
readonlyquantity:X12Decimal|undefined
reasonCode
readonlyreasonCode:string
reasonDescription
readonlyreasonDescription:string|undefined
X12RemitAmount
Decoded AMT segment - supplemental claim or service amount (allowed
charge, late filing penalty, capitation payment, etc.). qualifier
names which amount (AU coverage amount, B6 allowed actual, …).
Surfaced verbatim; never folded into the balance invariant (which
checks only CLP / CAS / PLB / SVC fields).
Example
import type { X12RemitAmount } from "@cosyte/x12";
declare const a: X12RemitAmount;
a.qualifier; // "B6"
a.amount.toString(); // "450.00"
Properties
amount
readonlyamount:X12Decimal
qualifier
readonlyqualifier:string
X12RemitClaim
Decoded Loop 2100 - Claim Payment Information. The clinical-claim
unit: one provider-billed claim adjudicated by the payer. Carries
the per-claim balance invariant (totalPaymentAmount + patientResponsibilityAmount + Σ(claim-level adjustments) === totalChargeAmount); a mismatch fires
X12_835_REMIT_BALANCE_MISMATCH and is NEVER silently rebalanced.
PHI surface: patientControlNumber (provider's account number),
payerClaimControlNumber, the patient name on NM1QC, and member ID
on NM1IL all carry PHI; the parser surfaces them verbatim, never
echoes them in warnings, and never normalizes.
Example
import type { X12RemitClaim } from "@cosyte/x12";
declare const c: X12RemitClaim;
c.patientControlNumber; // "PT-ACCT-001"
c.totalChargeAmount?.toString(); // "500.00", or undefined if none decoded
c.totalPaymentAmount?.toString(); // "450.00", or undefined if none decoded
c.claimStatusCode; // "1" - Processed as Primary
c.serviceLines.length; // count of SVC loops
Properties
adjustments
readonlyadjustments: readonlyX12RemitAdjustment[]
amounts
readonlyamounts: readonlyX12RemitAmount[]
claimFilingIndicatorCode
readonlyclaimFilingIndicatorCode:string|undefined
claimFrequencyCode
readonlyclaimFrequencyCode:string|undefined
claimStatusCode
readonlyclaimStatusCode:string
claimStatusDescription
readonlyclaimStatusDescription:string|undefined
correctedPatient
readonlycorrectedPatient:X12RemitPerson|undefined
facilityTypeCode
readonlyfacilityTypeCode:string|undefined
patient
readonlypatient:X12RemitPerson|undefined
patientControlNumber
readonlypatientControlNumber:string
patientResponsibilityAmount
readonlypatientResponsibilityAmount:X12Decimal|undefined
CLP-05, the patient responsibility amount. undefined where this library decoded no value
from that element - it was absent or empty, or it held bytes that do
not decode as a decimal (which also emits X12_UNPARSEABLE_DECIMAL at
its elementIndex). Through 0.0.12 both cases read
X12Decimal.ZERO, indistinguishable from an amount of zero the sender
did state, and the balance invariants summed that fabricated zero.
payerClaimControlNumber
readonlypayerClaimControlNumber:string|undefined
references
readonlyreferences: readonlyX12RemitReference[]
remarks
readonlyremarks: readonlyX12RemitRemark[]
renderingProvider
readonlyrenderingProvider:X12RemitProvider|undefined
serviceLines
readonlyserviceLines: readonlyX12RemitServiceLine[]
servicePeriodEnd
readonlyservicePeriodEnd:string|undefined
servicePeriodStart
readonlyservicePeriodStart:string|undefined
serviceProvider
readonlyserviceProvider:X12RemitProvider|undefined
subscriber
readonlysubscriber:X12RemitPerson|undefined
totalChargeAmount
readonlytotalChargeAmount:X12Decimal|undefined
CLP-03, the total submitted charge. undefined where this library decoded no value
from that element - it was absent or empty, or it held bytes that do
not decode as a decimal (which also emits X12_UNPARSEABLE_DECIMAL at
its elementIndex). Through 0.0.12 both cases read
X12Decimal.ZERO, indistinguishable from an amount of zero the sender
did state, and the balance invariants summed that fabricated zero.
totalPaymentAmount
readonlytotalPaymentAmount:X12Decimal|undefined
CLP-04, the total amount paid on the claim. undefined where this library decoded no value
from that element - it was absent or empty, or it held bytes that do
not decode as a decimal (which also emits X12_UNPARSEABLE_DECIMAL at
its elementIndex). Through 0.0.12 both cases read
X12Decimal.ZERO, indistinguishable from an amount of zero the sender
did state, and the balance invariants summed that fabricated zero.
X12RemitContact
Decoded PER contact segment. contactFunctionCode = "BL"
(Technical), "CX" (Payers' Claim Office), etc.; each contact may
carry up to 3 communication channels (TE/EX/EM/FX).
Example
import type { X12RemitContact } from "@cosyte/x12";
declare const c: X12RemitContact;
c.contactFunctionCode; // "BL"
c.name; // "JANE COORDINATOR"
c.communications[0]?.qualifier; // "TE"
c.communications[0]?.value; // "5551234567"
Properties
communications
readonlycommunications: readonlyobject[]
contactFunctionCode
readonlycontactFunctionCode:string
name
readonlyname:string|undefined
X12RemitParty
Decoded Loop 1000A (Payer Identification) or Loop 1000B (Payee Identification) party. The shape is uniform across both loops so a consumer can iterate by role. PHI surface here: payer/payee names + addresses + contact info are PII (payee may be an individual provider) but NOT PHI in the §164.514 sense - patient identity lives on the per-claim level.
Example
import type { X12RemitParty } from "@cosyte/x12";
declare const payer: X12RemitParty;
payer.name; // "PAYER NAME"
payer.idCode; // "12345" (NAIC / NPI / payer ID, verbatim)
Properties
additionalIdentifiers
readonlyadditionalIdentifiers: readonlyX12RemitReference[]
address
readonlyaddress:X12RemitAddress|undefined
contacts
readonlycontacts: readonlyX12RemitContact[]
entityIdentifierCode
readonlyentityIdentifierCode:string
idCode
readonlyidCode:string|undefined
idQualifier
readonlyidQualifier:string|undefined
name
readonlyname:string
X12RemitPaymentHeader
Decoded BPR - Financial Information / payment header. The PAYMENT
MOVEMENT primitive: actual payment amount, credit/debit flag, method
(ACH/CHK/NON/BOP/FWT), payment date. totalActualPayment
is the sum the bank actually moved - Σ(claim CLP-04) + Σ(PLB adjustments) === BPR-02 is the top-level balance invariant.
Example
import type { X12RemitPaymentHeader } from "@cosyte/x12";
declare const p: X12RemitPaymentHeader;
p.totalActualPayment?.toString(); // "945.00", or undefined if none decoded
p.method; // "ACH"
p.paymentDate; // "20260601" (CCYYMMDD, verbatim)
Properties
creditDebitFlag
readonlycreditDebitFlag:string
BPR-03 credit/debit flag. Spec-defined values: "C" (credit - money
to provider, the normal case) or "D" (debit - refund / chargeback,
uncommon). The field is typed as string to preserve verbatim any
non-spec value from a quirky payer; consumers branching on it should
compare against the literals.
method
readonlymethod:string
paymentDate
readonlypaymentDate:string
paymentFormatCode
readonlypaymentFormatCode:string|undefined
totalActualPayment
readonlytotalActualPayment:X12Decimal|undefined
BPR-02, the amount the bank actually moved. undefined where this library decoded no value
from that element - it was absent or empty, or it held bytes that do
not decode as a decimal (which also emits X12_UNPARSEABLE_DECIMAL at
its elementIndex). Through 0.0.12 both cases read
X12Decimal.ZERO, indistinguishable from an amount of zero the sender
did state, and the balance invariants summed that fabricated zero.
transactionHandlingCode
readonlytransactionHandlingCode:string
X12RemitPerson
Decoded NM1 person - patient, subscriber, or corrected patient. The
idQualifier distinguishes member ID (MI), Social Security
(34 - rare, regulated), payer ID, etc. PHI surface: every field on
a person model carries PHI.
Example
import type { X12RemitPerson } from "@cosyte/x12";
declare const p: X12RemitPerson;
p.entityIdentifierCode; // "QC" patient / "IL" insured / "74" corrected patient
p.lastName; // verbatim
p.idQualifier; // "MI"
p.idCode; // "MEMBER123"
Properties
entityIdentifierCode
readonlyentityIdentifierCode:string
firstName
readonlyfirstName:string|undefined
idCode
readonlyidCode:string|undefined
idQualifier
readonlyidQualifier:string|undefined
lastName
readonlylastName:string|undefined
middleName
readonlymiddleName:string|undefined
suffix
readonlysuffix:string|undefined
X12RemitProvider
Decoded NM1 provider - service provider (82), rendering provider
(82 in some contexts), crossover carrier (TT), other payer
(PR / GB), etc. Same shape as a person but the qualifier semantics
are organizational.
Example
import type { X12RemitProvider } from "@cosyte/x12";
declare const r: X12RemitProvider;
r.entityIdentifierCode; // "82" service provider
r.name; // "RENDERING PROVIDER INC"
r.idQualifier; // "XX" (NPI)
r.idCode; // "1234567890"
Properties
entityIdentifierCode
readonlyentityIdentifierCode:string
idCode
readonlyidCode:string|undefined
idQualifier
readonlyidQualifier:string|undefined
name
readonlyname:string|undefined
X12RemitProviderAdjustment
Decoded PLB - Provider-Level Adjustment. Off-claim adjustments (recoupments, interest, capitation, write-offs) that move money at the provider level, not the claim level. Each PLB segment carries up to 6 adjustment triples (reason + amount); the walker flattens these so each X12RemitProviderAdjustment is one adjustment.
Sign convention: a POSITIVE PLB amount REDUCES the provider's
payment (recoupment / take-back); a NEGATIVE PLB amount ADDS to the
payment (interest / advance payment). The 835 balance invariant
Σ(claim CLP-04) + Σ(PLB amounts) === BPR-02 works because PLB
amounts already carry the correct sign.
reasonCode is the composite PLB reason code (the qualifier +
optional reference together, e.g. WO:123456 for "withholding for
claim 123456"); subCode carries the optional second component.
Example
import type { X12RemitProviderAdjustment } from "@cosyte/x12";
declare const p: X12RemitProviderAdjustment;
p.providerId; // "1234567890" (NPI)
p.fiscalPeriodDate; // "20261231"
p.reasonCode; // "WO" (withholding)
p.subCode; // "123456" (related-claim reference)
p.amount?.toString();// "50.00", or undefined if none decoded
Properties
amount
readonlyamount:X12Decimal|undefined
The PLB adjustment amount, with its raw EDI sign. undefined where this library decoded no value
from that element - it was absent or empty, or it held bytes that do
not decode as a decimal (which also emits X12_UNPARSEABLE_DECIMAL at
its elementIndex). Through 0.0.12 both cases read
X12Decimal.ZERO, indistinguishable from an amount of zero the sender
did state, and the balance invariants summed that fabricated zero.
fiscalPeriodDate
readonlyfiscalPeriodDate:string
providerId
readonlyproviderId:string
reasonCode
readonlyreasonCode:string
subCode
readonlysubCode:string|undefined
X12RemitReference
Decoded REF segment - additional identifier (Tax ID, payer ID,
supplemental). qualifier is the X12 reference-identification
qualifier ("2U" payer ID, "TJ" Tax ID, "EV" participant
receiver, "D9" claim number, …); value is the verbatim ID. Used on
payer / payee loops and on per-claim contexts.
Example
import type { X12RemitReference } from "@cosyte/x12";
declare const r: X12RemitReference;
r.qualifier; // "TJ"
r.value; // "123456789"
Properties
description
readonlydescription:string|undefined
qualifier
readonlyqualifier:string
value
readonlyvalue:string
X12RemitRemark
Decoded remark segment (LQ at claim or service level). system is the
LQ-01 industry code system ("HE" healthcare remark codes /
RARC, "RX" reject-reason, etc.); code is the verbatim value;
description comes from the bundled RARC snapshot for HE codes,
undefined otherwise. Unknown HE codes also emit
X12_UNKNOWN_RARC.
Example
import type { X12RemitRemark } from "@cosyte/x12";
declare const r: X12RemitRemark;
r.system; // "HE"
r.code; // "N4"
r.description; // "Missing/incomplete/invalid prior insurance carrier(s) EOB."
Properties
code
readonlycode:string
description
readonlydescription:string|undefined
system
readonlysystem:string
X12RemitServiceLine
Decoded Loop 2110 - Service Payment Information. One per service line
adjudicated. Line-level CAS adjustments roll up into the claim-level
balance invariant (Σ(SVC paid) + Σ(line CAS) === CLP-04); a mismatch
fires X12_835_REMIT_BALANCE_MISMATCH on the parent claim.
productServiceIdQualifier is the SVC-01-1 procedure-code system
(HC HCPCS/CPT, AD ADA dental, N4 NDC, WK Advanced Billing
Concepts, IV HIPPS rate code, …); productServiceId is the verbatim
code. The qualifier governs interpretation - misreading it picks
the wrong code system and corrupts the clinical context.
X221A1 is reported to default an absent SVC-05 to one (secondhand, via X12's RFI #2163 - this library has not read the TR3). This reader does not apply that default, because fabricating a count the sender did not send is inventing data. Apply it yourself if you want it.
undefined on either quantity means "not decoded", not "absent". The
element may have been missing, or present and unparseable as a decimal -
the two are not distinguished here and neither raises a warning. Read the
verbatim element off tx.segments if you need to tell them apart.
Example
import type { X12RemitServiceLine } from "@cosyte/x12";
declare const s: X12RemitServiceLine;
s.productServiceIdQualifier; // "HC"
s.productServiceId; // "99213"
s.chargeAmount?.toString(); // "150.00", or undefined if none decoded
s.paymentAmount?.toString(); // "135.00", or undefined if none decoded
Properties
adjustments
readonlyadjustments: readonlyX12RemitAdjustment[]
amounts
readonlyamounts: readonlyX12RemitAmount[]
chargeAmount
readonlychargeAmount:X12Decimal|undefined
SVC-02, the line's submitted charge. undefined where this library decoded no value
from that element - it was absent or empty, or it held bytes that do
not decode as a decimal (which also emits X12_UNPARSEABLE_DECIMAL at
its elementIndex). Through 0.0.12 both cases read
X12Decimal.ZERO, indistinguishable from an amount of zero the sender
did state, and the balance invariants summed that fabricated zero.
modifiers
readonlymodifiers: readonlystring[]
originalServiceId
readonlyoriginalServiceId:string|undefined
originalServiceIdQualifier
readonlyoriginalServiceIdQualifier:string|undefined
originalUnitsOfService
readonlyoriginalUnitsOfService:X12Decimal|undefined
SVC-07 - Original Units of Service Count: the units as SUBMITTED. Sent
only when they differ from the paid count in SVC-05, so undefined here
does NOT mean zero submitted units - it means "same as paid".
paidUnitsOfService
readonlypaidUnitsOfService:X12Decimal|undefined
SVC-05 - Units of Service Paid Count: what the payer adjudicated.
paymentAmount
readonlypaymentAmount:X12Decimal|undefined
SVC-03, the amount paid on the line. undefined where this library decoded no value
from that element - it was absent or empty, or it held bytes that do
not decode as a decimal (which also emits X12_UNPARSEABLE_DECIMAL at
its elementIndex). Through 0.0.12 both cases read
X12Decimal.ZERO, indistinguishable from an amount of zero the sender
did state, and the balance invariants summed that fabricated zero.
productServiceId
readonlyproductServiceId:string
productServiceIdQualifier
readonlyproductServiceIdQualifier:string
references
readonlyreferences: readonlyX12RemitReference[]
remarks
readonlyremarks: readonlyX12RemitRemark[]
revenueCode
readonlyrevenueCode:string|undefined
SVC-04 - NUBC revenue code. Absent on a professional line.
serviceDateEnd
readonlyserviceDateEnd:string|undefined
serviceDateStart
readonlyserviceDateStart:string|undefined
X12Remittance
The top-level result returned by "./get-835.js".get835. Carries the payment header (BPR), the trace (TRN), payer + payee identification (Loop 1000A/1000B), every claim payment loop (Loop 2100 → Loop 2110), provider-level adjustments (PLB), and every warning surfaced during the walk - including the safety-critical "../../parser/warnings.js".WARNING_CODES.X12_835_REMIT_BALANCE_MISMATCH.
Example
import { parseX12, get835 } from "@cosyte/x12";
const ix = parseX12(raw);
const tx = ix.groups[0]?.transactions.find((t) => t.st.elements[1] === "835");
if (tx !== undefined) {
const remit = get835(ix.delimiters, tx);
remit.payment.totalActualPayment.toString();
for (const claim of remit.claims) {
claim.totalChargeAmount.toString();
claim.totalPaymentAmount.toString();
}
}
Properties
claims
readonlyclaims: readonlyX12RemitClaim[]
payee
readonlypayee:X12RemitParty|undefined
payer
readonlypayer:X12RemitParty|undefined
payment
readonlypayment:X12RemitPaymentHeader
providerAdjustments
readonlyproviderAdjustments: readonlyX12RemitProviderAdjustment[]
traces
readonlytraces: readonlyX12RemitTrace[]
warnings
readonlywarnings: readonlyX12ParseWarning[]
X12RemitTrace
Decoded TRN - Reassociation Trace Number. Pairs the 835 to the
originating payer's payment artifact (ACH trace, check number) so a
cash-poster can reconcile. referenceId is the trace number a bank
statement / ACH addenda will carry; originatingCompanyId is the
payer's CMS-assigned (or proprietary) routing identifier.
Example
import type { X12RemitTrace } from "@cosyte/x12";
declare const t: X12RemitTrace;
t.traceTypeCode; // "1" - Current Transaction Trace Numbers
t.referenceId; // e.g. "12345" (verbatim)
t.originatingCompanyId; // e.g. "1512345678"
Properties
originatingCompanyId
readonlyoriginatingCompanyId:string|undefined
originatingCompanySupplementalCode
readonlyoriginatingCompanySupplementalCode:string|undefined
referenceId
readonlyreferenceId:string
traceTypeCode
readonlytraceTypeCode:string
X12ReviewDecision
The HCR Health Care Services Review decision (response only, Loop 2000E /
2000F). actionCode (HCR-01) is the certification outcome and is
preserved verbatim - the parser never infers an outcome.
reviewIdentificationNumber (HCR-02) is the authorization / certification
number a provider quotes back to the payer.
Example
import type { X12ReviewDecision } from "@cosyte/x12";
declare const d: X12ReviewDecision;
d.actionCode; // "A1" (certified in total)
d.reviewIdentificationNumber; // "AUTH123456"
d.reasonCode; // "0" (HCR-03, free-form decision reason)
Properties
actionCode
readonlyactionCode:string
reasonCode
readonlyreasonCode:string|undefined
reviewIdentificationNumber
readonlyreviewIdentificationNumber:string|undefined
secondSurgicalOpinionCode
readonlysecondSurgicalOpinionCode:string|undefined
X12Segment
Immutable decoded X12 segment. elements is 1-indexed: elements[0] is
the segment id placeholder (matching "./types.js".IsaSegment,
GsSegment, etc. - every typed segment in the envelope follows the same
1-indexed shape so consumers learn one rule and never have to recall
whether a particular accessor offsets by one). raw preserves the exact
segment text from input (terminator stripped) so a byte-exact round-trip
survives even when downstream stages mutate the model.
Element values are stored RAW (pre-?-unescape). Reads via getSegmentValue apply unescapeRelease on demand - this keeps
round-trip byte-exact while still letting helpers receive
spec-compliant logical values.
Example
import type { X12Segment } from "@cosyte/x12";
declare const seg: X12Segment;
seg.id; // "NM1"
seg.elements[3]; // raw text of NM1-03 (post-element-split, pre-?-unescape)
Properties
elements
readonlyelements: readonlystring[]
id
readonlyid:string
raw
readonlyraw:string
X12ServiceLineStatus
One service-line status (Loop 2220). Triggered by an SVC; carries the procedure / revenue identification, line amounts, and its own STC statuses + REF / DTP.
Example
import type { X12ServiceLineStatus } from "@cosyte/x12";
declare const l: X12ServiceLineStatus;
l.procedureCode; // "99213"
l.lineChargeAmount?.toString(); // "150.00"
l.statuses[0]?.statuses[0]?.statusCode; // "20"
Properties
dates
readonlydates: readonlyX12StatusDate[]
lineChargeAmount
readonlylineChargeAmount:X12Decimal|undefined
linePaymentAmount
readonlylinePaymentAmount:X12Decimal|undefined
modifiers
readonlymodifiers: readonlystring[]
procedureCode
readonlyprocedureCode:string|undefined
references
readonlyreferences: readonlyX12StatusReference[]
revenueCode
readonlyrevenueCode:string|undefined
serviceIdQualifier
readonlyserviceIdQualifier:string|undefined
statuses
readonlystatuses: readonlyX12StatusInfo[]
unitsOfService
readonlyunitsOfService:X12Decimal|undefined
SVC-07, data element 380 (Quantity). Named "Units of Service Count" by
TR3 005010X212 and "Original Units of Service Count" by 005010X214;
the same element in the same position either way, so one field serves
both and the walker never has to know which TR3 it is reading.
SVC-05 is NOT USED in both TR3s, so unlike the 835 there is no second,
paid quantity to tell this one apart from. undefined means not
decoded, not "the sender sent zero": an absent element and a present
one that is not an X12 R-type decimal share it, and only the latter
raises X12_UNPARSEABLE_DECIMAL at position.elementIndex 7.
X12ServiceReview
One services-review item - a patient-event HL (EV, Loop 2000E) or a
service HL (SS, Loop 2000F). Carries the UM review information, the
optional HCR decision (response only), echoed TRN traces, HI
diagnoses, attached provider NM1s, and the supplemental REF/DTP/MSG.
Example
import type { X12ServiceReview } from "@cosyte/x12";
declare const r: X12ServiceReview;
r.requestCategoryCode; // "HS" (health services review) / "AR" (admission review)
r.certificationTypeCode; // "I" (initial) / "R" (renewal)
r.decision?.actionCode; // "A1" (certified) - response only
Properties
certificationTypeCode
readonlycertificationTypeCode:string|undefined
dates
readonlydates: readonlyX12AuthDate[]
decision
readonlydecision:X12ReviewDecision|undefined
diagnoses
readonlydiagnoses: readonlyX12AuthDiagnosis[]
hierarchy
readonlyhierarchy:X12Hl|undefined
levelOfServiceCode
readonlylevelOfServiceCode:string|undefined
messages
readonlymessages: readonlystring[]
providers
readonlyproviders: readonlyX12AuthEntity[]
references
readonlyreferences: readonlyX12AuthReference[]
requestCategoryCode
readonlyrequestCategoryCode:string|undefined
serviceTypeCode
readonlyserviceTypeCode:string|undefined
traces
readonlytraces: readonlyX12AuthTrace[]
X12ServicesReview
Top-level result of "./get-278.js".get278Request / "./get-278.js".get278Response. Carries the BHT header, the four named HL parties (UMO, requester, subscriber, dependent) resolved from the hierarchy, every per-event / per-service review item, the verbatim HL tree, and the warnings surfaced during the walk.
Example
import { parseX12, get278Response } from "@cosyte/x12";
const ix = parseX12(raw);
const tx = ix.groups[0]?.transactions.find((t) => t.st.elements[1] === "278");
if (tx !== undefined) {
const review = get278Response(ix.delimiters, tx);
review?.reviews[0]?.decision?.actionCode; // "A1" (certified)
}
Properties
dependent
readonlydependent:X12AuthMember|undefined
direction
readonlydirection:"request"|"response"
header
readonlyheader:X12AuthHeader
hierarchies
readonlyhierarchies: readonlyX12Hl[]
implementationConventionReference
readonlyimplementationConventionReference:string|undefined
requester
readonlyrequester:X12AuthEntity|undefined
reviews
readonlyreviews: readonlyX12ServiceReview[]
subscriber
readonlysubscriber:X12AuthMember|undefined
utilizationManagementOrganization
readonlyutilizationManagementOrganization:X12AuthEntity|undefined
warnings
readonlywarnings: readonlyX12ParseWarning[]
X12StatusCode
One Health Care Claim Status composite (C043, STC-01 / STC-10 / STC-11).
Pairs a CSCC (Claim Status Category Code, X12 source 507) with a
CSC (Claim Status Code, X12 source 508) and the responsible entity.
The verbatim codes are always preserved; descriptions resolve from the
bundled snapshots (or undefined outside the subset).
Example
import type { X12StatusCode } from "@cosyte/x12";
declare const c: X12StatusCode;
c.categoryCode; // "A7" (rejected/invalid)
c.statusCode; // "21" (Missing or invalid information)
c.statusDescription; // "Missing or invalid information."
c.entityCode; // "85" (billing provider)
Properties
categoryCode
readonlycategoryCode:string
categoryDescription
readonlycategoryDescription:string|undefined
entityCode
readonlyentityCode:string|undefined
statusCode
readonlystatusCode:string
statusDescription
readonlystatusDescription:string|undefined
X12StatusDate
A DTP date / date-range on a claim or service-line status (e.g. DTP472 service date, DTP050 received date).
Example
import type { X12StatusDate } from "@cosyte/x12";
declare const d: X12StatusDate;
d.qualifier; // "472"
d.formatQualifier; // "RD8"
d.value; // "20260601-20260601"
Properties
formatQualifier
readonlyformatQualifier:string
qualifier
readonlyqualifier:string
value
readonlyvalue:string
X12StatusEntity
A non-person entity decoded from an NM1 - the payer (Loop 2100A), information receiver (2100B), or service provider (2100C).
Example
import type { X12StatusEntity } from "@cosyte/x12";
declare const e: X12StatusEntity;
e.entityIdentifierCode; // "PR" / "41" / "1P"
e.name; // "MEDPAY INSURANCE"
e.idCode; // "00123"
Properties
entityIdentifierCode
readonlyentityIdentifierCode:string
entityTypeQualifier
readonlyentityTypeQualifier:string
idCode
readonlyidCode:string|undefined
idQualifier
readonlyidQualifier:string|undefined
name
readonlyname:string
X12StatusInfo
One decoded STC segment - the headline status fields plus the up-to-three
X12StatusCode composites (STC-01, STC-10, STC-11). A single claim
(or service line) can carry multiple STC segments; each becomes one
X12StatusInfo.
Example
import type { X12StatusInfo } from "@cosyte/x12";
declare const s: X12StatusInfo;
s.statusEffectiveDate; // "20260627"
s.totalChargeAmount?.toString(); // "150.00"
s.statuses[0]?.statusCode; // "20"
Properties
actionCode
readonlyactionCode:string|undefined
adjudicationDate
readonlyadjudicationDate:string|undefined
message
readonlymessage:string|undefined
paymentAmount
readonlypaymentAmount:X12Decimal|undefined
statusEffectiveDate
readonlystatusEffectiveDate:string|undefined
statuses
readonlystatuses: readonlyX12StatusCode[]
totalChargeAmount
readonlytotalChargeAmount:X12Decimal|undefined
X12StatusMember
A person (subscriber Loop 2100D / dependent Loop 2100E) decoded from an
NM1. idCode is the member identifier (NM1-09) - synthetic-only in
fixtures.
Example
import type { X12StatusMember } from "@cosyte/x12";
declare const m: X12StatusMember;
m.lastName; // "DOE"
m.idCode; // "MBR0001"
Properties
entityIdentifierCode
readonlyentityIdentifierCode:string
entityTypeQualifier
readonlyentityTypeQualifier:string
firstName
readonlyfirstName:string|undefined
idCode
readonlyidCode:string|undefined
idQualifier
readonlyidQualifier:string|undefined
lastName
readonlylastName:string|undefined
middleName
readonlymiddleName:string|undefined
suffix
readonlysuffix:string|undefined
X12StatusReference
A REF supplemental identifier on a claim or service-line status (e.g. REF1K payer claim control number, REFBLT bill type).
Example
import type { X12StatusReference } from "@cosyte/x12";
declare const r: X12StatusReference;
r.qualifier; // "1K"
r.value; // "PCN0001"
Properties
description
readonlydescription:string|undefined
qualifier
readonlyqualifier:string
value
readonlyvalue:string
X12StatusTrace
A reassociation trace (TRN). For a 277 claim status, referenceId
(TRN-02) echoes the requesting 276's trace number verbatim so the
provider can re-associate the answer. The walker never mutates it.
Example
import type { X12StatusTrace } from "@cosyte/x12";
declare const t: X12StatusTrace;
t.traceTypeCode; // "2"
t.referenceId; // "CLAIM20260627001"
Properties
originatingCompanyId
readonlyoriginatingCompanyId:string|undefined
referenceId
readonlyreferenceId:string
supplementalReferenceId
readonlysupplementalReferenceId:string|undefined
traceTypeCode
readonlytraceTypeCode:string
X12SubscriberInfo
Decoded SBR - Subscriber Information (Loop 2000B's primary trigger). Or decoded PAT - Patient Information when the patient is the subscriber.
payerResponsibilityCode(SBR-01 / X12 1138):PPrimary,SSecondary,TTertiary, etc. Drives COB ordering.individualRelationshipCode(SBR-02 / PAT-01 / X12 1069):18Self,01Spouse,19Child,G8Other Insured.groupNumber(SBR-03),groupName(SBR-04).claimFilingIndicator(SBR-09 / X12 1032):MCMedicaid,MBMedicare Part B,BLBlueCross/BlueShield,CICommercial, etc.
Example
import type { X12SubscriberInfo } from "@cosyte/x12";
declare const s: X12SubscriberInfo;
s.payerResponsibilityCode; // "P"
s.individualRelationshipCode; // "18" self
s.claimFilingIndicator; // "MB"
Properties
claimFilingIndicator
readonlyclaimFilingIndicator:string|undefined
groupName
readonlygroupName:string|undefined
groupNumber
readonlygroupNumber:string|undefined
individualRelationshipCode
readonlyindividualRelationshipCode:string|undefined
payerResponsibilityCode
readonlypayerResponsibilityCode:string|undefined
X12ToothInformation
Decoded TOO - Tooth Information (837D Loop 2400). qualifier is the
tooth-numbering code list (JP ADA Universal Tooth Numbering, JO
ANSI / ISO 3950 / FDI). toothCode is the verbatim tooth identifier;
surfaces are the per-surface codes (M mesial, O occlusal, D
distal, etc.) from TOO-03's composite components.
Example
import type { X12ToothInformation } from "@cosyte/x12";
declare const t: X12ToothInformation;
t.qualifier; // "JP"
t.toothCode; // "14"
t.surfaces; // ["O"]
Properties
qualifier
readonlyqualifier:string
surfaces
readonlysurfaces: readonlystring[]
toothCode
readonlytoothCode:string
X12TransactionSet
A single ST..SE transaction set inside a functional group. Phase 2
decodes every body segment via "./segment.js".decodeSegment so
segments carries typed X12Segment entries (ST through SE,
inclusive). rawSegments mirrors the same list as the verbatim raw
segment strings (terminator stripped) so a byte-exact round-trip survives
any downstream consumer that needs to re-emit the source.
elements on the ST and SE segments themselves IS decoded at envelope
time so envelope invariants can be checked (ST-02 ↔ SE-02 control-number
reconciliation, SE-01 segment count). Read "decoded" as element-SPLIT and
nothing more: the strings are PRE-?-unescape, and a reader that publishes
one to a consumer unescapes it first.
Example
import type { X12TransactionSet } from "@cosyte/x12";
declare const tx: X12TransactionSet;
tx.st.elements[1]; // ST-01 - transaction set ID (e.g. "835")
tx.segments[1]?.id; // first body segment id
tx.rawSegments[1]; // first body segment raw text
Properties
rawSegments
readonlyrawSegments: readonlystring[]
se
readonlyse: {elements: readonlystring[];raw:string; } |undefined
segments
readonlysegments: readonlyX12Segment[]
st
readonlyst:object
elements
readonlyelements: readonlystring[]
raw
readonlyraw:string
X12WarningPartition
The result of partitionWarnings: warnings split into those a profile leads you to EXPECT and those it does not.
Example
import type { X12WarningPartition } from "@cosyte/x12";
declare const p: X12WarningPartition;
p.unexpected.length; // alert only on these
Properties
expected
readonlyexpected: readonlyX12ParseWarning[]
unexpected
readonlyunexpected: readonlyX12ParseWarning[]
Type Aliases
AckBuildErrorCode
AckBuildErrorCode = typeof
ACK_BUILD_ERROR_CODES[keyof typeofACK_BUILD_ERROR_CODES]
String-literal union over ACK_BUILD_ERROR_CODES. Used as
AckBuildError.code.
Build837ServiceLineSpec
Build837ServiceLineSpec =
Build837ServiceLineProfessionalSpec|Build837ServiceLineInstitutionalSpec|Build837ServiceLineDentalSpec
Service-line spec - discriminated union keyed by variant. Every line in
a build837P spec must be "P", etc.; a mismatch is REFUSED.
Example
import type { Build837ServiceLineSpec } from "@cosyte/x12";
declare const sl: Build837ServiceLineSpec;
if (sl.variant === "P") sl.diagnosisPointers;
Claim837BuildErrorCode
Claim837BuildErrorCode = typeof
CLAIM_837_BUILD_ERROR_CODES[keyof typeofCLAIM_837_BUILD_ERROR_CODES]
String-literal union over CLAIM_837_BUILD_ERROR_CODES. Used as
Claim837BuildError.code.
ClaimAdjustmentGroupCode
ClaimAdjustmentGroupCode = typeof
CLAIM_ADJUSTMENT_GROUP_CODES[keyof typeofCLAIM_ADJUSTMENT_GROUP_CODES]
Discriminant type for a known Claim Adjustment Group Code. Used to
narrow the group field on a parsed claim adjustment; unknown
inbound values keep the verbatim string (NEVER coerced) and consumers
can distinguish via isClaimAdjustmentGroupCode.
Example
import type { ClaimAdjustmentGroupCode } from "@cosyte/x12";
const code: ClaimAdjustmentGroupCode = "PR";
ClaimStatus277BuildErrorCode
ClaimStatus277BuildErrorCode = typeof
CLAIM_STATUS_277_BUILD_ERROR_CODES[keyof typeofCLAIM_STATUS_277_BUILD_ERROR_CODES]
String-literal union over CLAIM_STATUS_277_BUILD_ERROR_CODES. Used
as ClaimStatus277BuildError.code.
Eligibility271BuildErrorCode
Eligibility271BuildErrorCode = typeof
ELIGIBILITY_271_BUILD_ERROR_CODES[keyof typeofELIGIBILITY_271_BUILD_ERROR_CODES]
String-literal union over ELIGIBILITY_271_BUILD_ERROR_CODES. Used
as Eligibility271BuildError.code.
Enrollment834BuildErrorCode
Enrollment834BuildErrorCode = typeof
ENROLLMENT_834_BUILD_ERROR_CODES[keyof typeofENROLLMENT_834_BUILD_ERROR_CODES]
String-literal union over ENROLLMENT_834_BUILD_ERROR_CODES. Used
as Enrollment834BuildError.code.
Ik304Code
Ik304Code = typeof
IK3_SYNTAX_ERROR_CODES[keyof typeofIK3_SYNTAX_ERROR_CODES]
String-literal union over IK3_SYNTAX_ERROR_CODES. Used as the
type of IK3-04 on the ack-spec/parsed-ack models.
Ik403Code
Ik403Code = typeof
IK4_SYNTAX_ERROR_CODES[keyof typeofIK4_SYNTAX_ERROR_CODES]
String-literal union over IK4_SYNTAX_ERROR_CODES. Used as the
type of IK4-03 on the ack-spec/parsed-ack models.
LoopMax
LoopMax =
number|">1"
Repetition count for a segment or child loop inside its parent. ">1"
means many (TR3 typically writes >1 to mean "no cap"). A finite max
surfaces as the numeric value. Phase 2 stores the value; Phase 3+'s
loop walker uses it for over-limit warnings.
Example
import type { LoopMax } from "@cosyte/x12";
const single: LoopMax = 1;
const many: LoopMax = ">1";
LoopUsage
LoopUsage =
"required"|"situational"|"optional"
Cardinality of a segment or child loop inside its parent. Mirrors TR3 spelling so the spec reads like the implementation guide:
required- the segment/loop MUST appear at least once.situational- the segment/loop MAY appear when its situational rule triggers; the parser does not enforce the rule itself but loop-walker warnings (Phase 3+) reference it.optional- the segment/loop MAY appear in any usage.
Example
import type { LoopUsage } from "@cosyte/x12";
const usage: LoopUsage = "required";
OnWarningCallback
OnWarningCallback = (
warning) =>void
Callback invoked inline each time the parser emits a Tier-2 warning.
Always fires BEFORE the warning is appended to X12Interchange.warnings
so consumers observe warnings in the same order the parser discovered them.
Parameters
warning
Returns
void
Example
import { parseX12, type OnWarningCallback } from "@cosyte/x12";
const onWarning: OnWarningCallback = (w) => {
console.warn(w.code, w.message);
};
parseX12(raw, { onWarning });
Premium820BuildErrorCode
Premium820BuildErrorCode = typeof
PREMIUM_820_BUILD_ERROR_CODES[keyof typeofPREMIUM_820_BUILD_ERROR_CODES]
String-literal union over PREMIUM_820_BUILD_ERROR_CODES. Used as
Premium820BuildError.code.
Remit835BuildErrorCode
Remit835BuildErrorCode = typeof
REMIT_835_BUILD_ERROR_CODES[keyof typeofREMIT_835_BUILD_ERROR_CODES]
String-literal union over REMIT_835_BUILD_ERROR_CODES. Used as
Remit835BuildError.code.
SegmentSpec
SegmentSpec = readonly
string[]
A single body segment as a raw element array: [segmentId, ...elements],
1-indexed against the X12 spec convention once placed (i.e. spec[1] is
element 1). Element values are LOGICAL - the builder applies the
?-release-character escape on emit so any active delimiter inside a value
survives. The segment id (spec[0]) is emitted verbatim. ST and SE are NOT
included here - the builder synthesizes them from TransactionSetSpec.
Example
const nm1: SegmentSpec = ["NM1", "IL", "1", "DOE", "JANE"];
ServicesReview278BuildErrorCode
ServicesReview278BuildErrorCode = typeof
AUTH_278_BUILD_ERROR_CODES[keyof typeofAUTH_278_BUILD_ERROR_CODES]
String-literal union over AUTH_278_BUILD_ERROR_CODES. Used as
ServicesReview278BuildError.code.
Ta1AckCode
Ta1AckCode = typeof
TA1_ACK_CODES[keyof typeofTA1_ACK_CODES]
String-literal union over TA1_ACK_CODES.
Ta1NoteCode
Ta1NoteCode = typeof
TA1_NOTE_CODES[keyof typeofTA1_NOTE_CODES]
String-literal union over TA1_NOTE_CODES - the standard-issued
note codes 000–028. Real-world inbound TA1 may carry a value past
028 (some revisions extend the list); parseTA1 exposes the
un-narrowed string on noteCodeRaw in that case, so the value survives
even when the union cannot statically type it. It is post-?-unescape
as of X12-TA1-RESIDUALS, and a clause here calling it VERBATIM is
deleted rather than reworded - raw.elements[5] is the byte surface.
X12_837ServiceLine
X12_837ServiceLine =
X12_837ServiceLineProfessional|X12_837ServiceLineInstitutional|X12_837ServiceLineDental
Service-line discriminated union - one variant per TR3. The walker
picks the variant from the segment id (SV1 → P, SV2 → I, SV3 →
D). When an LX opens a service line with no SVx segment that follows
before the next LX / SE, the line is dropped (an X12_UNEXPECTED_SEGMENT
warning will have already fired if the body content was structurally
impossible).
Example
import type { X12_837ServiceLine } from "@cosyte/x12";
declare const sl: X12_837ServiceLine;
switch (sl.variant) {
case "P": sl.procedureCode; sl.diagnosisPointers; break;
case "I": sl.revenueCode; break;
case "D": sl.toothInformation; break;
}
X12AckDispositionCode
X12AckDispositionCode = typeof
X12_ACK_DISPOSITION_CODES[keyof typeofX12_ACK_DISPOSITION_CODES]
String-literal union over X12_ACK_DISPOSITION_CODES. Used as the
type of AK9-01, IK5-01, and the disposition field on the
ack-spec/parsed-ack models.
Example
import type { X12AckDispositionCode } from "@cosyte/x12";
function isReject(code: X12AckDispositionCode): boolean {
return code === "R" || code === "M" || code === "W" || code === "X";
}
X12BalanceInvariant
X12BalanceInvariant = typeof
BALANCE_INVARIANTS[keyof typeofBALANCE_INVARIANTS]
String-literal union over BALANCE_INVARIANTS.
Example
import type { X12BalanceInvariant } from "@cosyte/x12";
const which: X12BalanceInvariant = "service-line";
X12BuildErrorCode
X12BuildErrorCode = typeof
X12_BUILD_ERROR_CODES[keyof typeofX12_BUILD_ERROR_CODES]
String-literal union over X12_BUILD_ERROR_CODES. Used as
X12BuildError.code.
X12Claim837Variant
X12Claim837Variant =
"P"|"I"|"D"|"unknown"
837 variant - discriminator for the service-line union and for any
variant-specific helper logic. "unknown" covers transactions where
neither ST-03 nor a service-line segment id resolved the variant.
Example
import type { X12Claim837Variant } from "@cosyte/x12";
const v: X12Claim837Variant = "P";
X12ControlNumberPair
X12ControlNumberPair = typeof
CONTROL_NUMBER_PAIRS[keyof typeofCONTROL_NUMBER_PAIRS]
String-literal union over CONTROL_NUMBER_PAIRS.
Example
import type { X12ControlNumberPair } from "@cosyte/x12";
const pair: X12ControlNumberPair = "group";
X12DecimalStatus
X12DecimalStatus =
"decoded"|"absent"|"unparseable"
Why a decimal read produced no X12Decimal, or that it produced
one. The three states are spec-distinct and were previously collapsed
onto a single undefined:
"decoded"- the element matched the shape "../decimal.js".X12Decimal decodes,[+-]?digits(.digits?)?."absent"- the element was missing or empty. The sender said nothing."unparseable"- the element held bytes outside that shape. The sender said something and this library could not read it, which is a materially different fact from"absent". That shape is what this library reads; no clause of X12.6 is cited for it, so do not read this as an assertion about what type R does and does not permit.
Example
import type { X12DecimalStatus } from "@cosyte/x12";
const status: X12DecimalStatus = "unparseable";
X12FatalCode
X12FatalCode = typeof
FATAL_CODES[keyof typeofFATAL_CODES]
Discriminant type for X12ParseError.code. Narrowing a caught error by
this code lets consumers write exhaustive switch blocks (enabled by the
switch-exhaustiveness-check lint rule) and guarantees a typo-free
comparison against the FATAL_CODES registry.
Example
import type { X12FatalCode } from "@cosyte/x12";
function describe(code: X12FatalCode): string {
switch (code) {
case "X12_EMPTY_INPUT":
return "input was empty";
case "X12_NO_ISA_HEADER":
return "missing ISA";
case "X12_ISA_TOO_SHORT":
return "ISA truncated";
case "X12_INVALID_DELIMITERS":
return "bad ISA delimiters";
}
}
X12HiCategory
X12HiCategory =
"diagnosis"|"procedure"|"external-cause"|"principal-diagnosis"|"admitting-diagnosis"|"patient-reason-for-visit"|"drg"|"condition"|"occurrence"|"occurrence-span"|"value"|"treatment"|"unknown"
Category of an HI qualifier - separates diagnoses from procedures from
the institutional NUBC code families. Consumers branching on the
category get exhaustiveness; the variant-specific helpers
(getDiagnoses / getProcedures) filter on it.
Example
import type { X12HiCategory } from "@cosyte/x12";
const c: X12HiCategory = "diagnosis";
X12HiCodeSystem
X12HiCodeSystem =
"ICD-10-CM"|"ICD-10-PCS"|"ICD-9-CM"|"ICD-9-PCS"|"DRG"|"NDC"|"NUBC-CONDITION"|"NUBC-OCCURRENCE"|"NUBC-OCCURRENCE-SPAN"|"NUBC-VALUE"|"NUBC-PATIENT-REASON"|"unknown"
Discriminant for the code system referenced by a single HI composite. The
"unknown" member is the catch-all for qualifiers outside the TR3-cited
set - verbatim code is preserved on the parsed structure and an
X12_UNKNOWN_HI_QUALIFIER warning is emitted.
Example
import type { X12HiCodeSystem } from "@cosyte/x12";
const sys: X12HiCodeSystem = "ICD-10-CM";
X12HiQualifier
X12HiQualifier = keyof typeof
HI_QUALIFIERS
Stable string-literal union of every known HI qualifier the parser recognizes. Inferred from HI_QUALIFIERS keys.
Example
import type { X12HiQualifier } from "@cosyte/x12";
const q: X12HiQualifier = "ABK";
X12OrphanAnchor
X12OrphanAnchor = {
groupIndex:number;kind:"interchange"; } | {groupIndex:number;kind:"group";transactionIndex:number; } | {groupIndex:number;kind:"transaction";segmentOffset:number;transactionIndex:number; }
Where an orphan sat in the STRUCTURE of the interchange, as opposed to
where it sat in the input byte stream. This is what lets serializeX12
put an orphan back without guessing.
X12OrphanSegment.segmentIndex cannot do that job. It indexes the INPUT
stream, and the emit is not in input order: ta1Segments are hoisted ahead
of the groups, and a doubled terminator's zero-length segment occupies an
input index that is never emitted. Either one shifts the output's indices
away from the input's, so replaying by index splices the orphan into
whatever occupies that slot - measurably, into an 835's ST..SE body,
where a re-parse reports nothing. An anchor names a slot in the typed tree
instead, which survives both reorderings because it does not mention bytes.
Three kinds, one per structural level:
"interchange"- between the ISA and the IEA but outside every functional group.groupIndexis the number of groups that had already closed, so the orphan is emitted immediately beforeix.groups[groupIndex](or before the IEA whengroupIndex === ix.groups.length)."group"- insideix.groups[groupIndex]but outside every transaction set in it.transactionIndexis the number of transactions that had already closed, so the orphan is emitted immediately before that group'stransactions[transactionIndex](or before itsGEwhentransactionIndex === transactions.length)."transaction"- inside an openST..SE, which only aTA1can be, since every other segment arriving there is body content.segmentOffsetis the number ofrawSegmentsalready collected, so the orphan is emitted immediately beforerawSegments[segmentOffset]. It is never0(theSTis alwaysrawSegments[0]) and never exceedsrawSegments.length. Such an orphan is written back BETWEEN theSTand theSE, soserializeX12counts it toward SE-01 in spec-clean mode even though it is not ontx.rawSegments- it is a segment of that transaction set per X12.6.
An anchor is a POSITION, so reshaping the model invalidates it. The
indices address ix.groups, that group's transactions, and that
transaction's rawSegments as they stand on the interchange you pass to
serializeX12. Filter or reorder any of those and an orphan's anchor may
still resolve while naming a different slot, and it will be emitted there
with no warning. An anchor that resolves to nothing is emitted at
interchange level before the IEA rather than dropped. Re-parse rather than
hand-edit if you need anchors to stay meaningful.
Union Members
Type Literal
{ groupIndex: number; kind: "interchange"; }
groupIndex
readonlygroupIndex:number
How many functional groups had closed before this segment arrived.
kind
readonlykind:"interchange"
Type Literal
{ groupIndex: number; kind: "group"; transactionIndex: number; }
groupIndex
readonlygroupIndex:number
Index into ix.groups of the group that was open.
kind
readonlykind:"group"
transactionIndex
readonlytransactionIndex:number
How many transaction sets in that group had closed.
Type Literal
{ groupIndex: number; kind: "transaction"; segmentOffset: number; transactionIndex: number; }
groupIndex
readonlygroupIndex:number
Index into ix.groups of the group that was open.
kind
readonlykind:"transaction"
segmentOffset
readonlysegmentOffset:number
How many of that set's rawSegments had been collected.
transactionIndex
readonlytransactionIndex:number
Index into that group's transactions of the set that was open.
Example
import { parseX12 } from "@cosyte/x12";
const ix = parseX12(raw);
for (const o of ix.orphanSegments) {
if (o.anchor.kind === "group") console.warn(o.anchor.groupIndex);
}
X12OrphanAnchorKind
X12OrphanAnchorKind =
X12OrphanAnchor["kind"]
String-literal union over the kind discriminant of X12OrphanAnchor.
Example
import type { X12OrphanAnchorKind } from "@cosyte/x12";
const kind: X12OrphanAnchorKind = "transaction";
X12ProfileEffect
X12ProfileEffect =
"relaxes"|"adds"|"requires"
The bucket a quirk falls into when rendered by X12Profile.describe. Mirrors the roadmap's "what this profile relaxes / adds / requires" framing.
relaxes- the partner tolerates / emits a structural variation the strict 005010 baseline would flag (e.g. an alternate component delimiter).adds- the partner emits extra spec-optional content (e.g. additional REF segments) a generic consumer might not expect.requires- the partner mandates a normally-situational element be present.
Example
import type { X12ProfileEffect } from "@cosyte/x12";
const effect: X12ProfileEffect = "adds";
X12RequiredLoop
X12RequiredLoop = typeof
REQUIRED_LOOPS[keyof typeofREQUIRED_LOOPS]
String-literal union over REQUIRED_LOOPS.
Example
import type { X12RequiredLoop } from "@cosyte/x12";
const loop: X12RequiredLoop = "2010BB";
X12UnexpectedSegmentContext
X12UnexpectedSegmentContext = typeof
UNEXPECTED_SEGMENT_CONTEXTS[keyof typeofUNEXPECTED_SEGMENT_CONTEXTS]
String-literal union over UNEXPECTED_SEGMENT_CONTEXTS.
Example
import type { X12UnexpectedSegmentContext } from "@cosyte/x12";
const ctx: X12UnexpectedSegmentContext = "se-without-st";
X12WarningCode
X12WarningCode = typeof
WARNING_CODES[keyof typeofWARNING_CODES]
Discriminant type for X12ParseWarning.code. Narrowing a warning by this
code lets consumers write exhaustive switch blocks and guarantees a
typo-free comparison against the WARNING_CODES registry.
Example
import type { X12ParseWarning, X12WarningCode } from "@cosyte/x12";
function describe(w: X12ParseWarning): string {
const code: X12WarningCode = w.code;
switch (code) {
case "X12_PRE_005010":
return "pre-005010 sender";
default:
return `warning: ${code}`;
}
}
Variables
ACK_BUILD_ERROR_CODES
constACK_BUILD_ERROR_CODES:object
Stable string codes for every AckBuildError thrown by the
acknowledgment builders. Locked here so consumers can narrow on
err.code exhaustively. Additions-only thereafter; renaming any of
these codes is a breaking change.
X12_ACK_INVALID_DISPOSITION- A disposition was supplied that does not match "./codes.js".X12AckDispositionCode (or "./codes.js".Ta1AckCode forbuildTA1).X12_ACK_INVALID_SPEC- A spec field violated a structural constraint the builder cannot recover from (e.g., an ISA-13 control number longer than the spec's 9-char limit).X12_ACK_ACCEPT_WITH_ERRORS- AnAdisposition was supplied alongside non-empty per-transaction errors or a transaction-set whose own disposition is notA. Refused - accept must mean accept. UseEfor "accepted, errors noted" orRfor "rejected" instead.X12_ACK_COUNT_MISMATCH- The functional-levelnumberOfTransactionSets/numberReceived/numberAcceptedare internally inconsistent (e.g., accepted > received) or do not match the suppliedtransactionResponseslist.X12_TA1_ACCEPT_WITH_NOTE- A TA1Aack code was supplied with a note code other than000(no error). Refused for the same safety reason: an accept cannot cite a non-zero note.
Type Declaration
X12_ACK_ACCEPT_WITH_ERRORS
readonlyX12_ACK_ACCEPT_WITH_ERRORS:"X12_ACK_ACCEPT_WITH_ERRORS"="X12_ACK_ACCEPT_WITH_ERRORS"
X12_ACK_COUNT_MISMATCH
readonlyX12_ACK_COUNT_MISMATCH:"X12_ACK_COUNT_MISMATCH"="X12_ACK_COUNT_MISMATCH"
X12_ACK_INVALID_DISPOSITION
readonlyX12_ACK_INVALID_DISPOSITION:"X12_ACK_INVALID_DISPOSITION"="X12_ACK_INVALID_DISPOSITION"
X12_ACK_INVALID_SPEC
readonlyX12_ACK_INVALID_SPEC:"X12_ACK_INVALID_SPEC"="X12_ACK_INVALID_SPEC"
X12_TA1_ACCEPT_WITH_NOTE
readonlyX12_TA1_ACCEPT_WITH_NOTE:"X12_TA1_ACCEPT_WITH_NOTE"="X12_TA1_ACCEPT_WITH_NOTE"
Example
import { ACK_BUILD_ERROR_CODES, AckBuildError } from "@cosyte/x12";
try {
buildSomeAck();
} catch (err) {
if (err instanceof AckBuildError && err.code === ACK_BUILD_ERROR_CODES.X12_ACK_ACCEPT_WITH_ERRORS) {
// application bug - never silently accept with errors
}
}
ALL_WARNING_MESSAGES
constALL_WARNING_MESSAGES:ReadonlySet<string>
Every message string this library can put on a warning. Exported so a
consumer, or a conformance gate, can assert set membership: if
ALL_WARNING_MESSAGES.has(w.message) is ever false, something
interpolated document bytes into a diagnostic.
Example
import { parseX12, ALL_WARNING_MESSAGES } from "@cosyte/x12";
const ix = parseX12(raw);
ix.warnings.every((w) => ALL_WARNING_MESSAGES.has(w.message)); // true, always
AUTH_278_BUILD_ERROR_CODES
constAUTH_278_BUILD_ERROR_CODES:object
Stable string codes for every ServicesReview278BuildError. Locked
here so consumers can narrow exhaustively on err.code; additions-only
thereafter (renaming any code is a breaking change).
X12_278_BUILD_INVALID_HIERARCHY- the nested tree cannot form a valid 278 HL spine (a subscriber with neither a review nor a dependent; a dependent with no review). The message carries structural indices + counts only - never a member id / name.X12_278_BUILD_INVALID_SPEC- a non-hierarchy precondition failed (a review whose HL-03levelCodeis outsideEV/SS; a review with norequestCategoryCode; a request spec carrying anHCRcertification decision -HCRis response-only; a response review with a decision whoseactionCodeis empty; an over-long ISA-13 control number). The message carries structural indices, counts and X12 control codes - never a member id / name.
Type Declaration
X12_278_BUILD_INVALID_HIERARCHY
readonlyX12_278_BUILD_INVALID_HIERARCHY:"X12_278_BUILD_INVALID_HIERARCHY"="X12_278_BUILD_INVALID_HIERARCHY"
X12_278_BUILD_INVALID_SPEC
readonlyX12_278_BUILD_INVALID_SPEC:"X12_278_BUILD_INVALID_SPEC"="X12_278_BUILD_INVALID_SPEC"
Example
import { AUTH_278_BUILD_ERROR_CODES, ServicesReview278BuildError, build278Response } from "@cosyte/x12";
try {
build278Response(spec);
} catch (err) {
if (
err instanceof ServicesReview278BuildError &&
err.code === AUTH_278_BUILD_ERROR_CODES.X12_278_BUILD_INVALID_HIERARCHY
) {
// the hierarchy is impossible - fix the tree, do not emit
}
}
AUTH_278_LOOP_2000A
constAUTH_278_LOOP_2000A:LoopSpec
278 Loop 2000A - Utilization Management Organization (UMO) HL. Triggered by
HL (HL-03 = "20") - the top of the hierarchy, no parent. Carries the
UMO name NM1.
Example
import { AUTH_278_LOOP_2000A } from "@cosyte/x12";
AUTH_278_LOOP_2000A.trigger; // "HL"
AUTH_278_LOOP_2000B
constAUTH_278_LOOP_2000B:LoopSpec
278 Loop 2000B - Requester HL. Triggered by HL (HL-03 = "21"). The
requesting provider / facility.
Example
import { AUTH_278_LOOP_2000B } from "@cosyte/x12";
AUTH_278_LOOP_2000B.id; // "2000B"
AUTH_278_LOOP_2000C
constAUTH_278_LOOP_2000C:LoopSpec
278 Loop 2000C - Subscriber HL. Triggered by HL (HL-03 = "22").
Carries the subscriber name NM1 + DMG demographics.
Example
import { AUTH_278_LOOP_2000C } from "@cosyte/x12";
AUTH_278_LOOP_2000C.id; // "2000C"
AUTH_278_LOOP_2000D
constAUTH_278_LOOP_2000D:LoopSpec
278 Loop 2000D - Dependent HL. Triggered by HL (HL-03 = "23"). Carries
the dependent name NM1 + DMG demographics.
Example
import { AUTH_278_LOOP_2000D } from "@cosyte/x12";
AUTH_278_LOOP_2000D.id; // "2000D"
AUTH_278_LOOP_2000E
constAUTH_278_LOOP_2000E:LoopSpec
278 Loop 2000E - Patient Event HL. Triggered by HL (HL-03 = "EV").
Anchors the UM services-review information, the HCR decision (response
only), HI diagnoses, the echoed TRN, and the service-provider NM1s.
Nests AUTH_278_LOOP_2000F.
Example
import { AUTH_278_LOOP_2000E } from "@cosyte/x12";
AUTH_278_LOOP_2000E.children[0]?.id; // "2000F"
AUTH_278_LOOP_2000F
constAUTH_278_LOOP_2000F:LoopSpec
278 Loop 2000F - Service HL. Triggered by HL (HL-03 = "SS"). Carries a
service-level UM review and, in a response, its HCR decision.
Example
import { AUTH_278_LOOP_2000F } from "@cosyte/x12";
AUTH_278_LOOP_2000F.trigger; // "HL"
BALANCE_INVARIANTS
constBALANCE_INVARIANTS:object
Which 835 balance invariant failed. A library-owned discriminant naming
the TR3 equation. The amounts on either side stay on the model as
X12Decimal and are never rendered into the message: an EDI amount is a
consumer-controlled element like any other, and a 300,000-digit "amount"
would otherwise become a 300,000-byte diagnostic.
Type Declaration
CLAIM
readonlyCLAIM:"claim"="claim"
CLP-04 + Σ(claim CAS + line CAS) == CLP-03.
REMIT_TOTAL
readonlyREMIT_TOTAL:"remit-total"="remit-total"
Σ(CLP-04) - Σ(PLB amounts) == BPR-02.
SERVICE_LINE
readonlySERVICE_LINE:"service-line"="service-line"
SVC-03 + Σ(line CAS) == SVC-02.
Example
import { remitBalanceMismatch, BALANCE_INVARIANTS } from "@cosyte/x12";
const w = remitBalanceMismatch({ segmentIndex: 12 }, BALANCE_INVARIANTS.CLAIM);
BUILD_REFUSAL_VALUE_MAX_LENGTH
constBUILD_REFUSAL_VALUE_MAX_LENGTH:63=63
How many characters of a caller-supplied value survive into a refusal
message, whether it comes from a build* function or from
defineProfile(). Set to mirror the parser's own SNIPPET_MAX_INPUT (63),
so the two bounded copies in this library agree rather than each picking a
number. Comfortably wider than every slot it guards: an ISA-13 / IEA-02
control number is 9, a TA1-05 note code 3, an ST-01 transaction set id 3, an
834 maintenance type 2-3, an 837 service-line variant 1.
Example
import { BUILD_REFUSAL_VALUE_MAX_LENGTH } from "@cosyte/x12";
BUILD_REFUSAL_VALUE_MAX_LENGTH; // 63
BUILD_REFUSAL_VALUE_MAX_RENDERED
constBUILD_REFUSAL_VALUE_MAX_RENDERED:number
Hard ceiling, in characters, on the fragment renderCallerValue
returns: BUILD_REFUSAL_VALUE_MAX_LENGTH surviving characters, two
quotes, one ellipsis, and the (N characters) suffix at its widest.
renderCallerJson is held to the same ceiling and comes in two
characters under it, because JSON supplies its own quotes.
This is the bound on the FRAGMENT, not on the message. A refusal message
is this plus the site's own fixed template text, which differs per site, so
the message is bounded by a constant but not by this constant. Measured on
this tree: a 120,000-character control number gives an 86-character fragment
and a 150-character X12BuildError.message from buildInterchange. Do
not quote the ceiling as though it were a message length - an earlier
revision of the docs did exactly that, reporting "now 90 bytes" for a message
that is 150. The suite asserts the fragment against this constant and each
message against its own site.
Example
import { BUILD_REFUSAL_VALUE_MAX_RENDERED } from "@cosyte/x12";
BUILD_REFUSAL_VALUE_MAX_RENDERED; // 90
CARC
constCARC:CodeListSnapshot
Bundled CARC snapshot. meta.publishedDate is the WPC publication
date this subset reflects; meta.snapshotDate is when cosyte captured
it. The codes map is frozen - use the lookupCarc helper for
the ergonomic { code, description } shape consumed by the 835
helper.
Example
import { CARC } from "@cosyte/x12";
CARC.meta.snapshotDate; // "2026-06-27"
CARC.codes["45"]; // "Charge exceeds fee schedule..."
Object.keys(CARC.codes).length; // count of bundled codes
CLAIM_837_BUILD_ERROR_CODES
constCLAIM_837_BUILD_ERROR_CODES:object
Stable string codes for every Claim837BuildError. Locked here so
consumers can narrow exhaustively on err.code; additions-only
thereafter (renaming any code is a breaking change).
X12_837_BUILD_INVALID_HIERARCHY- the billing-provider → subscriber → (claims | patient) tree cannot form a valid HL spine: no billing providers, a billing provider with no subscribers, a subscriber with neither direct claims nor dependent patients, or a dependent patient with no claims.X12_837_BUILD_INVALID_SPEC- a non-hierarchy structural precondition failed: an emptyclaimId, a claim with no service lines, a service line whosevariantdoes not match the builder, an empty procedure / revenue code, or an over-length control number.
Type Declaration
X12_837_BUILD_INVALID_HIERARCHY
readonlyX12_837_BUILD_INVALID_HIERARCHY:"X12_837_BUILD_INVALID_HIERARCHY"="X12_837_BUILD_INVALID_HIERARCHY"
X12_837_BUILD_INVALID_SPEC
readonlyX12_837_BUILD_INVALID_SPEC:"X12_837_BUILD_INVALID_SPEC"="X12_837_BUILD_INVALID_SPEC"
Example
import { CLAIM_837_BUILD_ERROR_CODES, Claim837BuildError, build837P } from "@cosyte/x12";
try {
build837P(spec);
} catch (err) {
if (
err instanceof Claim837BuildError &&
err.code === CLAIM_837_BUILD_ERROR_CODES.X12_837_BUILD_INVALID_HIERARCHY
) {
// the HL spine is impossible - fix the tree, do not emit
}
}
CLAIM_837_LOOP_1000A
constCLAIM_837_LOOP_1000A:LoopSpec
837 Loop 1000A - Submitter Name. Same across variants.
Example
import { CLAIM_837_LOOP_1000A } from "@cosyte/x12";
CLAIM_837_LOOP_1000A.id; // "1000A"
CLAIM_837_LOOP_1000B
constCLAIM_837_LOOP_1000B:LoopSpec
837 Loop 1000B - Receiver Name. Same across variants.
Example
import { CLAIM_837_LOOP_1000B } from "@cosyte/x12";
CLAIM_837_LOOP_1000B.id; // "1000B"
CLAIM_837_LOOP_2010AA
constCLAIM_837_LOOP_2010AA:LoopSpec
837 Loop 2010AA - Billing Provider Name. Triggered by NM1 with
NM1-01 = "85". The trigger qualifier value is enforced in the walker
(the loop spec keys off the segment id, not the element value).
Example
import { CLAIM_837_LOOP_2010AA } from "@cosyte/x12";
CLAIM_837_LOOP_2010AA.trigger; // "NM1"
CLAIM_837_LOOP_2010BA
constCLAIM_837_LOOP_2010BA:LoopSpec
837 Loop 2010BA - Subscriber Name (NM1*IL). The subscriber identity
- member id; address is situational.
Example
import { CLAIM_837_LOOP_2010BA } from "@cosyte/x12";
CLAIM_837_LOOP_2010BA.id; // "2010BA"
CLAIM_837_LOOP_2010BB
constCLAIM_837_LOOP_2010BB:LoopSpec
837 Loop 2010BB - Payer Name (NM1*PR). Identifies the payer the provider is billing for this hierarchy.
Example
import { CLAIM_837_LOOP_2010BB } from "@cosyte/x12";
CLAIM_837_LOOP_2010BB.id; // "2010BB"
CLAIM_837_LOOP_2010CA
constCLAIM_837_LOOP_2010CA:LoopSpec
837 Loop 2010CA - Patient Name (NM1*QC). Triggered only when Loop 2000C (patient HL) is present (patient ≠ subscriber).
Example
import { CLAIM_837_LOOP_2010CA } from "@cosyte/x12";
CLAIM_837_LOOP_2010CA.id; // "2010CA"
CLAIM_837_LOOP_2430
constCLAIM_837_LOOP_2430:LoopSpec
837 Loop 2430 - Line Adjudication Information. Triggered by SVD.
Captures a prior payer's adjudication of this line for COB.
Example
import { CLAIM_837_LOOP_2430 } from "@cosyte/x12";
CLAIM_837_LOOP_2430.trigger; // "SVD"
CLAIM_837D_LOOP_2000A
constCLAIM_837D_LOOP_2000A:LoopSpec
837D Loop 2000A - Billing Provider Hierarchical Level (dental).
Example
import { CLAIM_837D_LOOP_2000A } from "@cosyte/x12";
CLAIM_837D_LOOP_2000A.id; // "2000A"
CLAIM_837D_LOOP_2300
constCLAIM_837D_LOOP_2300:LoopSpec
837D Loop 2300 - Claim Information (dental). Triggered by CLM.
Nests CLAIM_837D_LOOP_2400 (SV3-led service lines).
Example
import { CLAIM_837D_LOOP_2300 } from "@cosyte/x12";
CLAIM_837D_LOOP_2300.trigger; // "CLM"
CLAIM_837D_LOOP_2400
constCLAIM_837D_LOOP_2400:LoopSpec
837D Loop 2400 - Service Line (dental). Body led by SV3; per-line
TOO segments capture tooth + surface detail.
Example
import { CLAIM_837D_LOOP_2400 } from "@cosyte/x12";
CLAIM_837D_LOOP_2400.trigger; // "LX"
CLAIM_837I_LOOP_2000A
constCLAIM_837I_LOOP_2000A:LoopSpec
837I Loop 2000A - Billing Provider Hierarchical Level (institutional).
Example
import { CLAIM_837I_LOOP_2000A } from "@cosyte/x12";
CLAIM_837I_LOOP_2000A.id; // "2000A"
CLAIM_837I_LOOP_2300
constCLAIM_837I_LOOP_2300:LoopSpec
837I Loop 2300 - Claim Information (institutional). Triggered by CLM.
Nests CLAIM_837I_LOOP_2400 (SV2-led service lines).
Example
import { CLAIM_837I_LOOP_2300 } from "@cosyte/x12";
CLAIM_837I_LOOP_2300.trigger; // "CLM"
CLAIM_837I_LOOP_2400
constCLAIM_837I_LOOP_2400:LoopSpec
837I Loop 2400 - Service Line (institutional). Body led by SV2
(revenue code + HCPCS).
Example
import { CLAIM_837I_LOOP_2400 } from "@cosyte/x12";
CLAIM_837I_LOOP_2400.trigger; // "LX"
CLAIM_837P_LOOP_2000A
constCLAIM_837P_LOOP_2000A:LoopSpec
837P Loop 2000A - Billing Provider Hierarchical Level (professional). Top of the HL tree for professional claims. Nests Loop 2010AA (Billing Provider Name) and Loop 2000B (Subscriber HL).
Example
import { CLAIM_837P_LOOP_2000A } from "@cosyte/x12";
CLAIM_837P_LOOP_2000A.id; // "2000A"
CLAIM_837P_LOOP_2300
constCLAIM_837P_LOOP_2300:LoopSpec
837P Loop 2300 - Claim Information (professional). Triggered by CLM.
Nests CLAIM_837P_LOOP_2400 (SV1-led service lines).
Example
import { CLAIM_837P_LOOP_2300 } from "@cosyte/x12";
CLAIM_837P_LOOP_2300.trigger; // "CLM"
CLAIM_837P_LOOP_2400
constCLAIM_837P_LOOP_2400:LoopSpec
837P Loop 2400 - Service Line (professional). Triggered by LX, body
led by SV1. Nests Loop 2410 (drug) and Loop 2430 (line adjudication).
Example
import { CLAIM_837P_LOOP_2400 } from "@cosyte/x12";
CLAIM_837P_LOOP_2400.trigger; // "LX"
CLAIM_837P_LOOP_2410
constCLAIM_837P_LOOP_2410:LoopSpec
837P Loop 2410 - Drug Identification. Triggered by LIN inside the
2400 service-line loop. Carries the NDC + dispensed quantity for a
professional pharmacy / injectable claim line.
Example
import { CLAIM_837P_LOOP_2410 } from "@cosyte/x12";
CLAIM_837P_LOOP_2410.trigger; // "LIN"
CLAIM_ADJUSTMENT_GROUP_CODES
constCLAIM_ADJUSTMENT_GROUP_CODES:object
The 4 spec-fixed Claim Adjustment Group Codes. Frozen literal union via
as const so consumers compare code === CLAIM_ADJUSTMENT_GROUP_CODES.PR
and TypeScript narrows exhaustively.
CO- Contractual Obligation. The provider's contracted write-off (e.g. payer fee schedule below billed charges). The PROVIDER eats this. PostingCOto patient responsibility is the wrong-party bug.PR- Patient Responsibility. Patient deductible / coinsurance / copay / non-covered. The PATIENT owes this. This is the patient-statement total.OA- Other Adjustment. Used when neither CO nor PR fits - typically prior-payer payments, COB adjustments, withholding for refund. Use is fact-pattern-specific.PI- Payer Initiated Reductions. Payer-side reduction the provider may not dispute under the contract - e.g. bundling edits, prepayment review reductions.
Type Declaration
CO
readonlyCO:"CO"="CO"
OA
readonlyOA:"OA"="OA"
PI
readonlyPI:"PI"="PI"
PR
readonlyPR:"PR"="PR"
Example
import { CLAIM_ADJUSTMENT_GROUP_CODES } from "@cosyte/x12";
function bucketFor(group: string): "provider" | "patient" | "other" | "payer-edit" | "unknown" {
switch (group) {
case CLAIM_ADJUSTMENT_GROUP_CODES.CO: return "provider";
case CLAIM_ADJUSTMENT_GROUP_CODES.PR: return "patient";
case CLAIM_ADJUSTMENT_GROUP_CODES.OA: return "other";
case CLAIM_ADJUSTMENT_GROUP_CODES.PI: return "payer-edit";
default: return "unknown";
}
}
CLAIM_STATUS_277_BUILD_ERROR_CODES
constCLAIM_STATUS_277_BUILD_ERROR_CODES:object
Stable string codes for every ClaimStatus277BuildError. Locked
here so consumers can narrow exhaustively on err.code; additions-only
thereafter (renaming any code is a breaking change).
X12_277_BUILD_INVALID_HIERARCHY- the nested tree cannot form a valid 277 HL spine (no sources, a source with no receiver, a receiver with no provider, a provider with no subscriber, a subscriber with neither claims nor dependents, a dependent with no claim). The message carries structural indices + counts only - never a member id / name.X12_277_BUILD_INVALID_SPEC- a non-hierarchy precondition failed (a claim that would not materialize on read - no trace, no statuses, no service lines; a status whose first composite has no category code; a service line with no SVC-07 units of service count, which005010X212makes REQUIRED and005010X214does not, so this arm fires forbuild277and never forbuild277CA; an over-long ISA-13 control number).
Type Declaration
X12_277_BUILD_INVALID_HIERARCHY
readonlyX12_277_BUILD_INVALID_HIERARCHY:"X12_277_BUILD_INVALID_HIERARCHY"="X12_277_BUILD_INVALID_HIERARCHY"
X12_277_BUILD_INVALID_SPEC
readonlyX12_277_BUILD_INVALID_SPEC:"X12_277_BUILD_INVALID_SPEC"="X12_277_BUILD_INVALID_SPEC"
Example
import { CLAIM_STATUS_277_BUILD_ERROR_CODES, ClaimStatus277BuildError, build277 } from "@cosyte/x12";
try {
build277(spec);
} catch (err) {
if (
err instanceof ClaimStatus277BuildError &&
err.code === CLAIM_STATUS_277_BUILD_ERROR_CODES.X12_277_BUILD_INVALID_HIERARCHY
) {
// the hierarchy is impossible - fix the tree, do not emit
}
}
CLAIM_STATUS_CATEGORY_CODES
constCLAIM_STATUS_CATEGORY_CODES:CodeListSnapshot
Bundled Claim Status Category Code (CSCC) snapshot. Used by the 277 and 277CA helpers to surface a human-readable category alongside each verbatim CSCC parsed from an STC composite.
Example
import { CLAIM_STATUS_CATEGORY_CODES } from "@cosyte/x12";
CLAIM_STATUS_CATEGORY_CODES.codes["A2"]; // "Acknowledgement/Acceptance into adjudication system"
CLAIM_STATUS_CATEGORY_CODES.codes["F2"]; // "Finalized/Denial"
CLAIM_STATUS_CODES
constCLAIM_STATUS_CODES:CodeListSnapshot
Bundled Claim Status Code (CSC) snapshot. Used by the 277 and 277CA helpers to surface a human-readable status alongside each verbatim CSC parsed from an STC composite.
Example
import { CLAIM_STATUS_CODES } from "@cosyte/x12";
CLAIM_STATUS_CODES.codes["20"]; // "Accepted for processing."
CLAIM_STATUS_CODES.codes["21"]; // "Missing or invalid information."
CLP_STATUS
constCLP_STATUS:CodeListSnapshot
Bundled CLP-02 (Claim Status) snapshot. Used by the 835 helper to surface a human-readable description alongside the verbatim disposition code.
Example
import { CLP_STATUS } from "@cosyte/x12";
CLP_STATUS.codes["1"]; // "Processed as Primary"
CLP_STATUS.codes["4"]; // "Denied"
CONTROL_NUMBER_PAIRS
constCONTROL_NUMBER_PAIRS:object
Which header/trailer control-number pair disagreed. A library-owned discriminant, NOT a value read out of the document: the useful part of the diagnostic is that the two disagree and where each one sits, never what either one says.
Type Declaration
GROUP
readonlyGROUP:"group"="group"
GS-06 against GE-02.
INTERCHANGE
readonlyINTERCHANGE:"interchange"="interchange"
ISA-13 against IEA-02.
TRANSACTION
readonlyTRANSACTION:"transaction"="transaction"
ST-02 against SE-02.
Example
import { controlNumberMismatch, CONTROL_NUMBER_PAIRS } from "@cosyte/x12";
const w = controlNumberMismatch({ segmentIndex: 6 }, CONTROL_NUMBER_PAIRS.INTERCHANGE);
DELIMITER_POSITIONS
constDELIMITER_POSITIONS:object
Internal
Zero-indexed byte positions of the four delimiter classes inside the 106-byte ISA. Locked by ASC X12 .5; do NOT make these configurable.
elementat byte 3 - the byte immediately after the literal"ISA".repetitionat byte 82 - ISA-11 (the Control Standards Identifier slot, repurposed as the repetition separator in 005010+).componentat byte 104 - ISA-16 (the LAST element).segmentat byte 105 - the byte immediately after ISA-16.
Type Declaration
component
readonlycomponent:104=104
element
readonlyelement:3=3
repetition
readonlyrepetition:82=82
segment
readonlysegment:105=105
Example
import { DELIMITER_POSITIONS } from "@cosyte/x12";
// The element separator is always the 4th byte of a well-formed ISA:
raw.charAt(DELIMITER_POSITIONS.element); // e.g. "*"
ELIGIBILITY_271_BUILD_ERROR_CODES
constELIGIBILITY_271_BUILD_ERROR_CODES:object
Stable string codes for every Eligibility271BuildError. Locked
here so consumers can narrow exhaustively on err.code; additions-only
thereafter (renaming any code is a breaking change).
X12_271_BUILD_INVALID_HIERARCHY- the nested tree cannot form a valid 271 HL spine (no information sources, a source with no receiver, a receiver with no subscriber). The message carries structural indices + counts only - never a member id / name (PHI discipline).X12_271_BUILD_INVALID_SPEC- a non-hierarchy precondition failed (an over-long ISA-13 interchange control number).
Type Declaration
X12_271_BUILD_INVALID_HIERARCHY
readonlyX12_271_BUILD_INVALID_HIERARCHY:"X12_271_BUILD_INVALID_HIERARCHY"="X12_271_BUILD_INVALID_HIERARCHY"
X12_271_BUILD_INVALID_SPEC
readonlyX12_271_BUILD_INVALID_SPEC:"X12_271_BUILD_INVALID_SPEC"="X12_271_BUILD_INVALID_SPEC"
Example
import { ELIGIBILITY_271_BUILD_ERROR_CODES, Eligibility271BuildError, build271 } from "@cosyte/x12";
try {
build271(spec);
} catch (err) {
if (
err instanceof Eligibility271BuildError &&
err.code === ELIGIBILITY_271_BUILD_ERROR_CODES.X12_271_BUILD_INVALID_HIERARCHY
) {
// the hierarchy is impossible - fix the tree, do not emit
}
}
ELIGIBILITY_271_LOOP_2000A
constELIGIBILITY_271_LOOP_2000A:LoopSpec
271 Loop 2000A - Information Source HL (payer). Triggered by HL
(HL-03 = "20"); the level-code check happens in the walker. Nests the
Loop 2100A payer name.
Example
import { ELIGIBILITY_271_LOOP_2000A } from "@cosyte/x12";
ELIGIBILITY_271_LOOP_2000A.trigger; // "HL"
ELIGIBILITY_271_LOOP_2000B
constELIGIBILITY_271_LOOP_2000B:LoopSpec
271 Loop 2000B - Information Receiver HL (provider). Triggered by HL
(HL-03 = "21"). Carries the receiver NM1 + optional REF/N3/N4/PER and
request-validation AAA segments.
Example
import { ELIGIBILITY_271_LOOP_2000B } from "@cosyte/x12";
ELIGIBILITY_271_LOOP_2000B.id; // "2000B"
ELIGIBILITY_271_LOOP_2000C
constELIGIBILITY_271_LOOP_2000C:LoopSpec
271 Loop 2000C - Subscriber HL. Triggered by HL (HL-03 = "22").
Carries the echoed subscriber TRN traces and nests
ELIGIBILITY_271_LOOP_2100C.
Example
import { ELIGIBILITY_271_LOOP_2000C } from "@cosyte/x12";
ELIGIBILITY_271_LOOP_2000C.children[0]?.id; // "2100C"
ELIGIBILITY_271_LOOP_2000D
constELIGIBILITY_271_LOOP_2000D:LoopSpec
271 Loop 2000D - Dependent HL. Triggered by HL (HL-03 = "23").
Carries the echoed dependent TRN traces and nests
ELIGIBILITY_271_LOOP_2100D.
Example
import { ELIGIBILITY_271_LOOP_2000D } from "@cosyte/x12";
ELIGIBILITY_271_LOOP_2000D.id; // "2000D"
ELIGIBILITY_271_LOOP_2100C
constELIGIBILITY_271_LOOP_2100C:LoopSpec
271 Loop 2100C - Subscriber Name. Triggered by NM1 (NM1-01 = "IL");
the qualifier check happens in the walker, not the spec. Nests
ELIGIBILITY_271_LOOP_2110.
Example
import { ELIGIBILITY_271_LOOP_2100C } from "@cosyte/x12";
ELIGIBILITY_271_LOOP_2100C.children[0]?.trigger; // "EB"
ELIGIBILITY_271_LOOP_2100D
constELIGIBILITY_271_LOOP_2100D:LoopSpec
271 Loop 2100D - Dependent Name. Triggered by NM1 (NM1-01 = "03").
Same shape as 2100C; nests ELIGIBILITY_271_LOOP_2110.
Example
import { ELIGIBILITY_271_LOOP_2100D } from "@cosyte/x12";
ELIGIBILITY_271_LOOP_2100D.id; // "2100D"
ELIGIBILITY_271_LOOP_2110
constELIGIBILITY_271_LOOP_2110:LoopSpec
271 Loop 2110 - Eligibility or Benefit Information. Triggered by EB.
Reused under both the subscriber (2110C) and dependent (2110D) name
loops - the segment shape is identical.
Example
import { ELIGIBILITY_271_LOOP_2110 } from "@cosyte/x12";
ELIGIBILITY_271_LOOP_2110.trigger; // "EB"
ENROLLMENT_834_BUILD_ERROR_CODES
constENROLLMENT_834_BUILD_ERROR_CODES:object
Stable string codes for every Enrollment834BuildError. Locked here
so consumers can narrow exhaustively on err.code; additions-only
thereafter (renaming any code is a breaking change).
X12_834_BUILD_UNKNOWN_MAINTENANCE_TYPE- anINS-03orHD-01maintenance type code falls outside the X12 Code Source 875 subset the library validates against. The message carries the structural index of the affected member / coverage and the offending code (an X12 control code, never PHI).X12_834_BUILD_INVALID_SPEC- a non-maintenance precondition failed: no member loop, an empty (required)INS-03, or an over-long ISA-13 interchange control number. The message carries structural indices + counts only - never a member id / name (PHI discipline).
Type Declaration
X12_834_BUILD_INVALID_SPEC
readonlyX12_834_BUILD_INVALID_SPEC:"X12_834_BUILD_INVALID_SPEC"="X12_834_BUILD_INVALID_SPEC"
X12_834_BUILD_UNKNOWN_MAINTENANCE_TYPE
readonlyX12_834_BUILD_UNKNOWN_MAINTENANCE_TYPE:"X12_834_BUILD_UNKNOWN_MAINTENANCE_TYPE"="X12_834_BUILD_UNKNOWN_MAINTENANCE_TYPE"
Example
import { ENROLLMENT_834_BUILD_ERROR_CODES, Enrollment834BuildError, build834 } from "@cosyte/x12";
try {
build834(spec);
} catch (err) {
if (
err instanceof Enrollment834BuildError &&
err.code === ENROLLMENT_834_BUILD_ERROR_CODES.X12_834_BUILD_UNKNOWN_MAINTENANCE_TYPE
) {
// the maintenance action is unrecognized - fix the code, do not emit
}
}
ENROLLMENT_834_LOOP_1000A
constENROLLMENT_834_LOOP_1000A:LoopSpec
834 Loop 1000A - Sponsor Name. Triggered by N1 with N1-01 = "P5".
Example
import { ENROLLMENT_834_LOOP_1000A } from "@cosyte/x12";
ENROLLMENT_834_LOOP_1000A.id; // "1000A"
ENROLLMENT_834_LOOP_1000B
constENROLLMENT_834_LOOP_1000B:LoopSpec
834 Loop 1000B - Payer. Triggered by N1 with N1-01 = "IN".
Example
import { ENROLLMENT_834_LOOP_1000B } from "@cosyte/x12";
ENROLLMENT_834_LOOP_1000B.id; // "1000B"
ENROLLMENT_834_LOOP_2000
constENROLLMENT_834_LOOP_2000:LoopSpec
834 Loop 2000 - Member Level Detail. Triggered by INS. The streaming
unit of "./get-834.js".get834Enrollments - one yielded
X12Enrollment per INS. Nests Loop 2100A (member name) and Loop 2300
(health coverage).
Example
import { ENROLLMENT_834_LOOP_2000 } from "@cosyte/x12";
ENROLLMENT_834_LOOP_2000.trigger; // "INS"
ENROLLMENT_834_LOOP_2000.children.map((c) => c.trigger); // ["NM1", "HD"]
ENROLLMENT_834_LOOP_2100A
constENROLLMENT_834_LOOP_2100A:LoopSpec
834 Loop 2100A - Member Name. Triggered by NM1 with NM1-01 = "IL".
Example
import { ENROLLMENT_834_LOOP_2100A } from "@cosyte/x12";
ENROLLMENT_834_LOOP_2100A.trigger; // "NM1"
ENROLLMENT_834_LOOP_2300
constENROLLMENT_834_LOOP_2300:LoopSpec
834 Loop 2300 - Health Coverage. Triggered by HD. Nests Loop 2320.
Example
import { ENROLLMENT_834_LOOP_2300 } from "@cosyte/x12";
ENROLLMENT_834_LOOP_2300.trigger; // "HD"
ENROLLMENT_834_LOOP_2300.children[0]?.trigger; // "COB"
ENROLLMENT_834_LOOP_2320
constENROLLMENT_834_LOOP_2320:LoopSpec
834 Loop 2320 - Coordination of Benefits. Triggered by COB.
Example
import { ENROLLMENT_834_LOOP_2320 } from "@cosyte/x12";
ENROLLMENT_834_LOOP_2320.trigger; // "COB"
FATAL_CODES
constFATAL_CODES:object
Stable string codes for every Tier-3 fatal parseX12 may throw. Phase 1
locks the registry at four codes: anything else MUST be a Tier-2 warning.
Consumers narrow on err.code to react to specific structural failures.
Type Declaration
X12_EMPTY_INPUT
readonlyX12_EMPTY_INPUT:"X12_EMPTY_INPUT"="X12_EMPTY_INPUT"
X12_INVALID_DELIMITERS
readonlyX12_INVALID_DELIMITERS:"X12_INVALID_DELIMITERS"="X12_INVALID_DELIMITERS"
X12_ISA_TOO_SHORT
readonlyX12_ISA_TOO_SHORT:"X12_ISA_TOO_SHORT"="X12_ISA_TOO_SHORT"
X12_NO_ISA_HEADER
readonlyX12_NO_ISA_HEADER:"X12_NO_ISA_HEADER"="X12_NO_ISA_HEADER"
Example
import { parseX12, FATAL_CODES, X12ParseError } from "@cosyte/x12";
try {
parseX12("");
} catch (err) {
if (err instanceof X12ParseError && err.code === FATAL_CODES.X12_EMPTY_INPUT) {
// handle empty input
}
}
HI_QUALIFIERS
constHI_QUALIFIERS:object
The HI qualifier → (X12HiCodeSystem + X12HiCategory)
registry. Frozen with as const so the keyset is type-narrowed for
downstream consumers. Each entry cites its TR3 use site in the
description so a reviewer can confirm against the source.
Snapshot covers the qualifiers cited across 837P/I/D TR3s plus the most common NUBC code-set qualifiers. Additions are non-breaking; renames or removals are breaking and require a public-surface bump.
Type Declaration
ABF
readonlyABF:object
ABF.category
readonlycategory:"diagnosis"="diagnosis"
ABF.description
readonlydescription:"Other (secondary) diagnosis, ICD-10-CM."="Other (secondary) diagnosis, ICD-10-CM."
ABF.system
readonlysystem:"ICD-10-CM"="ICD-10-CM"
ABJ
readonlyABJ:object
ABJ.category
readonlycategory:"admitting-diagnosis"="admitting-diagnosis"
ABJ.description
readonlydescription:"Admitting diagnosis, ICD-10-CM (837I inpatient)."="Admitting diagnosis, ICD-10-CM (837I inpatient)."
ABJ.system
readonlysystem:"ICD-10-CM"="ICD-10-CM"
ABK
readonlyABK:object
ABK.category
readonlycategory:"principal-diagnosis"="principal-diagnosis"
ABK.description
readonlydescription:"Principal diagnosis, ICD-10-CM (837I; 837P uses ABK in HI-01 for the principal)."="Principal diagnosis, ICD-10-CM (837I; 837P uses ABK in HI-01 for the principal)."
ABK.system
readonlysystem:"ICD-10-CM"="ICD-10-CM"
ABN
readonlyABN:object
ABN.category
readonlycategory:"patient-reason-for-visit"="patient-reason-for-visit"
ABN.description
readonlydescription:"Patient's reason for visit, ICD-10-CM (837I outpatient)."="Patient's reason for visit, ICD-10-CM (837I outpatient)."
ABN.system
readonlysystem:"ICD-10-CM"="ICD-10-CM"
APR
readonlyAPR:object
APR.category
readonlycategory:"external-cause"="external-cause"
APR.description
readonlydescription:"External cause of injury, ICD-10-CM (V-Y codes)."="External cause of injury, ICD-10-CM (V-Y codes)."
APR.system
readonlysystem:"ICD-10-CM"="ICD-10-CM"
BBA
readonlyBBA:object
BBA.category
readonlycategory:"procedure"="procedure"
BBA.description
readonlydescription:"Other procedure, ICD-9-PCS (legacy; replaced by BBR)."="Other procedure, ICD-9-PCS (legacy; replaced by BBR)."
BBA.system
readonlysystem:"ICD-9-PCS"="ICD-9-PCS"
BBQ
readonlyBBQ:object
BBQ.category
readonlycategory:"treatment"="treatment"
BBQ.description
readonlydescription:"Principal procedure, ICD-10-PCS (837I)."="Principal procedure, ICD-10-PCS (837I)."
BBQ.system
readonlysystem:"ICD-10-PCS"="ICD-10-PCS"
BBR
readonlyBBR:object
BBR.category
readonlycategory:"procedure"="procedure"
BBR.description
readonlydescription:"Other (secondary) procedure, ICD-10-PCS (837I)."="Other (secondary) procedure, ICD-10-PCS (837I)."
BBR.system
readonlysystem:"ICD-10-PCS"="ICD-10-PCS"
BE
readonlyBE:object
BE.category
readonlycategory:"value"="value"
BE.description
readonlydescription:"Value code (NUBC FL 39-41) - paired amount in HI-NN-5 as decimal."="Value code (NUBC FL 39-41) - paired amount in HI-NN-5 as decimal."
BE.system
readonlysystem:"NUBC-VALUE"="NUBC-VALUE"
BF
readonlyBF:object
BF.category
readonlycategory:"diagnosis"="diagnosis"
BF.description
readonlydescription:"Other diagnosis, ICD-9-CM (legacy; replaced by ABF)."="Other diagnosis, ICD-9-CM (legacy; replaced by ABF)."
BF.system
readonlysystem:"ICD-9-CM"="ICD-9-CM"
BG
readonlyBG:object
BG.category
readonlycategory:"condition"="condition"
BG.description
readonlydescription:"Condition code (NUBC FL 18-28)."="Condition code (NUBC FL 18-28)."
BG.system
readonlysystem:"NUBC-CONDITION"="NUBC-CONDITION"
BH
readonlyBH:object
BH.category
readonlycategory:"occurrence"="occurrence"
BH.description
readonlydescription:"Occurrence code (NUBC FL 31-34) - date paired in HI-NN-4."="Occurrence code (NUBC FL 31-34) - date paired in HI-NN-4."
BH.system
readonlysystem:"NUBC-OCCURRENCE"="NUBC-OCCURRENCE"
BI
readonlyBI:object
BI.category
readonlycategory:"occurrence-span"="occurrence-span"
BI.description
readonlydescription:"Occurrence span code (NUBC FL 35-36) - date range in HI-NN-5/6."="Occurrence span code (NUBC FL 35-36) - date range in HI-NN-5/6."
BI.system
readonlysystem:"NUBC-OCCURRENCE-SPAN"="NUBC-OCCURRENCE-SPAN"
BJ
readonlyBJ:object
BJ.category
readonlycategory:"admitting-diagnosis"="admitting-diagnosis"
BJ.description
readonlydescription:"Admitting diagnosis, ICD-9-CM (legacy; replaced by ABJ)."="Admitting diagnosis, ICD-9-CM (legacy; replaced by ABJ)."
BJ.system
readonlysystem:"ICD-9-CM"="ICD-9-CM"
BK
readonlyBK:object
BK.category
readonlycategory:"principal-diagnosis"="principal-diagnosis"
BK.description
readonlydescription:"Principal diagnosis, ICD-9-CM (legacy; replaced by ABK 2015-10-01 onward)."="Principal diagnosis, ICD-9-CM (legacy; replaced by ABK 2015-10-01 onward)."
BK.system
readonlysystem:"ICD-9-CM"="ICD-9-CM"
BN
readonlyBN:object
BN.category
readonlycategory:"patient-reason-for-visit"="patient-reason-for-visit"
BN.description
readonlydescription:"Reason for visit, ICD-9-CM (legacy; replaced by ABN)."="Reason for visit, ICD-9-CM (legacy; replaced by ABN)."
BN.system
readonlysystem:"ICD-9-CM"="ICD-9-CM"
BQ
readonlyBQ:object
BQ.category
readonlycategory:"treatment"="treatment"
BQ.description
readonlydescription:"Principal procedure, ICD-9-PCS (legacy; replaced by BBQ)."="Principal procedure, ICD-9-PCS (legacy; replaced by BBQ)."
BQ.system
readonlysystem:"ICD-9-PCS"="ICD-9-PCS"
BR
readonlyBR:object
BR.category
readonlycategory:"external-cause"="external-cause"
BR.description
readonlydescription:"External cause of injury, ICD-9-CM (legacy; replaced by APR)."="External cause of injury, ICD-9-CM (legacy; replaced by APR)."
BR.system
readonlysystem:"ICD-9-CM"="ICD-9-CM"
DR
readonlyDR:object
DR.category
readonlycategory:"drg"="drg"
DR.description
readonlydescription:"Diagnosis Related Group (DRG) - payment-grouping code."="Diagnosis Related Group (DRG) - payment-grouping code."
DR.system
readonlysystem:"DRG"="DRG"
PR
readonlyPR:object
PR.category
readonlycategory:"patient-reason-for-visit"="patient-reason-for-visit"
PR.description
readonlydescription:"Patient reason for visit (837I outpatient secondary code; ICD-10-CM coded)."="Patient reason for visit (837I outpatient secondary code; ICD-10-CM coded)."
PR.system
readonlysystem:"NUBC-PATIENT-REASON"="NUBC-PATIENT-REASON"
Example
import { HI_QUALIFIERS, resolveHiQualifier } from "@cosyte/x12";
HI_QUALIFIERS.ABK.system; // "ICD-10-CM"
resolveHiQualifier("ABK"); // { system: "ICD-10-CM", category: "principal-diagnosis", ... }
resolveHiQualifier("ZZZ"); // undefined
HL_LEVEL_CODES
constHL_LEVEL_CODES:Readonly<{DEPENDENT:"23";INFORMATION_RECEIVER:"21";INFORMATION_SOURCE:"20";SUBSCRIBER:"22"; }>
HL level codes per X12 0736 + 837 TR3 conventions. INFORMATION_SOURCE
is the billing provider (top of the tree); SUBSCRIBER is the
insurance subscriber; DEPENDENT is a non-subscriber patient.
Example
import { HL_LEVEL_CODES } from "@cosyte/x12";
HL_LEVEL_CODES.INFORMATION_SOURCE; // "20"
HL_LEVEL_CODES.SUBSCRIBER; // "22"
HL_LEVEL_CODES.DEPENDENT; // "23"
IK3_SYNTAX_ERROR_CODES
constIK3_SYNTAX_ERROR_CODES:object
IK3-04 implementation segment syntax error codes (ASC X12 code list 716). Cited per IK3 segment to identify the structural issue against the inbound segment. The library NEVER auto-classifies - the application supplies the code; the library mechanically builds the IK3 around it.
1- Unrecognized segment ID.2- Unexpected segment.3- Required segment missing.4- Loop occurs over maximum times.5- Segment exceeds maximum use.6- Segment not in defined transaction set.7- Segment not in proper sequence.8- Segment has data element errors.I4- Implementation "Not Used" segment present.I6- Implementation dependent segment missing.I7- Implementation loop occurs under minimum times.I8- Implementation segment below minimum use.I9- Implementation dependent "Not Used" segment present.
Type Declaration
1
readonly1:"1"="1"
2
readonly2:"2"="2"
3
readonly3:"3"="3"
4
readonly4:"4"="4"
5
readonly5:"5"="5"
6
readonly6:"6"="6"
7
readonly7:"7"="7"
8
readonly8:"8"="8"
I4
readonlyI4:"I4"="I4"
I6
readonlyI6:"I6"="I6"
I7
readonlyI7:"I7"="I7"
I8
readonlyI8:"I8"="I8"
I9
readonlyI9:"I9"="I9"
Example
import type { Ik304Code } from "@cosyte/x12";
const required: Ik304Code = "3";
IK4_SYNTAX_ERROR_CODES
constIK4_SYNTAX_ERROR_CODES:object
IK4-03 implementation data element syntax error codes (ASC X12 code list 723). Cited per IK4 segment to identify the issue against the inbound element/component/repetition.
1- Required data element missing.2- Conditional required data element missing.3- Too many data elements.4- Data element too short.5- Data element too long.6- Invalid character in data element.7- Invalid code value.8- Invalid date.9- Invalid time.10- Exclusion condition violated.12- Too many repetitions.13- Too many components.I6- Code value not used in implementation.I9- Implementation dependent data element missing.I10- Implementation "Not Used" data element present.I11- Implementation too few repetitions.I12- Implementation pattern match failure.I13- Implementation dependent "Not Used" data element present.
Type Declaration
1
readonly1:"1"="1"
10
readonly10:"10"="10"
12
readonly12:"12"="12"
13
readonly13:"13"="13"
2
readonly2:"2"="2"
3
readonly3:"3"="3"
4
readonly4:"4"="4"
5
readonly5:"5"="5"
6
readonly6:"6"="6"
7
readonly7:"7"="7"
8
readonly8:"8"="8"
9
readonly9:"9"="9"
I10
readonlyI10:"I10"="I10"
I11
readonlyI11:"I11"="I11"
I12
readonlyI12:"I12"="I12"
I13
readonlyI13:"I13"="I13"
I6
readonlyI6:"I6"="I6"
I9
readonlyI9:"I9"="I9"
Example
import type { Ik403Code } from "@cosyte/x12";
const tooShort: Ik403Code = "4";
ISA_MIN_LENGTH
constISA_MIN_LENGTH:106=106
Minimum number of bytes a valid ISA segment occupies. ASC X12 .5 fixes
the ISA at 106 bytes total, including the trailing segment
terminator: 3 ("ISA") + 16 element separators + 86 element-value bytes
(sum of fixed widths 2+10+2+10+2+15+2+15+6+4+1+5+9+1+1+1) + 1
terminator = 106. Anything shorter cannot carry the 16 ISA elements and
is Tier-3 X12_ISA_TOO_SHORT.
Example
import { ISA_MIN_LENGTH } from "@cosyte/x12";
ISA_MIN_LENGTH; // 106 - a raw interchange shorter than this is X12_ISA_TOO_SHORT
lookupCarc
constlookupCarc: (code) =>CodeListEntry|undefined
Look up a CARC code's bundled description. Returns undefined when
the code is not in the initial subset - the verbatim code is still
preserved on the parsed model and the 835 walker emits
X12_UNKNOWN_CARC so consumers know the description gap exists.
Parameters
code
string
Returns
CodeListEntry | undefined
Example
import { lookupCarc } from "@cosyte/x12";
lookupCarc("45")?.description; // "Charge exceeds fee schedule..."
lookupCarc("9999"); // undefined (outside the bundled subset)
lookupClaimStatus
constlookupClaimStatus: (code) =>CodeListEntry|undefined
Look up a Claim Status Code (CSC) description from the bundled snapshot.
Returns undefined for codes outside the subset; the verbatim code is
always preserved on the parsed status model.
Parameters
code
string
Returns
CodeListEntry | undefined
Example
import { lookupClaimStatus } from "@cosyte/x12";
lookupClaimStatus("20")?.description; // "Accepted for processing."
lookupClaimStatus("99999"); // undefined (outside subset)
lookupClaimStatusCategory
constlookupClaimStatusCategory: (code) =>CodeListEntry|undefined
Look up a Claim Status Category Code (CSCC) description from the bundled
snapshot. Returns undefined for codes outside the subset; the verbatim
code is always preserved on the parsed status model.
Parameters
code
string
Returns
CodeListEntry | undefined
Example
import { lookupClaimStatusCategory } from "@cosyte/x12";
lookupClaimStatusCategory("A2")?.description; // "Acknowledgement/Acceptance..."
lookupClaimStatusCategory("ZZ"); // undefined (outside subset)
lookupClpStatus
constlookupClpStatus: (code) =>CodeListEntry|undefined
Look up a CLP-02 claim status code's bundled description. Returns
undefined for codes outside the initial subset; the verbatim code is
still preserved on the parsed claim model.
Parameters
code
string
Returns
CodeListEntry | undefined
Example
import { lookupClpStatus } from "@cosyte/x12";
lookupClpStatus("1")?.description; // "Processed as Primary"
lookupClpStatus("99"); // undefined (outside subset)
lookupMaintenanceType
constlookupMaintenanceType: (code) =>CodeListEntry|undefined
Look up an INS-03 maintenance type code's bundled description. Returns
undefined for codes outside the subset; the verbatim code is still
preserved on the parsed enrollment, and the 834 helper raises an
X12_834_UNKNOWN_MAINTENANCE_TYPE warning so a consumer never silently
mis-applies an unknown action.
Parameters
code
string
Returns
CodeListEntry | undefined
Example
import { lookupMaintenanceType } from "@cosyte/x12";
lookupMaintenanceType("024")?.description; // "Cancellation or Termination"
lookupMaintenanceType("999"); // undefined (outside subset)
lookupRarc
constlookupRarc: (code) =>CodeListEntry|undefined
Look up a RARC code's bundled description. Same fail-safe semantics as
"./carc.js".lookupCarc: unknown codes return undefined, the
verbatim code is preserved on the parsed model, and the 835 walker
emits X12_UNKNOWN_RARC.
Parameters
code
string
Returns
CodeListEntry | undefined
Example
import { lookupRarc } from "@cosyte/x12";
lookupRarc("N4")?.description; // "Missing/incomplete/invalid prior insurance carrier(s) EOB."
lookupServiceType
constlookupServiceType: (code) =>CodeListEntry|undefined
Look up a Service Type Code (EB-03) description from the bundled
snapshot. Returns undefined for codes outside the initial subset; the
verbatim code is still preserved on the parsed benefit model.
Parameters
code
string
Returns
CodeListEntry | undefined
Example
import { lookupServiceType } from "@cosyte/x12";
lookupServiceType("30")?.description; // "Health Benefit Plan Coverage"
lookupServiceType("ZZ"); // undefined (outside subset)
MAINTENANCE_TYPE_CODES
constMAINTENANCE_TYPE_CODES:CodeListSnapshot
Bundled INS-03 (Maintenance Type) snapshot. Used by the 834 helper to
surface a human-readable description alongside the verbatim maintenance
code, and to drive the X12_834_UNKNOWN_MAINTENANCE_TYPE warning when a
code falls outside this set.
Example
import { MAINTENANCE_TYPE_CODES } from "@cosyte/x12";
MAINTENANCE_TYPE_CODES.codes["021"]; // "Addition"
MAINTENANCE_TYPE_CODES.codes["024"]; // "Cancellation or Termination"
NM1_QUALIFIERS
constNM1_QUALIFIERS:Readonly<{BILLING_PROVIDER:"85";PATIENT:"QC";PAY_TO_ADDRESS:"87";PAY_TO_PLAN:"PE";PAYER:"PR";RECEIVER:"40";SUBMITTER:"41";SUBSCRIBER:"IL"; }>
NM1-01 entity-identifier codes used by the 837 walker to route an NM1 onto the right entity slot. Curated to the qualifiers the v1 walker recognizes; an NM1 with a qualifier outside this set falls into the Loop 2310x / 2420x line-provider verbatim bucket. Frozen for type safety + IntelliSense - consumers should rarely need these (they're a walker-internal vocabulary), but they're exported for tests + the Phase 8 builder API.
Example
NM1_QUALIFIERS.BILLING_PROVIDER → "85".
NON_SPEC_SEGMENT_ID
constNON_SPEC_SEGMENT_ID:"(non-spec)"="(non-spec)"
The value X12Segment.id takes when the first element does not
match the X12 segment-id grammar. Not a valid segment id, so it can
never collide with a real one in a seg.id === "NM1" comparison.
Example
import { parseX12, NON_SPEC_SEGMENT_ID } from "@cosyte/x12";
const seg = parseX12(raw).groups[0]?.transactions[0]?.segments[1];
if (seg?.id === NON_SPEC_SEGMENT_ID) {
// the sender's "segment" name is not a spec segment id; its bytes are on seg.raw
}
PREMIUM_820_BUILD_ERROR_CODES
constPREMIUM_820_BUILD_ERROR_CODES:object
Stable string codes for every Premium820BuildError. Locked here so
consumers can narrow exhaustively on err.code; additions-only thereafter
(renaming any code is a breaking change).
X12_820_BUILD_INVALID_SPEC- a structural precondition failed: no TRN trace, no remittance loop, a remittance with neither anENTentity nor anNM1individual to open it, a remittance with noRMRopen item, an open item with no identity (empty qualifier + reference id), or an over-long ISA-13 interchange control number. The message carries structural indices + counts only - never a member id / name (PHI discipline).
Type Declaration
X12_820_BUILD_INVALID_SPEC
readonlyX12_820_BUILD_INVALID_SPEC:"X12_820_BUILD_INVALID_SPEC"="X12_820_BUILD_INVALID_SPEC"
Example
import { PREMIUM_820_BUILD_ERROR_CODES, Premium820BuildError, build820 } from "@cosyte/x12";
try {
build820(spec);
} catch (err) {
if (
err instanceof Premium820BuildError &&
err.code === PREMIUM_820_BUILD_ERROR_CODES.X12_820_BUILD_INVALID_SPEC
) {
// the remittance structure is impossible - fix the spec, do not emit
}
}
PREMIUM_820_LOOP_1000A
constPREMIUM_820_LOOP_1000A:LoopSpec
820 Loop 1000A - Premium Receiver's Name. Triggered by N1 with
N1-01 = "PE". The qualifier check happens in the walker;
defineLoopSpec keys off the segment id, not the element value.
Example
import { PREMIUM_820_LOOP_1000A } from "@cosyte/x12";
PREMIUM_820_LOOP_1000A.id; // "1000A"
PREMIUM_820_LOOP_1000B
constPREMIUM_820_LOOP_1000B:LoopSpec
820 Loop 1000B - Premium Payer's Name (remitter). Triggered by N1 with
N1-01 = "PR" or "RM". Same shape as Loop 1000A minus RDM.
Example
import { PREMIUM_820_LOOP_1000B } from "@cosyte/x12";
PREMIUM_820_LOOP_1000B.id; // "1000B"
PREMIUM_820_LOOP_2000A
constPREMIUM_820_LOOP_2000A:LoopSpec
820 Loop 2000A - Organization Summary Remittance. Triggered by ENT.
Nests Loop 2100A (party name) and Loop 2300A (remittance detail).
Cited as Loop 2000A in TR3 X218.
Example
import { PREMIUM_820_LOOP_2000A } from "@cosyte/x12";
PREMIUM_820_LOOP_2000A.trigger; // "ENT"
PREMIUM_820_LOOP_2000A.children.length; // 2 (2100A, 2300A)
PREMIUM_820_LOOP_2100A
constPREMIUM_820_LOOP_2100A:LoopSpec
820 Loop 2100A - Party Name (member / entity inside an organization
summary). Triggered by NM1.
Cited as Loop 2100A in TR3 X218.
Example
import { PREMIUM_820_LOOP_2100A } from "@cosyte/x12";
PREMIUM_820_LOOP_2100A.trigger; // "NM1"
PREMIUM_820_LOOP_2300A
constPREMIUM_820_LOOP_2300A:LoopSpec
820 Loop 2300A - Organization Summary Remittance Detail. Triggered by
RMR (the premium-line open-item reference). Nests Loop 2310A.
Cited as Loop 2300A in TR3 X218.
Example
import { PREMIUM_820_LOOP_2300A } from "@cosyte/x12";
PREMIUM_820_LOOP_2300A.trigger; // "RMR"
PREMIUM_820_LOOP_2300A.children[0]?.trigger; // "ADX"
PREMIUM_820_LOOP_2310A
constPREMIUM_820_LOOP_2310A:LoopSpec
820 Loop 2310A - Adjustment. Triggered by ADX. Innermost detail loop:
a signed monetary adjustment tied to the enclosing RMR open item.
Cited as Loop 2310A in TR3 X218.
Example
import { PREMIUM_820_LOOP_2310A } from "@cosyte/x12";
PREMIUM_820_LOOP_2310A.trigger; // "ADX"
profiles
constprofiles:object
Namespace object exposing the shipped built-in profiles. Each is authored
via the public defineProfile() API and grounded in a real Tier-2 fixture.
Type Declaration
availity
readonlyavaility:X12Profile
bcbsCommon
readonlybcbsCommon:X12Profile
Example
import { parseX12, profiles } from "@cosyte/x12";
const ix = parseX12(raw, { profile: profiles.availity });
ix.profile?.name; // "availity"
RARC
constRARC:CodeListSnapshot
Bundled RARC snapshot. Companion to "./carc.js".CARC; same freshness + safety posture. Use lookupRarc for the ergonomic lookup.
Example
import { RARC } from "@cosyte/x12";
RARC.codes["N4"]; // "Missing/incomplete/invalid prior insurance carrier(s) EOB."
RARC.codes["MA01"]; // (or undefined if outside this subset)
RELEASE_CHAR
constRELEASE_CHAR:"?"
Internal
The release character is conventionally ? per ASC X12; HIPAA 005010
does not transmit it as a fifth ISA delimiter. The library accepts ? as
the universal release character - a non-? release sequence has never
been observed in real-world US healthcare X12 traffic. If a future
consumer needs a different release character, the constant is as const
so a parameterized variant can be added without breaking the public API.
Example
import { RELEASE_CHAR } from "@cosyte/x12";
// `?~` is an escaped segment terminator inside a value, not a real one:
"PER*IC*ACME?~BILLING".includes(RELEASE_CHAR); // true
REMIT_835_BUILD_ERROR_CODES
constREMIT_835_BUILD_ERROR_CODES:object
Stable string codes for every Remit835BuildError. Locked here so
consumers can narrow exhaustively on err.code; additions-only
thereafter (renaming any code is a breaking change).
X12_835_BUILD_BALANCE_MISMATCH- a spec violated one of the three §1.10.2 balance invariants (service-lineSVC-02 == SVC-03 + Σ(line CAS), claimCLP-03 == CLP-04 + Σ(claim+line CAS), or top-of-remitBPR-02 == Σ(CLP-04) − Σ(PLB)). The message names the invariant, the spec'd vs computed totals, and the delta - numeric values only, never PHI.X12_835_BUILD_INVALID_SPEC- a structural precondition failed (no trace supplied, a claim with no patient-control number, etc.).
Type Declaration
X12_835_BUILD_BALANCE_MISMATCH
readonlyX12_835_BUILD_BALANCE_MISMATCH:"X12_835_BUILD_BALANCE_MISMATCH"="X12_835_BUILD_BALANCE_MISMATCH"
X12_835_BUILD_INVALID_SPEC
readonlyX12_835_BUILD_INVALID_SPEC:"X12_835_BUILD_INVALID_SPEC"="X12_835_BUILD_INVALID_SPEC"
Example
import { REMIT_835_BUILD_ERROR_CODES, Remit835BuildError, build835 } from "@cosyte/x12";
try {
build835(spec);
} catch (err) {
if (
err instanceof Remit835BuildError &&
err.code === REMIT_835_BUILD_ERROR_CODES.X12_835_BUILD_BALANCE_MISMATCH
) {
// the remit does not balance - fix the amounts, do not emit
}
}
REMIT_835_LOOP_1000A
constREMIT_835_LOOP_1000A:LoopSpec
835 Loop 1000A - Payer Identification. Triggered by N1 with
N1-01 = "PR". The trigger validation against the qualifier value
(PR vs PE) happens in the walker, not the loop spec - defineLoopSpec
keys off the segment id, not the element-level qualifier.
Example
import { REMIT_835_LOOP_1000A } from "@cosyte/x12";
REMIT_835_LOOP_1000A.id; // "1000A"
REMIT_835_LOOP_1000A.trigger; // "N1"
REMIT_835_LOOP_1000B
constREMIT_835_LOOP_1000B:LoopSpec
835 Loop 1000B - Payee Identification. Triggered by N1 with
N1-01 = "PE". Shape is the same as Loop 1000A (plus optional RDM)
but the role is the payment recipient.
Example
import { REMIT_835_LOOP_1000B } from "@cosyte/x12";
REMIT_835_LOOP_1000B.id; // "1000B"
REMIT_835_LOOP_2000
constREMIT_835_LOOP_2000:LoopSpec
835 Loop 2000 - Header Number. Triggered by LX. Nests Loop 2100.
Cited as Loop 2000 in TR3 X221A1; situational because some payers
(notably Medicare FFS) omit the LX header entirely and ship CLP loops
directly under the transaction set header. The Phase 4 walker handles
both shapes - claims appear inside Loop 2000 if LX is present, at
top level otherwise.
Example
import { REMIT_835_LOOP_2000 } from "@cosyte/x12";
REMIT_835_LOOP_2000.trigger; // "LX"
REMIT_835_LOOP_2000.children[0]?.trigger; // "CLP" (Loop 2100)
REMIT_835_LOOP_2100
constREMIT_835_LOOP_2100:LoopSpec
835 Loop 2100 - Claim Payment Information. Triggered by CLP. Nests
Loop 2110.
Cited as Loop 2100 in TR3 X221A1.
Example
import { REMIT_835_LOOP_2100 } from "@cosyte/x12";
REMIT_835_LOOP_2100.trigger; // "CLP"
REMIT_835_LOOP_2100.children.length; // 1 (Loop 2110)
REMIT_835_LOOP_2110
constREMIT_835_LOOP_2110:LoopSpec
835 Loop 2110 - Service Payment Information. Triggered by SVC.
Cited as Loop 2110 in TR3 X221A1.
Example
import { REMIT_835_LOOP_2110 } from "@cosyte/x12";
REMIT_835_LOOP_2110.id; // "2110"
REMIT_835_LOOP_2110.trigger; // "SVC"
REQUIRED_LOOPS
constREQUIRED_LOOPS:object
The TR3-required loops the parser reports as structurally absent. A
closed set owned by the loop specs under src/transactions/, so both the
loop id and its rationale are library constants rather than anything read
out of the document.
Type Declaration
BILLING_PROVIDER_2000A
readonlyBILLING_PROVIDER_2000A:"2000A"="2000A"
Loop 2000A, Billing Provider HL.
PAYER_NAME_2010BB
readonlyPAYER_NAME_2010BB:"2010BB"="2010BB"
Loop 2010BB, Payer Name.
SUBSCRIBER_2000B
readonlySUBSCRIBER_2000B:"2000B"="2000B"
Loop 2000B, Subscriber HL.
SUBSCRIBER_NAME_2010BA
readonlySUBSCRIBER_NAME_2010BA:"2010BA"="2010BA"
Loop 2010BA, Subscriber Name.
Example
import { missingRequiredLoop, REQUIRED_LOOPS } from "@cosyte/x12";
const w = missingRequiredLoop({ segmentIndex: 12 }, REQUIRED_LOOPS.PAYER_NAME_2010BB);
SERVICE_TYPE_CODES
constSERVICE_TYPE_CODES:CodeListSnapshot
Bundled Service Type Code (EB-03) snapshot. Used by the 271 helper to surface a human-readable description alongside each verbatim service type code under an eligibility/benefit statement.
Example
import { SERVICE_TYPE_CODES } from "@cosyte/x12";
SERVICE_TYPE_CODES.codes["30"]; // "Health Benefit Plan Coverage"
SERVICE_TYPE_CODES.codes["88"]; // "Pharmacy"
STATUS_277_LOOP_2000A
constSTATUS_277_LOOP_2000A:LoopSpec
277 Loop 2000A - Information Source HL (payer). Triggered by HL
(HL-03 = "20"); the level-code check happens in the walker.
Example
import { STATUS_277_LOOP_2000A } from "@cosyte/x12";
STATUS_277_LOOP_2000A.trigger; // "HL"
STATUS_277_LOOP_2000B
constSTATUS_277_LOOP_2000B:LoopSpec
277 Loop 2000B - Information Receiver HL. Triggered by HL
(HL-03 = "21").
Example
import { STATUS_277_LOOP_2000B } from "@cosyte/x12";
STATUS_277_LOOP_2000B.id; // "2000B"
STATUS_277_LOOP_2000C
constSTATUS_277_LOOP_2000C:LoopSpec
277 Loop 2000C - Service Provider HL. Triggered by HL (HL-03 = "19").
In a 277CA this level can also carry a Loop 2200 batch acknowledgment
(provider-level STC) - nested here as STATUS_277_LOOP_2200.
Example
import { STATUS_277_LOOP_2000C } from "@cosyte/x12";
STATUS_277_LOOP_2000C.children[0]?.id; // "2200"
STATUS_277_LOOP_2000D
constSTATUS_277_LOOP_2000D:LoopSpec
277 Loop 2000D - Subscriber HL. Triggered by HL (HL-03 = "22").
Carries the subscriber name (2100D) and its claim status tracking
(Loop 2200).
Example
import { STATUS_277_LOOP_2000D } from "@cosyte/x12";
STATUS_277_LOOP_2000D.children[0]?.id; // "2200"
STATUS_277_LOOP_2000E
constSTATUS_277_LOOP_2000E:LoopSpec
277 Loop 2000E - Dependent HL. Triggered by HL (HL-03 = "23").
Carries the dependent name (2100E) and its claim status tracking
(Loop 2200).
Example
import { STATUS_277_LOOP_2000E } from "@cosyte/x12";
STATUS_277_LOOP_2000E.id; // "2000E"
STATUS_277_LOOP_2200
constSTATUS_277_LOOP_2200:LoopSpec
277 Loop 2200 - Claim Status Tracking. Triggered by TRN (a 277 claim
status) - in a 277CA provider-level batch acknowledgment the same loop
may open on a standalone STC; the walker handles both. Nests
STATUS_277_LOOP_2220.
Example
import { STATUS_277_LOOP_2200 } from "@cosyte/x12";
STATUS_277_LOOP_2200.children[0]?.trigger; // "SVC"
STATUS_277_LOOP_2220
constSTATUS_277_LOOP_2220:LoopSpec
277 Loop 2220 - Service Line Status Information. Triggered by SVC.
Reused under both the subscriber (2220D) and dependent (2220E) claim
status loops.
Example
import { STATUS_277_LOOP_2220 } from "@cosyte/x12";
STATUS_277_LOOP_2220.trigger; // "SVC"
TA1_ACK_CODES
constTA1_ACK_CODES:object
TA1-04 interchange acknowledgment code (ASC X12 code list I13). Three
values: A accepted, E accepted with errors, R rejected. Distinct
from the 999 disposition (no M/W/X here - TA1 covers only the
interchange envelope, not crypto failures of contained groups).
Type Declaration
A
readonlyA:"A"="A"
E
readonlyE:"E"="E"
R
readonlyR:"R"="R"
Example
import type { Ta1AckCode } from "@cosyte/x12";
const accept: Ta1AckCode = "A";
TA1_NOTE_CODES
constTA1_NOTE_CODES:object
TA1-05 interchange note code (ASC X12 code list I18). Codes 000–028
are defined by the standard; values past 028 exist in some standard
revisions and are accepted on parse (Postel's Law) but not enumerated
here - the parsed model carries the un-narrowed string on noteCodeRaw,
post-?-unescape as of X12-TA1-RESIDUALS. A clause here said "verbatim"
and is deleted rather than reworded; raw.elements[5] is the byte surface.
000 is the canonical "no error" note paired with a TA1-04 == 'A'
acceptance. The build-time safety guard refuses a fabricated A paired
with any non-000 note (see "./errors.js".AckBuildError).
Standard-issued values:
000- No error.001- Interchange Control Number in the Header and Trailer do not match.002- Standard as noted in the Control Standards Identifier is not supported.003- Version of the controls is not supported.004- Segment Terminator is invalid.005- Invalid Interchange ID Qualifier for Sender.006- Invalid Interchange Sender ID.007- Invalid Interchange ID Qualifier for Receiver.008- Invalid Interchange Receiver ID.009- Unknown Interchange Receiver ID.010- Invalid Authorization Information Qualifier value.011- Invalid Authorization Information value.012- Invalid Security Information Qualifier value.013- Invalid Security Information value.014- Invalid Interchange Date value.015- Invalid Interchange Time value.016- Invalid Interchange Standards Identifier value.017- Invalid Interchange Version ID value.018- Invalid Interchange Control Number value.019- Invalid Acknowledgment Requested value.020- Invalid Test Indicator value.021- Invalid Number of Included Groups value.022- Invalid Control Structure.023- Improper (premature) end-of-file (transmission).024- Invalid Interchange Content (e.g., invalid GS segment).025- Duplicate Interchange Control Number.026- Invalid Data Element Separator.027- Invalid Component Element Separator.028- Invalid Delivery Date in Deferred Delivery Request.
Type Declaration
000
readonly000:"000"="000"
001
readonly001:"001"="001"
002
readonly002:"002"="002"
003
readonly003:"003"="003"
004
readonly004:"004"="004"
005
readonly005:"005"="005"
006
readonly006:"006"="006"
007
readonly007:"007"="007"
008
readonly008:"008"="008"
009
readonly009:"009"="009"
010
readonly010:"010"="010"
011
readonly011:"011"="011"
012
readonly012:"012"="012"
013
readonly013:"013"="013"
014
readonly014:"014"="014"
015
readonly015:"015"="015"
016
readonly016:"016"="016"
017
readonly017:"017"="017"
018
readonly018:"018"="018"
019
readonly019:"019"="019"
020
readonly020:"020"="020"
021
readonly021:"021"="021"
022
readonly022:"022"="022"
023
readonly023:"023"="023"
024
readonly024:"024"="024"
025
readonly025:"025"="025"
026
readonly026:"026"="026"
027
readonly027:"027"="027"
028
readonly028:"028"="028"
Example
import { TA1_NOTE_CODES, type Ta1NoteCode } from "@cosyte/x12";
const noError: Ta1NoteCode = TA1_NOTE_CODES["000"];
UNEXPECTED_SEGMENT_CONTEXTS
constUNEXPECTED_SEGMENT_CONTEXTS:object
Which structural rule an out-of-place segment broke. A closed, library-owned set. The segment's own id is deliberately NOT part of it: a segment that is not where it belongs is exactly the case where its first element is arbitrary sender bytes rather than a spec name.
Type Declaration
BODY_OUTSIDE_TRANSACTION
readonlyBODY_OUTSIDE_TRANSACTION:"body-outside-transaction"="body-outside-transaction"
A body segment appeared outside any open transaction set.
GE_WITHOUT_GS
readonlyGE_WITHOUT_GS:"ge-without-gs"="ge-without-gs"
A GE appeared with no open GS.
SE_WITHOUT_ST
readonlySE_WITHOUT_ST:"se-without-st"="se-without-st"
An SE appeared with no open transaction set.
ST_WITHOUT_GS
readonlyST_WITHOUT_GS:"st-without-gs"="st-without-gs"
An ST appeared with no open functional group.
TA1_INSIDE_GROUP
readonlyTA1_INSIDE_GROUP:"ta1-inside-group"="ta1-inside-group"
A TA1 (envelope-level by spec) appeared inside an open functional group.
Example
import { unexpectedSegment, UNEXPECTED_SEGMENT_CONTEXTS } from "@cosyte/x12";
const w = unexpectedSegment({ segmentIndex: 12 }, UNEXPECTED_SEGMENT_CONTEXTS.GE_WITHOUT_GS);
VERSION
constVERSION:string="0.0.17"
Library version string, synced with package.json#version at build
time by downstream phases. Exported now so consumers (and the
type-check pipeline) have at least one symbol to resolve through the
exports map.
Example
import { VERSION } from "@cosyte/x12";
console.log(VERSION);
WARNING_CODES
constWARNING_CODES:object
Stable string codes for every Tier-2 warning the parser may emit. The
registry is frozen via as const so TypeScript infers the exact string
literal union for X12WarningCode - zero runtime cost, no magic-
string comparisons for consumers.
Type Declaration
X12_834_UNKNOWN_MAINTENANCE_TYPE
readonlyX12_834_UNKNOWN_MAINTENANCE_TYPE:"X12_834_UNKNOWN_MAINTENANCE_TYPE"="X12_834_UNKNOWN_MAINTENANCE_TYPE"
X12_835_BALANCE_NOT_EVALUABLE
readonlyX12_835_BALANCE_NOT_EVALUABLE:"X12_835_BALANCE_NOT_EVALUABLE"="X12_835_BALANCE_NOT_EVALUABLE"
X12_835_REMIT_BALANCE_MISMATCH
readonlyX12_835_REMIT_BALANCE_MISMATCH:"X12_835_REMIT_BALANCE_MISMATCH"="X12_835_REMIT_BALANCE_MISMATCH"
X12_837_AMBIGUOUS_VARIANT
readonlyX12_837_AMBIGUOUS_VARIANT:"X12_837_AMBIGUOUS_VARIANT"="X12_837_AMBIGUOUS_VARIANT"
X12_837_ENTITY_SEGMENT_DISCARDED_AFTER_LX
readonlyX12_837_ENTITY_SEGMENT_DISCARDED_AFTER_LX:"X12_837_ENTITY_SEGMENT_DISCARDED_AFTER_LX"="X12_837_ENTITY_SEGMENT_DISCARDED_AFTER_LX"
X12_837_PAY_TO_ADDRESS_REPEATED
readonlyX12_837_PAY_TO_ADDRESS_REPEATED:"X12_837_PAY_TO_ADDRESS_REPEATED"="X12_837_PAY_TO_ADDRESS_REPEATED"
X12_837_SERVICE_LINE_DROPPED
readonlyX12_837_SERVICE_LINE_DROPPED:"X12_837_SERVICE_LINE_DROPPED"="X12_837_SERVICE_LINE_DROPPED"
X12_837_SERVICE_LINE_NOT_DECODED
readonlyX12_837_SERVICE_LINE_NOT_DECODED:"X12_837_SERVICE_LINE_NOT_DECODED"="X12_837_SERVICE_LINE_NOT_DECODED"
X12_837_SERVICE_SEGMENT_REPEATED
readonlyX12_837_SERVICE_SEGMENT_REPEATED:"X12_837_SERVICE_SEGMENT_REPEATED"="X12_837_SERVICE_SEGMENT_REPEATED"
X12_837_SERVICE_SEGMENT_WITHOUT_LX
readonlyX12_837_SERVICE_SEGMENT_WITHOUT_LX:"X12_837_SERVICE_SEGMENT_WITHOUT_LX"="X12_837_SERVICE_SEGMENT_WITHOUT_LX"
X12_837_UNKNOWN_VARIANT
readonlyX12_837_UNKNOWN_VARIANT:"X12_837_UNKNOWN_VARIANT"="X12_837_UNKNOWN_VARIANT"
X12_AMOUNT_ROW_DROPPED
readonlyX12_AMOUNT_ROW_DROPPED:"X12_AMOUNT_ROW_DROPPED"="X12_AMOUNT_ROW_DROPPED"
X12_CONTROL_NUMBER_MISMATCH
readonlyX12_CONTROL_NUMBER_MISMATCH:"X12_CONTROL_NUMBER_MISMATCH"="X12_CONTROL_NUMBER_MISMATCH"
X12_DANGLING_RELEASE_CHAR
readonlyX12_DANGLING_RELEASE_CHAR:"X12_DANGLING_RELEASE_CHAR"="X12_DANGLING_RELEASE_CHAR"
X12_GROUP_COUNT_MISMATCH
readonlyX12_GROUP_COUNT_MISMATCH:"X12_GROUP_COUNT_MISMATCH"="X12_GROUP_COUNT_MISMATCH"
X12_HL_PARENT_LEVEL_INVALID
readonlyX12_HL_PARENT_LEVEL_INVALID:"X12_HL_PARENT_LEVEL_INVALID"="X12_HL_PARENT_LEVEL_INVALID"
X12_HL_PARENT_MISMATCH
readonlyX12_HL_PARENT_MISMATCH:"X12_HL_PARENT_MISMATCH"="X12_HL_PARENT_MISMATCH"
X12_ISA_EXTRA_ELEMENT_SEPARATOR
readonlyX12_ISA_EXTRA_ELEMENT_SEPARATOR:"X12_ISA_EXTRA_ELEMENT_SEPARATOR"="X12_ISA_EXTRA_ELEMENT_SEPARATOR"
X12_MISSING_GE
readonlyX12_MISSING_GE:"X12_MISSING_GE"="X12_MISSING_GE"
X12_MISSING_IEA
readonlyX12_MISSING_IEA:"X12_MISSING_IEA"="X12_MISSING_IEA"
X12_MISSING_REQUIRED_LOOP
readonlyX12_MISSING_REQUIRED_LOOP:"X12_MISSING_REQUIRED_LOOP"="X12_MISSING_REQUIRED_LOOP"
X12_MISSING_SE
readonlyX12_MISSING_SE:"X12_MISSING_SE"="X12_MISSING_SE"
X12_PRE_005010
readonlyX12_PRE_005010:"X12_PRE_005010"="X12_PRE_005010"
X12_SEGMENT_COUNT_MISMATCH
readonlyX12_SEGMENT_COUNT_MISMATCH:"X12_SEGMENT_COUNT_MISMATCH"="X12_SEGMENT_COUNT_MISMATCH"
X12_STATED_AMOUNT_DISCARDED
readonlyX12_STATED_AMOUNT_DISCARDED:"X12_STATED_AMOUNT_DISCARDED"="X12_STATED_AMOUNT_DISCARDED"
X12_TRAILING_GARBAGE
readonlyX12_TRAILING_GARBAGE:"X12_TRAILING_GARBAGE"="X12_TRAILING_GARBAGE"
X12_TRANSACTION_COUNT_MISMATCH
readonlyX12_TRANSACTION_COUNT_MISMATCH:"X12_TRANSACTION_COUNT_MISMATCH"="X12_TRANSACTION_COUNT_MISMATCH"
X12_UNEXPECTED_SEGMENT
readonlyX12_UNEXPECTED_SEGMENT:"X12_UNEXPECTED_SEGMENT"="X12_UNEXPECTED_SEGMENT"
X12_UNKNOWN_CARC
readonlyX12_UNKNOWN_CARC:"X12_UNKNOWN_CARC"="X12_UNKNOWN_CARC"
X12_UNKNOWN_CLAIM_STATUS
readonlyX12_UNKNOWN_CLAIM_STATUS:"X12_UNKNOWN_CLAIM_STATUS"="X12_UNKNOWN_CLAIM_STATUS"
X12_UNKNOWN_CLAIM_STATUS_CATEGORY
readonlyX12_UNKNOWN_CLAIM_STATUS_CATEGORY:"X12_UNKNOWN_CLAIM_STATUS_CATEGORY"="X12_UNKNOWN_CLAIM_STATUS_CATEGORY"
X12_UNKNOWN_HI_QUALIFIER
readonlyX12_UNKNOWN_HI_QUALIFIER:"X12_UNKNOWN_HI_QUALIFIER"="X12_UNKNOWN_HI_QUALIFIER"
X12_UNKNOWN_RARC
readonlyX12_UNKNOWN_RARC:"X12_UNKNOWN_RARC"="X12_UNKNOWN_RARC"
X12_UNPARSEABLE_DECIMAL
readonlyX12_UNPARSEABLE_DECIMAL:"X12_UNPARSEABLE_DECIMAL"="X12_UNPARSEABLE_DECIMAL"
Example
import { parseX12, WARNING_CODES } from "@cosyte/x12";
const ix = parseX12(raw);
if (ix.warnings.some((w) => w.code === WARNING_CODES.X12_PRE_005010)) {
// sender is on a pre-005010 version family
}
X12_ACK_DISPOSITION_CODES
constX12_ACK_DISPOSITION_CODES:object
AK9-01 (functional group) + IK5-01 (transaction set) disposition codes.
Sourced from ASC X12 code list 715. The implementation acknowledges the
inbound functional group / transaction set with one of these dispositions;
the LIBRARY does not decide accept-vs-reject - the application does.
build999 / buildTA1 MECHANICALLY build the cited disposition; a
fabricated A against a non-empty error list is a bug and refused at
build time (see "./errors.js".AckBuildError).
A- Accepted.E- Accepted, but errors were noted.P- Partially accepted: at least one transaction set was rejected while the functional group as a whole was accepted.R- Rejected.M- Rejected: message authentication code (MAC) failed.W- Rejected: assurance failed validity tests.X- Rejected: content after decryption could not be analyzed.
Type Declaration
A
readonlyA:"A"="A"
E
readonlyE:"E"="E"
M
readonlyM:"M"="M"
P
readonlyP:"P"="P"
R
readonlyR:"R"="R"
W
readonlyW:"W"="W"
X
readonlyX:"X"="X"
Example
import type { X12AckDispositionCode } from "@cosyte/x12";
const accept: X12AckDispositionCode = "A";
X12_BUILD_ERROR_CODES
constX12_BUILD_ERROR_CODES:object
Stable string codes for every X12BuildError. Locked here so
consumers can narrow on err.code exhaustively; additions-only thereafter
(renaming any code is a breaking change).
X12_BUILD_INVALID_SPEC- a spec field violated a structural constraint the builder cannot recover from (an ISA-13 / IEA-02 control number longer than the 9-char fixed width, a segment spec with no segment id, etc.).
Type Declaration
X12_BUILD_INVALID_SPEC
readonlyX12_BUILD_INVALID_SPEC:"X12_BUILD_INVALID_SPEC"="X12_BUILD_INVALID_SPEC"
Example
import { X12_BUILD_ERROR_CODES, X12BuildError } from "@cosyte/x12";
try {
buildInterchange(spec);
} catch (err) {
if (err instanceof X12BuildError && err.code === X12_BUILD_ERROR_CODES.X12_BUILD_INVALID_SPEC) {
// application bug - the envelope spec is structurally impossible
}
}
Functions
ambiguous837Variant()
ambiguous837Variant(
position):X12ParseWarning
Build an X12_837_AMBIGUOUS_VARIANT warning. Emitted by the 837 helper
when the SVx fall-back is what resolved the variant AND the transaction
body carries service segments naming more than one variant, so the
resolution is a guess between contradictory evidence. The submission still
ships with the resolved variant on submission.variant; nothing about how
any claim or line decodes is changed by this warning.
It reports the RESOLUTION, not the document. A caller-supplied opts.type
wins ahead of the fall-back, and so does an ST-03 naming one of the three
known implementation-convention references, and in either case no guess was
made and this code is not raised however mixed the body is.
Which service segment is the stray one is deliberately not decided: this reader cannot tell a stray service segment from a conformant one, and the fall-back takes the first in the body whether or not a Loop 2400 was open at it. Distinct from unknown837Variant, which is raised where NOTHING resolved a variant; the two can never travel together, because a body with conflicting service segments has at least one to fall back on.
get837Claims anchors this at the ST, which is tx.segments[0] and
carries the ST-03 that would have settled the question. No elementIndex
is set: the conflict is a property of the body rather than of an element,
and one route into it is an ST-03 that is absent altogether.
Parameters
position
Returns
Example
import { ambiguous837Variant } from "@cosyte/x12";
const w = ambiguous837Variant({ segmentIndex: 0, transactionIndex: 0 });
amountRowDropped()
amountRowDropped(
position):X12ParseWarning
Build an X12_AMOUNT_ROW_DROPPED warning. Emitted where an AMT or ADX
decoded no value from its amount element (AMT-02, ADX-01) and the reader
therefore built no row at all, so the qualifier or adjustment reason code
the sender did state is off the model with it.
position names the AMT / ADX segment itself and carries NO
elementIndex: one of the two routes here is an absent element, and an
absent element has no index to name. The element the reader was reading is
fixed by the segment anyway - AMT-02 or ADX-01 - so the segment locates the
loss exactly.
It is raised for BOTH routes to an undecoded amount, and
unparseableDecimal is unchanged by it: a present-but-undecodable
element still raises X12_UNPARSEABLE_DECIMAL at its own elementIndex,
now ALONGSIDE this code rather than instead of it, so a consumer predicate
written against that code alone still fires exactly where it did. The
absent route raises this code and nothing else, which is what tells the two
apart.
Read the bound literally. This reports a row whose AMOUNT was read and
decoded no value. A segment a reader discards before reading its amount is
not on this channel, and neither is one whose amount decoded and then found
nothing open to attach the row to. An 820 RMR is not on it either, for its
own reason: decodeRmr drops on open-item IDENTITY, RMR-01 and RMR-02 both
empty, before the amount is read - so an RMR that states an open item and
no amount keeps its row with amountPaid undefined, while one that states
an amount and no open item is dropped whole. That second case is a separate
loss, as is an 837 AMT that decoded while a Loop 2430 adjudication was
open; statedAmountDiscarded reports both and this code reports
neither. Nothing is fabricated to stand in and the segments stay verbatim on
the transaction set.
Parameters
position
Returns
Example
import { amountRowDropped } from "@cosyte/x12";
const w = amountRowDropped({ segmentIndex: 7, transactionIndex: 0 });
balanceNotEvaluable()
balanceNotEvaluable(
position,invariant):X12ParseWarning
Build an X12_835_BALANCE_NOT_EVALUABLE warning. Emitted where a term of
a TR3 X221A1 §1.10.2 invariant is undefined on the model, so the
equation has nothing to compare on one side. invariant names which
equation could not be run.
This is deliberately a DIFFERENT code from
remitBalanceMismatch: that one asserts a computed inequality
between amounts the sender supplied, and this one asserts only that the
comparison could not be made. Reading an absent term as 0 is what made
the two indistinguishable before X12Decimal | undefined, and it is the
thing this code exists to stop.
Parameters
position
invariant
Returns
Example
import { balanceNotEvaluable, BALANCE_INVARIANTS } from "@cosyte/x12";
const w = balanceNotEvaluable(
{ segmentIndex: 12, groupIndex: 0, transactionIndex: 0 },
BALANCE_INVARIANTS.CLAIM,
);
build271()
build271(
spec):X12Interchange
build271 - assemble a 005010X279A1 271 around the supplied spec.
Refused via "./build-errors.js".Eligibility271BuildError:
- No information sources, a source with no receivers, or a receiver with
no subscribers →
X12_271_BUILD_INVALID_HIERARCHY. - An over-long (>9 char) interchange control number →
X12_271_BUILD_INVALID_SPEC.
Parameters
spec
Returns
Example
import { build271, X12Decimal } from "@cosyte/x12";
const ix = build271({
envelope: {
senderId: "MEDPAY", receiverId: "PROVIDER",
interchangeDate: "260601", interchangeTime: "1200",
interchangeControlNumber: "000000001",
groupControlNumber: "1", transactionSetControlNumber: "0001",
},
informationSources: [{
entity: { entityIdentifierCode: "PR", entityTypeQualifier: "2", name: "MEDPAY INSURANCE", idQualifier: "PI", idCode: "00123" },
receivers: [{
entity: { entityIdentifierCode: "1P", entityTypeQualifier: "2", name: "ANYTOWN CLINIC", idQualifier: "XX", idCode: "1234567890" },
subscribers: [{
traces: [{ traceTypeCode: "2", referenceId: "ELIG001" }],
name: { entityIdentifierCode: "IL", entityTypeQualifier: "1", lastName: "DOE", firstName: "JANE", idQualifier: "MI", idCode: "MBR0001" },
benefits: [{ eligibilityCode: "1", coverageLevelCode: "IND", serviceTypeCodes: [{ code: "30" }], monetaryAmount: X12Decimal.fromString("1000.00")! }],
}],
}],
}],
});
build277()
build277(
spec):X12Interchange
build277 - assemble a 005010X212 277 Claim Status Response around the
supplied spec.
Parameters
spec
Returns
Example
import { build277, X12Decimal } from "@cosyte/x12";
const ix = build277({
envelope: {
senderId: "MEDPAY", receiverId: "PROVIDER",
interchangeDate: "260601", interchangeTime: "1200",
interchangeControlNumber: "000000001",
groupControlNumber: "1", transactionSetControlNumber: "0001",
},
informationSources: [{
entity: { entityIdentifierCode: "PR", entityTypeQualifier: "2", name: "MEDPAY INSURANCE", idQualifier: "PI", idCode: "00123" },
receivers: [{
entity: { entityIdentifierCode: "41", entityTypeQualifier: "2", name: "CLEARINGHOUSE", idQualifier: "46", idCode: "CH001" },
providers: [{
entity: { entityIdentifierCode: "1P", entityTypeQualifier: "2", name: "ANYTOWN CLINIC", idQualifier: "XX", idCode: "1234567890" },
subscribers: [{
member: { entityIdentifierCode: "QC", entityTypeQualifier: "1", lastName: "DOE", firstName: "JANE" },
claims: [{ trace: { traceTypeCode: "2", referenceId: "CLAIM001" }, statuses: [{ statuses: [{ categoryCode: "A2", statusCode: "20" }] }] }],
}],
}],
}],
}],
});
build277CA()
build277CA(
spec):X12Interchange
build277CA - assemble a 005010X214 277CA Claim Acknowledgment around the
supplied spec. Identical body to build277; only the ST-03 / GS-08
version differs (so the parsed result is admitted by
"./get-277.js".get277CADisposition and carries
transactionType: "claim-acknowledgment").
Parameters
spec
Returns
Example
import { build277CA } from "@cosyte/x12";
declare const spec: import("@cosyte/x12").Build277Spec;
const ix = build277CA(spec); // ST-03 = 005010X214
build278Request()
build278Request(
spec):X12Interchange
build278Request - assemble a 005010X217 278 Request for Review around the
supplied spec. Refuses any review carrying an HCR decision (HCR is
response-only), and any review whose HL-03 levelCode is outside
EV / SS.
Parameters
spec
Returns
Example
import { build278Request } from "@cosyte/x12";
const ix = build278Request({
envelope: {
senderId: "SUBMITTER", receiverId: "UMOPAYER",
interchangeDate: "260601", interchangeTime: "1200",
interchangeControlNumber: "000000001",
groupControlNumber: "1", transactionSetControlNumber: "0001",
},
header: { structurePurposeCode: "0078", purposeCode: "13", referenceId: "AUTHREQ-202606" },
utilizationManagementOrganization: { entityIdentifierCode: "X3", entityTypeQualifier: "2", name: "UTILIZATION REVIEW CO", idQualifier: "PI", idCode: "UMO001" },
requester: { entityIdentifierCode: "1P", entityTypeQualifier: "2", name: "RENDERING CLINIC", idQualifier: "XX", idCode: "1234567893" },
subscriber: {
member: { entityIdentifierCode: "IL", entityTypeQualifier: "1", lastName: "DOE", firstName: "JANE", idQualifier: "MI", idCode: "MBR0001" },
reviews: [{ requestCategoryCode: "HS", certificationTypeCode: "I", serviceTypeCode: "1" }],
},
});
build278Response()
build278Response(
spec):X12Interchange
build278Response - assemble a 005010X216 278 Response around the supplied
spec. The HCR actionCode on each review's decision is emitted VERBATIM
(never inferred), so the response round-trips the exact certification
outcome through "./get-278.js".get278Response. A review whose HL-03
levelCode is outside EV / SS is REFUSED, because that round trip is
what an out-of-enum level breaks: the emitted review loop is one no reader
opens, so the decision fails to decode.
Parameters
spec
Returns
Example
import { build278Response } from "@cosyte/x12";
declare const base: import("@cosyte/x12").Build278Spec;
const ix = build278Response({
...base,
subscriber: {
...base.subscriber,
reviews: [{ requestCategoryCode: "HS", certificationTypeCode: "I", decision: { actionCode: "A1", reviewIdentificationNumber: "AUTH123456" } }],
},
}); // ST-03 = 005010X216, HCR*A1*AUTH123456
build820()
build820(
spec):X12Interchange
build820 - assemble a 005010X218 820 around the supplied spec.
Refused via "./build-errors.js".Premium820BuildError with code
X12_820_BUILD_INVALID_SPEC:
- no TRN trace, or no remittance loop;
- a remittance with neither an
entitynor anindividual(nothing opens its loop), or with noopenItems; - an open item with empty
qualifierAND emptyreferenceId(the read side drops it); - an over-long (> 9 char) interchange control number.
Parameters
spec
Returns
Example
import { build820, X12Decimal } from "@cosyte/x12";
const ix = build820({
envelope: {
senderId: "EMPLOYERCO", receiverId: "MEDPAY",
interchangeDate: "260601", interchangeTime: "1200",
interchangeControlNumber: "000000001",
groupControlNumber: "1", transactionSetControlNumber: "0001",
},
payment: {
transactionHandlingCode: "I",
totalPremiumAmount: X12Decimal.fromString("250.00")!,
creditDebitFlag: "C", method: "ACH", paymentDate: "20260601",
},
traces: [{ traceTypeCode: "1", referenceId: "PREM-202606" }],
remittances: [{
individual: { entityIdentifierCode: "IL", lastName: "DOE", idQualifier: "34", idCode: "MBR0001" },
openItems: [{ qualifier: "AZ", referenceId: "POL-0001", amountPaid: X12Decimal.fromString("250.00")! }],
}],
});
build834()
build834(
spec):X12Interchange
build834 - assemble a 005010X220A1 834 around the supplied spec.
Refused via "./build-errors.js".Enrollment834BuildError:
- an
INS-03orHD-01maintenance type code outside the validated X12 875 subset →X12_834_BUILD_UNKNOWN_MAINTENANCE_TYPE; - no member loop, an empty (required)
INS-03, or an over-long (> 9 char) interchange control number →X12_834_BUILD_INVALID_SPEC.
Parameters
spec
Returns
Example
import { build834 } from "@cosyte/x12";
const ix = build834({
envelope: {
senderId: "EMPLOYERCO", receiverId: "MEDPAY",
interchangeDate: "260601", interchangeTime: "1200",
interchangeControlNumber: "000000001",
groupControlNumber: "1", transactionSetControlNumber: "0001",
},
header: {
transactionSetPurposeCode: "00",
sponsor: { entityIdentifierCode: "P5", name: "EMPLOYER CO" },
payer: { entityIdentifierCode: "IN", name: "MEDPAY INSURANCE" },
},
members: [{
subscriberIndicator: "Y", relationshipCode: "18", maintenanceTypeCode: "021",
member: { lastName: "DOE", firstName: "JANE", idQualifier: "34", idCode: "MBR0001" },
healthCoverages: [{ maintenanceTypeCode: "021", insuranceLineCode: "HLT" }],
}],
});
build835()
build835(
spec):X12Interchange
build835 - assemble a 005010X221A1 835 around the supplied spec.
Refused via "./build-errors.js".Remit835BuildError:
- No trace supplied, or a claim with no patient-control number, etc. →
X12_835_BUILD_INVALID_SPEC. - Any §1.10.2 balance invariant violated (service-line
SVC-02 == SVC-03 + Σ(line CAS), claimCLP-03 == CLP-04 + Σ(claim+line CAS), or top-of-remitBPR-02 == Σ(CLP-04) − Σ(PLB)) →X12_835_BUILD_BALANCE_MISMATCH.
Parameters
spec
Returns
Example
import { build835, X12Decimal } from "@cosyte/x12";
const ix = build835({
envelope: {
senderId: "MEDICARE", receiverId: "SUBMITTER",
interchangeDate: "260601", interchangeTime: "1200",
interchangeControlNumber: "000000001",
groupControlNumber: "1", transactionSetControlNumber: "0001",
},
payment: {
transactionHandlingCode: "I",
totalActualPayment: X12Decimal.fromString("450.00")!,
creditDebitFlag: "C", method: "ACH", paymentDate: "20260601",
},
traces: [{ traceTypeCode: "1", referenceId: "0012345", originatingCompanyId: "1512345678" }],
claims: [
{
patientControlNumber: "PT-ACCT-001", claimStatusCode: "1",
totalChargeAmount: X12Decimal.fromString("500.00")!,
totalPaymentAmount: X12Decimal.fromString("450.00")!,
patientResponsibilityAmount: X12Decimal.fromString("50.00")!,
adjustments: [{ groupCode: "PR", reasonCode: "1", amount: X12Decimal.fromString("50.00")! }],
},
],
});
build837D()
build837D(
spec):X12Interchange
build837D - assemble a Dental 837 around the spec, declaring
005010X224A2 unless envelope.implementationConventionReference states
the guide your trading partner requires. Service lines must be
variant: "D" (SV3); per-line tooth detail rides on TOO.
Parameters
spec
Returns
Example
import { build837D, X12Decimal } from "@cosyte/x12";
declare const spec: import("@cosyte/x12").Build837Spec;
const ix = build837D(spec); // each serviceLine: { variant: "D", procedureQualifier: "AD", ... }
build837I()
build837I(
spec):X12Interchange
build837I - assemble an Institutional 837 around the spec, declaring
005010X223A3 unless envelope.implementationConventionReference states
the guide your trading partner requires. Service lines must be
variant: "I" (SV2).
Parameters
spec
Returns
Example
import { build837I, X12Decimal } from "@cosyte/x12";
declare const spec: import("@cosyte/x12").Build837Spec;
const ix = build837I(spec); // each serviceLine: { variant: "I", revenueCode: "0120", ... }
build837P()
build837P(
spec):X12Interchange
build837P - assemble a Professional 837 around the spec, declaring
005010X222A2 unless envelope.implementationConventionReference states
the guide your trading partner requires.
Parameters
spec
Returns
Example
import { build837P, X12Decimal } from "@cosyte/x12";
const ix = build837P({
envelope: {
senderId: "SUBMITTER", receiverId: "RECEIVER",
interchangeDate: "260601", interchangeTime: "1200",
interchangeControlNumber: "000000001",
groupControlNumber: "1", transactionSetControlNumber: "0001",
},
submitter: { entityIdentifierCode: "41", entityTypeQualifier: "2", name: "SUBMITTER ONE", idQualifier: "46", idCode: "SUB001" },
receiver: { entityIdentifierCode: "40", entityTypeQualifier: "2", name: "RECEIVER ONE", idQualifier: "46", idCode: "REC001" },
billingProviders: [{
provider: { entityIdentifierCode: "85", entityTypeQualifier: "2", name: "BILLING CLINIC INC", idQualifier: "XX", idCode: "1234567890" },
subscribers: [{
info: { payerResponsibilityCode: "P", individualRelationshipCode: "18", claimFilingIndicator: "MB" },
subscriber: { entityIdentifierCode: "IL", entityTypeQualifier: "1", name: "PATIENT", firstName: "TEST", idQualifier: "MI", idCode: "MEMBER001" },
payer: { entityIdentifierCode: "PR", entityTypeQualifier: "2", name: "PAYER ONE", idQualifier: "PI", idCode: "PAYER01" },
claims: [{
claimId: "PT-ACCT-001", totalCharge: X12Decimal.fromString("150.00")!,
diagnoses: [{ qualifier: "ABK", code: "J20.9" }],
serviceLines: [{ variant: "P", procedureQualifier: "HC", procedureCode: "99213", charge: X12Decimal.fromString("150.00")!, unitOfMeasure: "UN", units: X12Decimal.fromString("1")!, diagnosisPointers: ["1"] }],
}],
}],
}],
});
build999()
build999(
spec):X12Interchange
build999 - assemble a 005010X231A1 Implementation Acknowledgment
around the supplied envelope + functional-group spec.
Safety guards (refused via AckBuildError):
- Functional-level
Adisposition paired with any per-transaction non-Aresponse, or any per-transaction segment-error / syntax-error payload anywhere in the spec → "./errors.js".ACK_BUILD_ERROR_CODES.X12_ACK_ACCEPT_WITH_ERRORS. - Per-transaction
Adisposition paired with non-emptysegmentErrors/syntaxErrorCodes→ same. - AK9-04 (accepted) > AK9-03 (received), AK9-03 > AK9-02 (declared), or response-list length not equal to AK9-03 → "./errors.js".ACK_BUILD_ERROR_CODES.X12_ACK_COUNT_MISMATCH.
Parameters
spec
Returns
Example
import { build999 } from "@cosyte/x12";
const ix = build999({
envelope: {
senderId: "SENDER", receiverId: "RECEIVER",
interchangeDate: "250101", interchangeTime: "1200",
interchangeControlNumber: "000000001",
groupControlNumber: "1", transactionSetControlNumber: "0001",
},
functionalGroup: {
functionalIdCode: "HC", groupControlNumber: "1", versionRelease: "005010X222A2",
disposition: "A",
numberOfTransactionSets: 1, numberOfReceivedTransactionSets: 1, numberOfAcceptedTransactionSets: 1,
transactionResponses: [
{ transactionSetIdCode: "837", transactionSetControlNumber: "0001", disposition: "A" },
],
},
});
buildInterchange()
buildInterchange(
spec):X12Interchange
Assemble a complete X12Interchange from a segment-level InterchangeSpec. See the module header for the envelope mechanics the builder owns.
Parameters
spec
Returns
Example
import { buildInterchange } from "@cosyte/x12";
const ix = buildInterchange({
senderId: "SENDER", receiverId: "RECEIVER",
interchangeDate: "250101", interchangeTime: "1200",
interchangeControlNumber: "000000001",
groups: [
{
functionalIdCode: "HC", groupControlNumber: "1", versionRelease: "005010X222A2",
transactions: [
{
transactionSetIdCode: "837", transactionSetControlNumber: "0001",
implementationConventionReference: "005010X222A2",
segments: [["BHT", "0019", "00", "REF", "20250101", "1200", "CH"]],
},
],
},
],
});
buildTA1()
buildTA1(
spec,options?):Ta1Segment
buildTA1 - assemble a TA1 Interchange Acknowledgment segment from the
supplied spec. The returned Ta1Segment carries the 1-indexed
5-element value array (elements[0] = "TA1", elements[1] =
TA1-01, …, elements[5] = TA1-05) plus the verbatim wire text on raw
(no segment terminator appended - that's the envelope's job).
Safety guards (refused via AckBuildError):
ackCode === "A"paired withnoteCode !== "000"→ "./errors.js".ACK_BUILD_ERROR_CODES.X12_TA1_ACCEPT_WITH_NOTE. Accept must mean accept. UseE(accept with errors) when the inbound had structural defects you elected to ignore. This one runs FIRST and its precedence is unchanged.- Any of the five element values that is not a
string→ "./errors.js".ACK_BUILD_ERROR_CODES.X12_ACK_INVALID_SPEC. This is not a bonus guard: releasing a value means routing it through "../../builder/caller-string.js".makeCallerEscaper, and the bareescapeReleaseunderneath it returns its empty accumulator for anumber, so escaping without the type check would have replaced the shifted-element defect with a silently VANISHED TA1-01. A number or anundefinedcontrol number used to emit asTA1*12345*…(the number surviving ontoelements, in areadonly string[]) orTA1**250101*…; both now refuse.
Parameters
spec
The TA1 fields. interchangeControlNumber echoes the
inbound ISA-13; interchangeDate / interchangeTime echo
the inbound ISA-09 / ISA-10; ackCode is the disposition;
noteCode is the note (000 for no-error pairings).
options?
BuildTA1Options = {}
Optional delimiter overrides for callers building TA1
segments embedded in non-default envelopes. The
defaults match the cosyte parser archetype (* element,
~ segment) - override when wrapping a TA1 in an ISA
envelope whose declared delimiters differ.
Returns
Example
import { buildTA1 } from "@cosyte/x12";
// Accept (canonical "no error" pairing).
const ok = buildTA1({
interchangeControlNumber: "000000001",
interchangeDate: "250101",
interchangeTime: "1200",
ackCode: "A",
noteCode: "000",
});
ok.raw; // 'TA1*000000001*250101*1200*A*000'
// Reject (control number mismatch).
const reject = buildTA1({
interchangeControlNumber: "000000007",
interchangeDate: "250101",
interchangeTime: "1200",
ackCode: "R",
noteCode: "001",
});
checkClaimBalance()
checkClaimBalance(
claim,position):X12ParseWarning|undefined
Check the claim-level invariant CLP-03 === CLP-04 + Σ(all CAS in claim, both claim and line level). Returns the warning when out of
balance, or undefined otherwise. Pure - no side effects.
Parameters
claim
position
Returns
X12ParseWarning | undefined
Example
import { checkClaimBalance } from "@cosyte/x12";
declare const claim: X12RemitClaim;
const w = checkClaimBalance(claim, { segmentIndex: 12 });
if (w !== undefined) {
// not balanced - w.message names the TR3 equation; the amounts are on `claim`,
// and w.position.segmentIndex is the CLP's own index in the transaction body
}
checkRemitTotalBalance()
checkRemitTotalBalance(
bpr02,claims,providerAdjustments,position):X12ParseWarning|undefined
Check the top-of-remit invariant BPR-02 === Σ(CLP-04) - Σ(PLB amounts). PLB amounts are preserved with their raw EDI sign
(positive = take-back from provider; negative = credit to provider -
see "./types.js".X12RemitProviderAdjustment), so the
subtraction is what makes the equation balance. Returns the warning
when out of balance, or undefined when balanced.
Parameters
bpr02
X12Decimal | undefined
claims
readonly X12RemitClaim[]
providerAdjustments
readonly X12RemitProviderAdjustment[]
position
Returns
X12ParseWarning | undefined
Example
import { checkRemitTotalBalance } from "@cosyte/x12";
declare const remit: import("./types.js").X12Remittance;
const w = checkRemitTotalBalance(
remit.payment.totalActualPayment,
remit.claims,
remit.providerAdjustments,
{ segmentIndex: 2, transactionIndex: 0 },
);
checkServiceLineBalance()
checkServiceLineBalance(
claim,position): readonlyX12ParseWarning[]
Check the per-service-line invariant SVC-02 === SVC-03 + Σ(line CAS).
Returns one warning per out-of-balance service line. Header-only
adjudications (claims with zero service lines) produce no per-line
warning. Pure - no side effects.
Parameters
claim
position
Returns
readonly X12ParseWarning[]
Example
import { checkServiceLineBalance } from "@cosyte/x12";
declare const claim: X12RemitClaim;
const warnings = checkServiceLineBalance(claim, { segmentIndex: 14 });
collectElementValues()
collectElementValues(
seg,start,end,delimiters):string[]
Collect non-empty element values across the 1-indexed inclusive range
[start, end]. Returns a new array preserving order, omitting empty /
missing slots. Common for sweeping N3 address-line composites, MIA /
MOA remark code slots, etc.
Parameters
seg
start
number
end
number
delimiters
Returns
string[]
Example
import { collectElementValues } from "@cosyte/x12";
collectElementValues(n3Segment, 1, 2, delim); // ["123 Main St", "Apt 4"]
componentOptional()
componentOptional(
seg,n,p,delimiters):string|undefined
Read component P (1-indexed) of element N (1-indexed) as a string, or
undefined when absent / empty. The common shape for X12 composite
elements (HI-01-2, CLM-05-1, SVC-01-2, etc.).
Parameters
seg
n
number
p
number
delimiters
Returns
string | undefined
Example
import { componentOptional } from "@cosyte/x12";
componentOptional(seg, 1, 2, delim); // HI-01-2 (the actual code)
controlNumberMismatch()
controlNumberMismatch(
position,pair):X12ParseWarning
Build an X12_CONTROL_NUMBER_MISMATCH warning. Emitted when an
envelope-trailer control number does not match its matching header:
ISA-13 ↔ IEA-02, GS-06 ↔ GE-02, or ST-02 ↔ SE-02.
Neither side is echoed, not truncated and not hashed. A control number is free-form trading-partner text on five of the six slots (only ISA-13 is fixed-width), routinely carries a batch or patient-account identifier in the field, and is entirely sender-controlled.
Parameters
position
pair
Returns
Example
import { controlNumberMismatch, CONTROL_NUMBER_PAIRS } from "@cosyte/x12";
const w = controlNumberMismatch(
{ segmentIndex: 6, interchangeIndex: 0, elementIndex: 2 },
CONTROL_NUMBER_PAIRS.INTERCHANGE,
);
danglingReleaseChar()
danglingReleaseChar(
position):X12ParseWarning
Build an X12_DANGLING_RELEASE_CHAR warning. Emitted when a release
character (? per ASC X12 convention; see
"./release.js".RELEASE_CHAR) appears at the end of a segment or
element with no following byte to escape - the bytes are preserved
verbatim so round-trip stays byte-exact, but the structural truncation
is flagged so consumers can decide how to react.
Parameters
position
Returns
Example
import { danglingReleaseChar } from "@cosyte/x12";
const w = danglingReleaseChar({ segmentIndex: 7, interchangeIndex: 0 });
decodeSegment()
decodeSegment(
raw,delimiters,emit,position):X12Segment
Decode a raw segment string into an X12Segment. Splits on the
detected element separator (honouring the ?-release-character escape),
preserves the verbatim raw text, and surfaces dangling-release warnings
via the supplied emitter with positional context tied to the segment.
Never throws - malformed input produces a best-effort segment and any
issues surface as Tier-2 warnings via emit. An empty input string
decodes to an empty segment (id: "", elements: [""]); callers that
care can guard.
A degenerate delimiter set whose ELEMENT SEPARATOR is itself ? splits
literally, because one byte cannot both separate and escape. Only that
role is guarded here: a ? repetition or component separator is a
different call and is deliberately unchanged (see
"./release.js".splitWithRelease).
Parameters
raw
string
delimiters
emit
(w) => void
position
Returns
Example
import { decodeSegment } from "@cosyte/x12";
const d = { element: "*", repetition: "^", component: ":", segment: "~" };
const seg = decodeSegment("NM1*IL*1*DOE*JANE", d, () => {}, { segmentIndex: 5 });
seg.id; // "NM1"
seg.elements[3]; // "DOE"
defineLoopSpec()
defineLoopSpec(
input):LoopSpec
Define a TR3 loop specification. Validates structurally, freezes the
resulting LoopSpec (along with its segments and children
arrays), and returns it. Pure - no I/O, no global state.
Parameters
input
Returns
Example
import { defineLoopSpec } from "@cosyte/x12";
const Loop2110 = defineLoopSpec({
id: "2110",
description: "835 Service Payment Information",
trigger: "SVC",
segments: [
{ id: "SVC", usage: "required", max: 1 },
{ id: "DTM", usage: "situational", max: ">1" },
{ id: "CAS", usage: "situational", max: ">1" },
{ id: "REF", usage: "situational", max: ">1" },
{ id: "AMT", usage: "situational", max: ">1" },
{ id: "LQ", usage: "situational", max: ">1" },
],
});
Loop2110.trigger; // "SVC"
defineProfile()
defineProfile(
opts):X12Profile
Build a readonly X12Profile from a validated spec. Invalid input
throws "./errors.js".X12ProfileError with an actionable message:
missing/empty name, unknown option key (with a typo hint), or a quirk that
violates the locked hard rule (missing fixture, bad effect, unknown
expectedWarnings code).
extends composes parent profiles: lineage flattens + dedupes, quirks
merge by id (child wins on collision, non-colliding parent quirks survive),
and description is last-wins.
Parameters
opts
Returns
Example
import { defineProfile } from "@cosyte/x12";
const availity = defineProfile({
name: "availity",
description: "Availity clearinghouse 835 ERA conventions",
quirks: [
{
id: "payer-loop-ref-2u",
effect: "adds",
summary: "Payer Loop 1000A carries a REF*2U additional payer identifier.",
fixture: "remit/835-availity-quirk.edi",
sourceCategory: "Availity 835 ERA companion guide - payer-loop REF",
},
],
});
availity.name; // "availity"
availity.lineage; // ["availity"]
availity.describe().adds; // [{ id: "payer-loop-ref-2u", ... }]
detectDelimiters()
detectDelimiters(
raw):Delimiters
Detect the four X12 delimiters from a raw input string by reading fixed byte positions inside the ISA envelope. Validates that:
- the input is at least ISA_MIN_LENGTH bytes (else
X12_ISA_TOO_SHORT), - the input begins with the literal
"ISA"(elseX12_NO_ISA_HEADER), - each delimiter is a single visible (non-whitespace, non-control)
character and the four are mutually distinct (else
X12_INVALID_DELIMITERS), - the detected element separator actually appears at every fixed ISA
element-separator position (else
X12_INVALID_DELIMITERS) - guards against an input that begins with"ISA"followed by structurally wrong bytes (e.g. a tab as element separator with:further in).
Phase 1 is liberal in what it accepts AFTER the ISA - downstream envelope walking emits Tier-2 warnings rather than throwing. But the ISA itself MUST be structurally readable; otherwise no later stage has a delimiter set to work with.
Parameters
raw
string
Returns
Example
import { detectDelimiters } from "@cosyte/x12";
const d = detectDelimiters("ISA*00* *00* *ZZ*SENDER *ZZ*RECEIVER *250101*1200*^*00501*000000001*0*P*:~GS*HC*S*R*20250101*1200*1*X*005010X222A2~...");
d.element; // "*"
d.repetition; // "^"
d.component; // ":"
d.segment; // "~"
elementDecimal()
elementDecimal(
seg,n,delimiters,sink?):X12Decimal|undefined
Read element N (1-indexed) as an X12Decimal, or undefined
when absent / empty / malformed. The walker discipline for every
monetary or quantity field - NEVER parseFloat.
undefined here means "not decoded", not "absent." When sink is
supplied, a PRESENT element that does not decode emits
X12_UNPARSEABLE_DECIMAL carrying elementIndex: n, so the two cases are
told apart on the warning channel. Without a sink the ambiguity is
silent, which is why every reader in this library passes one; use
readElementDecimal when you want the distinction in-band instead.
An ABSENT element returns undefined and does NOT warn.
Parameters
seg
n
number
delimiters
sink?
Returns
X12Decimal | undefined
Example
import { elementDecimal } from "@cosyte/x12";
elementDecimal(seg, 2, delim)?.toString(); // BPR-02 verbatim decimal
elementDecimalOrZero()
elementDecimalOrZero(
seg,n,delimiters,sink?):X12Decimal
Read element N (1-indexed) as an X12Decimal, defaulting to
X12Decimal.ZERO when absent. Convenient for fields the walker treats
as "missing means zero" (charge totals, etc.).
The 0 this returns for a PRESENT-but-unparseable element is a
stand-in, not a reading. A slot typed X12Decimal cannot express
"did not decode", so a consumer looking only at the model cannot tell
that 0 from a 0 the sender sent: on a paid amount that is a fabricated
amount presented as read. When sink is supplied the case emits
X12_UNPARSEABLE_DECIMAL, which is the only signal that distinguishes
them. Pass one, or use readElementDecimal and decide for
yourself.
An ABSENT element still returns X12Decimal.ZERO and does NOT warn: that
is the documented "missing means zero" convention of the slots that use
this helper, and it is unchanged.
Parameters
seg
n
number
delimiters
sink?
Returns
Example
import { elementDecimalOrZero } from "@cosyte/x12";
elementDecimalOrZero(seg, 2, delim).toString();
elementOptional()
elementOptional(
seg,n,delimiters):string|undefined
Read element N (1-indexed) as string | undefined. Empty strings
collapse to undefined - the conventional "absent" sentinel for
optional element slots.
Parameters
seg
n
number
delimiters
Returns
string | undefined
Example
import { elementOptional } from "@cosyte/x12";
// returns undefined when NM1-04 is "" or missing
elementValue()
elementValue(
seg,n,delimiters):string
Read element N (1-indexed) from a decoded segment as a string. Returns
"" when the element is absent or empty - convenient when downstream
code wants to fold "absent" and "empty" into one branch. For
"absent / empty → undefined" use elementOptional.
Parameters
seg
n
number
delimiters
Returns
string
Example
import { decodeSegment, elementValue } from "@cosyte/x12";
declare const seg: ReturnType<typeof decodeSegment>;
declare const delim: import("./types.js").Delimiters;
elementValue(seg, 3, delim); // verbatim text of element 3, or "".
entitySegmentDiscardedAfterLx()
entitySegmentDiscardedAfterLx(
position):X12ParseWarning
Build an X12_837_ENTITY_SEGMENT_DISCARDED_AFTER_LX warning. Emitted by
the 837 helper for an N3 / N4 / PER / REF that reached no party
because an earlier LX with no CLM open closed the entity loop that was
current at it. position names the discarded segment itself, not the LX:
the loss is per segment (two N3s are two losses), and the segment is the
one thing a consumer needs to resolve back through tx.segments.
It is the narrow companion to serviceLineDropped, which is raised at
that same LX and reports the SERVICE LINE. Neither reports what the other
does, and both can be on one transaction's channel.
Read its bound literally: this is not a general "unattached entity
segment" code. It fires only after such an LX and only while nothing has
opened a new loop since, so an N3 / N4 / PER / REF that reaches no
party by any other route stays silent, exactly as it did before this code
existed. Widening it is a guard change and would be its own decision.
It reports that the segment reached no party, NOT that it would have reached
one: this reader surfaces neither a PER on a patient nor one on a pay-to
address, on any release.
Parameters
position
Returns
Example
import { entitySegmentDiscardedAfterLx } from "@cosyte/x12";
const w = entitySegmentDiscardedAfterLx({ segmentIndex: 8, transactionIndex: 0 });
escapeRelease()
escapeRelease(
value,delimiters):string
Apply X12 release-character escapes to a value so it can be emitted
inside a segment without ambiguity. Every occurrence of the four
delimiters (or the release character itself) is preceded by ?; other
bytes pass through verbatim. The companion to unescapeRelease.
Throws TypeError on a non-string, and the previous behaviour was the
defect. This function is declared over string, but a JavaScript or
JSON-driven caller is not held to that. Reading value.length gave three
different wrong answers depending on what arrived: a number, a boolean
or a plain object has no .length, so undefined === 0 was false, i < undefined was false, and the function returned the empty accumulator -
the value vanished with no error and no warning; null and undefined threw
on the property read; an array or an array-like threw on charAt. The silent
one was by far the worst: build835 emitted CLP**1*500.00*… with
warnings.length === 0, dropping the CLP-01 reassociation key TR3
005010X221A1 requires. All three now terminate the same way.
TypeError and not a code-tagged library error is deliberate, and it is not
the untyped-refusal defect this package has fixed elsewhere. This is a pure
text utility with no spec, no element and no caller context to name, so
TypeError is the accurate answer for a wrong-typed argument. Nothing
inside this library can reach it: every builder routes its elements
through src/builder/caller-string.ts, which refuses first with the calling
builder's own typed, code-tagged error. (No count: it is asserted by
test/builder-string-type.test.ts and was stale here.) This throw is the backstop for a
consumer calling the export directly, where the alternative was silent data
loss.
Parameters
value
string
delimiters
Returns
string
Throws
TypeError if value is not a string
Example
import { escapeRelease } from "@cosyte/x12";
const d = { element: "*", repetition: "^", component: ":", segment: "~" };
escapeRelease("ab~cd*ef:gh", d); // "ab?~cd?*ef?:gh"
escapeRelease("a?b", d); // "a??b"
escapeRelease(1 as unknown as string, d); // TypeError (was "")
get271Eligibility()
get271Eligibility(
delimiters,tx):X12Eligibility|undefined
Extract a typed X12Eligibility from a 271 transaction set. Pure
function - no I/O, no global state. Returns undefined only when the
input transaction's ST-01 is not "271" (mis-routed call); every other
deviation is recoverable and surfaces on result.warnings.
Parameters
delimiters
tx
Returns
X12Eligibility | undefined
Example
import { parseX12, get271Eligibility } from "@cosyte/x12";
const ix = parseX12(raw);
for (const group of ix.groups) {
for (const tx of group.transactions) {
if (tx.st.elements[1] !== "271") continue;
const elig = get271Eligibility(ix.delimiters, tx);
for (const sub of elig?.subscribers ?? []) {
sub.traces[0]?.referenceId; // echoed 270 trace number
sub.benefits[0]?.eligibilityCode; // "1" (Active Coverage)
}
}
}
get277CADisposition()
get277CADisposition(
delimiters,tx):X12ClaimStatusResponse|undefined
Extract a 277CA Claim Acknowledgment (005010X214). Returns undefined
unless the transaction is a 277 whose ST-03 is 005010X214 - use
get277Status for the general 277 Claim Status Response. The
returned model is the same X12ClaimStatusResponse; the
transactionType is always "claim-acknowledgment".
Parameters
delimiters
tx
Returns
X12ClaimStatusResponse | undefined
Example
import { parseX12, get277CADisposition } from "@cosyte/x12";
const ix = parseX12(raw);
const tx = ix.groups[0]?.transactions.find((t) => t.st.elements[1] === "277");
const ack = tx === undefined ? undefined : get277CADisposition(ix.delimiters, tx);
ack?.claims[0]?.statuses[0]?.statuses[0]?.categoryCode; // "A1" / "A2" / "A3"
get277Status()
get277Status(
delimiters,tx):X12ClaimStatusResponse|undefined
Extract a typed X12ClaimStatusResponse from a 277 / 277CA
transaction set. Pure function - no I/O, no global state. Returns
undefined only when ST-01 is not "277" (mis-routed call); every
other deviation is recoverable and surfaces on result.warnings. The
transactionType discriminator is derived from ST-03
(005010X214 → "claim-acknowledgment", otherwise "claim-status").
Parameters
delimiters
tx
Returns
X12ClaimStatusResponse | undefined
Example
import { parseX12, get277Status } from "@cosyte/x12";
const ix = parseX12(raw);
for (const group of ix.groups) {
for (const tx of group.transactions) {
if (tx.st.elements[1] !== "277") continue;
const status = get277Status(ix.delimiters, tx);
for (const claim of status?.claims ?? []) {
claim.traces[0]?.referenceId; // echoed 276 trace
claim.statuses[0]?.statuses[0]?.statusCode; // "20"
}
}
}
get278Request()
get278Request(
delimiters,tx):X12ServicesReview|undefined
Extract a typed X12ServicesReview from a 278 request
(005010X217). Pure function - no I/O. Returns undefined only when the
transaction's ST-01 is not "278" (mis-routed call); every other
deviation is recoverable and surfaces on result.warnings.
Parameters
delimiters
tx
Returns
X12ServicesReview | undefined
Example
import { parseX12, get278Request } from "@cosyte/x12";
const ix = parseX12(raw);
const tx = ix.groups[0]?.transactions.find((t) => t.st.elements[1] === "278");
if (tx !== undefined) {
const req = get278Request(ix.delimiters, tx);
req?.reviews[0]?.requestCategoryCode; // "HS"
req?.reviews[0]?.diagnoses[0]?.code; // "E1165"
}
get278Response()
get278Response(
delimiters,tx):X12ServicesReview|undefined
Extract a typed X12ServicesReview from a 278 response
(005010X216). Same lenient walk as get278Request; the HCR
decision under each event / service review is the response's
safety-critical addition. Returns undefined only on a mis-routed ST-01.
Parameters
delimiters
tx
Returns
X12ServicesReview | undefined
Example
import { parseX12, get278Response } from "@cosyte/x12";
const ix = parseX12(raw);
const tx = ix.groups[0]?.transactions.find((t) => t.st.elements[1] === "278");
if (tx !== undefined) {
const resp = get278Response(ix.delimiters, tx);
resp?.reviews[0]?.decision?.actionCode; // "A1"
resp?.reviews[0]?.decision?.reviewIdentificationNumber; // "AUTH123456"
}
get820Payments()
get820Payments(
delimiters,tx):X12PremiumPayments|undefined
Extract a typed X12PremiumPayments from an 820 transaction set.
Pure function - no I/O, no global state. Returns undefined only if the
input transaction's ST-01 is not "820" (mis-routed call); every other
deviation is recoverable and the verbatim segments remain on
tx.segments.
Parameters
delimiters
tx
Returns
X12PremiumPayments | undefined
Example
import { parseX12, get820Payments } from "@cosyte/x12";
const ix = parseX12(raw);
const tx = ix.groups[0]?.transactions.find((t) => t.st.elements[1] === "820");
if (tx !== undefined) {
const prem = get820Payments(ix.delimiters, tx);
prem?.payment.totalPremiumAmount?.toString();
for (const r of prem?.remittances ?? []) {
r.openItems[0]?.amountPaid?.toString();
}
}
get834Enrollments()
get834Enrollments(
delimiters,tx):AsyncIterable<X12Enrollment>
Stream the 834 member-level detail loops - one X12Enrollment per
INS segment. For a non-834 transaction the iterable yields nothing.
Async-generator typed so the contract leaves room for a future
file→iterator streaming source; the v1 implementation iterates the
already-parsed tx.segments synchronously under the hood.
Parameters
delimiters
tx
Returns
AsyncIterable<X12Enrollment>
Example
import { parseX12, get834Enrollments } from "@cosyte/x12";
const ix = parseX12(raw);
const tx = ix.groups[0]?.transactions.find((t) => t.st.elements[1] === "834");
if (tx !== undefined) {
for await (const member of get834Enrollments(ix.delimiters, tx)) {
member.maintenanceTypeCode; // "021"
member.member?.idCode; // verbatim member id
}
}
get834Header()
get834Header(
delimiters,tx):X12EnrollmentHeader|undefined
Extract the 834 header - BGN + sponsor (N1*P5) + payer (N1*IN).
Pure function. Returns undefined only if the input transaction's ST-01
is not "834" (mis-routed call). Stops collecting header parties at the
first INS (member-level detail) - those belong to the member stream.
Parameters
delimiters
tx
Returns
X12EnrollmentHeader | undefined
Example
import { parseX12, get834Header } from "@cosyte/x12";
const ix = parseX12(raw);
const tx = ix.groups[0]?.transactions.find((t) => t.st.elements[1] === "834");
const header = tx === undefined ? undefined : get834Header(ix.delimiters, tx);
header?.sponsor?.name;
get835()
get835(
delimiters,tx):X12Remittance|undefined
Extract a typed X12Remittance from an 835 transaction set.
Pure function - no I/O, no global state. Returns undefined only if
the input transaction's ST-01 is not "835" (mis-routed call); every
other deviation is recoverable and surfaces on result.warnings.
Parameters
delimiters
tx
Returns
X12Remittance | undefined
Example
import { parseX12, get835 } from "@cosyte/x12";
const ix = parseX12(raw);
for (const group of ix.groups) {
for (const tx of group.transactions) {
if (tx.st.elements[1] !== "835") continue;
const remit = get835(ix.delimiters, tx);
remit?.payment.totalActualPayment?.toString();
for (const claim of remit?.claims ?? []) {
claim.totalPaymentAmount?.toString();
}
}
}
get837Claims()
get837Claims(
delimiters,tx,opts?):X12_837Submission|undefined
Extract a typed X12_837Submission from an 837 transaction set.
Pure function - no I/O, no global state. Returns undefined when the
input transaction's ST-01 is not "837" (mis-routed call); every other
deviation is recoverable and surfaces on submission.warnings.
Parameters
delimiters
tx
opts?
type?
"P" | "I" | "D"
Returns
X12_837Submission | undefined
Example
import { parseX12, get837Claims } from "@cosyte/x12";
const ix = parseX12(raw);
for (const group of ix.groups) {
for (const tx of group.transactions) {
if (tx.st.elements[1] !== "837") continue;
const sub = get837Claims(ix.delimiters, tx);
sub?.variant; // "P" / "I" / "D" / "unknown"
for (const claim of sub?.claims ?? []) {
claim.totalCharge?.toString();
claim.diagnoses[0]?.codeSystem; // "ICD-10-CM"
}
}
}
getAllSegmentValues()
getAllSegmentValues(
segment,path,delimiters,emit?): readonlystring[]
Return every repetition / component matching the dot-path. For a path
with no [N] and no -N (e.g. "03"), returns every repetition's
decoded element text. For a path with -N and no [N], returns each
repetition's Nth component. With both [N] and -N specified, returns
a single-element array (or empty if the path doesn't resolve). Every
returned string is post-?-unescape.
Parameters
segment
path
string
delimiters
emit?
(w) => void
Returns
readonly string[]
Example
import { decodeSegment, getAllSegmentValues } from "@cosyte/x12";
const d = { element: "*", repetition: "^", component: ":", segment: "~" };
const seg = decodeSegment(
"HI*ABK:J45.50^ABF:I10",
d,
() => {},
{ segmentIndex: 0 },
);
getAllSegmentValues(seg, "01", d); // ["ABK:J45.50", "ABF:I10"]
getAllSegmentValues(seg, "01-1", d); // ["ABK", "ABF"]
getDefaultProfile()
getDefaultProfile():
X12Profile|undefined
Return the current default profile, or undefined if none is registered.
Returns
X12Profile | undefined
Example
import { getDefaultProfile } from "@cosyte/x12";
const p = getDefaultProfile();
if (p !== undefined) console.log("default profile:", p.name);
getSegmentValue()
getSegmentValue(
segment,path,delimiters,emit?):string|undefined
Resolve a dot-path against a decoded X12Segment and return the
decoded leaf value (post-?-unescape) or undefined if the path does
not resolve (missing element, out-of-range repetition, out-of-range
component). Throws TypeError only when path itself is malformed.
Optional emit collects any dangling-release warnings discovered on the
read path; pass a no-op to silently decode.
Parameters
segment
path
string
delimiters
emit?
(w) => void
Returns
string | undefined
Example
import { decodeSegment, getSegmentValue } from "@cosyte/x12";
const d = { element: "*", repetition: "^", component: ":", segment: "~" };
const seg = decodeSegment(
"HI*ABK:J45.50*ABF:I10",
d,
() => {},
{ segmentIndex: 0 },
);
getSegmentValue(seg, "01-1", d); // "ABK"
getSegmentValue(seg, "01-2", d); // "J45.50"
getSegmentValue(seg, "02-1", d); // "ABF"
groupCountMismatch()
groupCountMismatch(
position):X12ParseWarning
Build an X12_GROUP_COUNT_MISMATCH warning. Emitted when IEA-01 does not
equal the actual number of GS..GE groups present in the interchange.
Trading partners use this to detect transmission truncation. Both numbers
stay on the model and neither is silently corrected.
Parameters
position
Returns
Example
import { groupCountMismatch } from "@cosyte/x12";
const w = groupCountMismatch({ segmentIndex: 5, interchangeIndex: 0, elementIndex: 1 });
hlParentLevelInvalid()
hlParentLevelInvalid(
position):X12ParseWarning
Build an X12_HL_PARENT_LEVEL_INVALID warning. Emitted when an HL's
level code (HL-03) is inconsistent with its declared parent's level code
per the TR3 (e.g. a 22 Subscriber claiming a 22 Subscriber as its
parent, where the parent must be 20 Information Source). Both level
codes stay verbatim on the model.
Parameters
position
Returns
Example
import { hlParentLevelInvalid } from "@cosyte/x12";
const w = hlParentLevelInvalid({ segmentIndex: 14, groupIndex: 0, transactionIndex: 0 });
hlParentMismatch()
hlParentMismatch(
position):X12ParseWarning
Build an X12_HL_PARENT_MISMATCH warning. Emitted when an HL segment's
HL-02 (parent id) does not match any earlier-emitted HL-01 in the same
transaction. The walker NEVER silently re-numbers the hierarchy (HL
parent-pointer integrity is the safety primitive of the 837), so the
declared pointer stays verbatim on hierarchy.parentHlId and the warning
reports only that the pointer is dangling, and where.
Parameters
position
Returns
Example
import { hlParentMismatch } from "@cosyte/x12";
const w = hlParentMismatch({ segmentIndex: 14, groupIndex: 0, transactionIndex: 0 });
isAcceptDisposition()
isAcceptDisposition(
code):boolean
True when the supplied disposition is some form of "accept" (A, E,
P) rather than reject (R, M, W, X). Used by the build-time
safety guard and by consumer code that wants a yes/no on the inbound.
Parameters
code
Returns
boolean
Example
import { isAcceptDisposition } from "@cosyte/x12";
isAcceptDisposition("A"); // true
isAcceptDisposition("R"); // false
isaExtraElementSeparator()
isaExtraElementSeparator(
position):X12ParseWarning
Build an X12_ISA_EXTRA_ELEMENT_SEPARATOR warning. Emitted when the ISA
element area (bytes 0..104) splits on the detected element separator into
anything other than ["ISA", e1, …, e16].
detectDelimiters has already verified that the separator sits at all 16
fixed 005010 positions, so the split can only come out LONGER than 17: an
ISA element value is itself carrying the byte that was declared in-band as
the element separator. The interchange is not 005010-conformant either way,
and the parser does not choose between the two readings of that byte - it
reports that the header did not frame and leaves isa.elements exactly as
the split produced it, with isa.raw carrying all 106 bytes verbatim.
decodeEnvelope raises this ahead of every warning it raises after it,
because when it is present the ISA-derived diagnostics that follow
(X12_PRE_005010 off elements[12], X12_CONTROL_NUMBER_MISMATCH off
elements[13]) may be reading a displaced element rather than the one they
name. That is a statement about parseX12's warnings (and onWarning)
and about nothing else. serializeX12(ix, { specClean: true }) runs its own
reconciliation off interchange.isa.elements[13] with no arity awareness and
never raises this code, so on that channel a lone
X12_CONTROL_NUMBER_MISMATCH can be a displaced read - and its absence is not
evidence the header framed. Filed, not fixed here.
Parameters
position
Returns
Example
import { isaExtraElementSeparator } from "@cosyte/x12";
const w = isaExtraElementSeparator({ segmentIndex: 0, interchangeIndex: 0 });
isClaimAdjustmentGroupCode()
isClaimAdjustmentGroupCode(
value):value is ClaimAdjustmentGroupCode
Narrow an inbound CAS-01 string to a ClaimAdjustmentGroupCode.
false means the inbound code is not one of the 4 spec-defined values
(e.g. a typo "CR" from a quirky payer); the verbatim value is still
preserved on the parsed model, and the consumer can branch on the
narrow result.
Parameters
value
string
Returns
value is ClaimAdjustmentGroupCode
Example
import { isClaimAdjustmentGroupCode } from "@cosyte/x12";
isClaimAdjustmentGroupCode("PR"); // true
isClaimAdjustmentGroupCode("CR"); // false (unknown)
isDiagnosisQualifier()
isDiagnosisQualifier(
qualifier):boolean
Decide whether an HI qualifier represents a diagnosis (principal, secondary, admitting, reason-for-visit, external-cause). Used by variant-specific extractors that split the HI segment family into diagnoses vs procedures.
Parameters
qualifier
string
Returns
boolean
Example
import { isDiagnosisQualifier } from "@cosyte/x12";
isDiagnosisQualifier("ABK"); // true (principal diagnosis)
isDiagnosisQualifier("BBR"); // false (procedure)
isDiagnosisQualifier("XYZ"); // false
isProcedureQualifier()
isProcedureQualifier(
qualifier):boolean
Decide whether an HI qualifier represents a procedure (principal or other) - current ICD-10-PCS or legacy ICD-9-PCS.
Parameters
qualifier
string
Returns
boolean
Example
import { isProcedureQualifier } from "@cosyte/x12";
isProcedureQualifier("BBR"); // true (other procedure, ICD-10-PCS)
isProcedureQualifier("ABK"); // false (diagnosis)
missingGe()
missingGe(
position):X12ParseWarning
Build an X12_MISSING_GE warning. Emitted when a GS opened a functional
group but no matching GE appeared before the next GS or IEA. The parser
returns the group with ge: undefined and the transactions it managed
to collect.
Parameters
position
Returns
Example
import { missingGe } from "@cosyte/x12";
const w = missingGe({ segmentIndex: 3, interchangeIndex: 0, groupIndex: 0 });
missingIea()
missingIea(
position):X12ParseWarning
Build an X12_MISSING_IEA warning. Emitted when the input opened a
valid ISA but EOF arrived before any IEA segment. The parser returns the
groups it managed to decode with iea: undefined; the warning surfaces
the structural break so consumers know the interchange is truncated.
Parameters
position
Returns
Example
import { missingIea } from "@cosyte/x12";
const w = missingIea({ segmentIndex: 4, interchangeIndex: 0 });
missingRequiredLoop()
missingRequiredLoop(
position,loop):X12ParseWarning
Build an X12_MISSING_REQUIRED_LOOP warning. Emitted when a TR3-required
loop is structurally absent (e.g. no Loop 2010BB Payer Name inside a
Subscriber HL). The parser does not enforce situational rules: only loops
marked usage: "required" in the loop spec fire this warning, so the
loop id and its rationale are both library constants.
Parameters
position
loop
Returns
Example
import { missingRequiredLoop, REQUIRED_LOOPS } from "@cosyte/x12";
const w = missingRequiredLoop(
{ segmentIndex: 12, groupIndex: 0, transactionIndex: 0 },
REQUIRED_LOOPS.PAYER_NAME_2010BB,
);
missingSe()
missingSe(
position):X12ParseWarning
Build an X12_MISSING_SE warning. Emitted when an ST opened a
transaction set but no matching SE appeared before the next ST, GE, or
IEA. The parser returns the transaction with se: undefined and the
segments it managed to collect.
Parameters
position
Returns
Example
import { missingSe } from "@cosyte/x12";
const w = missingSe({ segmentIndex: 2, groupIndex: 0, transactionIndex: 0 });
parse999()
parse999(
raw,options?):X12Ack999|undefined
Decode a 005010X231A1 Implementation Acknowledgment from a raw string
or Buffer. Returns the typed X12Ack999 or undefined when the
input does not contain any 999 transaction set. Lenient on parse: every
recoverable deviation surfaces as an envelope-level warning (see
X12Ack999.warnings).
Parameters
raw
string | Buffer<ArrayBufferLike>
options?
X12ParseOptions = {}
Returns
X12Ack999 | undefined
Example
import { parse999 } from "@cosyte/x12";
const ack = parse999(rawBytes);
if (ack !== undefined) {
ack.ak9.disposition; // "A" | "E" | "P" | "R" | "M" | "W" | "X"
ack.transactionResponses[0]?.ik5.disposition;
}
parseTA1()
parseTA1(
interchange):X12AckTA1|undefined
Decode the first TA1 Interchange Acknowledgment on the supplied
interchange. Returns the typed X12AckTA1 or undefined when
the interchange has no TA1 (the common case for non-ack inbounds).
Parameters
interchange
Returns
X12AckTA1 | undefined
Example
import { parseTA1, parseX12 } from "@cosyte/x12";
const ix = parseX12(rawAckBytes);
const ta1 = parseTA1(ix);
if (ta1?.ackCode === "R") {
// inbound interchange was rejected
}
parseX12()
Internal
- implementation signature; overload signatures above carry the public JSDoc + @example.
Call Signature
parseX12(
raw):X12Interchange
Parse a raw X12 healthcare interchange (string or Buffer) into an
X12Interchange. The parser is lenient by default: recoverable
deviations from 005010 are reported via ix.warnings and (optionally)
options.onWarning, never thrown. Four unrecoverable structural errors
throw X12ParseError: X12_EMPTY_INPUT, X12_NO_ISA_HEADER,
X12_ISA_TOO_SHORT, X12_INVALID_DELIMITERS. Opt into strict mode with
{ strict: true } to escalate every Tier-2 warning into an
X12ParseError carrying the warning's code. A strict-mode escalation
carries an empty snippet: the warning it wraps is registry-built and
fully located by position, so there is nothing to redact.
Phase 1 decodes the envelope (ISA / GS / ST / SE / GE / IEA) and
detects the four delimiters from fixed ISA byte positions. Transaction-
set bodies inside each ST..SE are kept opaque at this phase -
tx.segments carries the raw segment strings (terminator stripped).
Phase 2 adds segment/element/composite/repetition decode on top.
Parameters
raw
string | Buffer<ArrayBufferLike>
Returns
Example
import { parseX12, WARNING_CODES } from "@cosyte/x12";
const raw = "ISA*00* *00* *ZZ*SENDER *ZZ*RECEIVER *250101*1200*^*00501*000000001*0*P*:~GS*HC*S*R*20250101*1200*1*X*005010X222A2~ST*837*0001~SE*2*0001~GE*1*1~IEA*1*000000001~";
const ix = parseX12(raw);
ix.delimiters.element; // "*"
ix.delimiters.component; // ":"
ix.delimiters.segment; // "~"
ix.groups[0]?.gs.elements[1]; // raw text of GS-01 (pre-?-unescape)
for (const w of ix.warnings) {
if (w.code === WARNING_CODES.X12_PRE_005010) {
// sender on pre-005010 version family
}
}
Call Signature
parseX12(
raw,options):X12Interchange
Parse a raw X12 healthcare interchange (string or Buffer) into an
X12Interchange. The parser is lenient by default: recoverable
deviations from 005010 are reported via ix.warnings and (optionally)
options.onWarning, never thrown. Four unrecoverable structural errors
throw X12ParseError: X12_EMPTY_INPUT, X12_NO_ISA_HEADER,
X12_ISA_TOO_SHORT, X12_INVALID_DELIMITERS. Opt into strict mode with
{ strict: true } to escalate every Tier-2 warning into an
X12ParseError carrying the warning's code. A strict-mode escalation
carries an empty snippet: the warning it wraps is registry-built and
fully located by position, so there is nothing to redact.
Phase 1 decodes the envelope (ISA / GS / ST / SE / GE / IEA) and
detects the four delimiters from fixed ISA byte positions. Transaction-
set bodies inside each ST..SE are kept opaque at this phase -
tx.segments carries the raw segment strings (terminator stripped).
Phase 2 adds segment/element/composite/repetition decode on top.
Parameters
raw
string | Buffer<ArrayBufferLike>
options
Returns
Example
import { parseX12, WARNING_CODES } from "@cosyte/x12";
const raw = "ISA*00* *00* *ZZ*SENDER *ZZ*RECEIVER *250101*1200*^*00501*000000001*0*P*:~GS*HC*S*R*20250101*1200*1*X*005010X222A2~ST*837*0001~SE*2*0001~GE*1*1~IEA*1*000000001~";
const ix = parseX12(raw);
ix.delimiters.element; // "*"
ix.delimiters.component; // ":"
ix.delimiters.segment; // "~"
ix.groups[0]?.gs.elements[1]; // raw text of GS-01 (pre-?-unescape)
for (const w of ix.warnings) {
if (w.code === WARNING_CODES.X12_PRE_005010) {
// sender on pre-005010 version family
}
}
partitionWarnings()
partitionWarnings(
warnings,profile):X12WarningPartition
Split a parse's warnings against a profile's expected-warning union. A
warning whose code is in the profile's expectedWarnings lands in
expected; everything else lands in unexpected. Order within each bucket
preserves the input order.
Parameters
warnings
readonly X12ParseWarning[]
profile
Returns
Example
import { parseX12, partitionWarnings, profiles } from "@cosyte/x12";
const ix = parseX12(raw, { profile: profiles.availity });
const { expected, unexpected } = partitionWarnings(ix.warnings, profiles.availity);
if (unexpected.length > 0) flagForReview(unexpected);
payToAddressRepeated()
payToAddressRepeated(
position):X12ParseWarning
Build an X12_837_PAY_TO_ADDRESS_REPEATED warning. Emitted by the 837
helper at the second and each subsequent NM1*87 within one Loop 2000A,
where the TR3s allow Loop 2010AB at most once. position names the
repeated NM1*87 itself, which is the segment a consumer resolves back
through tx.segments; there is no elementIndex, because what is being
reported is a second occurrence of the segment rather than a defect in
any element of it.
Once per repeat, so two repeats in one Loop 2000A are two warnings. The
counter resets at the Loop 2000A HL, beside the pay-to slot it guards -
a first NM1*87 under a later billing provider is a first, not a repeat.
It reports that the DOCUMENT named the pay-to address more than once. It does NOT report that anything was mis-read, and it is not a service-line or entity-segment code: nothing else on the channel says this, and this says nothing about the other 837 codes' subjects.
The rule the reader applies, because a consumer cannot infer it from a
one-slot model: occurrences are never merged, the last occurrence that
states an address of its own wins, and an occurrence that states none does
not blank one that did. "States an address" means exactly what the emit
side would write a segment for - see ./address-segments.ts, which both
sides share so they cannot drift.
Parameters
position
Returns
Example
import { payToAddressRepeated } from "@cosyte/x12";
const w = payToAddressRepeated({ segmentIndex: 12, transactionIndex: 0 });
pre005010()
pre005010(
position):X12ParseWarning
Build an X12_PRE_005010 warning. Emitted when ISA-12 declares any version
other than 00501, the HIPAA-mandated baseline. The code name reads as a
"pre-005010" test and the guard is an inequality, so a LATER family
(00602, 00700) raises it too. The parser still
accepts the input (Postel's Law: lenient on parse) but flags the
mismatch so consumers know the input may diverge from 005010 semantics.
The declared version stays on isa.elements[12].
Parameters
position
Returns
Example
import { pre005010 } from "@cosyte/x12";
const w = pre005010({ segmentIndex: 0, interchangeIndex: 0, elementIndex: 12 });
readElementDecimal()
readElementDecimal(
seg,n,delimiters):X12DecimalRead
Read element N (1-indexed) as an X12Decimal and say WHY when there is no value. This is the chokepoint every decimal read in the library goes through, and the only surface that distinguishes an element the sender omitted from one this library could not decode.
Pure: it never warns and never throws. elementDecimal and elementDecimalOrZero wrap it and add the diagnostic.
Parameters
seg
n
number
delimiters
Returns
Example
import { readElementDecimal } from "@cosyte/x12";
readElementDecimal(seg, 2, delim); // { value: undefined, status: "unparseable" }
remitBalanceMismatch()
remitBalanceMismatch(
position,invariant):X12ParseWarning
Build an X12_835_REMIT_BALANCE_MISMATCH warning. Emitted by the 835
helper when a TR3 X221A1 §1.10.2 balance invariant fails. invariant
names which equation broke; the spec'd, computed and delta amounts stay
on the model as "../decimal.js".X12Decimal values and are never
rendered into the message.
The parser ALWAYS surfaces this and NEVER silently rebalances. To report
the numbers, recompute them from the model: claim.totalChargeAmount,
claim.totalPaymentAmount and the CAS adjustments are all present.
Parameters
position
invariant
Returns
Example
import { remitBalanceMismatch, BALANCE_INVARIANTS } from "@cosyte/x12";
const w = remitBalanceMismatch(
{ segmentIndex: 12, groupIndex: 0, transactionIndex: 0 },
BALANCE_INVARIANTS.CLAIM,
);
renderCallerValue()
renderCallerValue(
value):string
Render a caller-supplied value as a bounded, quoted fragment for a build*
refusal message. This is the only sanctioned route a caller value takes
into a thrown message, and test/builder-refusal-bounds.test.ts scans
src/ for any other route - a twenty-fifth refusal site that interpolates a
value directly reds that test. That scan keys on throw new *BuildError( and
on template-literal holes, so it is a strong tripwire for the shape this
library uses rather than a proof over every shape one could write.
Returns the value quoted when it fits, and otherwise the first BUILD_REFUSAL_VALUE_MAX_LENGTH characters, an ellipsis, and the true length - the length is the diagnostically useful part when the value is over-long, since that is usually why the builder refused.
Parameters
value
string | number
Returns
string
Example
import { renderCallerValue } from "@cosyte/x12";
renderCallerValue("000000001"); // '"000000001"'
renderCallerValue("9".repeat(120000)); // '"999…" (120000 characters)'
resolveHiQualifier()
resolveHiQualifier(
qualifier):HiQualifierEntry|undefined
Resolve an HI qualifier string into a HiQualifierEntry, or
undefined if the qualifier is outside the bundled snapshot. Unknown
qualifiers still parse - the parser preserves the verbatim qualifier on
the diagnosis/procedure and emits X12_UNKNOWN_HI_QUALIFIER. The lookup
is case-sensitive (TR3 qualifiers are uppercase).
Parameters
qualifier
string
Returns
HiQualifierEntry | undefined
Example
import { resolveHiQualifier } from "@cosyte/x12";
resolveHiQualifier("ABK")?.system; // "ICD-10-CM"
resolveHiQualifier("ABK")?.category; // "principal-diagnosis"
resolveHiQualifier("XYZ"); // undefined
segmentCountMismatch()
segmentCountMismatch(
position):X12ParseWarning
Build an X12_SEGMENT_COUNT_MISMATCH warning. Emitted by the spec-clean
serializer when an SE-01 value does not equal the actual number of
segments in the transaction set it closes (ST through SE inclusive).
Corrected counts are emitted only on serializeX12(ix, { specClean: true, recomputeCounts: true }). The parser does not emit this code (it leaves
SE-01 reconciliation to the emit half); it is a Phase-8 serializer
diagnostic.
Parameters
position
Returns
Example
import { segmentCountMismatch } from "@cosyte/x12";
const w = segmentCountMismatch({ segmentIndex: 2, transactionIndex: 0, elementIndex: 1 });
serializeX12()
serializeX12(
interchange,opts?):string
Serialize an X12Interchange back to an X12 byte stream. Pure function - never throws, never mutates the input, never performs I/O. See the module header for the two emit modes.
Parameters
interchange
opts?
SerializeOptions = {}
Returns
string
Example
import { parseX12, serializeX12 } from "@cosyte/x12";
const ix = parseX12(raw);
// Segments on the model come back verbatim, orphans included. Anything the
// parser did not record (line breaks, a doubled terminator, ...) does not,
// so this is not guaranteed to equal `raw`. See the module header.
const bytes = serializeX12(ix);
serviceLineDropped()
serviceLineDropped(
position):X12ParseWarning
Build an X12_837_SERVICE_LINE_DROPPED warning. Emitted by the 837
helper when an LX opens no Loop 2400 at all, so the service line never
reaches any claim's serviceLines: either no CLM is open at that point
in the walk, or the submission's variant is not one of P / I / D
and there is no variant-specific line shape to build. That second cause
is reachable WITHOUT X12_837_UNKNOWN_VARIANT, because a caller-supplied
opts.type outside the union (from JavaScript or a JSON payload) is a
variant this reader never resolved and never warned about. Distinct from
serviceLineNotDecoded, where the line IS retained and only its
service segment went unread. position names the LX itself - the same
anchor, for the same reason: it is the one segment present in every
case. Nothing is fabricated to stand in, and the segments stay verbatim
on the transaction set.
Parameters
position
Returns
Example
import { serviceLineDropped } from "@cosyte/x12";
const w = serviceLineDropped({ segmentIndex: 7, transactionIndex: 0 });
serviceLineNotDecoded()
serviceLineNotDecoded(
position):X12ParseWarning
Build an X12_837_SERVICE_LINE_NOT_DECODED warning. Emitted by the 837
helper when a Loop 2400 service line is closed without ever having
decoded an SV1 / SV2 / SV3 for the resolved variant: either the line
carries no SVx at all, or it carries one belonging to a different 837
variant than ST-03 (or the caller's type option) named. The line is
still retained, and every segment stays verbatim on the transaction set,
but the line's charge and units are undefined rather than anything
read off the wire. Through 0.0.12 they were the accumulator's seeded
X12Decimal.ZERO, which a consumer could not tell from a charge of zero
the sender did state. position names the LX segment that opened the
line.
Parameters
position
Returns
Example
import { serviceLineNotDecoded } from "@cosyte/x12";
const w = serviceLineNotDecoded({ segmentIndex: 9, transactionIndex: 0 });
serviceSegmentRepeated()
serviceSegmentRepeated(
position):X12ParseWarning
Build an X12_837_SERVICE_SEGMENT_REPEATED warning. Emitted by the 837
helper at the second and each subsequent SV1 / SV2 / SV3 to arrive
inside one open Loop 2400. position names the repeated service segment
itself, which is the segment a consumer resolves back through
tx.segments; there is no elementIndex, because what is reported is a
second occurrence of the segment rather than a defect in any element of it.
Once per repeat, so three service segments in one Loop 2400 are two
warnings. The count lives on the line and is cleared when the line flushes,
so a first service segment under a later LX is a first and never a
repeat - a scope, not a latch.
The rule the reader applies, because a consumer cannot infer it from a
one-slot model: occurrences are never merged and the LAST one matching
the submission's resolved variant wins, writing every slot its kind writes.
So an earlier matching occurrence leaves nothing on the line, not even in a
slot the later one's own element is absent from - there the later one's
undefined replaces an amount the earlier one stated. Through 0.0.13 a
charge of 8500 and a CPT of 99213 were replaced by a repeat's 12 and
99999 with warnings: []. An occurrence whose kind does NOT match the
resolved variant is read into nothing and overwrites nothing.
It reports that the DOCUMENT sent more than one, and asserts nothing about what usage the TR3s give the segment. It does not decide which occurrence the sender meant: this reader cannot tell a stray service segment from a conformant one, exactly as ambiguous837Variant records for the variant fallback.
Disjoint from serviceSegmentWithoutLx by construction - that one
fires only where no Loop 2400 is open and this one only where one is - so
the two can never name the same segment. Read that as disjointness only:
a service segment following an LX that opened no line is named by
NEITHER, because serviceLineDropped at that LX already reports
the loss and suppresses the orphan code. serviceLineNotDecoded is
raised at the LX and reports that no matching service segment decoded
onto the line at all; a document can carry both codes on different
segments.
Parameters
position
Returns
Example
import { serviceSegmentRepeated } from "@cosyte/x12";
const w = serviceSegmentRepeated({ segmentIndex: 9, transactionIndex: 0 });
serviceSegmentWithoutLx()
serviceSegmentWithoutLx(
position):X12ParseWarning
Build an X12_837_SERVICE_SEGMENT_WITHOUT_LX warning. Emitted by the 837
helper when an SV1 / SV2 / SV3 arrives with no Loop 2400 open, so there is
no service line to decode it into and nothing the segment carries is read.
position names the service segment itself, because it is the only
segment the case has: the other two 837 service-line codes both anchor at
an LX, and there is no LX in scope here to anchor to. An LX may still
appear elsewhere in the transaction - in an earlier claim, say - so read
the condition as "no line was open", not as "the file has no LX".
The three do not overlap on one segment. serviceLineDropped is raised at an LX that opened no line, serviceLineNotDecoded at an LX whose line was retained undecoded, and this one only where no line is open. Nothing is fabricated to stand in and no line or claim is synthesized; the segments stay verbatim on the transaction set.
It says nothing about the submission's variant. A caller-supplied type
option wins first; absent one, and where ST-03 names no known
implementation convention, the reader falls back to the first
SV1 / SV2 / SV3 in the transaction, and a segment reported here is
eligible for that fallback like any other - pre-existing behaviour,
documented in KNOWN-LIMITATIONS.md and unchanged. Where that fallback
decided the variant and the body names more than one,
ambiguous837Variant reports the resolution as contested; it is
additive and does not change which documents reach this code.
Parameters
position
Returns
Example
import { serviceSegmentWithoutLx } from "@cosyte/x12";
const w = serviceSegmentWithoutLx({ segmentIndex: 8, transactionIndex: 0 });
setDefaultProfile()
setDefaultProfile(
profile):void
Register a process-scoped default profile. parseX12(raw) (no explicit
profile arg) consults getDefaultProfile() and attaches the returned
profile to the result. Pass null (or undefined) to clear.
Explicit args ALWAYS win - parseX12(raw, { profile: myProfile }) uses
myProfile regardless of the default; parseX12(raw, { profile: null })
opts out of the default for a single call without changing the registered
default.
Test hygiene: the only mutable module-scoped state in the library.
Tests that call this MUST clean up in afterEach (setDefaultProfile(null)).
Parameters
profile
X12Profile | null
Returns
void
Example
import { setDefaultProfile, getDefaultProfile, profiles, parseX12 } from "@cosyte/x12";
setDefaultProfile(profiles.availity);
const ix = parseX12(raw);
ix.profile?.name; // "availity"
setDefaultProfile(null); // clear (or in test teardown)
statedAmountDiscarded()
statedAmountDiscarded(
position):X12ParseWarning
Build an X12_STATED_AMOUNT_DISCARDED warning. Emitted where a segment
POPULATED its amount element, the loop that would carry its row was open,
and the reader built no row anyway - for a reason that is not a failure to
decode that amount. The money the sender wrote is on no part of the typed
model. This code asserts nothing about whether that amount is decodable:
route 2 below decoded it, route 1 never attempted the decode.
Two routes, enumerated because a count without its list cannot correct itself:
- An 820
RMRunder an open remittance loop whose RMR-01 and RMR-02 are BOTH empty while RMR-04 or RMR-05 is populated.decodeRmrrefuses the open item on identity before either amount element is read, so a stated payment, a stated amount due and the payment action code beside them are lost together. - An 837
AMTarriving while a Loop 2430 line adjudication (SVD) is open, whose AMT-02 decoded. The v1 adjudication model carries no amount row, so the row is skipped rather than attached to the service line, which is this reader's own line and not the other payer's.
position names the RMR / AMT segment itself and carries NO
elementIndex: on the first route the loss spans RMR-04 and RMR-05 and no
single element names it, and on the second the element is fixed by the
segment.
Read the bound as a property of the READ. This does NOT report an AMT or
ADX that reaches a reader with no loop open to carry its row at all: the
834's AMT with no HD open, the 820's ADX with no remittance open, and
the 835's and the 837's AMT that decodes before any claim or service line
is open are all still silent, and recorded in KNOWN-LIMITATIONS.md. It is
additive: unparseableDecimal and amountRowDropped fire on
exactly the documents they fired on before. On route 1 no
X12_UNPARSEABLE_DECIMAL accompanies this code even where the amount bytes
are unreadable, because that route never attempts the decode - so never read
an unaccompanied instance as evidence the bytes are postable. Read them off
the segment and decode them yourself.
Parameters
position
Returns
Example
import { statedAmountDiscarded } from "@cosyte/x12";
const w = statedAmountDiscarded({ segmentIndex: 9, transactionIndex: 0 });
trailingGarbage()
trailingGarbage(
position):X12ParseWarning
Build an X12_TRAILING_GARBAGE warning. Emitted when non-empty bytes
appear after the IEA segment terminator and any optional CRLF. The bytes
are preserved verbatim on "./types.js".X12Interchange.trailingBytes so consumers can inspect,
measure, or re-emit them. Common cause: a second interchange concatenated
into the same file (multi-ISA, out of v1 scope; only the first
interchange is decoded).
Parameters
position
Returns
Example
import { trailingGarbage } from "@cosyte/x12";
const w = trailingGarbage({ segmentIndex: 6, interchangeIndex: 0 });
transactionCountMismatch()
transactionCountMismatch(
position):X12ParseWarning
Build an X12_TRANSACTION_COUNT_MISMATCH warning. Emitted when GE-01
does not equal the actual number of ST..SE transaction sets present in
the group. Both numbers stay on the model.
Parameters
position
Returns
Example
import { transactionCountMismatch } from "@cosyte/x12";
const w = transactionCountMismatch({ segmentIndex: 4, groupIndex: 0, elementIndex: 1 });
unescapeRelease()
unescapeRelease(
input,delimiters,emit,position):string
Reverse a single X12 release-character escape sequence. Consumes ? plus
its target byte when the target is one of the four detected delimiters or
another ?; preserves the ? verbatim when the target is anything else
(Postel's-Law tolerance - the spec leaves the ?A case ambiguous and
preserving the bytes is the most defensible behavior).
Emits a single Tier-2 X12_DANGLING_RELEASE_CHAR warning when the input
ends with a bare ? (no target byte to escape) - the bytes are preserved
verbatim so round-trip is still byte-exact.
Parameters
input
string
delimiters
emit
(w) => void
position
Returns
string
Example
import { unescapeRelease } from "@cosyte/x12";
const d = { element: "*", repetition: "^", component: ":", segment: "~" };
unescapeRelease("a?~b", d, () => {}, { segmentIndex: 0 }); // "a~b"
unescapeRelease("a??b", d, () => {}, { segmentIndex: 0 }); // "a?b"
unescapeRelease("a?Xb", d, () => {}, { segmentIndex: 0 }); // "a?Xb" (preserved)
unexpectedSegment()
unexpectedSegment(
position,context):X12ParseWarning
Build an X12_UNEXPECTED_SEGMENT warning. Emitted when a structurally
meaningful segment (GE, SE, ST, TA1, or a body segment) appears
outside its expected parent. The parser preserves lenient-never-throw and
continues; context names which structural rule broke and position
locates the segment.
The segment's own id is deliberately not a parameter. Note that a segment
in one of these positions is NOT retained on the model at all (it has no
open container to belong to), so position.segmentIndex against the input
is the only way back to its bytes. For a segment that IS retained, the
X12Segment.id a consumer reads is bounded to the X12 segment-id grammar
(see "./segment.js".decodeSegment) while seg.raw and
seg.elements[0] stay verbatim.
Parameters
position
context
Returns
Example
import { unexpectedSegment, UNEXPECTED_SEGMENT_CONTEXTS } from "@cosyte/x12";
const w = unexpectedSegment(
{ segmentIndex: 12, interchangeIndex: 0 },
UNEXPECTED_SEGMENT_CONTEXTS.GE_WITHOUT_GS,
);
unknown837Variant()
unknown837Variant(
position):X12ParseWarning
Build an X12_837_UNKNOWN_VARIANT warning. Emitted when the 837 helper
cannot resolve the variant from ST-03's implementation-convention
reference AND no SVx service-line segment is present to fall back on.
The parsed submission still ships with variant: "unknown", and the
walker does its best on shared structure (envelope, HL, claim header) and
skips variant-specific service-line decoding. This message deliberately
points at no model field. Recognition reads ST-03 as FRAMED while
submission.implementationConventionReference is decoded of any ? release
escape, so on a document that escapes a delimiter inside ST-03 the two
differ and the model field can hold an identifier this code just said was
not recognised. A pointer stood here and
in the message text and is DELETED, not reworded.
get837Claims anchors this at the ST, which is tx.segments[0] and
carries the ST-03 the resolution reads. Through 0.0.10 it passed
segmentIndex: 1, which is the BHT and has no part in resolving a variant.
Parameters
position
Returns
Example
import { unknown837Variant } from "@cosyte/x12";
const w = unknown837Variant({ segmentIndex: 0, groupIndex: 0, transactionIndex: 0 });
unknownCarc()
unknownCarc(
position):X12ParseWarning
Build an X12_UNKNOWN_CARC warning. Emitted when a CAS adjustment
carries a CARC code outside the bundled snapshot (see
"../code-lists/carc.js".CARC). The verbatim code is preserved on
the parsed adjustment (adjustment.reasonCode); only the description is
missing.
Parameters
position
Returns
Example
import { unknownCarc } from "@cosyte/x12";
const w = unknownCarc({ segmentIndex: 14, groupIndex: 0, transactionIndex: 0 });
unknownClaimStatus()
unknownClaimStatus(
position):X12ParseWarning
Build an X12_UNKNOWN_CLAIM_STATUS warning. Companion to
unknownClaimStatusCategory for the Claim Status Code (CSC, the
second component of an STC composite; X12 code source 508). Same
verbatim-preserve posture.
Parameters
position
Returns
Example
import { unknownClaimStatus } from "@cosyte/x12";
const w = unknownClaimStatus({ segmentIndex: 18, transactionIndex: 0 });
unknownClaimStatusCategory()
unknownClaimStatusCategory(
position):X12ParseWarning
Build an X12_UNKNOWN_CLAIM_STATUS_CATEGORY warning. Emitted by the 277
/ 277CA helpers when an STC composite's Claim Status Category Code
(CSCC, first component; X12 code source 507) is outside the bundled
snapshot. The verbatim CSCC is preserved on the parsed status; only the
description is missing.
Parameters
position
Returns
Example
import { unknownClaimStatusCategory } from "@cosyte/x12";
const w = unknownClaimStatusCategory({ segmentIndex: 18, transactionIndex: 0 });
unknownHiQualifier()
unknownHiQualifier(
position):X12ParseWarning
Build an X12_UNKNOWN_HI_QUALIFIER warning. Emitted by the 837 / 278
helpers when an HI composite's qualifier (first component) is outside the
bundled snapshot at "../code-lists/hi-qualifiers.js". HI_QUALIFIERS. The verbatim qualifier and code are preserved on the
parsed diagnosis / procedure with codeSystem: "unknown" so consumers
can still react.
Parameters
position
Returns
Example
import { unknownHiQualifier } from "@cosyte/x12";
const w = unknownHiQualifier({ segmentIndex: 25, groupIndex: 0, transactionIndex: 0 });
unknownMaintenanceType()
unknownMaintenanceType(
position):X12ParseWarning
Build an X12_834_UNKNOWN_MAINTENANCE_TYPE warning. Emitted by the 834
helper when a member-level INS-03 (or a health-coverage HD-01)
maintenance type code falls outside the bundled snapshot (see
"../code-lists/maintenance-type.js".MAINTENANCE_TYPE_CODES).
Maintenance type is the 834's safety-critical field: an unknown action
code must NEVER be silently coerced to add / change / terminate, so the
verbatim code is preserved on the parsed enrollment and this warning
flags the gap.
Parameters
position
Returns
Example
import { unknownMaintenanceType } from "@cosyte/x12";
const w = unknownMaintenanceType({ segmentIndex: 9, transactionIndex: 0 });
unknownRarc()
unknownRarc(
position):X12ParseWarning
Build an X12_UNKNOWN_RARC warning. Companion to unknownCarc
for RARC codes on MIA / MOA / LQ / NTE. Same verbatim-preserve
posture; the code lives on the parsed remark.
Parameters
position
Returns
Example
import { unknownRarc } from "@cosyte/x12";
const w = unknownRarc({ segmentIndex: 16, groupIndex: 0, transactionIndex: 0 });
unparseableDecimal()
unparseableDecimal(
position):X12ParseWarning
Build an X12_UNPARSEABLE_DECIMAL warning. Emitted whenever an element
read as a decimal held bytes that are NOT empty and do not match the shape
"../decimal.js".X12Decimal decodes, [+-]?digits(.digits?)? - a
thousands separator, a currency symbol, N/A, two decimal points, a
trailing sign, and so on. That shape is what this library reads, stated as
such: no clause of X12.6 is cited for it here, so do not read the code as
an assertion about what type R does and does not permit.
The warning is a property of the READ, not of what the caller does with the result: it fires whether the decoded slot ends up on the model, is discarded, or is replaced by a stand-in. That is what makes it countable against the input rather than against the walker's control flow.
position.elementIndex is the 1-indexed element that failed, so a
consumer can go read the verbatim bytes off the segment. The message
takes NO discriminant and deliberately does not name what landed in the
slot instead: this library's own readers now either leave the slot
undefined or drop the row entirely, and a reader built on
"./segment.js".elementDecimalOrZero still substitutes
X12Decimal.ZERO. The one thing true of all of them is that whatever
occupies that slot is not the sender's. Read the model field itself to
see which happened.
Parameters
position
Returns
Example
import { unparseableDecimal } from "@cosyte/x12";
const w = unparseableDecimal({ segmentIndex: 3, transactionIndex: 0, elementIndex: 2 });