Flow · 12 steps

Ordering stock in, and counting it when it lands

Order stock in, receive it, and name tracked units.

A purchase order tells inventory what is coming, so incoming rises before anything arrives. When the goods land, an untracked SKU can be sold at once. A serial- or batch-tracked SKU cannot: its units wait in awaitingIdentification until someone says which units they are, because a unit nobody can name cannot be picked, held or shipped.

Services involved

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

  • Inventory Manager: https://inventory.getmanifold.io
  • Purchasing Manager: https://purchasing.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 Create a serial-tracked SKU

Tracked stock must start at zero. There is no such thing as an opening balance of serialised units — every one of them has to arrive through receiving so it has a document behind it.

POST /items Inventory Manager

Request · application/json
{
  "sku": "WIDGET-SERIAL",
  "name": "Blue widget, serialised",
  "quantity": 0,
  "tracking": "serial"
}

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

Records inventory.item-created.

2 Stock arrives with no paperwork

A direct receive — a transfer, a correction, a channel that is not purchasing. The quantity is recorded, and it is not sellable.

POST /items/WIDGET-SERIAL/receive Inventory Manager

Request · application/json
{
  "quantity": 3,
  "reference": "transfer-4417"
}

What the answer holds: the operation's example.

Records inventory.stock-received.

3 See it held out of the pool

Three units on the floor, none of them promisable: onHand is 0 and awaitingIdentification is 3. This is the number to watch when goods are visibly in the warehouse but nothing can be sold.

GET /items/WIDGET-SERIAL/stock Inventory Manager

What the answer holds: the operation's example.

4 Name the units

One serial per unit. This is the step that moves them into on-hand — and it refuses more units than actually arrived, a batch number for a serial SKU, or any attempt to identify an untracked SKU.

POST /items/WIDGET-SERIAL/identify Inventory Manager

Request · application/json
{
  "quantity": 3,
  "serials": [
    "SN-4417-001",
    "SN-4417-002",
    "SN-4417-003"
  ],
  "reference": "transfer-4417"
}

What the answer holds: the operation's example.

Records inventory.stock-identified.

5 Raise a purchase order for more

The supply side proper: forty more on order from the supplier.

POST /pos Purchasing Manager

Request · application/json
{
  "reference": "PO-WIDGET-SERIAL",
  "supplier": "Northwind Components",
  "lines": [
    {
      "sku": "WIDGET-SERIAL",
      "quantity": 40,
      "unitCostCents": 1250
    }
  ]
}

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

From your answer, later steps send id as {poId}.

Records purchasing.po-created.

6 Authorise it

Committing to the purchase registers the expectation in inventory, which is what puts the units on the SKU's incoming list before they physically exist.

POST /pos/{poId}/authorise Purchasing Manager

What the answer holds: the operation's example.

Records purchasing.po-authorised, inventory.incoming-expected.

7 Read the whole picture

Three sellable, forty on the way, nothing owed out — projected is 43. One read answers what is free, what is promised away, what is coming and whether that covers the orders already taken.

GET /items/WIDGET-SERIAL/stock Inventory Manager

What the answer holds: the operation's example.

8 Check the order itself

The PO with its lines, and how much of each has been received so far.

GET /pos/{poId} Purchasing Manager

What the answer holds: the operation's example.

9 Receive against the order, with identity

Purchasing validates the serials against the SKU's tracking mode and against every serial already registered, commands inventory to take the quantity, then names the units itself — so a well-formed receipt never leaves stock stranded in the holding bucket. The receipt id is the idempotency key on both halves.

POST /pos/{poId}/receipts Purchasing Manager

Request · application/json
{
  "receiptId": "rcpt_01a15864-bc4f-7f80-b1c3-5d6e7f809a1b",
  "lines": [
    {
      "sku": "WIDGET-SERIAL",
      "quantity": 2,
      "serials": [
        "SN-9001",
        "SN-9002"
      ]
    }
  ]
}

What the answer holds: the operation's example.

Records purchasing.receipt-requested, purchasing.receipt-recorded, inventory.stock-received, inventory.stock-identified.

10 The incoming draws down as the goods land

Five sellable now, thirty-eight still expected. The expectation is consumed on arrival, not on identification — the purchase order delivered whether or not anyone has counted the serials yet, and leaving it open would count those units twice.

GET /items/WIDGET-SERIAL/stock Inventory Manager

What the answer holds: the operation's example.

11 See the named units on the shelf

The registry's FEFO view: which physical units are free to pick, soonest expiry first. Identity that came through a purchase order reaches here; identity captured by a bare identify does not yet.

GET /shelf/WIDGET-SERIAL Fulfillment Manager

What the answer holds: the operation's example.

12 And the catalogue reflects it

The organization's items, as Manifold holds them now.

GET /items Inventory Manager

What the answer holds: the operation's example.

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