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.

Every account-scoped resource in Tally — every wallet, agent, API key, transaction, webhook — carries a mode: either test or live. The two are fully partitioned. A test API key cannot touch a live wallet; a live agent does not appear in a test list; a live payment cannot leave a test wallet. The model is borrowed from Stripe’s developer UX, for the same reason: you should be able to ship code against a sandbox and run the same code against production by flipping one variable.

What differs between modes

AspectTest modeLive mode
NetworkBase SepoliaBase mainnet
USDCTestnet USDC (no real value)Production USDC
Privy appTally’s test Privy appTally’s live Privy app (separate config)
API key prefixtly_test_…tly_live_…
Webhook secret prefixwhsec_test_…whsec_live_…
Cost of mistakesZeroReal money
Everything else — the SDK surface, the dashboard UX, the policy model, the webhook events — is identical. The whole point is that your code shouldn’t care which mode it’s running in. If it works in test, it works in live.

How partitioning works

Every account has both a test side and a live side. They share:
  • The same dashboard URL (resources are filtered by the mode badge in the sidebar)
  • The same team members and roles
  • The same billing account
They do not share:
  • Wallets — a test wallet’s address is different from any live wallet
  • Agents — registering research-bot in test mode doesn’t create a live research-bot
  • API keys — keys are stamped with mode at creation; you can’t change a key’s mode
  • Transactions, webhooks, audit log entries — every row carries its mode and queries only see its own side
Mixing modes in code is impossible without explicit intent: the SDK rejects API keys without the tly_test_ or tly_live_ prefix before sending a request, and the server rejects any attempt to act on a mismatched-mode resource with a forbidden error.

Working in test mode

Test mode is the default for every new account, and the only mode that’s fully wired up today (see “Live mode availability” below). A few things to lean on while you’re developing:
  • Get test USDC from a Base Sepolia faucet. Circle’s faucet drops test USDC into any Base Sepolia address. Use it to fund agent wallets without spending real money.
  • Use the dashboard’s mode badge. The sidebar shows which mode you’re viewing. It’s the fastest way to confirm you’re not about to grant a permission on the wrong network.
  • Webhooks fire in test mode. All the events listed in Webhooks fire on Base Sepolia activity — useful for integration testing.

Switching between modes

In code, switching modes is one variable:
const tally = new Tally({
  apiKey: process.env.TALLY_API_KEY!, // tly_test_… in staging, tly_live_… in prod
});
In the dashboard, the mode selector lives in the sidebar; toggling it filters every list to the chosen mode.

Live mode availability

Live mode is partially built. The schema, key prefix, resource partitioning, and Privy configuration scaffolding are all in place — but the customer-facing flow to opt an account into live mode isn’t wired up yet. Today, getDashboardMode() returns "test" for every session, and no tly_live_ keys are issued. The plan: live mode lights up after testnet hardening is done — production Privy app, mainnet RPC, KMS, observability, a one-time per-account opt-in (“I want to handle real USDC”) with the appropriate confirmations. Code paths are already mode-aware so the cutover is configuration, not refactoring. If you have a use case that needs live-mode access soon, reach out.

Best practices

  • Treat test and live as separate environments, with separate API keys, separate webhook endpoints, and separate secret stores. Don’t share TALLY_API_KEY across staging and production.
  • Validate the prefix at boot. A tiny startup check that process.env.TALLY_API_KEY!.startsWith("tly_test_") (or tly_live_) for the environment catches misconfigured deploys before the first request.
  • Never run automated tests against live mode. The two-prefix split is precisely so you don’t accidentally fire integration tests at real USDC. Pin tests to tly_test_ keys.
  • Use deterministic agent IDs across modes. The same id can exist in test and live independently; if you make them match (research-bot in both), you can reuse code paths without conditional logic.