Measura API documentation · v1
Manage recipes linked to existing Shopify products and variants.
These endpoints require a public API key with Public API access and an active Kit Builder add-on with an available tier. Kit IDs are 24 hexadecimal characters. Shopify product and variant IDs are positive legacy numeric ID strings, rather than GraphQL GIDs.
Recipe writes and stock:
GET /api/v1/kits
Headers:
Authorization: Bearer <api-key>Scroll horizontally to see all columns.
| Parameter | Type | Description |
|---|---|---|
limit | integer | Optional. 1–100 recipes; default 50. |
cursor | string | Optional. Use meta.nextCursor from the previous page. Recipe cursors are kit IDs. |
{
"success": true,
"data": [
{
"id": "507f1f77bcf86cd799439011",
"title": "Coffee gift box",
"description": "Two measured portions",
"productId": "100",
"variantId": "101",
"components": [
{
"productId": "200",
"variantId": "201",
"quantity": 2,
"measurement": {
"value": 250,
"unit": "g",
"type": "weight"
}
}
],
"revision": "2026-10-17T08:00:00.000Z",
"createdAt": "2026-10-17T08:00:00.000Z",
"updatedAt": "2026-10-17T08:00:00.000Z"
}
],
"error": null,
"meta": {
"hasMore": false,
"nextCursor": null
}
}Note
Recipes are ordered by kit ID ascending. This forward pagination has no prevCursor. All kit reads and writes return Cache-Control: no-store.
GET /api/v1/kits/{id}
Headers:
Authorization: Bearer <api-key>Scroll horizontally to see all columns.
| Parameter | Type | Description |
|---|---|---|
id | string | Required. Kit ID, 24 hexadecimal characters. |
{
"success": true,
"data": {
"id": "507f1f77bcf86cd799439011",
"title": "Coffee gift box",
"description": "Two measured portions",
"productId": "100",
"variantId": "101",
"components": [
{
"productId": "200",
"variantId": "201",
"quantity": 2,
"measurement": {
"value": 250,
"unit": "g",
"type": "weight"
}
}
],
"revision": "2026-10-17T08:00:00.000Z",
"createdAt": "2026-10-17T08:00:00.000Z",
"updatedAt": "2026-10-17T08:00:00.000Z"
},
"error": null
}Scroll horizontally to see all columns.
| Field | Type | Description |
|---|---|---|
data.id | string | Kit recipe ID. |
data.title / description | string | Recipe title and optional description. Description may be omitted. |
data.productId / variantId | string | Existing Shopify product and output variant linked to the kit. |
data.components | array | Component definitions, including quantity and optional measurement. |
data.revision | string | Exact ISO timestamp to pass as expectedRevision for PATCH or DELETE. |
data.createdAt / updatedAt | string | ISO timestamps for creation and last update. |
POST /api/v1/kits
Headers:
Authorization: Bearer <api-key>
Content-Type: application/json
Idempotency-Key: <unique-operation-key>{
"title": "Coffee gift box",
"description": "Two measured portions",
"productId": "100",
"variantId": "101",
"components": [
{
"productId": "200",
"variantId": "201",
"quantity": 2,
"measurement": {
"value": 250,
"unit": "g",
"type": "weight"
}
}
]
}{
"success": true,
"data": {
"kit": {
"id": "507f1f77bcf86cd799439011",
"title": "Coffee gift box",
"description": "Two measured portions",
"productId": "100",
"variantId": "101",
"components": [
{
"productId": "200",
"variantId": "201",
"quantity": 2,
"measurement": {
"value": 250,
"unit": "g",
"type": "weight"
}
}
],
"revision": "2026-10-17T08:00:00.000Z",
"createdAt": "2026-10-17T08:00:00.000Z",
"updatedAt": "2026-10-17T08:00:00.000Z"
},
"operationId": "7f7831f2-2675-4f5c-ae59-4c2d04095a60",
"operationStatus": "completed"
},
"error": null
}Note
A successful create returns HTTP 200. Creation consumes the kit allowance of the active add-on tier; an exhausted allowance returns kit_limit_reached (409).
Scroll horizontally to see all columns.
| Field | Type | Description |
|---|---|---|
title | string | Required on create. Nonblank, at most 255 characters; surrounding whitespace is trimmed. |
description | string | Optional, at most 5,000 characters. Use an empty string to clear it. |
productId / variantId | string | Required on create. Existing product and output variant IDs; the variant must belong to the product. |
components | array | Required on create. 1–50 component objects. PATCH replaces this entire array when supplied. |
components[].productId / variantId | string | Required existing Shopify IDs. Each variant must belong to its product and cannot be the kit output variant. |
components[].quantity | integer | Required. 1–1,000,000. Without measurement, consumes this many stock units per kit. |
components[].measurement | object | Optional. When supplied, each quantity consumes this measured amount; the server converts it to the variant’s configured stock units. |
measurement.value | number | Required within measurement. Finite, greater than zero and at most 1,000,000,000. |
measurement.type | string | Required within measurement. weight, length, volume, area or time; must match the component’s measurement configuration. |
measurement.unit | string | Required within measurement. A known unit label or name for the stated type. Unknown or incompatible units are rejected. |
Unknown fields are rejected at every validated object level. Numeric strings are not accepted for quantity or measurement.value. Measured variants must be eligible under the shop’s configuration and plan; the API also validates conversion and supported numeric limits before saving.
PATCH /api/v1/kits/{id}
Headers:
Authorization: Bearer <api-key>
Content-Type: application/json
Idempotency-Key: <unique-operation-key>Scroll horizontally to see all columns.
| Parameter | Type | Description |
|---|---|---|
id | string | Required. Kit ID. |
{
"expectedRevision": "2026-10-17T08:00:00.000Z",
"title": "Coffee sampler box"
}Note
Pass the exact current revision from GET and at least one recipe field to update. Omitted fields keep their current values. The response has the same data.kit, operationId and operationStatus shape as create, with the updated recipe. A concurrent change returns revision_conflict (409); read the latest recipe before preparing a new operation.
DELETE /api/v1/kits/{id}
Headers:
Authorization: Bearer <api-key>
Content-Type: application/json
Idempotency-Key: <unique-operation-key>Scroll horizontally to see all columns.
| Parameter | Type | Description |
|---|---|---|
id | string | Required. Kit ID. |
{
"expectedRevision": "2026-10-17T08:00:00.000Z"
}{
"success": true,
"data": {
"deleted": true,
"kitId": "507f1f77bcf86cd799439011",
"operationId": "7f7831f2-2675-4f5c-ae59-4c2d04095a60",
"operationStatus": "completed"
},
"error": null
}Note
The body accepts only expectedRevision. Deletion removes the recipe while preserving Shopify products, inventory and production history. Historical public assemblies retain the snapshots needed for disassembly.
Every write requires an Idempotency-Key of 1–255 characters. Receipts are retained permanently for this shop. Retry the same operation with the same key; a completed replay returns Idempotency-Replayed: true. Recipe writes and assemblies share the shop’s kit write scope, so another pending operation can temporarily block a write.
If the result is uncertain, retrieve the operation using the operationId in the response or error details. Follow the write safety guide before starting another write.
Scroll horizontally to see all columns.
| Status | Description |
|---|---|
| 400 | Malformed JSON or missing/invalid Idempotency-Key. |
| 401 / 403 | Invalid credentials, unavailable Public API access, or inactive/unavailable Kit Builder add-on tier. |
| 404 | Kit not found in the authenticated shop. |
| 405 | Unsupported method. |
| 409 | revision_conflict, kit_limit_reached, idempotency_key_reused, operation_in_progress, resource_in_progress or operation_requires_review. |
| 422 | Invalid fields/IDs/revisions, variant_product_mismatch, variant_not_eligible or invalid measurement/conversion configuration. |
| 500 | Unexpected server or upstream failure. Preserve the key when retrying an uncertain request. |