NEWFree ROI Calculators — quantify what prior auth and siloed data are costing your organization.Prior Auth ROI Siloed Data ROI
HL7 v2Data Type7 min read

HL7 CP Data Type: Composite Price

The CP (Composite Price) data type was introduced in HL7 v2.3 to express more than a bare monetary amount. CP wraps a MO price together with a price-type qualifier (actual, deposit, indirect, total), a numeric range (from / to), the units of that range, and a range-type code that says whether the price is flat, banded, or a percentage. CP is the dominant pricing composite in HL7 v2's financial segments (FT1) and pharmacy order/encoded segments (RXO, RXE).

Purpose

A single price field rarely carries enough context for downstream billing systems. A medication's price varies by quantity dispensed; a procedure's charge varies by duration; a deposit differs from the actual charge. CP packages all of that into one composite: the amount (CP.1), what kind of amount it is (CP.2), and — when the price is range-based — the numeric range, its units, and whether it's a flat band or a percentage (CP.3 – CP.6).

In practice most senders populate only CP.1 and CP.2; the range components are used by pharmacy and by tiered fee schedules where the price applies across a quantity range.

Component reference

Source: HAPI HL7v2 v2.8.1 javadocs — CP. CP has 6 components separated by ^. Length is not published in the javadocs ().

SeqNameData TypeLengthReqDescription
CP.1PricemoRThe monetary amount, as quantity + ISO 4217 currency code.
CP.2Price TypeidODrawn from HL7 table [HL70205]: AP actual price, DP deposit, IP indirect, TP total price.
CP.3From ValuenmOLower bound of the range over which CP.1 applies (e.g. first ml dispensed).
CP.4To ValuenmOUpper bound of the range.
CP.5Range UnitscweOUnits for CP.3 / CP.4 — typically UCUM (ml, mg, min).
CP.6Range TypeidODrawn from HL7 table [HL70298]: F flat rate, FT from-to, P percentage.

CP.1 is the only required component. Everything else qualifies it.

Most-used components

  • CP.1 Price — the MO value. The quantity-plus-currency pair carries the actual money. Without CP.1 the composite is meaningless.
  • CP.2 Price Type — distinguishes a deposit from the actual charge from the total. Critical for billing systems that post different price types to different ledgers.
  • CP.5 Range Units — when CP.3 / CP.4 are populated, the units must be unambiguous. UCUM codes are the modern default.
  • CP.6 Range Type — tells the receiver whether to apply CP.1 as a flat amount across the range, as a from-to rate, or as a percentage.

Where it's used

  • FT1-22 Transaction Amount — Extended — in v2.5+ profiles that retyped the original MO field to CP for richer pricing.
  • FT1-23 Transaction Quantity — paired with CP for unit-priced charges.
  • RXO-23 / RXO-24 Pharmacy Order pricing — drug cost and dispense cost.
  • RXE-29 Give Per (Time Unit) pricing variants in some profiles.
  • BLG-1 / BLG-3 Billing segment charge amounts.
  • Various Z-segment fee fields in vendor charge-master interfaces.

CP is overwhelmingly an ADT/billing and pharmacy data type; clinical result segments rarely see it.

Version differences

  • v2.3 — CP introduced with 6 components.
  • v2.3.1 / v2.4 / v2.5 — structurally stable. CP.5 carried CE in early versions and was retyped to CWE as the standard migrated coded fields.
  • v2.6 / v2.7 — CP.5 firmly CWE; HL70205 / HL70298 stable.
  • v2.7.1 / v2.8 / v2.8.1 / v2.8.2 — structurally stable per the HAPI v2.8.1 javadoc. Same six components.

Common mistakes

  • Sending CP.1 as a bare number (100) rather than a full MO (100^USD). The MO composite requires the currency code; engines that strict-parse will reject the field.
  • Omitting CP.2 when CP.1 is a deposit. Without the price-type qualifier, billing systems post the value as an actual charge.
  • Populating CP.3 / CP.4 without CP.5 — the receiver cannot interpret a range whose units are unspecified.
  • Using a non-ISO-4217 currency code in CP.1.2 (the MO currency sub-component). US$, Dollars, USD (trailing space) all break downstream rules.
  • Treating CP.6 = P as the amount being a percentage of CP.1. The percentage interpretation is of the range, not of the price; senders that confuse this end up off by orders of magnitude.

Examples

