Measura API documentation · v1

Kit assemblies

Consume components, produce kits, and reverse production using saved recipe snapshots.

Production requirements

Requires a public API key with Public API access and an active Kit Builder add-on with an available tier. Each request operates at one active Shopify location and accepts 1–50 unique kits, changing at most 100 distinct variants after component/output deltas are merged. The server calculates inventory deltas from saved recipes and their measurement configuration.

Inventory validation:

Tracked variants must be stocked at the requested location. Measura checks exact integer plus fractional inventory under its inventory coordination mechanism. Untracked variants do not constrain capacity or receive stock writes. Current availability can be read through Kit availability.
Code example
POST /api/v1/kit-assemblies

Headers:
  Authorization: Bearer <api-key>
  Content-Type: application/json
  Idempotency-Key: <unique-operation-key>

Request body

Code example
{
  "direction": "assemble",
  "locationId": "123456",
  "kits": [
    {
      "kitId": "507f1f77bcf86cd799439011",
      "quantity": 2,
      "expectedRevision": "2026-10-17T08:00:00.000Z"
    }
  ]
}

Response example (200 success)

Code example
{
  "success": true,
  "data": {
    "direction": "assemble",
    "locationId": "123456",
    "assemblyLogId": "507f1f77bcf86cd799439012",
    "kits": [
      {
        "kitId": "507f1f77bcf86cd799439011",
        "quantity": 2,
        "revision": "2026-10-17T08:00:00.000Z"
      }
    ],
    "inventoryDeltas": [
      {
        "variantId": "201",
        "productId": "200",
        "stockUnits": -1,
        "unit": "kg",
        "measurementPerStockUnit": 1
      },
      {
        "variantId": "101",
        "productId": "100",
        "stockUnits": 2,
        "measurementPerStockUnit": 1
      }
    ],
    "operationId": "7f7831f2-2675-4f5c-ae59-4c2d04095a60",
    "operationStatus": "completed"
  },
  "error": null
}

Note

Assembly consumes the calculated component quantities and adds one stock unit of the linked kit output variant per kit. A successful request completes synchronously and returns HTTP 200. No separate preview or queued-job endpoint is provided.

Request fields

Scroll horizontally to see all columns.

FieldTypeDescription
directionstringRequired. assemble or disassemble.
locationIdstringRequired. Positive Shopify legacy numeric location ID string, not a GraphQL GID.
kitsarrayRequired. 1–50 objects with unique kit IDs.
kits[].kitIdstringRequired. Kit ID, 24 hexadecimal characters.
kits[].quantityintegerRequired. Whole-kit count from 1 to 1,000,000. Numeric strings and fractional quantities are rejected.
kits[].expectedRevisionstringOptional. Exact current recipe revision for assembly; exact original snapshot revision for disassembly. Mismatch returns revision_conflict (409).
assemblyIdstringRequired only for disassemble. UUID operationId of the completed original public assembly, not assemblyLogId.
allowInsufficientInventorybooleanOptional, defaults to false. true explicitly permits tracked inventory to become negative; other validation and concurrency checks still apply.

Unknown request and kit-item fields are rejected. Do not send client-calculated inventory deltas. Shared component requirements are merged across the whole batch, and all resulting deltas must fit supported numeric and Shopify inventory limits.

Code example
POST /api/v1/kit-assemblies

Headers:
  Authorization: Bearer <api-key>
  Content-Type: application/json
  Idempotency-Key: <unique-operation-key>

Request body

Code example
{
  "direction": "disassemble",
  "locationId": "123456",
  "assemblyId": "7f7831f2-2675-4f5c-ae59-4c2d04095a60",
  "kits": [
    {
      "kitId": "507f1f77bcf86cd799439011",
      "quantity": 1,
      "expectedRevision": "2026-10-17T08:00:00.000Z"
    }
  ]
}

Note

Use a new idempotency key for disassembly. The original assembly must be completed, belong to this shop and use the same location. Disassembly removes assembled output and returns components using the original saved recipe and stock-unit conversions, even after the recipe is edited or deleted. Cumulative completed disassemblies cannot exceed each kit’s original quantity. Its response also includes originalAssemblyId.

Completed write result

Scroll horizontally to see all columns.

FieldTypeDescription
data.operationId / operationStatusstringPermanent public operation UUID and completed status. Use this operationId for status retrieval and future disassembly.
data.direction / locationIdstringExecuted direction and location.
data.assemblyLogIdstringIdentifier of the merchant’s Kit Builder production-history entry; distinct from operationId.
data.originalAssemblyIdstringPresent for disassembly; references the original assembly operation.
data.kitsarrayExecuted kitId, positive quantity and snapshot revision for every requested kit.
data.inventoryDeltasarrayMerged deltas for all component and output variants. Zero net deltas are omitted.
inventoryDeltas[].variantId / productIdstringShopify legacy numeric IDs.
inventoryDeltas[].stockUnitsnumberSigned change in Shopify stock units. Negative consumes stock; positive adds stock.
inventoryDeltas[].measurementPerStockUnitnumberMeasured value represented by one stock unit; 1 for ordinary quantity/output deltas.
inventoryDeltas[].unitstringPresent for measured components, in the configured base unit. Multiply stockUnits by measurementPerStockUnit to obtain the signed measured change.
Code example
GET /api/v1/kit-assemblies

