StockroomAPIOpen the app
Reference

Receipts

One record per delivery against a purchase order: what came in, to where, on what date, at what cost. Recording a receipt moves stock, so it requires an Idempotency-Key; voiding one reverses the movement instead of editing a number back down.

#

List an order's receipts

GETapi.stockroom.app/v2/purchase_orders/{id}/receipts

Every receipt, voided ones included (voided_at set).

Path
idintegerpathrequired
Responses
200
Receipts, oldest first.
a page of Receipt in data, with next_cursor and has_more
Request
curl "https://api.stockroom.app/v2/purchase_orders/1042/receipts" \
  -H "Authorization: Bearer $STOCKROOM_KEY"
Response 200
{
  "data": [
    {
      "id": 1,
      "purchase_order_id": 1042,
      "received_at": null,
      "voided_at": null,
      "source": "api",
      "location": {
        "id": 61234567890,
        "name": "Main warehouse"
      },
      "invoice": {
        "reference": "INV-8812",
        "date": "2026-09-02",
        "total": "324.75"
      },
      "exchange_rate": 1.36,
      "rejected_disposition": "replace",
      "note": "Two cartons short; supplier notified.",
      "lines": [
        {
          "id": 5001,
          "line_id": 5001,
          "quantity": 24,
          "surplus_quantity": 0,
          "rejected_quantity": 0,
          "unit_cost": "12.50",
          "landed_unit_cost": "13.10",
          "allocated_charge_amount": "0.60"
        }
      ],
      "shopify_sync": {
        "state": "synced",
        "attempted_at": "2026-09-11T08:12:46Z",
        "error": null
      },
      "created_at": "2026-09-01T10:00:00Z",
      "updated_at": "2026-09-11T08:12:44Z"
    }
  ]
}
#

Record a receipt

POSTapi.stockroom.app/v2/purchase_orders/{id}/receipts

Books a delivery against the order: quantities per line, rejected units and their disposition, per-line cost corrections, bins and lots, plus unordered items that arrived. Stock is written to Shopify from a queue; the receipt's shopify_sync says when it landed. Over-delivery follows the store's setting. Requires an Idempotency-Key header.

