Skip to content

Endpoint reference

The tables below are a quick scan of the routes and filters. For full request/response schemas, the interactive explorer is the richer view.

The full machine-readable contract is served publicly (no auth, no shop data) at:

GET https://assemblified.com/api/v1/openapi.json

Point Postman, Insomnia, or any OpenAPI 3.1 client at that URL to generate a typed client or browse every parameter and response shape.

MethodPathScopeWhat it does
GET/api/v1/raw-materialsreadList raw materials (filters: search, usageFilter, originFilter, vendorFilter (repeatable), sortBy, sortOrder, page, pageSize)
GET/api/v1/raw-materials/{variantId}readOne material; ?includeConnections=true adds the BOMs + sub-assemblies that use it
PATCH/api/v1/raw-materials/{variantId}writeEdit fields — virtual (VMAT-*) materials only
GET/api/v1/raw-materials/{variantId}/inventoryreadReal per-location stock (?locationIds= repeatable) — live from Shopify for Shopify-linked materials
PATCH/api/v1/raw-materials/{variantId}/inventorywriteSet per-location stock — virtual (VMAT-*) materials only
GET/api/v1/bills-of-materialsreadList bills of materials (filters: search, statusFilter, sortBy, sortOrder, page, pageSize)
GET/api/v1/bills-of-materials/{id}readOne BOM with its fully hydrated recipe — raw materials, recursive sub-assemblies, cost factors
GET/api/v1/bills-of-materials/{id}/buildablereadThe computed per-location max-buildable (?locationIds= repeatable)
GET/api/v1/openapi.jsonpublicThe machine-readable spec — no auth required

sortBy on the list accepts productName (default), variantName, or inventoryQuantity; an unrecognized value is ignored and the default productName ordering is used.

Shopify-managed materials are read-only in v1

Section titled “Shopify-managed materials are read-only in v1”

Every GET works for both origins — Shopify-linked and virtual. The two PATCH endpoints accept only virtual materials (ids starting VMAT-). A PATCH against a numeric Shopify variant id returns 400 INVALID_INPUT with a “read-only in API v1” message, before anything is changed. This is deliberate: fields like name, sku, price, and cost on Shopify-linked materials are mirrored from Shopify, so a local API edit would be silently reverted by the next product update. Editing those belongs in the Shopify admin (or a future API version with true write-back).

Terminal window
curl -s -H "Authorization: Bearer $ASMK_TOKEN" \
"https://assemblified.com/api/v1/raw-materials?originFilter=virtual&usageFilter=unused&pageSize=25"
{
"data": {
"items": [
{
"variantId": "VMAT-VAR-7f3d2c1a-9b4e-4c8d-a2f6-5e1b0d9c8a7f",
"productId": "VMAT-PROD-2a9c8b7d-6e5f-4a3b-8c1d-0e9f8a7b6c5d",
"inventoryItemId": "VMAT-INV-5c4d3e2f-1a0b-4c9d-8e7f-6a5b4c3d2e1f",
"productName": "Oak board 20 mm",
"variantName": "120 x 60 cm",
"sku": "OAK-20-120",
"vendor": "Holzwerk GmbH",
"unit": "pcs",
"unitCost": 12.5,
"unitPrice": 0,
"inventoryQuantity": 240,
"isVirtual": true,
"bomUsageCount": 0,
"subAssemblyUsageCount": 0
/* … specifications, imageUrl, isNonEssentialMaterial, weightValue,
weightUnitId, productType, productCategory … */
}
],
"totalCount": 7, "page": 1, "pageSize": 25, "totalPages": 1,
"availableVendors": ["Holzwerk GmbH", "Acme Supplies"]
},
"meta": { "requestId": "", "apiVersion": "1.1" }
}
Terminal window
curl -s -H "Authorization: Bearer $ASMK_TOKEN" \
"https://assemblified.com/api/v1/raw-materials/VMAT-VAR-7f3d2c1a-9b4e-4c8d-a2f6-5e1b0d9c8a7f?includeConnections=true"

Returns data.material (same fields as a list row, minus the usage counts) plus data.connections with boms and subAssemblies arrays — each entry names the BOM / sub-assembly, the quantity of this material it uses, and its location. Works for Shopify-linked materials too (numeric id in the path).

Terminal window
curl -s -X PATCH \
-H "Authorization: Bearer $ASMK_TOKEN" -H "Content-Type: application/json" \
-d '{ "unitCost": 13.1, "vendor": "Holzwerk GmbH" }' \
"https://assemblified.com/api/v1/raw-materials/VMAT-VAR-7f3d2c1a-9b4e-4c8d-a2f6-5e1b0d9c8a7f"

Returns data.material — the full updated row. Only the fields you send change; the editable field list is in Conventions.

