> ## Documentation Index
> Fetch the complete documentation index at: https://docs.tuco.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# Agency API Keys

> The tucoagency_ key lets an agency create workspaces, move lines between them and read stats across the whole group from one credential — without signing in.

If you run several Tuco workspaces under one agency account, an **agency API key**
lets you manage the whole group from one credential: create a workspace for a new
client, move a line between clients, and pull numbers across every workspace —
without signing in and without juggling one key per workspace.

<Note>
  Agency API keys are only available on agency accounts. If you have a single
  workspace, use a normal [workspace API key](/api-reference/api-keys) — it already
  does everything you need.
</Note>

## The two kinds of key

Tuco has two API keys and they are not interchangeable. You can tell them apart by
the prefix.

| | Workspace key | Agency key |
| - | - | - |
| Prefix | `tuco_…` | `tucoagency_…` |
| Scope | one workspace | every workspace in your agency |
| Created from | Integrations → API keys, in that workspace | Agency view → Settings → API key |
| Who can create it | workspace owner or admin | the **agency owner** only |
| Works on | every documented endpoint | the five agency endpoints below, and nothing else |

A workspace key sent to an agency endpoint is refused with `AGENCY_KEY_REQUIRED`,
and an agency key sent anywhere else is refused with `AGENCY_KEY_WRONG_ENDPOINT`.
Neither is a silent failure — the error tells you which key to use.

## Creating an agency key

1. Open the **agency view** (the workspace switcher → *Agency view*).
2. Go to **Settings → API key**.
3. Give the key a name and press **Create agency key**.
4. Copy the key. It is shown once and never again.

Only the agency owner sees this screen. Agency co-admins can use the agency
dashboard but cannot create, list or revoke agency keys.

Revoking is immediate: press **Revoke** and the key stops working on the next
request.

## What an agency key can do

```
GET  /api/agency/subaccounts        list the workspaces in your agency
POST /api/agency/subaccounts        create a workspace
GET  /api/agency/lines              list every line across the agency
POST /api/agency/lines              move a line between your workspaces
GET  /api/agency/overview           stats across all sub-workspaces
GET  /api/agency/email-preferences  who gets Tuco emails, per workspace
POST /api/agency/email-preferences  turn Tuco's emails off across the group
GET  /api/agency/webhooks           every client webhook, and who has none
POST /api/agency/webhooks           register one for a client — or all of them
DELETE /api/agency/webhooks/{id}    remove one
POST /api/agency/billing/subscribe  put a client on a plan (no checkout page)
```

That is the whole list. An agency key cannot send a message, upload a lead, read a
conversation, manage your card or create another API key. For any of that, use the
workspace key for the workspace you mean.

## What an agency key deliberately cannot do

* **Leave your group.** Every workspace id you pass is checked against your agency.
  Another agency's workspace is refused, and another agency's key cannot touch yours.
* **Delete anything.** Deleting a line is reversible only by re-provisioning it, so
  it stays on a signed-in agency-owner session. An agency key moving a line is safe:
  one more call moves it back.
* **Create or revoke API keys.** Key management is session-only, so a leaked key
  cannot be used to issue more keys.
* **Touch your card or your members.** `/api/agency/billing`,
  `/api/agency/members` and `/api/agency/admins` stay in the dashboard. The key
  can subscribe a client to a plan on the card, but cannot change the card.
* **Reach outside your own agency.** Lines move between YOUR workspaces. Moving
  one to a different agency is not something either side can do — that still
  comes to us.

## Authentication

Send the key as a bearer token, exactly like a workspace key:

```bash theme={null}
curl https://app.tuco.ai/api/agency/overview \
  -H "Authorization: Bearer tucoagency_xxxxxxxxxxxxxxxx"
```

Unlike workspace keys, agency keys are **not** accepted via HTTP Basic auth — a
group-wide credential travels in the `Authorization` header only.

## Two ways your agency pays

| | Stripe billing (default) | Invoice billing |
| - | - | - |
| Who pays | Your saved card, charged per client subscription | Tuco invoices your agency offline |
| `subscribe` returns | a real `subscriptionId` | `subscriptionId: null`, `billingMode: "invoice"` |
| Card required | yes | no |
| Client in Stripe | yes, its own subscription | **no — not at all** |
| Can a client be dunned or emailed about payment? | yes, through your card | **no. There is nothing in Stripe to fail** |
| Add-on lines | charged to your card | granted, added to your agency invoice |

Both modes still put every client on a **plan** — that's what grants its line
limits, not the charge. Invoice billing is arranged with Tuco; it is not
self-serve.

