OlaiDocs
Open the desk

Guides

Read the ledger

Every line kind, how to page through them, and how to check that nobody has edited one.

The ledger is the record. Everything else, the event stream, the session record, the model's own account of what it bought, is commentary.

From the desk

The receipt is in the Details drawer, third tab, Ledger. It reads back as the same plain sentences the conversation uses, newest first, with the line count beside the heading and filter chips above: Everything, Payments, Orders, Rules, Notes. A line carrying a settlement hash links it to BscScan. Click The ledger line on any sentence and the raw record opens underneath it: the line number, the kind, the actor, the first twelve characters of the hash, and the whole JSON payload.

Verify chain recomputes the whole hash chain on the service, not anything already sitting in the browser, and answers either "Chain holds across N lines" or "Broken at line N" with the reason, the same two shapes GET /api/ledger/verify returns below. A replay has no service to recompute anything, so it reads "Recorded chain: verified at capture, N lines" instead of offering a button that would prove nothing. This is packages/web/src/components/conversation/ledger-list.tsx, with the sentences from packages/web/src/lib/describe.ts.

From the command line

bash
curl "http://localhost:4000/api/ledger?limit=50" \
  -H "Authorization: Bearer $OLAI_OWNER_TOKEN"
json
{
  "entries": [
    {
      "seq": 14,
      "ts": "2026-09-06T09:12:51.882Z",
      "kind": "payment.settled",
      "actor": "agent",
      "payload": { "summary": "Paid $0.0100 for ...", "url": "..." },
      "costUsd": 0.01,
      "txHash": "0x...",
      "sessionId": "ol-3f0c...",
      "prevHash": "9f2a...",
      "hash": "c471..."
    }
  ],
  "nextAfterSeq": 14
}

nextAfterSeq is what to send as afterSeq to get the next page. null means you have reached the end.

Query it

Parameter Meaning
afterSeq Return lines after this sequence number. This is how you page forward.
limit 1 to 500, default 100.
kinds A comma-separated list of line kinds. An unknown kind is a 400 naming it.
sessionId Only lines from one question.

Every data payment in one session, for example:

bash
curl "http://localhost:4000/api/ledger?sessionId=ol-3f0c...&kinds=payment.preview,payment.signed,payment.settled" \
  -H "Authorization: Bearer $OLAI_OWNER_TOKEN"

The line kinds

From packages/agent/src/ledger/types.ts.

Kind Written when
rulebook.set A rulebook is saved. The whole rulebook is in the payload.
question A question starts a session.
discovery A Bazaar search ran. The payload carries the query, the price cap and the URLs found.
payment.preview A payment was priced and checked against the rulebook, before any signature.
payment.signed Olai is about to ask the wallet to sign. Written before the signature, so a crash mid-payment cannot lead to a second one.
payment.settled The merchant answered the paid call. Carries costUsd and the settlement txHash.
data.received Data came back from a merchant.
proposal The agent proposed an action that passed the rulebook, or proposed holding.
approval The owner approved.
rejection The owner rejected, with their reason.
order.sent An order left for Binance, or, in a dry run, was recorded and not sent (dryRun: true).
order.filled Binance filled it.
order.failed Binance refused it, or the call threw.
rule.refused The rulebook refused something. Carries the reasons and the rule ids.
kill The kill switch went on.
resume The kill switch went off.
note Everything else worth recording: a free market read, the day's opening equity, a tool failure.

The actor on each line is one of owner, agent, rulebook, binance, merchant, system, so "who did this" is answerable without reading the payload.

Check that nobody edited it

bash
curl http://localhost:4000/api/ledger/verify \
  -H "Authorization: Bearer $OLAI_OWNER_TOKEN"
json
{ "ok": true, "length": 148 }

A broken chain answers with the first line that does not hold up and why:

json
{ "ok": false, "brokenAtSeq": 91, "reason": "the stored hash does not match the contents of this line, it was edited" }

Three reasons it can give: a missing line ("line 90 is missing, the ledger jumps to line 91"), a line that does not point at the line before it, or a line whose stored hash does not match its contents.

What the numbers mean

Money is stored as whole cents and shown back as dollars. costUsd on a payment.settled line is what that one call cost. The daily data budget is measured by adding the cents on settled payments since midnight UTC, which is why the total is exact rather than a floating-point approximation of exact.

The one number to read with care is the daily loss on GET /api/account. It is the difference between the account's equity now and its equity at the first read of the UTC day, so it counts unrealised price moves on positions you were already holding, not only losses from trades Olai made. That is a stated weakness, not a bug in the arithmetic.