Skip to main content

Documentation Index

Fetch the complete documentation index at: https://docs.oneshotagent.com/llms.txt

Use this file to discover all available pages before exploring further.

Every paid tool call accepts two optional audit fields:
FieldTypePurpose
memostring (≤ 1000 chars)Human-readable reason this tool was called. Shows up on the receipt — useful when you’re triaging spend or debugging an agent that went off the rails.
decisionContextobjectMachine-readable companion. Open schema with known fields (goal, goalId, alternatives, confidence) plus any extras. Consumed by supervisor / auditor agents.
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

import { OneShot } from "@oneshot-agent/sdk";

const agent = await OneShot.create({ cdp: true });

await agent.email(
  { to: "[email protected]", subject: "Follow-up", body: "..." },
  {
    memo: "Following up on demo request from yesterday's webinar",
    decisionContext: {
      goal: "Convert webinar leads to discovery calls",
      goalId: "goal_01HX...",
      alternatives: ["sms_send", "voice_call"],
      confidence: 0.78,
      // Open schema — any extra keys are stored verbatim
      campaign: "webinar-q2",
    },
  },
);
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

from oneshot import OneShot

agent = OneShot.create(cdp=True)

await agent.email(
    {"to": "[email protected]", "subject": "Follow-up", "body": "..."},
    memo="Following up on demo request from yesterday's webinar",
    decision_context={
        "goal": "Convert webinar leads to discovery calls",
        "goalId": "goal_01HX...",
        "alternatives": ["sms_send", "voice_call"],
        "confidence": 0.78,
        "campaign": "webinar-q2",
    },
)
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:
curl -X POST https://win.oneshotagent.com/v1/tools/email/send \
  -H "Content-Type: application/json" \
  -H "X-Payment-Proof: ..." \
  -d '{
    "quote_id": "qte_01HX...",
    "from_address": "[email protected]",
    "to_address": "[email protected]",
    "subject": "Follow-up",
    "body": "...",
    "memo": "Following up on demo request from yesterday'\''s webinar",
    "decisionContext": {
      "goal": "Convert webinar leads to discovery calls",
      "confidence": 0.78
    }
  }'

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:
{
  "receipt_id": "rcpt_01HGW2HB4V4T0PZGJ8PFDRCHQM",
  "category": "communication",
  "subcategory": "email",
  "amount_usdc": "0.150000",
  "memo": "Following up on demo request from yesterday's webinar",
  "decisionContext": {
    "goal": "Convert webinar leads to discovery calls",
    "confidence": 0.78,
    "campaign": "webinar-q2"
  },
  "status": "settled",
  "created_at": "2026-05-11T14:30:00Z"
}
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:
FieldSet whenAnswers
memoAt call timeWhy did I make this call?
decisionContextAt call timeWhat was the structured reasoning?
value_tagAfter the outcome is known — via PATCH /v1/analytics/receipts/{receiptId}/valueDid this call generate value?
Together they form the input → outcome chain that powers RoCS.