# Getting started with the Supplier API

Connect the systems a supplier already runs, an ERP, a warehouse management system, a courier integration, straight to the purchase orders Orbit stores send you. The Supplier API is a small, purpose-built REST surface: pull orders, acknowledge them, ship parcels, push tracking and stock, and subscribe to signed webhooks. It is authenticated with a key you mint yourself in the supplier dashboard. No partner account, no plugin, no OAuth.

## Who this is for

Orbit Commerce has two API surfaces for two different businesses:

| | Supplier API | Public API |
|---|---|---|
| You are | A supplier: a business that receives purchase orders from Orbit stores | A store, or a developer building for stores |
| Credential | Supplier API key, `sup_sk_…`, minted in the supplier dashboard | Store API key (`oc_sk_…`) or a plugin token |
| Base path | `/api/supplier-api/v1` | `/v1` |
| Scopes | `supplier_api:*` | `product:read`, `order:read`, and the rest of the [Scope Catalog](/scope-catalog) |
| What you see | Only the purchase orders sent to you, and only your own listings | A store's own data |

If you are integrating a store's own systems, read [Store API keys](/guides/api-keys) instead. If you build software that many stores install, start at [Getting started with plugins](/guides/getting-started). Everything on this page and the guides beside it is for suppliers.

## Creating a key

In the supplier dashboard, open **Settings**, then **API Keys**, and choose **Create API key**. Creating keys needs the supplier permission to manage settings, so an owner or an admin does this.

1. **Name it after the system that will hold it.** "Warehouse WMS connector", "Sage 200 sync". The name is how you tell keys apart later.
2. **Pick scopes.** A key can only call the endpoints its scopes cover. Grant the least the system needs.
3. **Set an expiry if you want one.** Keys are long-lived by default and stay valid until revoked. An expiry must be in the future.
4. **Copy the key immediately.** It is shown exactly once. Orbit stores only a fingerprint, so a lost key cannot be recovered, only revoked and replaced.

Keys look like `sup_sk_` followed by 43 characters. The dashboard shows the first twelve characters of each key so you can match a key in your configuration to a row in the list. A supplier can hold up to 10 active keys, which is enough for one per connected system with room to rotate.

### The four scopes

| Scope | Grants |
|---|---|
| `supplier_api:orders:read` | List and read purchase orders, and the carrier catalogue. |
| `supplier_api:orders:write` | Acknowledge orders, record shipments, and push tracking updates. |
| `supplier_api:stock:write` | Push stock levels for your listings in bulk. |
| `supplier_api:webhooks:manage` | Create, list, pause, delete and test webhook subscriptions, read their delivery log, and redeliver. |

Scopes narrow the key, not the supplier. A key holding every scope can do exactly what the dashboard can do on these surfaces, nothing more.

## Making your first call

Send the key as a bearer token. The supplier is derived from the key itself, so there is no supplier or store identifier to pass.

```http
GET /api/supplier-api/v1/orders?status=sent&limit=20 HTTP/1.1
Host: api.myorbitcommerce.net
Authorization: Bearer sup_sk_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
```

```ts
const response = await fetch(
  'https://api.myorbitcommerce.net/api/supplier-api/v1/orders?status=sent&limit=20',
  { headers: { Authorization: `Bearer ${process.env.ORBIT_SUPPLIER_API_KEY}` } },
);
const { data } = await response.json(); // { items, meta }
```

Every successful response arrives in the platform's standard envelope. Read the `data` field; the shapes documented in these guides are what you find inside it.

```json
{
  "statusCode": 200,
  "message": "Success",
  "data": {
    "items": [ ... ],
    "meta": { "page": 1, "limit": 20, "total": 3, "totalPages": 1, "statusCounts": { "sent": 3 } }
  },
  "timestamp": "2026-09-07T09:01:20.963Z"
}
```

A `POST` that creates something answers `201` with `"message": "Created"`; everything else answers `200`, and a queued redelivery answers `202`.

## The endpoints

