Create a goods receipt
Add arriving goods to a warehouse, with or without a purchase order.
Overview
A goods receipt records goods arriving at a warehouse. They go on hand at once, or wait for a quality check if your company uses one.
Request
Enabled on request Goods receipts need Purchasing, part of Warehouse Management. Your O2M account manager can enable it.
POST/goods-receipts
Needs the permission inbound:receive
curl -X POST "https://api.o2m.in/api/v1/goods-receipts" \
-H "X-Access-Key: $O2M_ACCESS_KEY" \
-H "X-Secret-Key: $O2M_SECRET_KEY" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: receipt-INV-88" \
-d '{
"warehouse_code": "BLR",
"invoice_no": "INV-88",
"note": "From the factory",
"lines": [
{
"sku": "MUG-BLUE",
"qty": 100,
"lot_no": "L-2026-10",
"expiry_date": "2027-10-01"
}
]
}'Important Always send an Idempotency-Key. Without one, a retry receives the goods a second time.
Good to know The key of a 3PL client cannot create goods receipts.
Body
| Parameter | Type | Required | Description |
|---|---|---|---|
warehouse_code | string | No | The warehouse's code. Without a warehouse, the Default warehouse is used. |
warehouse_id | string | No | The warehouse's ID, instead of its code. |
po_id | string | No | O2M's ID of an open purchase order to receive against. The order's warehouse and supplier are then used. |
supplier_id | string | No | O2M's ID of the supplier, when there is no purchase order. |
invoice_no | string | No | The supplier's invoice number, up to 60 characters. |
invoice_date | date | No | The invoice date, as YYYY-MM-DD. |
note | string | No | Up to 1,000 characters. |
qc | boolean | No | Whether the goods wait for a quality check. The default is your company's setting. |
hold | boolean | No | Keep accepted units back from sale until they are released. The default is false. |
receive | boolean | No | true (the default) receives the goods at once. false saves a draft to finish in O2M. |
lines | array | Yes | From 1 to 1,000 lines. A SKU may be on several lines, one per lot. |
Each line
| Parameter | Type | Required | Description |
|---|---|---|---|
sku | string | Yes | The item's SKU or the barcode on the unit. |
qty | number | Yes | A whole number from 1 to 10,000,000. |
lot_no | string | For items tracked by lot | Up to 60 characters. A new lot number creates the lot. |
mfg_date | date | No | The manufacturing date, as YYYY-MM-DD. |
expiry_date | date | No | The expiry date, as YYYY-MM-DD. |
serials | array | No | Serial numbers, one per unit, or leave it out. |
note | string | No | Up to 500 characters. |
Good to know Purchase prices cannot be entered through the API. Receive against a purchase order, or add costs in O2M.
Response
201 with the receipt.
{
"id": "91",
"number": "GRN-2627-00091",
"status": "completed",
"warehouse": "BLR",
"lines": [
{
"sku": "MUG-BLUE",
"qty": 100,
"lot_no": "L-2026-10"
}
]
}| Field | Type | Description |
|---|---|---|
id, number | string | O2M's ID and the document number. |
status | string | completed: the units are on hand. qc_pending: they wait on QC hold for a quality check. draft: nothing received yet. |
warehouse | string | The warehouse's code. |
lines | array | The lines, with sku, qty and lot_no. |
If a line is refused, the whole receipt is refused and no stock changes.
Errors
| Status | Code | Message | What to do |
|---|---|---|---|
| 403 | CLIENT_KEY | A client's key cannot change stock: this is done by the warehouse | Use a key of your own company. |
| 403 | MODULE_NOT_ENABLED | Purchasing is not enabled for your company by the platform administrator | Ask your O2M account manager to enable it. |
| 403 | — | You are not assigned to Bengaluru. Ask a warehouse manager to add you. | The key is limited to other warehouses. |
| 403 | — | Line 1: you cannot enter costs (it needs the permission to see purchase prices) | Leave out unit_cost. |
| 404 | — | No warehouse has the code XXX | Check warehouse_code. |
| 404 | — | Warehouse not found | Check warehouse_id. |
| 404 | — | Purchase order not found | Check po_id. |
| 404 | — | Supplier not found | Check supplier_id. |
| 404 | — | Line 1: no product or variant has SKU or barcode GHOST | Check the SKU in O2M. |
| 409 | LOT_REQUIRED | Line 1: MUG-BLUE is tracked by lot. Enter the lot number printed on the goods. | Add lot_no. |
| 409 | LOT_DATES | Line 1: lot L-2026-10 is already recorded with expiry date 2027-10-01 | Use the lot's recorded dates, or leave them out. |
| 409 | SERIAL_EXISTS | Line 1: serial SN-1 is already on record | Correct the serial numbers. |
| 409 | NOT_ON_ORDER | MUG-BLUE is not on PO-2627-00012: receive it without an order | Leave it out, or receive it separately. |
| 409 | OVER_RECEIPT | MUG-BLUE: PO-2627-00012 orders 100, so at most 110 can be received on it (10% over is allowed). Receive the extra units without an order. | Lower the quantity, or receive the extra units without po_id. |
| 409 | — | Send PO-2627-00012 before receiving on it | Send the purchase order in O2M first. |
| 409 | — | PO-2627-00012 is finished: receive these units without an order | Leave out po_id. |
| 409 | — | Bengaluru does not take stock changes | The warehouse is inactive, or is run by a channel. |
| 422 | — | Add at least one line (SKU and units) | Send lines. |
| 422 | — | A receipt has at most 1000 lines | Split the receipt. |
| 422 | — | Line 1: SKU is required | Add the sku. |
| 422 | — | Line 1: units must be a whole number, 1 or more | Correct qty. |
| 422 | — | Line 1: the lot number is too long (at most 60 characters) | Shorten lot_no. |
| 422 | — | Line 1: the expiry date must be a date (YYYY-MM-DD) | Correct the date. The same applies to mfg_date and invoice_date. |
| 422 | — | Line 1: the expiry date is before the manufacturing date | Correct the dates. |
| 422 | — | Line 1: 1 serial number(s) for 2 unit(s). List one per unit, or none. | Send one serial per unit. |
| 422 | — | The supplier's invoice number is too long (at most 60 characters) | Shorten invoice_no. |
Every endpoint can also return the common errors: a missing or invalid key, a missing permission, the rate limit, or a temporary failure.