# Authentication

> API keys, read and write scopes, revoking keys and keeping them safe.

The API uses secret API keys. Each key belongs to one workspace.

## Send the key

Put the key in the `Authorization` header as a bearer token:

```http
GET /api/v1/workspace HTTP/1.1
Host: tradecatalog.app
Authorization: Bearer tc_live_Xk2…
```

```bash
curl https://tradecatalog.app/api/v1/workspace \
  -H "Authorization: Bearer $TRADECATALOG_API_KEY"
```

Keys always start with `tc_live_`. There are no test keys: try things out on a workspace with sample data, or read before you write.

## Make a key

Only the workspace **owner** or an **admin** can make keys, in **Settings → API**.

| Setting      | What it means                                                                  |
| ------------ | ------------------------------------------------------------------------------ |
| Name         | Your label, e.g. “Sage stock sync”. Shown in Settings and in the activity log. |
| Read only    | `GET` requests only.                                                           |
| Read & write | Also `PUT /products`, `PUT /customers` and `PATCH /orders/{id}`.               |

The key is shown **once**. We store only a SHA-256 hash, so nobody at TradeCatalog can see it again. Settings shows the first few characters (like `tc_live_Xk2m…`) so you can tell keys apart.

A workspace can have up to **20 live keys**. Give each system its own key, so you can revoke one without breaking the others.

## Who can have keys

The workspace needs one of these to make keys:

- an active subscription
- a Pro trial
- a pilot account (arranged with Happy Webs)

Demo workspaces can’t make or use keys.

If the subscription lapses, you get 14 days’ grace. After that the workspace returns to Free. Existing keys can still read, but API writes fail with `403 read_only` until Pro is active again. Catalog edits and buyer orders in the app keep working.

## What a key can do

A key acts with the **permissions of the person who made it**, as they are now. A key made by an owner or admin can read every customer, every customer’s prices, every order and the activity log. Treat it like that person’s password. A key made by someone limited to their assigned customers or regions sees only those customers and their orders, prices and activity; any other customer or order returns `404`, the same as one that doesn’t exist, and price changes return `403`.

If that person is later given a narrower role, the key narrows with them: a write the new role isn’t allowed to make fails with `403 forbidden`, the same as in the app. If they leave the workspace, the key stops working with `401 key_owner_removed`. Make a new key from someone who still has access.

## Last used and revoking

Settings shows when each key was last used (updated at most once an hour). Choose **Revoke** to stop a key straight away. The next request with it gets `401 unauthorized`. Revoked keys can’t be restored.

## Who the changes are logged as

Writes appear in the workspace’s activity log as `API key “Sage stock sync”`. Order status changes are recorded against the person who made the key.

## Keep keys safe

- Keep keys on your server, in environment variables or a secrets manager.
- Never put a key in a web page, browser extension or mobile app. The API doesn’t allow browser (CORS) requests for this reason.
- Never commit a key to git. If you do, revoke it and make a new one.
- Use a read-only key wherever you only need to read.

## Errors

| Status | Code                 | Why                                                                                                                                      |
| ------ | -------------------- | ---------------------------------------------------------------------------------------------------------------------------------------- |
| 401    | `unauthorized`       | No `Authorization` header, a malformed one, an unknown or revoked key, or a demo workspace. The response has `WWW-Authenticate: Bearer`. |
| 401    | `key_owner_removed`  | The person who made the key no longer has access to the workspace. Make a new key.                                                       |
| 403    | `insufficient_scope` | A read-only key tried to write.                                                                                                          |
| 403    | `forbidden`          | The person who made the key isn’t allowed to do that (for example, a Viewer can’t write).                                                |
| 403    | `read_only`          | API writes are unavailable on the Free plan.                                                                                             |

See [Errors](/docs/api/errors) for the full list.

**AI apps use a different sign-in:** Claude, ChatGPT and other MCP clients don’t use API keys. Each person signs in with their own login through OAuth. See [MCP](/docs/mcp).