Minimal — flat actual price with currency only:

100^USD

With price type — explicit actual price:

100^USD^AP

Multi-component — actual price, flat rate:

100^USD^AP^^^F

From-to range with units — $0.50 per ml from 1 to 100 ml:

0.50^USD^AP^1^100^ml^UCUM^FT

(Note the CP.5 CWE: code ml, system UCUM.)

Percentage range type — a 10% surcharge band:

10^USD^IP^0^1000^USD^UCUM^P

In context — FT1 transaction with a deposit and an actual price (repetitions):

FT1|1|TXN-1001||20260610|20260610|CG|99213^Office visit^CPT4||1|||100^USD^AP~25^USD^DP|||||||||MERCY^^^ISO

Common pitfall — bare amount with no currency:

FT1|1|TXN-1001||20260610|20260610|CG|99213^Office visit^CPT4||1|||100|||||||||MERCY^^^ISO

The receiver parses CP.1 as the literal string 100 and cannot resolve the currency; some engines default to a site-configured currency and silently mis-bill cross-border encounters.

FHIR mapping

The HL7 v2-to-FHIR Implementation Guide does not publish a dedicated ConceptMap for CP — the datatype maps index lists Money and ChargeItem-adjacent maps but not CP itself. In practice CP decomposes across Money, optionally Range, and (in charge contexts) into ChargeItem.priceComponent.

HL7 v2FHIR targetNotes
CP.1 PriceMoney (.value + .currency)The MO sub-components map directly.
CP.2 Price TypeChargeItem.priceComponent.type or an extensionHL70205 → FHIR InvoicePriceComponentType where it aligns (base, deduction, etc.).
CP.3 / CP.4 From / To ValueRange.low.value / Range.high.valueCarried as an extension when CP.6 = FT.
CP.5 Range UnitsRange.low.unit / .system / .codeUCUM mapping straight through.
CP.6 Range TypeExtension on the price componentNo first-class FHIR analogue.

In a ChargeItem-centric workflow, CP populates ChargeItem.priceComponent (one component for the base price, additional components for deposits or surcharges). In an Invoice-centric workflow, CP populates Invoice.lineItem.priceComponent.

Engine considerations

  • MO nesting — CP.1 is itself a composite. Engines must split CP on ^ then split CP.1 on & (sub-component delimiter) to recover the MO quantity and currency. A flat parse that treats CP.1 as a scalar will mis-handle the currency.
  • Currency normalization — sites occasionally emit non-ISO currency labels. The engine should map to ISO 4217 at the boundary and emit a warning, not silently rewrite.
  • HL70205 / HL70298 validation — CP.2 and CP.6 are ID fields drawn from fixed HL7 tables. Unknown values should be rejected at parse time rather than passed through.
  • Range semantics — when CP.3 / CP.4 are populated, downstream consumers must read CP.6 to know how to apply CP.1. Engines that drop CP.6 silently make all ranges flat.
  • HAPI typingca.uhn.hl7v2.model.v281.datatype.CP exposes getCp1_Price() returning MO, getCp2_PriceType() returning ID, getCp3_FromValue() / getCp4_ToValue() returning NM, getCp5_RangeUnits() returning CWE, and getCp6_RangeType() returning ID.

How Vorro parses and produces CP

On inbound, Vorro parses CP composites with explicit MO decomposition: CP.1 becomes a typed Money value with ISO-4217 currency normalization at the boundary, and any non-conforming currency tokens (US$, Dollars) are mapped to USD with a structured warning attached to the message — not silently rewritten. CP.5 Range Units are validated against the UCUM dictionary; non-UCUM units are preserved but flagged so downstream FHIR converters can route through an alternative units extension.

On outbound, Vorro emits CP only when the destination profile defines the field as CP. For v2.5+ destinations that retyped FT1-22 from MO to CP, Vorro promotes a bare MO to MO^AP^^^^F so the price type and range type are explicit. For ChargeItem-shaped FHIR sources we expand Invoice.lineItem.priceComponent into multiple CP repetitions (one per price component), preserving deposit / actual / total distinctions via CP.2.

Sources

← Back to HL7 v2 Guide

Ready to Integrate This Into Your Workflow?

Talk to a Vorro expert about implementing HL7 v2 in your specific environment.

Browse HL7 v2 Guides
HL7 CP Data Type: Composite Price | Vorro Academy | Vorro