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.

Permissions are the linchpin of Tally’s non-custodial model. Every agent payment is validated against an on-chain grant signed by the user. No grant, no spend.

Mental model

A grant is a tuple, signed by the user’s treasury wallet, that says:
Agent <id> may spend up to <amount> USDC until <expiry>.
When your code calls tally.pay, the SDK looks up the active grant for that agent, checks the remaining allowance, and only broadcasts if there’s room.

Creating a grant

Today, grants are created through the dashboard’s signature flow — the user clicks Grant permission, picks an agent and an amount, and signs with their treasury wallet.
Programmatic grant creation (via the SDK) is on the roadmap. If you need it for a specific use case, reach out.

Checking remaining allowance

const { remaining, granted, spent } = await tally.permissions.get({
  agent_id: "research-bot",
});

console.log(`${remaining} USDC remaining of ${granted}`);

Revoking a grant

A user can revoke a grant at any time from the dashboard. Revocation is a single on-chain transaction that takes effect immediately — in-flight payments may still succeed, but no new ones will be authorized.
// Revocation from the SDK is server-side only. It surfaces the same
// on-chain revocation flow the dashboard uses.
await tally.permissions.revoke({
  agent_id: "research-bot",
});

Why on-chain?

If Tally went away tomorrow, your users would still control their grants directly via the underlying contract. That’s the property we’re trading some convenience for — and the reason we never become a custodian.

Handling insufficient_allowance

try {
  await tally.pay({ agent_id: "research-bot", to, amount_usdc });
} catch (err) {
  if (err.code === "insufficient_allowance") {
    // Prompt the user to top up their grant from your UI
  }
  throw err;
}