Skip to main content
Every paid tool call accepts two optional audit fields: The SDK warns (does not error) when a paid tool is called without memo. Both fields are stored on the receipt — see GET /v1/analytics/receipts.

TypeScript SDK

memo is plain text. decisionContext is any JSON-serialisable object — known fields are typed (see DecisionContext in the SDK types), extras are kept as-is.

Python SDK

Python accepts both decisionContext and decision_context — the SDK normalises to camelCase before sending.

Raw HTTP

If you’re not using an SDK, just include memo and decisionContext in the JSON body of any paid tool call:

Validation

The SDK does light client-side validation before sending:
  • memo over 1000 chars → truncated with a warning log
  • memo empty / non-string → dropped silently
  • decisionContext.confidence outside [0, 1] → dropped silently
  • decisionContext non-object → dropped silently
These guardrails keep malformed values from blocking the underlying tool call.

Where it shows up

Both fields are written onto the receipt at creation time:
Query via GET /v1/analytics/receipts. The fields are returned alongside every other receipt attribute — no extra request needed.

When to use which

  • Memo only — quick debugging. Set it on every paid call as a one-liner (“why am I calling this?”). The SDK nudges you with a warn log if you forget.
  • Memo + decisionContext — agents under programmatic oversight (supervisor agents, audit pipelines, eval rigs). The structured context lets a downstream system reason about the decision without parsing prose.
  • Neither — fine for fire-and-forget scripts where the receipts are noise. The SDK won’t block you; you just lose the audit trail.

Tag vs memo vs decisionContext

These three fields tell different stories about the same receipt: Together they form the input → outcome chain that powers RoCS.