Decision records · Value formats
D-036 Where is the currency of a money value, and must it be present with the value?
What the schemas do
Every money value is a bare number of at least 0. Every object that carries one carries a currency (ISO 4217) beside it, required with the value. A currency is never inherited from an enclosing object. The commitment and a min_commitment[] threshold have a basis that says whether amount is money. When basis is spend, the amount is money and its currency is required. When basis is units, it is a whole count of units with no currency. Where the specification gives an object money and no currency, the schema carries the money alone until it adds one.
Options
Why
The specification writes money as a bare number with a sibling currency: pricing[].currency beside gross_rate, seller_rate, and floor, and the commitment's currency, REQUIRED when basis is spend. OpenRTB writes money the same way, with bidfloor beside bidfloorcur and price beside cur. A CPM-style rate is a sum of money per unit of the cost method, so it is the same concept as a budget and takes the same type. A money value without its currency can't be read, so where the value is required the currency is required, and where the value is optional the currency is required when the value is present, which dependentRequired states. Where the specification gives the currency a condition, as the commitment does, the condition says when the value is money, and the schema keeps it. The commitment's basis is spend or units, so its amount is money for spend and a count of units for units, a whole number of at least 0, as derived_units is. A min_commitment[] threshold writes basis, amount, and currency as the commitment does, so it is read the same way: its currency is required when basis is spend, a units threshold has none, and its amount is a count when basis is units. An amount means nothing without its basis, so a threshold that gives an amount gives its basis. Inheriting a currency fails because pricing[] is a list: its entries may name different currencies, so none of them defines the currency of min_spend or of a budget bound. A { amount, currency } object would depart further from the specification's form and from OpenRTB's than the missing currencies need.
What we ask the specification to state
Give every object that carries money a currency (ISO 4217) beside it. Make it required with the money, as the commitment does for basis = spend.
- These have no currency in their object:
min_spend, the budget bounds ofcommitment_bounds, a production option'scost, and an option'sdelta_cpmanddelta_flat. pricing[]is a list whose entries may name different currencies, so it can't supply one for a line-item amount.- State for a
min_commitment[]threshold, as for the commitment, thatcurrencyis REQUIRED whenbasis = spend. Also state that a threshold with anamountgives itsbasis. - State for both that
amountis a whole number of units whenbasisisunits.
The specification lines it rests on
Each line is quoted as the record pins it. Expand an item to read the quote.
main
§ 5.6, the
pricing[]row L267 at 44dfaafpricing[]| Array[Object] | mixed | See below§ 5.6, the
pricing[].gross_raterow L269 at 44dfaafpricing[].gross_rate| Number | seller-set | The list rate the buyer pays§ 5.6, the
pricing[].currencyrow L273 at 44dfaafpricing[].currency| String | seller-set | ISO-4217§ 5.6.1, the
commitment.amountkey row L292 at 44dfaafamount| REQUIRED | The figure committed§ 5.6.1, the
commitment.basiskey row L291 at 44dfaafbasis| REQUIRED |spend|units§ 5.6.1, the
commitment.currencykey row L293 at 44dfaafcurrency| REQUIRED whenbasis = spend| ISO-4217§ 5.6, the
min_spendrow L279 at 44dfaafmin_spend| Number | seller-set | Minimum spend for this line item§ 5.6, the
commitment_boundsrow's description: the inline object L276 at 44dfaaf{ min_impressions, max_impressions, min_budget, max_budget }
§ 5.4, the
productionrow's description: the inline object L249 at 44dfaaf{ custom_unit, build_owner, lead_time, cost }
§ 3.1, the
pricingkey row L146 at 44dfaafpricing| OPTIONAL | Delta per option beyond those included, as{ option_id: { delta_cpm | delta_flat | delta_pct } }§ 3.1, the
pricingkey row's meaning: the inline object L146 at 44dfaaf{ option_id: { delta_cpm | delta_flat | delta_pct } }
With the open PRs
§ 5.6, the
pricing[]row L260 on main at 981a74epricing[]| Array[Object] | mixed | See below§ 5.6, the
pricing[].gross_raterow L262 on main at 981a74epricing[].gross_rate| Number | seller-set | The list rate the buyer pays§ 5.6, the
pricing[].currencyrow L266 on main at 981a74epricing[].currency| String | seller-set | ISO-4217§ 5.6.1, the
commitment.amountkey row L285 on main at 981a74eamount| REQUIRED | The figure committed§ 5.6.1, the
commitment.basiskey row L284 on main at 981a74ebasis| REQUIRED |spend|units§ 5.6.1, the
commitment.currencykey row L286 on main at 981a74ecurrency| REQUIRED whenbasis = spend| ISO-4217§ 5.6.3, the
requires.min_commitment[]key row's meaning: the inline object L328 in #70{ line_item_id, basis, amount, currency }
§ 5.6, the
min_spendrow L272 on main at 981a74emin_spend| Number | seller-set | Minimum spend for this line item§ 5.6, the
commitment_boundsrow's description: the inline object L269 on main at 981a74e{ min_impressions, max_impressions, min_budget, max_budget }
§ 5.4, the
productionrow's description: the inline object L242 on main at 981a74e{ custom_unit, build_owner, lead_time, cost }
§ 3.1, the
pricingkey row L139 on main at 981a74epricing| OPTIONAL | Delta per option beyond those included, as{ option_id: { delta_cpm | delta_flat | delta_pct } }§ 3.1, the
pricingkey row's meaning: the inline object L139 on main at 981a74e{ option_id: { delta_cpm | delta_flat | delta_pct } }
What it shapes
main: Amount, PriceAdjustment, Commitment.amount, Commitment.basis, Commitment.currency, CommitmentBounds.max_budget, CommitmentBounds.max_impressions, CommitmentBounds.min_budget, CommitmentBounds.min_impressions, LineItem.min_spend, LineItem.pricing, LineItemSummaryPricingEntry.currency, LineItemSummaryPricingEntry.gross_rate, PricingEntry.currency, PricingEntry.gross_rate, ProductionOption.build_owner, ProductionOption.cost, ProductionOption.custom_unit, ProductionOption.lead_time
With the open PRs: Amount, PriceAdjustment, Commitment.amount, Commitment.basis, Commitment.currency, CommitmentBounds.max_budget, CommitmentBounds.max_impressions, CommitmentBounds.min_budget, CommitmentBounds.min_impressions, LineItem.min_spend, LineItem.pricing, LineItemSummaryPricingEntry.currency, LineItemSummaryPricingEntry.gross_rate, MinCommitmentEntry.amount, MinCommitmentEntry.basis, MinCommitmentEntry.currency, MinCommitmentEntry.line_item_id, PricingEntry.currency, PricingEntry.gross_rate, ProductionOption.build_owner, ProductionOption.cost, ProductionOption.custom_unit, ProductionOption.lead_time