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.

The Tally TypeScript SDK is published as @tallyforagents/sdk. It targets Node 20+ and uses the platform’s native fetch — no extra dependencies for the network layer.

Install

npm install @tallyforagents/sdk
pnpm, yarn, and bun work the same way. The SDK has no peer dependencies and ships its own type definitions.

Construct a client

import { Tally } from "@tallyforagents/sdk";

const tally = new Tally({
  apiKey: process.env.TALLY_API_KEY!,
});
new Tally({ apiKey }) is the only call you’ll make to set up. The returned client exposes agents, payments, and webhooks resources.

ClientOptions

FieldTypeRequiredDescription
apiKeystringYesA Tally API key starting with tly_test_ (test mode) or tly_live_ (live mode).
baseUrlstringNoBase URL of the Tally API. Defaults to http://localhost:3000. Production callers should set this explicitly.
fetchtypeof fetchNoCustom fetch implementation. Useful for tests, non-Node runtimes, or wrapping with retry middleware.

API key validation

The constructor validates the key prefix and throws a TallyError (type: "validation_failed") if the key doesn’t start with tly_test_ or tly_live_. This catches misconfigured environments at startup, not at first request.
try {
  const tally = new Tally({ apiKey: "wrong_prefix_key" });
} catch (err) {
  // err.message: "Invalid API key. Tally keys start with 'tly_test_' or 'tly_live_'."
}

Setting baseUrl in production

The SDK defaults baseUrl to http://localhost:3000 so a fresh install Just Works against a locally running Tally. For any deployed environment, set it explicitly:
const tally = new Tally({
  apiKey: process.env.TALLY_API_KEY!,
  baseUrl: process.env.TALLY_BASE_URL ?? "https://api.tally.example.com",
});
Trailing slashes are stripped — https://api.example.com/ and https://api.example.com are equivalent.

Custom fetch

If you want to wrap requests with logging, retries, or use a runtime where globalThis.fetch isn’t available, pass a custom implementation:
import fetch from "node-fetch"; // or any fetch-compatible impl

const tally = new Tally({
  apiKey: process.env.TALLY_API_KEY!,
  fetch: fetch as unknown as typeof globalThis.fetch,
});
The SDK doesn’t add automatic retries on its own — the client is a thin transport and idempotency is the recommended retry primitive. See Payments for the idempotency_key pattern.

Request shape

Every SDK call goes through one HTTP request. Headers Tally sends:
HeaderValue
AuthorizationBearer <apiKey>
Content-Typeapplication/json (when there’s a body)
Acceptapplication/json
Responses are always JSON. Non-2xx responses are mapped to typed exceptions — see Errors.

Minimal end-to-end example

The smallest working app: load an env, construct a client, upsert an agent.
import { Tally } from "@tallyforagents/sdk";

async function main() {
  const tally = new Tally({
    apiKey: process.env.TALLY_API_KEY!,
    baseUrl: process.env.TALLY_BASE_URL,
  });

  const agent = await tally.agents.upsert({ id: "smoke-test" });
  console.log(`agent ${agent.id} status=${agent.status}`);
}

main().catch((err) => {
  console.error(err);
  process.exit(1);
});
Run with node --env-file=.env.local index.ts (Node 20+) and you should see agent smoke-test status=no_permissions.

Where to go next

  • Agentstally.agents.*
  • Paymentstally.payments.*
  • Webhookstally.webhooks.verifySignature
  • Errors — typed exceptions and the recovery patterns