Normalise supplier quotes to one comparable unit price (currency, unit of measure, tax, discount)

$0.005 USDC per call · Business, finance and compliance · POST /api/v1/quote-normalize · Id quote-normalize

Converts up to 200 quoted prices to a net price per base unit in one currency, for an agent comparing supplier quotes. Each line: price for `per` units of a unit of measure, optional tax-inclusive flag and rate, optional percentage discount, any currency. Uses only the caller's exchange rates and unit factors (1 uom = factor base units); a currency without a rate, a unit without a factor, or a tax-inclusive price without a tax rate returns unknown for that line with a witness naming what is missing. Never fetches an FX rate and never assumes a unit conversion (a pack, a cup, a case). Output prices carry 8 decimal places (half-even) because unit prices are often below the minor unit. Does not choose a supplier or check quote validity dates.

What you get

Quotes arrive per case, per 1000, tax-inclusive and in three currencies. Compared only after the same exact normalisation, with every missing input named.

Call it

Send the JSON body below to https://agents.writerslogic.com/api/v1/quote-normalize. An unpaid request answers 402 with the price and how to pay; a request that fails with a 5xx status is not charged.

curl -i -X POST https://agents.writerslogic.com/api/v1/quote-normalize \
  -H 'content-type: application/json' \
  -d '{"targetCurrency":"USD","baseUom":"each","fxRates":[{"from":"EUR","rate":"1.10"}],"uomFactors":[{"uom":"case","factor":"12"}],"lines":[{"id":"A","currency":"USD","price":"24.00","uom":"case"},{"id":"B","currency":"EUR","price":"2.40","taxIncluded":true,"taxRate":"20","uom":"each"},{"id":"C","currency":"GBP","price":"2.00"}]}'

Input

FieldTypeRequiredDescription
targetCurrencystringyesISO 4217 alphabetic code, upper case.
baseUomstring; length 1..16noName of the base unit prices are normalised to (default "unit").
linesarray<object>; max 200 itemsyes
fxRatesarray<object>; max 50 itemsno
uomFactorsarray<object>; max 50 itemsno

Example request body

{
  "targetCurrency": "USD",
  "baseUom": "each",
  "fxRates": [
    {
      "from": "EUR",
      "rate": "1.10"
    }
  ],
  "uomFactors": [
    {
      "uom": "case",
      "factor": "12"
    }
  ],
  "lines": [
    {
      "id": "A",
      "currency": "USD",
      "price": "24.00",
      "uom": "case"
    },
    {
      "id": "B",
      "currency": "EUR",
      "price": "2.40",
      "taxIncluded": true,
      "taxRate": "20",
      "uom": "each"
    },
    {
      "id": "C",
      "currency": "GBP",
      "price": "2.00"
    }
  ]
}

Result

The response is { "data": ..., "_provenance": ... }. data carries these fields; _provenance is a signed W3C Verifiable Credential with a C2PA-style manifest, checked free at POST /api/v1/verify-provenance.

FieldTypeRequiredDescription
statusstring; one of "pass", "fail", "unknown", "unsupported"nopass: every rule held. fail: a rule was violated (see witnesses). unknown: the input lacks the evidence to decide. unsupported: outside what this engine covers. Missing evidence is never a pass.
linesarray<object>no
cheapeststringnoId of the lowest normalised unit price among resolved lines (first on ties); absent if none resolved.
targetCurrencystringno
baseUomstringno
witnessesarray<object>no
versionsobjectnoEvery semantic dependency of this answer (engine, tables and their as-of dates, tokenizer, calendar, rounding profile).
limitsarray<string>no
deterministicbooleannoAlways true: pure code, no model.

Pay and connect

Available through: x402 (USDC on Base), MCP. MCP clients reach it through the money-math-kit package.

Machine-readable