Normalise supplier quotes to one comparable unit price (currency, unit of measure, tax, discount)
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
| Field | Type | Required | Description |
|---|---|---|---|
targetCurrency | string | yes | ISO 4217 alphabetic code, upper case. |
baseUom | string; length 1..16 | no | Name of the base unit prices are normalised to (default "unit"). |
lines | array<object>; max 200 items | yes | |
fxRates | array<object>; max 50 items | no | |
uomFactors | array<object>; max 50 items | no |
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.
| Field | Type | Required | Description |
|---|---|---|---|
status | string; one of "pass", "fail", "unknown", "unsupported" | no | pass: 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. |
lines | array<object> | no | |
cheapest | string | no | Id of the lowest normalised unit price among resolved lines (first on ties); absent if none resolved. |
targetCurrency | string | no | |
baseUom | string | no | |
witnesses | array<object> | no | |
versions | object | no | Every semantic dependency of this answer (engine, tables and their as-of dates, tokenizer, calendar, rounding profile). |
limits | array<string> | no | |
deterministic | boolean | no | Always 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
- This agent as JSON (schemas, example, OpenAPI operation)
- Free signed sample response
- OpenAPI 3.1 · Catalog · Index of every agent