Terminal window
curl -s -H "Authorization: Bearer $ASMK_TOKEN" \
"https://assemblified.com/api/v1/raw-materials/VMAT-VAR-7f3d2c1a-9b4e-4c8d-a2f6-5e1b0d9c8a7f/inventory"
{
"data": {
"variantId": "VMAT-VAR-7f3d2c1a-9b4e-4c8d-a2f6-5e1b0d9c8a7f",
"origin": "virtual",
"totalAvailable": 240,
"cachedQuantity": 240,
"levels": [
{ "locationId": "74001236152", "available": 190 },
{ "locationId": "74001268920", "available": 50 }
]
},
"meta": { "requestId": "", "apiVersion": "1.1" }
}

For a Shopify-linked material (numeric id), origin is "shopify", the levels are a live Shopify read, and each level row additionally carries a locationName. Virtual materials return locationId + available only — no locationName.

Terminal window
curl -s -X PATCH \
-H "Authorization: Bearer $ASMK_TOKEN" -H "Content-Type: application/json" \
-d '{ "updates": [ { "locationId": "74001236152", "absolute": 200 } ] }' \
"https://assemblified.com/api/v1/raw-materials/VMAT-VAR-7f3d2c1a-9b4e-4c8d-a2f6-5e1b0d9c8a7f/inventory"

Returns the per-row batch envelope (results / okCount / failedCount / skippedCount). Each row carries exactly one of absolute (retry-safe — prefer it) or delta; full body semantics in Conventions. Every adjustment is recorded in the material’s adjustment history.

The three bills-of-materials endpoints expose your BOMsBill of MaterialsA bill of materials tells Assemblified how to build one unit of a finished good. When a customer orders the finished-good variant, Assemblified deducts the right component quantities from inventory automatically. Read more → — finished goods and their recipes. They are read-only in this version.

Terminal window
curl -s -H "Authorization: Bearer $ASMK_TOKEN" \
"https://assemblified.com/api/v1/bills-of-materials?statusFilter=active&pageSize=25"

Returns data.items (the projected BOM rows) plus the pagination fields and a stats block (total, active, inactive, totalValue, avgCost, shopifyLinked) aggregated over the full BOM set.

Terminal window
curl -s -H "Authorization: Bearer $ASMK_TOKEN" \
"https://assemblified.com/api/v1/bills-of-materials/BOM-1748441466223"
{
"data": {
"bomId": "BOM-1748441466223",
"status": "active",
"name": "Oak Table",
"productId": "8613244518724", "variantId": "45217109934404",
"sku": "TABLE-OAK", "price": 499,
"totalRawMaterialCost": 96.5, "totalSubAssemblyCost": 41.0, "totalCost": 137.5,
"directCostFactorCost": 26.7,
"preAssembledQuantity": 3,
"rawMaterialReferences": [
{ "nodeId": "VMAT-VAR-…", "quantity": 4, "wastePercentage": 5,
"node": { "productName": "Oak board 20 mm", "unit": "pcs", "unitCost": 12.5 } }
],
"subAssemblyReferences": [
{ "nodeId": "ASM-…", "quantity": 2,
"node": { "assemblyName": "Table leg", "unitCost": 20.5,
"rawMaterialReferences": [], "subAssemblyReferences": [] } }
],
"costFactorReferences": [
{ "costFactorId": "CF-…", "quantity": 0.5,
"node": { "name": "Assembly labour", "kind": "labour", "unit": "hour", "unitCost": 40 } }
]
},
"meta": { "requestId": "", "apiVersion": "1.1" }
}

Sub-assemblies nest recursively — each subAssemblyReferences[].node carries its own rawMaterialReferences and subAssemblyReferences, so one call returns the complete tree.

Terminal window
curl -s -H "Authorization: Bearer $ASMK_TOKEN" \
"https://assemblified.com/api/v1/bills-of-materials/BOM-1748441466223/buildable"
{
"data": {
"bomId": "BOM-1748441466223",
"variantId": "45217109934404",
"hasSellableSplit": false,
"perLocation": [
{ "locationId": "74001236152", "locationName": "Main warehouse",
"maxBuildable": 24, "sellable": 24,
"limitingComponents": [
{ "nodeId": "VMAT-VAR-…", "name": "Oak board 20 mm — 120 x 60 cm",
"origin": "virtual", "quantityPerUnit": 4, "wastePercentage": 5,
"isNonEssential": false, "maxUnitsByThisComponent": 24, "availableAtLocation": 96 }
] }
],
"totals": { "maxBuildable": 24, "sellable": 24 },
"globalFallback": false
},
"meta": { "requestId": "", "apiVersion": "1.1" }
}

This is the same number the admin UI’s Max Buildable column shows: the full component tree against live Shopify raw-material levels, virtual levels, and nested pre-assembled sub-assembly stock — waste included, non-essential components excluded. Notes:

  • sellable respects sub-assemblies flagged only consume pre-assembled; it differs from maxBuildable only when hasSellableSplit is true.
  • limitingComponents is a top-level, indicative view of what constrains the build — the maxBuildable number is the authoritative full-tree result.
  • When the BOM’s variant has no per-location Shopify data, totals falls back to a single global computation and globalFallback is true.
  • This is the most expensive read on the surface (it reads live Shopify levels) — cache the result rather than polling it.