> ## 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.

# Agents

> How Tally models the autonomous units you run.

An agent is the identity Tally attaches to every action — payments, balances, analytics, audit trail. You register one agent per autonomous unit you run: one per bot, one per workflow, one per LLM-driven task, whatever maps to "this thing spends money."

## Mental model

An agent is **not a wallet**. It's an *identity* that can be granted spending power on one or more wallets. A single agent — say `procurement-bot` — might be authorized to spend from three different wallets you own, each with its own policy. A single wallet might host five agents, each scoped to a different category of spend.

The split exists because the question "which of my agents spent what?" is different from "which wallet did the funds come from?" Agents are the abstraction over the first question; wallets are the abstraction over the second. Permissions link the two — see [Permissions](/permissions).

## Agent fields

| Field             | Description                                                                                                              |
| ----------------- | ------------------------------------------------------------------------------------------------------------------------ |
| `id`              | A stable, user-provided string identifier. Same `id` can exist independently in test and live mode for the same account. |
| `status`          | `active` (≥1 authorized signer) or `no_permissions` (registered but nothing's been granted yet).                         |
| `mode`            | `test` or `live`. Fixed at creation; can't be moved.                                                                     |
| `created_at`      | ISO 8601 timestamp.                                                                                                      |
| `active_signers`  | Count of authorized signers on this agent.                                                                               |
| `pending_signers` | Count of signers waiting for the wallet owner's passkey signature.                                                       |

## Registering an agent

`upsert` is idempotent — safe to call on every deploy.

```ts theme={null}
import { Tally } from "@tallyforagents/sdk";

const tally = new Tally({ apiKey: process.env.TALLY_API_KEY! });

const agent = await tally.agents.upsert({ id: "research-bot" });

console.log(agent.status);
// → "no_permissions"  (until a wallet owner grants spending power)
```

The `id` is the only input. Pick a stable string — `research-bot`, `procurement-agent-v2`, `slack-mentions-handler` — that describes the unit, not a UUID you might regenerate on each deploy.

After upserting, the agent exists but has no wallets it can spend from. To give it spending power, you have to authorize a permission on one of your wallets — see [Permissions](/permissions).

## Fetching agents

```ts theme={null}
const agent = await tally.agents.get("research-bot");

const { data } = await tally.agents.list();
```

Both methods are scoped to the API key's account + mode. A `tly_test_` key only sees test-mode agents; a `tly_live_` key only sees live-mode agents.

## ID rules and gotchas

* **Permanent.** Once you upsert an agent with a given `id`, that string is its name forever. Renaming isn't supported — register a new agent and migrate.
* **Mode-scoped.** `research-bot` can exist as a test agent and a live agent simultaneously, completely independent of each other. This matches how Stripe handles test/live separation.
* **Account-scoped.** Two different accounts can both have `research-bot`; they're separate entities.
* **Public-ish.** Agent IDs appear in dashboard URLs and webhook payloads. Don't embed secrets, customer PII, or anything you'd rather not see in a log.

## Common patterns

### One agent per feature

If you have "summarizer," "researcher," and "publisher" capabilities that each spend independently, give each one its own agent. Per-agent analytics in the dashboard make cost allocation trivial — and per-agent permissions let you authorize them independently ($50/day for the summarizer, $5/day for the publisher).

### One agent across many wallets

A single agent can be authorized on multiple wallets — useful for setups where the *same* logical agent operates against several wallets you own (one per project, per environment, per category of spend). In future multi-tenant setups, the same primitive serves several wallets owned by separate end users. Each permission is its own policy on its own wallet; revoking one doesn't affect the others.

### One agent per scope

The inverse pattern, useful for isolated environments: per-project, per-tenant, per-experiment. Give each scope its own agent `id`. Per-agent attribution makes incident response (something reports unexpected spend) much faster.

## What's not yet implemented

* **`agents.delete()`** — soft-delete is planned but not in the public SDK today. Revoking the agent's grants is the current equivalent; the agent record stays on the account but loses all spending power.
* **Display names** — currently the `id` doubles as the human-readable label. A separate `display_name` field is on the roadmap once there's product demand for non-developer-friendly labels.
* **Agent renaming.** No technical reason it can't exist; we just haven't built it because IDs propagate into webhooks and audit logs where rename semantics get complicated.
