Menu

Authentication & abilities

Every call carries an API token. The token decides which workspace the call is about and which endpoints it may use.

Send the token

Send the token as a bearer token in the Authorization header, on every call:

curl "https://picked.nl/api/v1/stock?sku=YOUR-SKU" \
  -H "Authorization: Bearer $PICKED_TOKEN" \
  -H "Accept: application/json"

A call without a valid token answers 401 with the code unauthenticated. That includes a token that was revoked.

One token, one workspace

A token belongs to the workspace it was issued in, and every call it makes reads and writes that workspace's data only. You never send a workspace id: Picked takes it from the token. The base URL is https://picked.nl/api/v1 for every workspace. If you call the API on your workspace's own address instead, the token must belong to that workspace, or the call answers 403 with the code forbidden. The node catalogue is the same for every workspace and skips this check.

Abilities

When you issue a token, you choose its abilities. Each endpoint needs one of them:

Endpoint Ability
POST /api/v1/orders orders:write
GET /api/v1/orders/{id} orders:read
GET /api/v1/orders/changes orders:read
GET /api/v1/stock stock:read
GET /api/v1/stock/changes stock:read
GET /api/v1/stock/changes/feed stock:read
POST /api/v1/receipts receipts:write
GET /api/v1/receipts/{id} receipts:write
POST /api/v1/process-events/{eventKey} process-events:write
POST /api/v1/processes/{process}/runs process-runs:write
GET /api/v1/process-runs/{id} process-runs:write
POST /api/v1/process-runs/callbacks/{token} no token
GET /api/v1/node-catalog any valid token
GET /api/v1/warehouses any API token
GET /api/v1/locations any API token

Why the callback needs none: Let your system decide a step.

A token without the ability an endpoint needs answers 403 with the code missing_ability. You can't add an ability to an existing token: issue a new token with the abilities you need, and revoke the old one.

One token per integration

Give each integration its own token, with only the abilities it uses. A webshop that only shows stock gets a stock:read token; the ERP that sends orders gets an orders:write token. Then a leaked token can do as little as possible, and you can revoke one integration's access without stopping the others.

Each token's recent calls are listed under Requests next to the token on the API tokens page: the last 100 calls, kept for 30 days, with their status. Request bodies are never stored.

How long a token lasts

A token has no expiry date. It keeps working until you revoke it, or until the member who issued it is removed from your workspace: removing a member deletes every token they issued. The API tokens page shows who issued each token and when it was last used.

So issue an integration's token from an account that will stay, not from the account of someone who might leave.

Revoke a token

Choose Revoke next to the token on the API tokens page. It stops working at once: the next call with it answers 401. Revoke a token as soon as you suspect it leaked, and when the integration that used it goes away. Revoking takes the same permission as issuing.

Rotate a token

To replace a token without downtime:

  1. Issue a new token with the same abilities.
  2. Put the new token in your integration's configuration and deploy it.
  3. Check on the API tokens page that the old token is no longer being used.
  4. Revoke the old token.