Path
idintegerpathrequired
Headers
Idempotency-Keystringheaderrequired
Unique per request, up to 255 characters. The same key with the same body replays the stored response; with a different body it is 409 idempotency_key_reused.
BodyJSON
location_idintegerrequired
Shopify location the goods arrived at.
received_atstring (date) or null
notestring or null
invoice_referencestring or null
invoice_totalnumber or string or null
invoice_datestring (date) or null
exchange_ratenumber or null
Store currency per 1 unit of the order currency, if it differs from the order's.
route_to_destinationsboolean or null
Receive each line at its own location_id instead of one location.
rejected_dispositionstring or null
What happens to rejected units - keep them outstanding for a replacement, or remove them from the order.
replaceremove
linesarray of objectrequired
Every line to receive against. Zero quantity is allowed (nothing arrived on that line).
line_idintegerrequired
quantitynumberrequired
rejectedinteger or null
unit_costnumber or string or null
A receive-time cost correction.
bin_locationstring or null
lot_numberstring or null
lot_expirystring (date) or null
lot_manufacturedstring (date) or null
lot_idinteger or null
unorderedarray of object
Items that arrived without a line. Added to the order and received in one step.
variant_idinteger or null
inventory_item_idinteger or null
product_titlestring or null
variant_titlestring or null
skustring or null
barcodestring or null
quantitynumberrequired
unit_costnumber or string or null
Responses
201
The order after the receipt, with the receipt embedded in receipts.
PurchaseOrder in data
409
idempotency_key_reused.
Request
curl -X POST "https://api.stockroom.app/v2/purchase_orders/1042/receipts" \
  -H "Authorization: Bearer $STOCKROOM_KEY" \
  -H "Idempotency-Key: $(uuidgen)" \
  -H "Content-Type: application/json" \
  -d '{
  "location_id": 61234567890,
  "received_at": "2026-09-11",
  "note": "Two cartons short; supplier notified.",
  "invoice_reference": "INV-8812",
  "invoice_total": 324.75,
  "invoice_date": "2026-09-11",
  "exchange_rate": 1.36,
  "route_to_destinations": false,
  "rejected_disposition": "replace",
  "lines": [
    {
      "line_id": 5001,
      "quantity": 24,
      "rejected": null,
      "unit_cost": 12.5,
      "bin_location": "A-12",
      "lot_number": null,
      "lot_expiry": "2026-09-11",
      "lot_manufactured": "2026-09-11",
      "lot_id": null
    }
  ],
  "unordered": []
}'
Body
{
  "location_id": 61234567890,
  "received_at": "2026-09-11",
  "note": "Two cartons short; supplier notified.",
  "invoice_reference": "INV-8812",
  "invoice_total": 324.75,
  "invoice_date": "2026-09-11",
  "exchange_rate": 1.36,
  "route_to_destinations": false,
  "rejected_disposition": "replace",
  "lines": [
    {
      "line_id": 5001,
      "quantity": 24,
      "rejected": null,
      "unit_cost": 12.5,
      "bin_location": "A-12",
      "lot_number": null,
      "lot_expiry": "2026-09-11",
      "lot_manufactured": "2026-09-11",
      "lot_id": null
    }
  ],
  "unordered": []
}
Response 201
{
  "data": {
    "receipts": [
      {
        "id": 311,
        "purchase_order_id": 1042,
        "received_at": null,
        "voided_at": null,
        "source": "api",
        "location": {
          "id": 61234567890,
          "name": "Main warehouse"
        },
        "invoice": {
          "reference": "INV-8812",
          "date": "2026-09-02",
          "total": "324.75"
        },
        "exchange_rate": 1.36,
        "rejected_disposition": "replace",
        "note": "Two cartons short; supplier notified.",
        "lines": [
          {
            "id": 5001,
            "line_id": 5001,
            "quantity": 24,
            "surplus_quantity": 0,
            "rejected_quantity": 0,
            "unit_cost": "12.50",
            "landed_unit_cost": "13.10",
            "allocated_charge_amount": "0.60"
          }
        ],
        "shopify_sync": {
          "state": "synced",
          "attempted_at": "2026-09-11T08:12:46Z",
          "error": null
        },
        "created_at": "2026-09-01T10:00:00Z",
        "updated_at": "2026-09-11T08:12:44Z"
      }
    ],
    "payments": [
      {
        "id": 52,
        "amount": "324.75",
        "currency": "USD",
        "paid_on": "2026-09-30",
        "method": "bank_transfer",
        "reference": "Wire 4471",
        "note": "Paid by wire.",
        "created_at": "2026-09-01T10:00:00Z"
      }
    ],
    "id": 1,
    "number": "PO-1042",
    "sequential_id": 1042,
    "status": "ordered",
    "type": "purchase",
    "archived": false,
    "archived_at": null,
    "source": "api",
    "supplier": {
      "id": 7,
      "name": "Acme Supply Co"
    },
    "supplier_id": 7,
    "currency": "USD",
    "exchange_rate": {
      "rate": 1.36,
      "base_currency": "USD",
      "date": "2026-09-02",
      "source": "api"
    },
    "reference": "INV-8812",
    "customer_order_number": null,
    "supplier_order_number": "SO-77120",
    "invoice_number": null,
    "account_number": "AC-2231",
    "notes": null,
    "expected_at": "2026-09-20",
    "payment_due_on": "2026-10-02",
    "payment_status": "unpaid",
    "paid_at": null,
    "location": {
      "id": 61234567890,
      "name": "Main warehouse"
    },
    "updates_stock": true,
    "ships_to_customer": false,
    "ship_to_address": null,
    "tax": {
      "rate_id": 1,
      "name": "Acme Supply Co",
      "rate_percent": 8.25,
      "taxes_included": false,
      "charges_taxable": true
    },
    "totals": {
      "currency": "USD",
      "subtotal": "300.00",
      "charges": "0.00",
      "tax": "24.75",
      "total": "324.75"
    },
    "lines": [
      {
        "id": 5001,
        "position": 1,
        "product_title": "Stoneware mug",
        "variant_title": "Blue",
        "sku": "MUG-BLU",
        "supplier_sku": "ACME-MUG-BLU",
        "barcode": "0123456789012",
        "pack_code": "CS12",
        "inventory_item_id": 44811223344,
        "variant_id": 40011223344,
        "product_id": 7011223344,
        "location_id": 61234567890,
        "quantity": 24,
        "cancelled_quantity": 0,
        "received_quantity": 12,
        "outstanding_quantity": 12,
        "unit_cost": "12.50",
        "discount_percent": null,
        "line_total": "300.00",
        "taxable": true,
        "tax_rate_percent": 8.25,
        "weight_grams": 250,
        "supplier_note": null,
        "internal_note": null
      }
    ],
    "charges": [],
    "shopify_sync": {
      "state": "synced",
      "attempted_at": "2026-09-11T08:12:46Z",
      "error": null
    },
    "sent_at": "2026-09-02T14:03:22Z",
    "ordered_at": "2026-09-02T14:05:10Z",
    "in_transit_at": null,
    "received_at": null,
    "closed_at": null,
    "created_at": "2026-09-01T10:00:00Z",
    "updated_at": "2026-09-11T08:12:44Z"
  }
}
#

