Flow · 17 steps
Running more than one location
Open a second location, move stock to it, and see what fulfillable changes.
Every organization starts with one location that can ship. A location that is not fulfillable can receive, hold and transfer stock, but never sell it: right for a quarantine bay, a repair bench or a 3PL you have not switched on yet.
Services involved
A filled dot is a read; a ring is a call that changes something.
- Inventory Manager:
https://inventory.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 See what you already have
One fulfillable location, opened with the account. The last fulfillable one can be neither archived nor switched off, so this list is never empty.
GET /locations Inventory Manager
What the answer holds: the operation's example.
From your answer, later steps send items[0].id as {mainLocationId}.
2 Stock the main site
Forty units at the site the account was created with — the only place, so far, that anything can be sold from.
POST /items Inventory Manager
{
"sku": "WIDGET-BLUE",
"name": "Blue widget, 40mm",
"quantity": 40,
"locationId": "{mainLocationId}"
}Answers 201. What the answer holds: the operation's example.
Records inventory.item-created.
3 Open a quarantine bay
fulfillable: false is the flag with teeth. Stock here is real, counted and visible — and nothing can reserve, allocate or dispatch it to a customer.
POST /locations Inventory Manager
{
"name": "Quarantine bay",
"fulfillable": false,
"note": "Goods held pending inspection."
}Answers 201. What the answer holds: the operation's example.
From your answer, later steps send id as {locationId}.
Records inventory.location-created.
4 Move ten units into it
A transfer is a document first: this opens it and moves nothing. Transferring into a non-fulfillable site is entirely normal — it is how stock reaches quarantine in the first place.
POST /transfers Inventory Manager
{
"fromLocationId": "{mainLocationId}",
"toLocationId": "{locationId}",
"reference": "QA-2291",
"lines": [
{
"sku": "WIDGET-BLUE",
"quantity": 10
}
]
}Answers 201. What the answer holds: the operation's example.
From your answer, later steps send id as {transferId}.
Records inventory.transfer-created.
5 Send it
The units come off the source's shelf and land in the destination's inTransit. Sellable at neither end, which is the honest position for stock in a van. The source must hold them free — units already reserved for an order cannot be sent.
POST /transfers/{transferId}/despatch Inventory Manager
{
"reference": "van-WIDGET-BLUE"
}What the answer holds: the operation's example.
Records inventory.transfer-despatched.
6 Watch them disappear from both sides
Thirty available at main, ten in transit, forty on hand across the organization. Nothing was lost and nothing is sellable twice.
GET /items/WIDGET-BLUE/stock Inventory Manager
What the answer holds: the operation's example.
7 Book them in
inTransit falls and on-hand rises at the destination. Naming fewer units than are on the road records a short delivery and leaves the rest in transit, rather than quietly losing them.
POST /transfers/{transferId}/receive Inventory Manager
{
"reference": "van-WIDGET-BLUE-in"
}What the answer holds: the operation's example.
Records inventory.transfer-received.
8 The flag does its work
Forty units on hand, and only thirty available: the ten in quarantine are physically present and cannot be promised to anybody. byLocation shows exactly where each figure comes from — and this is the number that would be wrong if availability were a simple sum.
GET /items/WIDGET-BLUE/stock Inventory Manager
What the answer holds: the operation's example.
9 Read the transfer back
Per line: what was asked for, what left, and what arrived. The gap between the last two is what is still on the road.
GET /transfers/{transferId} Inventory Manager
What the answer holds: the operation's example.
10 See how this organization may move stock
An organization that has set nothing gets the conservative shape: two-step, the only mode that never claims stock arrived before it did. That is what the transfer above used.
GET /settings Inventory Manager
What the answer holds: the operation's example.
11 Allow instant moves as well
unrestricted lets the caller pick per transfer. instant would force it, two-step would forbid it, and off would refuse transfers entirely — for merchants whose stock only ever moves in and out, never sideways.
PUT /settings Inventory Manager
{
"transfers": "unrestricted"
}What the answer holds: the operation's example.
Records inventory.settings-configured.
12 Move stock with no van involved
Between two bays of the same building there is no moment at which the stock is anywhere else, so instant moves it in a single commit and the transfer comes back already received. The journal records one fact — inventory.transfer-completed — rather than a despatch and a receipt describing a transit that never happened.
POST /transfers Inventory Manager
{
"fromLocationId": "{mainLocationId}",
"toLocationId": "{locationId}",
"mode": "instant",
"reference": "QA-2292",
"lines": [
{
"sku": "WIDGET-BLUE",
"quantity": 5
}
]
}Answers 201. What the answer holds: the operation's example.
Records inventory.transfer-completed.
13 Rename the bay, and let it sell
Locations are editable. Switching one back to fulfillable puts its stock on sale without moving a unit — and the last fulfillable location cannot be switched off, so an organization always has somewhere to ship from.
PATCH /locations/{locationId} Inventory Manager
{
"name": "Bay 2",
"fulfillable": true
}What the answer holds: the operation's example.
Records inventory.location-updated.
14 Take an order — routed to one site
Allocation picks the shelf, and the parcel it opens carries the locationId it will ship from. Two sites now hold this SKU, and routing chose between them: what a line is held against is a decision, recorded on the allocation fact.
POST /orders Fulfillment Manager
{
"reference": "WEB-10288",
"lines": [
{
"sku": "WIDGET-BLUE",
"quantity": 2,
"unitPriceCents": 2400
}
],
"customer": {
"personId": "psn_01a15890-1b2c-7d3e-8f4a-5b6c7d8e9f0a"
}
}Answers 201. What the answer holds: the operation's example.
From your answer, later steps send id as {orderId} and lines[0].id as {lineId}.
Records fulfillment.order-created, fulfillment.stock-allocated, fulfillment.shipment-created.
15 Move the hold to the other site
Allocation is final until a person changes it — nothing re-routes a held line on its own. This is that person: the units are released where they were and taken where they are going in one transaction, the pending parcel moves with them (joining a parcel already open there, or opening a fresh one), and reference makes it a move that cannot happen twice. A parcel already picked is refused — by then the stock is on a bench, and moving it is a physical act.
POST /orders/{orderId}/lines/{lineId}/allocation Fulfillment Manager
{
"toLocationId": "{locationId}",
"reference": "move-WIDGET-BLUE",
"reason": "Bay 2 is closer to the courier"
}What the answer holds: the operation's example.
Records fulfillment.allocation-moved.
16 Look at it on its own
One location, with whether it can sell and when it was opened.
GET /locations/{locationId} Inventory Manager
What the answer holds: the operation's example.
17 Try to close it while it still holds stock
Refused. Archiving a site holding units would strand them where nothing can reach them, so the error names the SKUs still there — transfer them out first, which is what transfers are for.
POST /locations/{locationId}/archive Inventory Manager
{
"_tag": "LocationNotEmpty",
"locationId": "{locationId}",
"skus": [
"WIDGET-BLUE"
]
}Records nothing.
What a recorded fact is: Facts and the journal. Why a repeated step changes nothing: Idempotency and retries.