01API
Authentication and permissions
Send a key in an Authorization header on every call:
A key belongs to one store. The store is never named in a request: the key decides, and a call sees only that store's data. Keys are made by an owner or a manager in the dealer app (Settings, API keys), are shown once, and only a hash of each is stored. A revoked key stops working at once for any call that changes something, and within a minute for a read (keys are cached for up to 60 seconds).
The four kinds of key
| Prefix | Kind | Where it runs | What it can do |
|---|---|---|---|
rm_pub_ | Public catalog | A web page. Not a secret. | Search and read products, public columns only. 120 calls a minute. |
rm_prv_ (made before permissions) | Private catalog | Your server | The catalog, and /staff/products with cost, MAP, MSRP and distributor offers. It keeps exactly this meaning. |
rm_prv_ (made with permissions) | Scoped private | Your server | Only what its ticked permissions say, below. This is the key plugins use. |
rm_chk_ | FFL Checkout | Your server | The FFL Checkout API under /checkout, and nothing else. |
Everything added after the catalog and FFL Checkout (orders, distributor-order drafts, inventory, webhooks, /me) is server to server: it sends no CORS headers and refuses a request that carries an Origin or Sec-Fetch-Site header (a browser sends them; a server's HTTP client does not). Put your own endpoint between your web page and Rollmark. A public key is the only key that may be in a web page.
A key can never gain permissions. To change what a key may do, make a new one and revoke the old.
Permissions
A scoped private key carries a list of permissions. Nothing is ticked by default when a key is made. A call that needs a permission the key lacks is 403 missing_permission, and the error says which one it needed (required).
| Permission | Allows | Never allows |
|---|---|---|
catalog:read | The catalog endpoints, from a server | |
catalog:cost:read | GET /staff/products/{key}, and the unit cost and quoted totals on distributor orders. The only way the store's cost leaves Rollmark. | Writing any of it |
orders:read | List and read orders, lines, tracking and where each line stands, and the shopper's name, email, phone and addresses | Writing |
orders:write | Send orders, match them to your store's order, add, change and remove lines before they are fulfilled, cancel, mark ready, shipped and delivered | Reading the shopper (that is orders:read) |
inventory:read | List and read stock items: hand-managed and FastBound (read only, serial as its last four) | |
inventory:write | Make and change hand-managed items by your own id: quantity, price, hide or show, zero, remove | An item from FastBound; the item's cost; pricing rules |
distributor_orders:read | Read the store's orders to distributors: status, tracking, the distributor's confirmation number | |
distributor_orders:write | Make and extend drafts from order lines; take lines off a draft; delete a draft | Marking ready, sending, confirming, cancelling, recording shipments or receipts, a stock order: staff only |
webhooks:manage | Register, change and remove webhook endpoints; send a test; resend a delivery; read the log | An endpoint is told only what its key could read |
Marking an order shipped through the API counts as a Rollmark Transfers shipment on the store's usage page, exactly as it does in the dealer app, so that call requires an Idempotency-Key and is audited with the key's id.
Some permissions need a plan that has the thing: distributor orders need a plan with distributor orders; inventory needs a plan with a shelf (not Rollmark Transfers alone). A call that the plan does not include is 403 plan_not_allowed. A store whose subscription needs attention can still read; a write is 403 billing_read_only.
A key's own facts: GET /me
Returns the store's name, the key's id, kind, family and effective permissions (a key made before permissions shows what it has always had), the plan, and the key's request limit. It never shows another key or any secret. Use it when your plugin is installed, to say "this key cannot create orders" before the first order is lost.
Every authentication failure
| Status | code | When |
|---|---|---|
| 401 | missing_key | No Authorization: Bearer header |
| 401 | bad_key | The key is unknown or revoked, or the store is suspended or cancelled. One answer for all, so nothing says which. |
| 403 | wrong_scope | An FFL Checkout key on any route but /checkout, or a scoped route with a checkout key |
| 403 | missing_permission | The key lacks the permission; required names it |
| 403 | server_side_only | The request carries Origin or Sec-Fetch-Site |
| 403 | plan_not_allowed | The store's plan does not include this |
| 403 | billing_read_only | A write while the store's account is read-only |
The three catalog routes keep their original error bodies as well; see Errors.