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

# API overview

> Conventions every Tally REST endpoint follows.

The Tally REST API is the same surface the [TypeScript SDK](/sdk/installation) wraps. Use the REST endpoints directly when you're working in a language the SDK doesn't cover yet, or when you want full control over HTTP behavior (custom retry middleware, structured logging, etc.).

## Base URL

```
https://api.tally.example.com
```

Set this explicitly in production. The SDK defaults to `http://localhost:3000` for local development — that's helpful for dev, but every deployed environment should set the base URL.

## Versioning

Every endpoint is prefixed with `/v1`. The `v1` family is stable: we add fields and endpoints, but we don't remove or repurpose them. Breaking changes will live under `/v2` whenever they happen — `v1` will keep working in parallel.

## Request format

* **HTTPS only.** Plain HTTP is rejected.
* **JSON only.** Set `Content-Type: application/json` on every request with a body. Tally returns `application/json` on every response, including errors.
* **Field names are `snake_case`** — `agent_id`, `amount_usdc`, `idempotency_key`. The SDK preserves this casing in TypeScript types.

```bash theme={null}
curl https://api.tally.example.com/v1/agents \
  -H "Authorization: Bearer $TALLY_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"id": "research-bot"}'
```

## Response format

Successful responses return a JSON object with the resource keyed under its name:

```json theme={null}
{
  "agent": {
    "id": "research-bot",
    "status": "no_permissions",
    "mode": "test",
    "created_at": "2026-05-18T12:00:00Z",
    "active_signers": 0,
    "pending_signers": 0
  }
}
```

List endpoints return arrays under a plural key:

```json theme={null}
{ "agents": [ { "id": "research-bot", ... }, { "id": "summarizer", ... } ] }
```

This shape is consistent across the API — your client can lift fields by their resource name without per-endpoint parsing.

## Error format

Errors use a consistent envelope across every endpoint:

```json theme={null}
{
  "error": {
    "type": "validation_failed",
    "message": "Amount exceeds per-tx max.",
    "code": "amount_too_large",
    "details": { "max_per_tx_usdc": "10", "requested": "15" }
  }
}
```

| Field     | Type              | Description                                                                                         |
| --------- | ----------------- | --------------------------------------------------------------------------------------------------- |
| `type`    | string            | Coarse-grained category — `unauthenticated`, `forbidden`, `not_found`, etc. Drives the HTTP status. |
| `message` | string            | Human-readable. Safe to log; no PII.                                                                |
| `code`    | string (optional) | Specific failure mode within `type`.                                                                |
| `details` | any (optional)    | Structured context — often the failed Zod issue list.                                               |

The HTTP status code follows from `type`. See [Errors](/api/errors) for the full table.

## Authentication

Bearer-token, scoped to one (account, mode). See [Authentication](/api/authentication) for the details.

## Where to go from here

* [Authentication](/api/authentication) — how API keys work.
* [Errors](/api/errors) — full error type table and status codes.
* [Rate limits](/api/rate-limits) — request ceilings and `Retry-After` semantics.
* [Idempotency](/api/idempotency) — making writes safe across retries.

Resource endpoints:

* [Agents](/api/agents) — `POST /v1/agents`, `GET /v1/agents`, `GET /v1/agents/{id}`
* [Payments](/api/payments) — `POST /v1/payments`, `GET /v1/payments/{id}`
