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:
- Issue a new token with the same abilities.
- Put the new token in your integration's configuration and deploy it.
- Check on the API tokens page that the old token is no longer being used.
- Revoke the old token.