OpenProposal 3.0 JSON Schema Unofficial

Decision records · Value formats

D-036 Where is the currency of a money value, and must it be present with the value?

Gap Decision 10 on the supporting page of #121. Cited on main and with the open PRs.

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

  • sibling-currency Chosen

    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.

  • inherited

    A money value with no currency beside it is in the currency of the line item's pricing[].

  • money-object

    Every money value is an object { amount, currency }.

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 of commitment_bounds, a production option's cost, and an option's delta_cpm and delta_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, that currency is REQUIRED when basis = spend. Also state that a threshold with an amount gives its basis.
  • State for both that amount is a whole number of units when basis is units.

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 44dfaaf
    pricing[] | Array[Object] | mixed | See below
  • § 5.6, the pricing[].gross_rate row L269 at 44dfaaf
    pricing[].gross_rate | Number | seller-set | The list rate the buyer pays
  • § 5.6, the pricing[].currency row L273 at 44dfaaf
    pricing[].currency | String | seller-set | ISO-4217
  • § 5.6.1, the commitment.amount key row L292 at 44dfaaf
    amount | REQUIRED | The figure committed
  • § 5.6.1, the commitment.basis key row L291 at 44dfaaf
    basis | REQUIRED | spend | units
  • § 5.6.1, the commitment.currency key row L293 at 44dfaaf
    currency | REQUIRED when basis = spend | ISO-4217
  • § 5.6, the min_spend row L279 at 44dfaaf
    min_spend | Number | seller-set | Minimum spend for this line item
  • § 5.6, the commitment_bounds row's description: the inline object L276 at 44dfaaf
    { min_impressions, max_impressions, min_budget, max_budget }
  • § 5.4, the production row's description: the inline object L249 at 44dfaaf
    { custom_unit, build_owner, lead_time, cost }
  • § 3.1, the pricing key row L146 at 44dfaaf
    pricing | OPTIONAL | Delta per option beyond those included, as { option_id: { delta_cpm | delta_flat | delta_pct } }
  • § 3.1, the pricing key 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 981a74e
    pricing[] | Array[Object] | mixed | See below
  • § 5.6, the pricing[].gross_rate row L262 on main at 981a74e
    pricing[].gross_rate | Number | seller-set | The list rate the buyer pays
  • § 5.6, the pricing[].currency row L266 on main at 981a74e
    pricing[].currency | String | seller-set | ISO-4217
  • § 5.6.1, the commitment.amount key row L285 on main at 981a74e
    amount | REQUIRED | The figure committed
  • § 5.6.1, the commitment.basis key row L284 on main at 981a74e
    basis | REQUIRED | spend | units
  • § 5.6.1, the commitment.currency key row L286 on main at 981a74e
    currency | REQUIRED when basis = 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_spend row L272 on main at 981a74e
    min_spend | Number | seller-set | Minimum spend for this line item
  • § 5.6, the commitment_bounds row's description: the inline object L269 on main at 981a74e
    { min_impressions, max_impressions, min_budget, max_budget }
  • § 5.4, the production row's description: the inline object L242 on main at 981a74e
    { custom_unit, build_owner, lead_time, cost }
  • § 3.1, the pricing key row L139 on main at 981a74e
    pricing | OPTIONAL | Delta per option beyond those included, as { option_id: { delta_cpm | delta_flat | delta_pct } }
  • § 3.1, the pricing key 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

The record's YAML file