Headers:
  Authorization: Bearer <api-key>

Query parameters

Scroll horizontally to see all columns.

ParameterTypeDescription
limitintegerOptional. 1–100 operations per page; default 50.
cursorstringOptional. Opaque meta.nextCursor from the preceding response.

Response fields

Scroll horizontally to see all columns.

FieldTypeDescription
dataarrayPublic kit_assembly operation records, including rejected and uncertain operations as well as completed assemblies/disassemblies.
meta.hasMore / nextCursorboolean / string | nullForward pagination metadata; ordered by creation time descending, with operation ID as a tie-breaker.

Note

History is scoped to the authenticated shop and contains public API assembly operation receipts. Reads use Cache-Control: no-store.

Code example
GET /api/v1/kit-assemblies/{id}

Headers:
  Authorization: Bearer <api-key>

Path parameters

Scroll horizontally to see all columns.

ParameterTypeDescription
idstringRequired. Public assembly operation UUID, returned as operationId by POST.

Response example (200 success)

Code example
{
  "success": true,
  "data": {
    "id": "7f7831f2-2675-4f5c-ae59-4c2d04095a60",
    "kind": "kit_assembly",
    "status": "completed",
    "phase": "finished",
    "createdAt": "2026-10-17T08:30:00.000Z",
    "updatedAt": "2026-10-17T08:30:01.000Z",
    "result": {
      "direction": "assemble",
      "locationId": "123456",
      "assemblyLogId": "507f1f77bcf86cd799439012",
      "kits": [
        {
          "kitId": "507f1f77bcf86cd799439011",
          "quantity": 2,
          "revision": "2026-10-17T08:00:00.000Z"
        }
      ],
      "inventoryDeltas": [
        {
          "variantId": "201",
          "productId": "200",
          "stockUnits": -1,
          "unit": "kg",
          "measurementPerStockUnit": 1
        },
        {
          "variantId": "101",
          "productId": "100",
          "stockUnits": 2,
          "measurementPerStockUnit": 1
        }
      ]
    }
  },
  "error": null
}

Response fields

Scroll horizontally to see all columns.

FieldTypeDescription
data.id / kindstringOperation UUID and kit_assembly kind.
data.resourceIdstringPresent for disassembly: the original assembly operation ID.
data.statusstringprocessing, completed, rejected or requires_review.
data.phasestringvalidating, applying or finished.
data.createdAt / updatedAtstringISO timestamps for the receipt.
data.snapshotobjectPresent once preparation has been recorded: original recipes, calculated inventory deltas, direction/location and inventory plan. Omitted from the compact example above.
data.resultobjectCompleted domain result. operationId and operationStatus belong to the POST response wrapper; the receipt uses id and status.
data.errorobjectRecorded code, message and optional details for rejected/requires_review outcomes. Optional fields are omitted when unavailable.

Note

HTTP 200 means the receipt was retrieved, so inspect data.status to determine whether the production operation completed. Invalid, missing, wrong-kind and other-shop operation IDs return 404.

Safe retries and errors

Every write requires an Idempotency-Key of 1–255 characters. Operation receipts are retained permanently for this shop. Retry the same operation with the same key; terminal replays include Idempotency-Replayed: true. A key used for a different request returns idempotency_key_reused.

Uncertain production outcome:

An operation_in_progress or operation_requires_review response includes an operationId in error.details. Read the receipt before retrying. requires_review means changes may have applied and must be reconciled before another write; a fresh key must not be used to repeat production. All kit recipe and assembly writes share one shop scope, so an uncertain operation also blocks other kit writes. See Write safety.
Code example
{
  "success": false,
  "data": null,
  "error": {
    "code": "operation_requires_review",
    "message": "The operation may have applied changes. Retrieve its status and reconcile it before starting another write.",
    "details": {
      "operationId": "7f7831f2-2675-4f5c-ae59-4c2d04095a60",
      "operationStatus": "requires_review"
    }
  }
}

Scroll horizontally to see all columns.

StatusDescription
400Malformed JSON, invalid/missing Idempotency-Key or invalid operation cursor.
401 / 403Invalid credentials, unavailable Public API access, or inactive/unavailable Kit Builder add-on tier.
404Kit or public assembly operation not found.
405Unsupported method.
409insufficient_kit_inventory (details.shortages lists available/required/shortage by variant), disassembly_quantity_exceeded, revision_conflict, inventory_conflict, idempotency_key_reused, operation_in_progress, resource_in_progress or operation_requires_review.
422Invalid fields, IDs or quantities; batch_too_large; invalid original assembly; unavailable snapshot; invalid/ineligible recipe, location, stock or measurements. Invalid list limit is also 422.
500Unexpected preparation, storage or upstream failure. Preserve the key while checking the outcome.