Scanning from your own hardware

If you are not using a Skuflo tablet or phone, POST /v1/scan is the one endpoint your hardware needs: a scan station token (see Authentication) is locked to one event, produce, stock or dispatch, so a request can never claim to be something it is not.

The scan endpoint

Shell
curl -X POST https://api.skuflo.io/v1/scan \
  -H "Authorization: Bearer st_live_..." \
  -H "Content-Type: application/json" \
  -d '{ "barcode": "OAK 7F3K9QZ2", "location": "A3" }'

barcode is required. location is only read on a stock station (a rack bay, for example A3), and falls back to the station’s configured default location when left out.client_scan_id is for offline clients: see below.

Full parameter and response reference: POST /v1/scan.

Every outcome

The response is always { ok, outcome, barcode, item, order, ... }. ok and the HTTP status tell you at a glance whether to show a green tick or a red cross; outcome says exactly why.

OutcomeStatusMeaning
ok200Accepted. The piece moved to its next state.
duplicate200This exact scan already happened (same piece, same event), or a replayed client_scan_id.
not_found409The barcode does not match a label in this factory.
not_produced409A stock or dispatch scan arrived before the piece was ever produced.
already_dispatched409The piece has already been loaded; it cannot move again.
cancelled409The order this piece belongs to was cancelled.
voided409This label was voided. A response field replacement_barcode names the piece that replaced it, if any.
location_required409A stock scan needs a rack bay: pass location, or set a default location on the station.
bad_location409The rack bay given does not exist, or is out of range for that rack.
test200The printed hardware test label was scanned. Nothing was touched; this just proves the scanner and the station can talk to each other.

Offline replay

A phone or handheld that queues scans while it has no signal should generate its own client_scan_idfor every scan (a UUID is fine) and send the same id if that queued scan is ever replayed. The first attempt is recorded normally; every later attempt with the same id comes back as outcome duplicate, with replay: true, so the piece is only ever counted once no matter how many times the network makes you retry.

Barcode normalisation

Whatever a scanner or a keyboard wedge setting actually sends is cleaned up before it is matched against a label, so your hardware does not need to get this exactly right:

  • Control characters (carriage return, tab, the FNC1/GS prefix some scanners add) are stripped from anywhere in the payload.
  • A leading AIM symbology identifier (for example ]C0 or ]Q6) is removed.
  • Our own QR link (https://skuflo.io/i/<code> or skuflo://i/<code>) is unwrapped to the plain barcode underneath, and URL decoded.
  • Internal whitespace is collapsed to a single space, and the result is uppercased.
  • If a scanner drops the space between the label prefix and the code (for example OAK7F3K9QZ2), it is reattached when the shape is unambiguous.

In short: send whatever the scanner gives you as the barcode field, raw. There is no need to clean it up on the device first.

The hardware test label

GET /v1/hardware/test-label returns a printable PDF or ZPL label with a fixed code. Scanning it at any station always returns outcome test and never touches an order, so it is safe to use while you are getting a new scanner or a new build of your app talking to Skuflo for the first time.