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;
};
type AgentUpsertInput = {
/** User-provided stable string identifier. */
id: string;
};
Methods
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
| Field | Type | Description |
|---|
input.id | string | Stable 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
| Error | When |
|---|
ValidationError | The id is missing, empty, or fails server-side format checks. |
AuthenticationError | The 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
| Field | Type | Description |
|---|
id | string | The agent’s stable identifier. URL-encoded automatically. |
Returns: Promise<Agent>.
Throws
| Error | When |
|---|
NotFoundError | No agent with that id exists in this (account, mode). |
AuthenticationError | The 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.