# REST API

> What the TradeCatalog REST API covers, who can use it and every endpoint at a glance.

The REST API gives your own systems the same data your staff see in TradeCatalog: products, customer prices, customers, orders, price changes and the activity log. It uses JSON over HTTPS and one API key per system.

## Base URL

```text
https://tradecatalog.app/api/v1
```

Every request needs an API key in the `Authorization` header. See [Authentication](/docs/api/authentication).

## Who can use it

- **Owners** make and revoke keys. Staff and buyers can’t.
- The workspace needs an **active subscription**, a **free trial** or a **pilot** account to make keys.
- **Demo workspaces** can’t use the API at all.
- If a subscription lapses and the workspace goes read-only, existing keys can still read but can’t write.

A key belongs to one workspace. It acts with owner rights on that workspace, so it can see every customer’s prices.

## Endpoints

| Method | Path                                                                    | What it does                                               | Scope |
| ------ | ----------------------------------------------------------------------- | ---------------------------------------------------------- | ----- |
| GET    | [`/workspace`](/docs/api/workspace)                                     | The workspace this key belongs to                          | read  |
| GET    | [`/products`](/docs/api/products#list-or-search-products)               | List or search products, optionally at a customer’s prices | read  |
| GET    | [`/products/{id}`](/docs/api/products#get-one-product)                  | One product with its price                                 | read  |
| PUT    | [`/products`](/docs/api/products#create-or-update-products)             | Create or update up to 100 products by SKU                 | write |
| GET    | [`/brands`](/docs/api/products#brands-and-categories)                   | All brands                                                 | read  |
| GET    | [`/categories`](/docs/api/products#brands-and-categories)               | All categories                                             | read  |
| GET    | [`/prices`](/docs/api/prices)                                           | What a customer pays for a SKU, and why                    | read  |
| GET    | [`/customers`](/docs/api/customers#list-customers)                      | Trade customers                                            | read  |
| GET    | [`/customers/{id}`](/docs/api/customers#get-one-customer)               | One customer’s terms, rules, agreed prices and buyers      | read  |
| PUT    | [`/customers`](/docs/api/customers#create-or-update-customers)          | Create or update up to 100 customers                       | write |
| GET    | [`/orders`](/docs/api/orders#list-orders)                               | Recent orders, newest first                                | read  |
| GET    | [`/orders/{id}`](/docs/api/orders#get-one-order)                        | One order with lines and status history                    | read  |
| PATCH  | [`/orders/{id}`](/docs/api/orders#move-an-order-on)                     | Move an order on                                           | write |
| GET    | [`/price-changes`](/docs/api/price-changes#list-price-changes)          | Price changes, newest first                                | read  |
| GET    | [`/price-changes/{id}`](/docs/api/price-changes#preview-a-price-change) | Preview one price change                                   | read  |
| GET    | [`/activity`](/docs/api/activity)                                       | Who changed what                                           | read  |

The full machine-readable description is at [`/api/v1/openapi.json`](/docs/api/openapi).

## Before you build

- Read [Conventions](/docs/api/conventions) for money, paging, dates and how `PUT` works.
- Read [Errors](/docs/api/errors) for status codes and retries.
- Keep keys on your server. The API doesn’t allow browser (CORS) requests.

## Not in the API yet

- Webhooks: poll `GET /orders?status=new` instead.
- Publishing, scheduling or cancelling price changes: do that in the app.
- Discount rules and agreed prices: read them with `GET /customers/{id}`, change them in the app.
- Deleting products or customers, uploading images directly, inviting buyers, placing orders as a buyer.
