MIT · Bun
The receipt
A receipt you can hand to someone who does not trust you.
Every GTM dashboard shows you a cost per meeting. It is a number the dashboard computed about itself. This one is the sum of 147 signed rows, and the signature is not ours to forge.
Paid actions run through the OneShot API, which settles per call in USDC on Base and returns a cryptographically signed receipt. oneshot-gtm writes that receipt into your local ledger with the reason the call happened attached. Nothing about the row is reconstructed after the fact.
- play_name
- show-hn
- call_type
- email.send
- settlement
- USDC · base
- value_tag
- meeting booked
The memo says why the call happened; the value tag is written back when the outcome lands.
What is in one
Ten fields, and two of them are the point.
Field names are the schema’s own, out of ReceiptRecord. Three bookkeeping columns are left off here, the row id and the two timestamps.
memo and value_tag are the pair that turns a log line into an account. One says why the money went out. The other says what came back, and it is written long after the row was signed.
- play_name
- Which play spent the money.
- call_type
- The priced primitive that ran, one of the six in the table above.
- cost_usd
- What that call cost, to three decimals.
- signed_receipt
- The signature itself. This is the column that makes the row evidence rather than a log line.
- oneshot_request_id
- The call’s id on the OneShot side, so the row can be reconciled against the source.
- sender_identity
- Which mailbox sent it. Set on email.send receipts, null for anything that predates rotation.
- memo
- Human-readable call reason, mirrored from the call-time SDK memo. Why this call happened at all.
- decision_context
- JSON of the call-time decisionContext blob. The structured version of the same answer.
- value_tag
- The outcome, written back once a reply or a deal lands. JSON of type, amount and label, set by tagOutcomeValue.
- goal_id
- Cadence correlation key, mirroring decisionContext.goalId. Groups every receipt a single cadence produced.
The arithmetic
Divide signed spend by outcomes and CAC comes out in single dollars.
The Measure page does one sum. Total the receipts for a play, count the outcomes tagged back onto them, divide. There is no model in the middle and no blended average, which is why the number survives contact with an investor.
oneshot-gtm measure --by playreceipts 147 · spend $2.94sent 44 · replied 8 · won 2$0.37 per reply · $1.47 per won
One seeded install, not a customer. The prospects in it are fictional. The prices, the receipts and the division are the product’s own.
What a call costs
- email.send
- $0.004
- email.verify
- $0.008
- web.search
- $0.012
- email.find
- $0.020
- enrich.profile
- $0.050
- research.person
- $0.120
A first touch that lands is four tenths of a cent. Most of what a play spends goes on finding out whether the person is worth writing to at all, which is the spend a blended CAC hides.
The write-back
Attribution that runs backwards.
A receipt is written when the money goes out, before anyone knows whether it worked. When a reply or a closed deal lands weeks later, tagOutcomeValue walks back along the goal_id and tags the value onto every receipt in that cadence, including the enrichment call that made the first touch worth sending.
That is the difference between attested and estimated. A dashboard that attributes a win to the last email is crediting the cheapest call in the sequence. The research call at twelve cents is usually the one that earned it.
The same value is PATCHed back to OneShot, so the row reconciles on both sides. Nothing about your prospects leaves the machine. What moves is a type, an amount and a label.
- play_name
- competitor-switch
- call_type
- research.person
- goal_id
- goal_35b3b41b0e98…
- memo
- dossier for Priya Shah
- value_tag
- deal won · $4,800
Tagged 15 days after the call settled, when the deal closed. The research spend and the revenue sit on one row because the goal id held the cadence together.
What this does not prove
A signature is not an audit.
It attests the call, not the judgment
The receipt proves an email was sent and what it cost. Whether it should have been sent is a question for the memo, which is why the memo is a column and not a comment.
Outcome tagging is only as good as your inbox
Replies are detected from connected mailboxes. Bounce handling is Gmail-only: sends through OneShot domains and Smartlead mailboxes have no equivalent feed yet, and doctor names them as not covered rather than reporting a false zero.
Not every surface has made the round trip
STATUS.md lists seven that are tested and typechecked but have never run against the live API, last checked 2026-08-25. The voice and SMS legs are two of them, because both need a real phone number. None of the six priced calls in the table above is on that list.
The numbers on this page are a seeded install
They come from the ledger demo seed builds against a fixed timestamp, which is what makes them reproducible. They are not a customer result and nothing here presents them as one.
The receipts are in the repo, the prices are in the repo, and the arithmetic is one division. Read it before you trust it.