# 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** 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 free 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 is read-only: existing keys can still read, but writes fail with `403 read_only` until the subscription is active again.

## What a key can see

A key acts with **owner rights** on its workspace. It can read every customer, every customer’s prices, every order and the activity log. Treat it like the owner’s password.

## 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 owner 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`. |
| 403    | `insufficient_scope` | A read-only key tried to write.                                                                                                          |
| 403    | `read_only`          | The workspace is read-only: its free trial or subscription has ended.                                                                    |

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