Get a receipt

GETapi.stockroom.app/v2/purchase_orders/{id}/receipts/{receipt_id}
Path
idintegerpathrequired
receipt_idintegerpathrequired
Responses
200
The receipt.
Receipt in data
Request
curl "https://api.stockroom.app/v2/purchase_orders/1042/receipts/311" \
  -H "Authorization: Bearer $STOCKROOM_KEY"
Response 200
{
  "data": {
    "id": 1,
    "purchase_order_id": 1042,
    "received_at": null,
    "voided_at": null,
    "source": "api",
    "location": {
      "id": 61234567890,
      "name": "Main warehouse"
    },
    "invoice": {
      "reference": "INV-8812",
      "date": "2026-09-02",
      "total": "324.75"
    },
    "exchange_rate": 1.36,
    "rejected_disposition": "replace",
    "note": "Two cartons short; supplier notified.",
    "lines": [
      {
        "id": 5001,
        "line_id": 5001,
        "quantity": 24,
        "surplus_quantity": 0,
        "rejected_quantity": 0,
        "unit_cost": "12.50",
        "landed_unit_cost": "13.10",
        "allocated_charge_amount": "0.60"
      }
    ],
    "shopify_sync": {
      "state": "synced",
      "attempted_at": "2026-09-11T08:12:46Z",
      "error": null
    },
    "created_at": "2026-09-01T10:00:00Z",
    "updated_at": "2026-09-11T08:12:44Z"
  }
}
#

Void a receipt

POSTapi.stockroom.app/v2/purchase_orders/{id}/receipts/{receipt_id}/void

Reverses the receipt - quantities return to outstanding and the stock movement is reversed in Shopify. The receipt stays in the list with voided_at set.

Path
idintegerpathrequired
receipt_idintegerpathrequired
Responses
200
The order after the void.
PurchaseOrder in data
Request
curl -X POST "https://api.stockroom.app/v2/purchase_orders/1042/receipts/311/void" \
  -H "Authorization: Bearer $STOCKROOM_KEY"