All paths are relative to `https://api.myorbitcommerce.net/api/supplier-api/v1`.

| Method and path | Scope | Purpose |
|---|---|---|
| `GET /orders` | `orders:read` | List purchase orders with filters, paging and an incremental `updatedSince` cursor. |
| `GET /orders/{id}` | `orders:read` | One purchase order with its lines, ship-to address and parcels. |
| `POST /orders/{id}/acknowledge` | `orders:write` | Confirm you have received an order. |
| `POST /orders/{id}/shipments` | `orders:write` | Record a parcel against one or more lines, with tracking. Accepts an `Idempotency-Key`. |
| `POST /tracking-updates` | `orders:write` | Push tracking rows keyed by order number or your own reference, up to 500 at a time, with a dry run. |
| `GET /carriers` | `orders:read` | The carrier catalogue: codes, names and tracking URL patterns. |
| `POST /stock/bulk` | `stock:write` | Set stock levels for up to 500 listings in one call. |
| `GET /webhooks/topics` | `webhooks:manage` | The topics you can subscribe to. |
| `GET /webhooks`, `POST /webhooks` | `webhooks:manage` | List your subscriptions, create one (the signing secret is returned once). |
| `PATCH /webhooks/{id}`, `DELETE /webhooks/{id}` | `webhooks:manage` | Pause or resume, delete. |
| `GET /webhooks/{id}/deliveries` | `webhooks:manage` | The last 20 deliveries with response codes and errors. |
| `POST /webhooks/{id}/test` | `webhooks:manage` | Send a signed test ping now. |
| `POST /webhooks/{id}/deliveries/{deliveryId}/redeliver` | `webhooks:manage` | Queue a delivery again. |

The scope column omits the `supplier_api:` prefix for space; the full strings are in the table above. Request and response fields for every endpoint are in the [Supplier API Reference](/supplier-api/reference), and the walkthroughs cover the behaviour that a schema cannot: [Purchase orders and shipments](/supplier-api/guides/purchase-orders), [Stock updates](/supplier-api/guides/stock), [Webhooks](/supplier-api/guides/webhooks), and [Idempotency, rate limits and errors](/supplier-api/guides/reliability).

## Key lifecycle

**Revocation is immediate.** Revoking a key in the dashboard takes effect on its next request. There is no cache to wait out. If a key may have leaked, revoke first and rewire after.

**Scopes are fixed at creation.** There is deliberately no way to widen a live key, because that would silently escalate a credential some system already holds. To change access, create a new key with the scopes you want, switch the system over, and revoke the old one.

**Rotation is a recipe, not a mechanism.** Keys do not rotate themselves. Create the successor, deploy it, confirm traffic, revoke the predecessor. Two keys can be live side by side for as long as the migration needs.

**Webhooks belong to the key that created them.** A subscription created through the API is owned by that key. Revoking the key deletes its subscriptions, and a key that reaches its expiry date stops its subscriptions delivering. Recreate them with the replacement key as part of the rotation. Subscriptions created in the dashboard are owned by the supplier and are unaffected. See [Webhooks](/supplier-api/guides/webhooks).

**Watch last used.** The key list shows when each key last made a call, updated at most once a minute. A key whose activity you cannot account for should simply be revoked.

## Security practices

- **Server-side only.** A key in a browser, a mobile app or a public repository is public. Keep it in your server's secret manager or environment.
- **One key per system.** Separate keys for the ERP and the warehouse mean revoking one does not break the other.
- **Least scopes.** A job that only reads orders needs `supplier_api:orders:read`, not `orders:write`.
- **Never log it.** Redact the key from request logs and error reports. The `sup_sk_` prefix makes it easy to scan for.

## Next steps

- Pull orders, acknowledge them, and ship: [Purchase orders and shipments](/supplier-api/guides/purchase-orders).
- Get told when an order arrives instead of polling: [Webhooks](/supplier-api/guides/webhooks).
- Every request and response shape: [Supplier API Reference](/supplier-api/reference).
