Skip to content

Conventions

Every 200 wraps the result in data, with a small meta block:

{
"data": { /* the resource(s) */ },
"meta": { "requestId": "0f8c…", "apiVersion": "1.0" }
}
  • meta.requestId — also returned as the X-Request-Id response header. Quote it in support requests.
  • meta.apiVersion — the REST API version (1.0).

The list endpoint uses page-number pagination (not cursors):

  • page — 1-based page number (default 1).
  • pageSize — rows per page (up to 1000).

and returns them inside data alongside the totals:

{
"data": {
"items": [ /* … */ ],
"totalCount": 128,
"page": 2,
"pageSize": 50,
"totalPages": 3,
"availableVendors": ["Holzwerk GmbH", "Acme Supplies"]
},
"meta": { "requestId": "", "apiVersion": "1.0" }
}
Terminal window
# page 1
curl -s -H "Authorization: Bearer $ASMK_TOKEN" \
"https://assemblified.com/api/v1/raw-materials?pageSize=50"
# page 2
curl -s -H "Authorization: Bearer $ASMK_TOKEN" \
"https://assemblified.com/api/v1/raw-materials?pageSize=50&page=2"

The list endpoint accepts query filters — search, usageFilter, originFilter, sortBy, sortOrder — see the reference for values.

Two parameters are repeatable — pass them once per value:

  • vendorFilter on the list: ?vendorFilter=Holzwerk%20GmbH&vendorFilter=Acme%20Supplies
  • locationIds on the inventory read: ?locationIds=74001236152&locationIds=74001268920

{variantId} in a path is either a numeric Shopify variant id (e.g. 45067340286136) or a virtual-material id (VMAT-VAR-…). Full gid://shopify/… ids are not supported in paths.

GET and PATCH are the only supported methods. Any other method returns 405 with an Allow header listing the methods valid for that path (e.g. Allow: GET, PATCH).

Both PATCH endpoints accept virtual (VMAT-*) materials only — a Shopify-managed id returns 400 INVALID_INPUT before anything is dispatched. Send a JSON object body with Content-Type: application/json.

Field updates — PATCH /raw-materials/{variantId}

Section titled “Field updates — PATCH /raw-materials/{variantId}”

The body is a flat partial object of the editable fields: productName, variantName, sku, unit, unitCost, unitPrice, inventoryQuantity, vendor, specifications, imageUrl, isNonEssentialMaterial, weightValue, weightUnitId. Unrecognized fields are ignored (deny-by-default allowlist); only the fields you send are changed.

Inventory updates — PATCH /raw-materials/{variantId}/inventory

Section titled “Inventory updates — PATCH /raw-materials/{variantId}/inventory”

The body is a batch of per-location rows:

{
"updates": [
{ "locationId": "74001236152", "absolute": 120 },
{ "locationId": "74001268920", "delta": -5 }
]
}
  • Each row carries exactly one of delta (relative adjustment) or absolute (target level) — both or neither is 400 INVALID_INPUT.
  • absolute is converted to a delta server-side inside the transaction, making it the retry-safe form — prefer it for stock-takes.
  • Negative deltas respect the shop’s allow negative inventory setting: by default, levels clamp at zero server-side — a past-zero delta still returns ok: true with the applied change truncated (re-read the levels to confirm). absolute must be >= 0 either way.
  • A row may optionally repeat variantId, but it must equal the path id; a mismatch is 400 INVALID_INPUT.

The response is a per-row batch envelope — check each row’s ok, don’t assume all-or-nothing:

{
"data": {
"results": [
{ "index": 0, "ok": true, "id": "VMAT-VAR-7f3d2c1a-9b4e-4c8d-a2f6-5e1b0d9c8a7f" },
{ "index": 1, "ok": false, "error": { "code": "INVALID_INPUT", "message": "" } }
],
"okCount": 1,
"failedCount": 1,
"skippedCount": 0
},
"meta": { "requestId": "", "apiVersion": "1.0" }
}

When every row fails with the same error (for example, the material doesn’t exist), the API collapses the batch into a single request-level error instead — e.g. one 404 NOT_FOUND — so common failures surface with a proper status code.