Skip to main content

Documentation Index

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

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

The tally.agents resource manages agent identities — the things you run that spend money. See Agents (concept) for the model.

Types

Agent

type Agent = {
  /** Stable user-provided identifier (e.g., "research-bot"). */
  id: string;
  /** "active" — at least one activated (non-revoked) signer is attached.
   *  "no_permissions" — no activated signer yet. */
  status: "no_permissions" | "active";
  mode: "test" | "live";
  /** ISO 8601 timestamp. */
  created_at: string;
  /** Count of non-revoked, activated signers. */
  active_signers: number;
  /** Count of non-revoked, not-yet-activated signers. */
  pending_signers: number;
};

AgentUpsertInput

type AgentUpsertInput = {
  /** User-provided stable string identifier. */
  id: string;
};

Methods

agents.upsert(input)

Creates an agent if it doesn’t exist; returns the existing record if it does. Idempotent — safe to run on every deploy.
const agent = await tally.agents.upsert({ id: "research-bot" });
Parameters
FieldTypeDescription
input.idstringStable identifier. Must be unique within the API key’s (account, mode).
Returns: Promise<Agent>. For a freshly registered agent, status will be "no_permissions" and both signer counts will be 0 until a user authorizes a grant. See Permissions for the grant flow. Throws
ErrorWhen
ValidationErrorThe id is missing, empty, or fails server-side format checks.
AuthenticationErrorThe API key is missing, revoked, or out of its rotation grace window.

agents.list()

Returns every agent in the API key’s (account, mode).
const agents = await tally.agents.list();
Returns: Promise<Agent[]>. No pagination today — accounts with hundreds of agents will get the full list. Cursor-paginated variant is on the roadmap; until it lands, this is a single round-trip. Throws: AuthenticationError if the API key is invalid.

agents.get(id)

Fetches a single agent by id.
const agent = await tally.agents.get("research-bot");
Parameters
FieldTypeDescription
idstringThe agent’s stable identifier. URL-encoded automatically.
Returns: Promise<Agent>. Throws
ErrorWhen
NotFoundErrorNo agent with that id exists in this (account, mode).
AuthenticationErrorThe API key is invalid.

Patterns

Idempotent registration on deploy

Because upsert is idempotent, the cleanest pattern is to register every agent your service needs at startup:
const REQUIRED_AGENTS = ["research-bot", "summarizer", "publisher"] as const;

for (const id of REQUIRED_AGENTS) {
  await tally.agents.upsert({ id });
}
If you change REQUIRED_AGENTS in a later deploy, the new entries get registered automatically and existing ones are unchanged.

Checking grant status before sending a payment

Agent.status reflects whether any wallet has authorized this agent to spend. Use it as a gate before invoking spend-related flows:
const agent = await tally.agents.get("research-bot");

if (agent.status === "no_permissions") {
  // Surface to the end user: they need to grant permission via the dashboard.
  return;
}

// agent.status === "active" → safe to call tally.payments.create
Note status: "active" only confirms the agent has some grant; it doesn’t tell you which wallets or what allowance remains. For that, today you have to either attempt the payment and branch on the error, or check the dashboard.

Not yet in the SDK

  • agents.delete(id) — soft-delete an agent. Tracked in BUILD_LOG.md.
  • agents.list({ limit, starting_after }) — cursor pagination.
  • tally.permissions.list({ agent_id }) — per-grant inspection (allowance, policy summary, wallet). Currently dashboard-only.
When those land, the docs sweep notes in mintlify-docs/permissions.mdx get removed.