## Errors

| Status | Code | When |
| - | - | - |
| `401` | `UNAUTHORIZED` | No key, or a key that is unknown, revoked or expired |
| `403` | `AGENCY_KEY_REQUIRED` | A workspace key (`tuco_…`) was sent to an agency endpoint |
| `403` | `AGENCY_KEY_WRONG_ENDPOINT` | An agency key was sent to a non-agency endpoint. The body lists the endpoints it does work on |
| `403` | `NOT_AN_AGENCY` | The account behind the key is no longer an agency |
| `403` | `AGENCY_OWNER_REQUIRED` | A co-admin tried to manage agency keys |
| `403` | `AGENCY_DELETE_SESSION_ONLY` | `action: "delete"` was attempted with an API key |

A `AGENCY_KEY_WRONG_ENDPOINT` response tells you what to do next:

```json theme={null}
{
  "error": "An agency API key only works on the agency endpoints: GET /api/agency/subaccounts, POST /api/agency/subaccounts, GET /api/agency/lines, POST /api/agency/lines, GET /api/agency/overview. Use a workspace API key (tuco_…) for /api/messages and every other endpoint.",
  "code": "AGENCY_KEY_WRONG_ENDPOINT",
  "agencyEndpoints": [
    "GET /api/agency/subaccounts",
    "POST /api/agency/subaccounts",
    "GET /api/agency/lines",
    "POST /api/agency/lines",
    "GET /api/agency/overview",
    "GET /api/agency/email-preferences",
    "POST /api/agency/email-preferences",
    "GET /api/agency/webhooks",
    "POST /api/agency/webhooks",
    "DELETE /api/agency/webhooks/{id}",
    "POST /api/agency/billing/subscribe"
  ],
  "requestedPath": "/api/messages"
}
```

## A typical onboarding script

Create the client's workspace, then mint a workspace key inside it from the
dashboard to do the day-to-day sending.

```bash theme={null}
AGENCY_KEY="tucoagency_xxxxxxxxxxxxxxxx"

# 1. Create the workspace. The response also carries a ready-to-use
#    workspace key (tuco_...) for the new workspace — save it, it is
#    shown once.
CREATED=$(curl -s https://app.tuco.ai/api/agency/subaccounts \
  -H "Authorization: Bearer $AGENCY_KEY" \
  -H "Content-Type: application/json" \
  -d '{"name":"Acme Roofing","legalName":"Acme Roofing LLC","timezone":"America/Denver"}')
WS=$(echo "$CREATED" | jq -r '.subAccount.clerkOrgId')
WS_KEY=$(echo "$CREATED" | jq -r '.workspaceApiKey')

# 2. Put them on a plan — one call, charged to your card, no checkout page
curl -s https://app.tuco.ai/api/agency/billing/subscribe \
  -H "Authorization: Bearer $AGENCY_KEY" \
  -H "Content-Type: application/json" \
  -d "{\"workspaceId\":\"$WS\",\"plan\":\"starter\"}"

# 3. Move a spare line into it
curl -s https://app.tuco.ai/api/agency/lines \
  -H "Authorization: Bearer $AGENCY_KEY" \
  -H "Content-Type: application/json" \
  -d "{\"action\":\"transfer\",\"lineId\":\"6a3d7d7ef8c81f91304ed6f1\",\"targetWorkspaceId\":\"$WS\"}"

# 4. Register their webhook — no need to hold their key
curl -s https://app.tuco.ai/api/agency/webhooks \
  -H "Authorization: Bearer $AGENCY_KEY" \
  -H "Content-Type: application/json" \
  -d "{\"workspaceId\":\"$WS\",\"url\":\"https://yourapp.com/hooks/tuco\",\"events\":[\"message.reply\"],\"name\":\"Acme\"}"

# 5. Invite the client in, using the workspace key you just got
curl -s https://app.tuco.ai/api/team/invite \
  -H "Authorization: Bearer $WS_KEY" \
  -H "Content-Type: application/json" \
  -d '{"email":"owner@acmeroofing.com","role":"org:admin"}'

# 6. Stop Tuco emailing your clients directly
curl -s https://app.tuco.ai/api/agency/email-preferences \
  -H "Authorization: Bearer $AGENCY_KEY" \
  -H "Content-Type: application/json" \
  -d '{"enabled":false}'

# 7. Check in on everyone next month
curl -s "https://app.tuco.ai/api/agency/overview?days=30" \
  -H "Authorization: Bearer $AGENCY_KEY"
```


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.