Skip to content
Developersskuflo.iov1Changelog
Guides

Authentication

Every request carries one Bearer token. Which kind of token depends on what you are building.

Factory API keys#

In the app, go to Settings, then Webhooks and API keys, and create a key. It is shown to you once, as plain text starting sk_live_. Store it somewhere safe: Skuflo only ever keeps a hash of it, so a lost key cannot be recovered, only revoked and replaced.

An API key has full access to your factory's data. It can read every order, push new ones, print labels, record loads and manage retailers. It cannot change your team, API keys, webhooks, company settings or billing: those need an admin signed in to the app. Treat it like a password: never put it in client side code, a mobile app bundle, or a public repository.

Revoke a key in the app, under Settings, then Webhooks and API keys: it stops working immediately. There is no limit on how many keys a factory can hold, so a key per integration (one for your ERP, one for a script) means revoking one never affects another.

Retailer API keys#

A retailer can connect its own systems (a Shopify store, an ERP, a script) to the manufacturers it buys from. An Owner on the retailer account makes a key in the portal, under Integrations, then API keys. It is shown once, starting rk_live_, and belongs to the retailer's account, not to the person who made it: one key works with every manufacturer the retailer is an Owner at. Manufacturers they join later can be added to the key in the same place.

GET /v1/portal/manufacturers lists the manufacturers a key works with, each with its id. When a key works with more than one, every request that belongs to one manufacturer names it with?manufacturer=<id>: sending an order or a sheet, and looking up its SKUs, catalogue or product types. Without it the answer is 400 manufacturer_required, with the manufacturers list to choose from, and nothing is sent. With only one manufacturer it can be left out. Reading orders covers all of them at once (filter with ?manufacturer=), and changing or deleting an order finds its manufacturer by itself.

A key with the orders access sends orders (POST /v1/portal/orders, or a sheet), changes or deletes them while they wait for review, and reads them back. A read key only reads. Orders sent with a key wait in the manufacturer's Review, exactly like orders placed in the portal. Sending an order number that is already on file answers 409 duplicate_order and changes nothing, so a sync can safely retry.

A retailer key sees only the retailer's own orders, at the manufacturers it works with. It cannot add people, make keys, change webhooks or settings, or reach any factory route. The Retailer API section of the reference lists everything it can call. The retailer's Owners can revoke it in the portal, which ends it everywhere. A manufacturer can revoke it on the retailer's Integrations tab, which ends it at that manufacturer only, and is never told which other manufacturers it works with.

Scan station tokens#

A scan station token is different on purpose: it can only ever record one kind of scan (produce, stock or dispatch), for one physical station, and nothing else. A compromised station token cannot read an order, list retailers, or touch a webhook.

Pairing is a two step handshake, built for a tablet, phone or a piece of hardware you built yourself:

  1. With a factory API key or a staff session, create a ten minute pairing code: POST /v1/stations/pairing-codes. Show it, or its QR form, to whoever is setting up the station.
  2. The device swaps that code for its permanent token: POST /v1/stations/pair, no other auth needed. The token is shown once, starting st_live_: store it on the device.

See Scanning from your own hardware for what the token can then do.

Sending the header#

Every authenticated request needs one header, whichever kind of token you are using: Authorization: Bearer <token>.

A missing or unrecognised token returns 401. A token that is the right shape but for a role that cannot do what you asked returns 403. Both are covered in Errors.

Staff and retailer sessions#

The app itself (and the retailer portal) signs staff and retailer users in with a short lived session token, not an API key. Those login endpoints live under /v1/auth and /v1/portal/auth and are not documented here: they are how our own web app signs a person in, not something a third party integration should call. If you are building an integration, a factory API key, a retailer API key or a station token is what you want.