Response 200
{
  "data": {
    "receipts": [
      {
        "id": 311,
        "purchase_order_id": 1042,
        "received_at": null,
        "voided_at": null,
        "source": "api",
        "location": {
          "id": 61234567890,
          "name": "Main warehouse"
        },
        "invoice": {
          "reference": "INV-8812",
          "date": "2026-09-02",
          "total": "324.75"
        },
        "exchange_rate": 1.36,
        "rejected_disposition": "replace",
        "note": "Two cartons short; supplier notified.",
        "lines": [
          {
            "id": 5001,
            "line_id": 5001,
            "quantity": 24,
            "surplus_quantity": 0,
            "rejected_quantity": 0,
            "unit_cost": "12.50",
            "landed_unit_cost": "13.10",
            "allocated_charge_amount": "0.60"
          }
        ],
        "shopify_sync": {
          "state": "synced",
          "attempted_at": "2026-09-11T08:12:46Z",
          "error": null
        },
        "created_at": "2026-09-01T10:00:00Z",
        "updated_at": "2026-09-11T08:12:44Z"
      }
    ],
    "payments": [
      {
        "id": 52,
        "amount": "324.75",
        "currency": "USD",
        "paid_on": "2026-09-30",
        "method": "bank_transfer",
        "reference": "Wire 4471",
        "note": "Paid by wire.",
        "created_at": "2026-09-01T10:00:00Z"
      }
    ],
    "id": 1,
    "number": "PO-1042",
    "sequential_id": 1042,
    "status": "ordered",
    "type": "purchase",
    "archived": false,
    "archived_at": null,
    "source": "api",
    "supplier": {
      "id": 7,
      "name": "Acme Supply Co"
    },
    "supplier_id": 7,
    "currency": "USD",
    "exchange_rate": {
      "rate": 1.36,
      "base_currency": "USD",
      "date": "2026-09-02",
      "source": "api"
    },
    "reference": "INV-8812",
    "customer_order_number": null,
    "supplier_order_number": "SO-77120",
    "invoice_number": null,
    "account_number": "AC-2231",
    "notes": null,
    "expected_at": "2026-09-20",
    "payment_due_on": "2026-10-02",
    "payment_status": "unpaid",
    "paid_at": null,
    "location": {
      "id": 61234567890,
      "name": "Main warehouse"
    },
    "updates_stock": true,
    "ships_to_customer": false,
    "ship_to_address": null,
    "tax": {
      "rate_id": 1,
      "name": "Acme Supply Co",
      "rate_percent": 8.25,
      "taxes_included": false,
      "charges_taxable": true
    },
    "totals": {
      "currency": "USD",
      "subtotal": "300.00",
      "charges": "0.00",
      "tax": "24.75",
      "total": "324.75"
    },
    "lines": [
      {
        "id": 5001,
        "position": 1,
        "product_title": "Stoneware mug",
        "variant_title": "Blue",
        "sku": "MUG-BLU",
        "supplier_sku": "ACME-MUG-BLU",
        "barcode": "0123456789012",
        "pack_code": "CS12",
        "inventory_item_id": 44811223344,
        "variant_id": 40011223344,
        "product_id": 7011223344,
        "location_id": 61234567890,
        "quantity": 24,
        "cancelled_quantity": 0,
        "received_quantity": 12,
        "outstanding_quantity": 12,
        "unit_cost": "12.50",
        "discount_percent": null,
        "line_total": "300.00",
        "taxable": true,
        "tax_rate_percent": 8.25,
        "weight_grams": 250,
        "supplier_note": null,
        "internal_note": null
      }
    ],
    "charges": [],
    "shopify_sync": {
      "state": "synced",
      "attempted_at": "2026-09-11T08:12:46Z",
      "error": null
    },
    "sent_at": "2026-09-02T14:03:22Z",
    "ordered_at": "2026-09-02T14:05:10Z",
    "in_transit_at": null,
    "received_at": null,
    "closed_at": null,
    "created_at": "2026-09-01T10:00:00Z",
    "updated_at": "2026-09-11T08:12:44Z"
  }
}