Flow · 12 steps

Print labels at a site

Add a site's label printer and print a SKU's shelf labels on it.

A printer belongs to a site and is reached by the site's print agent — the desktop app on a PC there, enrolled in Settings › Printers and agents. A print job is routed to the printer named, else to the site's default for its purpose, and waits for the agent to take it. Printing stays at the organization's own sites, so read-only mode does not hold it.

Services involved

A filled dot is a read; a ring is a call that changes something.

  • Inventory Manager: https://inventory.getmanifold.io
  • Auth: https://auth.getmanifold.io
  • Fulfillment Manager: https://fulfillment.getmanifold.io

Every call carries Authorization: Bearer $MANIFOLD_TOKEN unless its step says otherwise (getting a token). Run a flow in your sandbox, not your live organization: see Before you start.

1 The site

The site the organization was created with: where the printer stands.

GET /locations Inventory Manager

What the answer holds: the operation's example.

From your answer, later steps send items[0].id as {locationId}.

2 Enrol the site's print agent

The desktop app on the dispatch PC becomes the site's print agent. The answer carries its credential once, to paste into the app (File › Print Agent…); the agent's id is the enroller's, so enrolling again is a retry.

POST /api/auth/print-agents/org_01a15a0d-0000-7e51-8f62-9cadbecfd0e1 Auth

Sent as the person's own sign-in session.

Request · application/json
{
  "agentId": "pag_01a15a0d-0000-7e51-8f62-9cadbecfd0e1",
  "locationId": "{locationId}",
  "name": "Dispatch PC"
}

What the answer holds: the operation's example.

From your answer, later steps send agent.agentId as {agentId}.

Records auth.print-agent-enrolled.

3 The agent, as fulfillment checks it

Before a printer may name an agent, fulfillment asks auth for it with the caller's token: it must be the organization's, enrolled at the printer's site, and not revoked.

GET /api/auth/organizations/org_01a15a0d-0000-7e51-8f62-9cadbecfd0e1/print-agents/{agentId} Auth

What the answer holds: the operation's example.

4 A SKU to label

Its label shows its name and barcodes its first barcode — the SKU itself when it has none.

POST /items Inventory Manager

Request · application/json
{
  "sku": "MUG-SHELF",
  "name": "Shelf mug",
  "quantity": 12
}

Answers 201. What the answer holds: the operation's example.

Records inventory.item-created.

5 Add the printer

A Zebra on the dispatch bench, reached raw on port 9100 by the site's print agent, loaded with 50×25 mm labels, and the site's default printer for SKU labels. The id is the client's, so saving again is a retry.

PUT /printers/prn_01a15a10-2c00-7a11-8b22-5e6f7a8b9c0d Fulfillment Manager

Request · application/json
{
  "name": "Dispatch Zebra",
  "locationId": "{locationId}",
  "agentId": "{agentId}",
  "language": "zpl",
  "media": {
    "widthMm": 50,
    "heightMm": 25,
    "dpi": 203
  },
  "connection": {
    "_tag": "network-raw",
    "host": "192.168.1.40",
    "port": 9100
  },
  "defaultFor": [
    "sku-label"
  ]
}

What the answer holds: the operation's example.

Records fulfillment.printer-saved.

6 Save it again

Idempotent by content: the printer as it already stands is answered as it is, with no second fact.

PUT /printers/prn_01a15a10-2c00-7a11-8b22-5e6f7a8b9c0d Fulfillment Manager

Request · application/json
{
  "name": "Dispatch Zebra",
  "locationId": "{locationId}",
  "agentId": "{agentId}",
  "language": "zpl",
  "media": {
    "widthMm": 50,
    "heightMm": 25,
    "dpi": 203
  },
  "connection": {
    "_tag": "network-raw",
    "host": "192.168.1.40",
    "port": 9100
  },
  "defaultFor": [
    "sku-label"
  ]
}

What the answer holds: the operation's example.

Records nothing.

7 The site's printers

What Settings › Printing lists for the site.

GET /printers?locationId=%7BlocationId%7D Fulfillment Manager

What the answer holds: the operation's example.

8 Print twelve shelf labels

No printer is named, so the job goes to the site's default for SKU labels, and waits queued for that printer's agent. The job id is the caller's.

POST /print-jobs Fulfillment Manager

Request · application/json
{
  "jobId": "pjb_01a15a20-4400-7e55-8f66-8b9c0d1e2f3a",
  "locationId": "{locationId}",
  "document": {
    "_tag": "sku-labels",
    "sku": "MUG-SHELF",
    "copies": 12
  }
}

What the answer holds: the operation's example.

Records fulfillment.print-job-requested.

9 Ask again

A retry with the same jobId answers the job as it stands and appends nothing: the labels print once.

POST /print-jobs Fulfillment Manager

Request · application/json
{
  "jobId": "pjb_01a15a20-4400-7e55-8f66-8b9c0d1e2f3a",
  "locationId": "{locationId}",
  "document": {
    "_tag": "sku-labels",
    "sku": "MUG-SHELF",
    "copies": 12
  }
}

What the answer holds: the operation's example.

Records nothing.

10 The job

Queued until the agent takes it; then sent, and printed or failed with the agent's reason.

GET /print-jobs/pjb_01a15a20-4400-7e55-8f66-8b9c0d1e2f3a Fulfillment Manager

What the answer holds: the operation's example.

11 The site's jobs

The newest first, as the settings screen shows them.

GET /print-jobs?locationId=%7BlocationId%7D Fulfillment Manager

What the answer holds: the operation's example.

12 Remove the printer

Nothing new is sent to it and it is the default for nothing. The shelf labels were still queued — no agent took them — so they fail in the same commit, with why; a job an agent had already taken would finish. Saving it again restores it.

POST /printers/prn_01a15a10-2c00-7a11-8b22-5e6f7a8b9c0d/remove Fulfillment Manager

What the answer holds: the operation's example.

Records fulfillment.printer-removed, fulfillment.print-job-failed.

What a recorded fact is: Facts and the journal. Why a repeated step changes nothing: Idempotency and retries.