Agent quoted $13.31 for a 13-cent Sume job: the micros divisor
Divide billable_amount_usd_micros by 1,000,000 for dollars. Dividing by 10,000 gives cents and overstates spend 100x. Sume MCP flags this as usd_unit_mismatch.

If your agent told a user a Sume job cost $13.31 and the real charge was about 13 cents, it divided micros by 10,000 instead of 1,000,000. Quote usage.billable_amount_usd directly, or divide billable_amount_usd_micros by 1,000,000 for dollars.
Where the 100x comes from
Sume reports money in integer micros of a US dollar, so 1,000,000 micros is one dollar. A model that remembers cents (100 per dollar) and micros as a vague "millionth" will often land on 10,000 as the divisor, because 10,000 micros is one cent. The hosted MCP server knows this failure mode by name. Its tool results carry an agent.recovery object with the code usd_unit_mismatch, and the hint says: quote usage.billable_amount_usd in dollars, divide micros by 1,000,000 for dollars, divide by 10,000 for integer cents, and never quote micros divided by 10,000 as dollars. Its own worked example is 133,061 micros, which is $0.13 and not $13.31.
The recovery fires when the reported dollar amount equals the micros value divided by 10,000 rather than by 1,000,000, which is exactly the shape of the mistake.
Three fields, three units
The public usage object returns the same amount in three fields. Pick one and stay in its unit.
| Field | Unit | 133,061 micros reads as |
|---|---|---|
| billable_amount_usd | US dollars (decimal) | 0.133061 |
| billable_amount_usd_micros | millionths of a dollar (integer) | 133061 |
| billable_amount_usd_cents | whole cents, rounded up | 14 |
A guard you can put in the agent loop
If your harness post-processes tool results, check the quoted number against the integer before it reaches the user. This function is runnable as is.
def usd_from_micros(micros: int) -> float:
if not isinstance(micros, int) or micros < 0:
raise ValueError('micros must be a non-negative integer')
return micros / 1_000_000
def check_quote(quoted_usd: float, micros: int) -> float:
true_usd = usd_from_micros(micros)
if micros and abs(quoted_usd - micros / 10_000) < 1e-9 and quoted_usd != true_usd:
raise ValueError(f'unit mismatch: {quoted_usd} is micros/10000')
return true_usd
print(check_quote(0.133061, 133_061))What to tell the agent
Put one line in the system prompt: "Quote usage.billable_amount_usd. Never compute dollars from micros yourself." For run-level totals, ask for the ledger summary instead of summing rows; the usage_get versus held cost post covers which number is the real debit.
Limits: this guards unit mistakes only. It does not cap spend. For that, send max_spend_usd on paid calls, as described in the preflight post. A cheap decision model can phrase the answer, but the arithmetic belongs in code.
Checklist before you ship
- Tell the agent which field to quote, by name, in the system prompt.
- Reject any dollar figure that equals micros divided by 10,000 before it reaches a user.
- Treat the cents field as rounded up, so it can exceed the exact dollar amount by under one cent.
- Log the integer micros next to every quoted figure so a support reader can recompute it.
Sources
Related posts
More in Developers
- catalog_list vs tools_list: finding HTTP-only Sume features
tools_list shows what this MCP session can call. catalog_list shows API capabilities, some with no MCP tool. Read both before telling a user it can't be done.
- Agent run webhook: created_at orders deliveries, request_id dedupes
An agent.run.terminal delivery has two ids that look alike. request_id dedupes retries; created_at orders deliveries. Includes a Python receiver.
- Run webhook payload is null: payload_too_large means fetch result_url
Sume cannot send a receipt over 1 MiB inline. The webhook arrives with payload null and error.code payload_too_large. The run did not fail. Fetch result_url.
- Missed an agent run webhook? Poll status_url, redeliver is Format-only
Sume's docs describe a webhook redeliver route for Format runs. For an Agent Completion you did not get a POST for, read the run from its status or result URL.
Written by Sume