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.

If you have five minutes and want the whole picture before you dive into specifics, you’re in the right place. This page walks through every primitive and how they fit together.

The five primitives

Every interaction with Tally touches some combination of these:
  1. Account — the top-level container. Holds wallets, agents, API keys, members, webhooks. The trust boundary for everything.
  2. Wallet — a Privy server wallet that holds USDC. You own it via passkey; Tally never has owner-level access.
  3. Agent — the identity you attach to autonomous units you run. Wallet-agnostic; a single agent can be authorized on many wallets.
  4. Permission — a policy you approve with your passkey, authorizing one specific agent to spend from one specific wallet under bounded rules. The linchpin of the trust model.
  5. Payment — a USDC transfer signed by the agent’s key, validated against the permission by both Tally and Privy’s enclave, broadcast to Base.

The lifecycle, end to end

Here’s what happens, in order, from your first sign-in to your agent making its first payment:

1. Sign in

On first sign-in to Tally’s /login flow, Tally auto-provisions:
  • A Tally account (named after your email).
  • A test-mode wallet on Base Sepolia called “Main Wallet.”
  • An ownership membership tying you to the account.
No setup wizard, no manual provisioning. You land on /[slug]/overview with a wallet ready to receive USDC. See Accounts for the model details.

2. Register an agent

From your server:
const agent = await tally.agents.upsert({ id: "research-bot" });
console.log(agent.status); // → "no_permissions"
The agent exists but can’t spend yet — it has no signing power on any wallet. The status field reflects this. See Agents for the ID model and patterns.

3. Grant the agent a permission

This is the load-bearing step. From the dashboard, pick the agent, pick a wallet, set the policy (per-transaction max, optional daily cap, optional recipient allowlist, optional expiry), and approve it with your passkey. Under the hood:
  • Tally generates a fresh P-256 keypair for this (agent, wallet) pair.
  • The private key is envelope-encrypted via AWS KMS and stored.
  • The public key is registered with Privy as an additional signer on the wallet, attached to the policy.
  • Your passkey approval attaches the signer to the wallet on-chain.
After that, the agent has authority to spend from that wallet, bounded by the policy. See Wallets for the signer/policy mechanics and Permissions for the full flow.

4. Your agent makes a payment

From your server, when the agent needs to spend:
const payment = await tally.payments.create({
  agent_id: "research-bot",
  wallet: "0x7a3f...",
  to: "0xC0fee...",
  amount_usdc: "4.50",
});
Two enforcement layers fire before the transaction touches the chain:
  • Tally pre-checks the request against the permission — per-tx max, daily cap, recipient and contract allowlists, expiry.
  • Privy’s enclave independently re-checks the per-tx max and allowlists before signing.
A compromised Tally server can’t sneak a payment past the second check, because Privy doesn’t trust Tally — it trusts the policy you approved. See Payments for the full flow and Permissions for what the policy bounds.

5. You react to the result

payments.create() returns immediately with status: "pending" and the broadcast tx_hash. To know when the payment confirms, you have two options:
  • Poll tally.payments.get(payment_id) until status flips to confirmed or failed.
  • Subscribe to payment.confirmed and payment.failed webhooks.
Webhooks are the right call for production. See Webhooks.

What this means in practice

A few properties fall out of the model that are worth holding in your head:
  • You never see private key material. Privy holds the wallet keys; you control them through your passkey. The SDK surfaces addresses and balances, never the keys themselves.
  • Agents can’t move funds without a permission. No permission, no spend. The error from payments.create() is well-defined, so your code can branch on it.
  • The audit trail is immediate. Every payment, every permission change, every revocation is logged the moment it happens — visible in the dashboard and queryable via webhooks.
  • If Tally goes away, your wallet persists. You keep control through Privy directly. Permissions stay active or revocable. Your code stops working; the funds don’t.

Where to go from here

If you came here to evaluate Tally:
  • Wallets — the most-differentiated concept; this is where the trust model lives.
  • Permissions — the grant flow and what policies enforce.
If you came here to build: If you came here from another payments product: