Printago API
POST /v1/skus

Create a new SKU

Create a SKU: a sellable product made of one or more parts. Printing a SKU (with POST /v2/builds, or by printing an order that contains it) prints every linked part in the configured quantity.

Send Authorization: ApiKey <your-api-key>.

A SKU has:

  • A SKU code (sku) that must be unique within your store. This is the code your storefront sends with orders. A duplicate code is rejected with 400.
  • Linked parts (linkedParts): the parts that make up one unit, each with its own quantity, label and optional parameters and materialAssignments. For a 3MF linked part, set the copies per plate in extensions["3mf"].plateQuantities.
  • Variant options (optional, optionBindings): IDs of variant options such as Color or Size, created with POST /v1/sku-variants. Binding an option lets orders and builds pick a value for it, and a linked part can take its materials, parameter values or plate quantities from the chosen value through a variant property:
    • materialAssignments: use { "propertyId": "<material property ID>" } in place of a material spec.
    • parameterBindings: map a part parameter name to a text property ID.
    • plateQuantitiesBinding: the ID of a plate quantities property.

The response is the new SKU with the created linkedParts. Each linked part's id is the key to use in linkedPartConfigs when you override it in POST /v2/builds.

To make SKUs straight from existing parts (one SKU per part), use POST /v1/parts/create-skus.

Requires: sku.create

Request Body

The SKU data including name, price, and linked parts

SkuInsert
customMetadataoptional
Record<string, any>
Construct a type with a set of properties K of type T
descriptionrequired
string
externalIdrequirednullable
string

ID of the matching product in an external system, or null.

externalProviderrequirednullable
"etsy" | "shopify"

Marketplace the externalId belongs to, or null.

etsyshopify
folderIdoptionalnullable
string
pattern: ^[a-z0-9]{24}$
inputsoptional
object[]
connectedPropertyIdoptionalnullable
string
idoptional
string
namerequired
string
typerequired
"text" | "material" | "plate_quantities"
textmaterialplate_quantities
linkedPartsrequired
object[]

The parts in one unit of this SKU.

exposedParametersrequired
string[]

Required. Send [].

extensionsoptionalnullable
object
3mfoptional
object
plateLabelsoptional
Record<string, string>
plateQuantitiesrequired
Record<string, number>
skipObjectsoptional
Record<string, string[]>
Construct a type with a set of properties K of type T
labelrequired
string

Label shown on this part's print jobs.

materialAssignmentsoptionalnullable
Record<string, object[]>

Material per filament channel, keyed by channel index. Each value is a list of specs in order of preference: { "variantId" }, { "materialId" }, { "groupId" }, { "materialType" }, or { "propertyId" } to take the material from a variant property.

parameterBindingsoptionalnullable
Record<string, string>

Map of part parameter name to the ID of a text variant property. The value of the selected option drives the parameter.

parametersrequired
object[]

Fixed parameter values for parametric parts, as { "name", "value", "type" } entries. type is string, number, boolean or file.

namerequired
string
typerequired
"number" | "string" | "boolean" | "file"
numberstringbooleanfile
valueoptional
number | string | boolean
partIdrequired
string

ID of the part, from GET /v1/parts.

pattern: ^[a-z0-9]{24}$
plateQuantitiesBindingoptionalnullable
string

ID of a plate_quantities variant property. The selected option value decides how many copies of each 3MF plate to print.

quantityrequired
number

Copies of this part in one unit of the SKU, 0 to 500.

min: 0max: 500
sequenceBindingsoptionalnullable
Record<string, string>
Construct a type with a set of properties K of type T
skuIdoptional
string
pattern: ^[a-z0-9]{24}$
optionBindingsoptional
string[]

IDs of variant options (from GET /v1/sku-variants) to bind to the new SKU. Each becomes a required option on orders for this SKU. Use POST /v1/sku-variants/bindings to add more later or to make one optional.

skurequired
string

The SKU code. Must be unique within your store; this is the code orders refer to.

titlerequired
string

Display name of the product.

Example Request

application/json
{
  "linkedParts": [
    {
      "skuId": "string",
      "parameters": [
        {
          "name": "string",
          "type": "number",
          "value": 1
        }
      ],
      "partId": "string",
      "quantity": 0,
      "label": "string",
      "extensions": {
        "3mf": {
          "skipObjects": {},
          "plateQuantities": {},
          "plateLabels": {}
        }
      },
      "materialAssignments": {},
      "exposedParameters": [
        "string"
      ],
      "parameterBindings": {},
      "sequenceBindings": {},
      "plateQuantitiesBinding": "string"
    }
  ],
  "inputs": [
    {
      "id": "string",
      "type": "text",
      "name": "string",
      "connectedPropertyId": "string"
    }
  ],
  "optionBindings": [
    "string"
  ],
  "description": "string",
  "externalId": "string",
  "customMetadata": {},
  "folderId": "string",
  "sku": "string",
  "title": "string",
  "externalProvider": "etsy"
}

Examples

Create a single-part SKU

Request
{
  "sku": "CABLE-CLIP",
  "title": "Cable Clip (4 pack)",
  "description": "",
  "externalId": null,
  "externalProvider": null,
  "linkedParts": [
    {
      "partId": "c7l1i5p9c3l6i0p4q8w2e5r9",
      "label": "Cable Clip",
      "quantity": 4,
      "parameters": [],
      "exposedParameters": []
    }
  ]
}
Response
{
  "id": "s8k2u6c0o4a7s1t5e9r3f2g6",
  "storeId": "k3m9x2p7q8r4t6v1w5y0z3a2",
  "sku": "CABLE-CLIP",
  "title": "Cable Clip (4 pack)",
  "description": "",
  "externalId": null,
  "externalProvider": null,
  "folderId": null,
  "totalCogs": 0,
  "createdAt": "2026-09-23T16:02:18.340Z",
  "updatedAt": "2026-09-23T16:02:18.340Z",
  "linkedParts": [
    {
      "id": "l7z1x5c9v3b6n0m4k8j2h5g9",
      "storeId": "k3m9x2p7q8r4t6v1w5y0z3a2",
      "skuId": "s8k2u6c0o4a7s1t5e9r3f2g6",
      "partId": "c7l1i5p9c3l6i0p4q8w2e5r9",
      "label": "Cable Clip",
      "quantity": 4,
      "parameters": [],
      "exposedParameters": [],
      "materialAssignments": null,
      "extensions": null,
      "parameterBindings": null,
      "plateQuantitiesBinding": null,
      "createdAt": "2026-09-23T16:02:18.362Z",
      "updatedAt": "2026-09-23T16:02:18.362Z"
    }
  ]
}

Create a SKU whose color comes from a variant option

Bind the Color option, and let the chosen color's Filament property decide the material of filament channel 0.

Request
{
  "sku": "BENCHY",
  "title": "Benchy",
  "description": "The classic calibration boat.",
  "externalId": null,
  "externalProvider": null,
  "optionBindings": [
    "v2a6r0i4a8n1t5c9o3l7o2r6"
  ],
  "linkedParts": [
    {
      "partId": "p8f2k6m1q9w3e7r5t0y4u2i6",
      "label": "Benchy",
      "quantity": 1,
      "parameters": [],
      "exposedParameters": [],
      "materialAssignments": {
        "0": [
          {
            "propertyId": "f1l4m7n0t3p6r9q2w5e8r1t4"
          }
        ]
      }
    }
  ]
}
Response
{
  "id": "s5h1j7k3l9a2s6d0f4g8h2j5",
  "storeId": "k3m9x2p7q8r4t6v1w5y0z3a2",
  "sku": "BENCHY",
  "title": "Benchy",
  "description": "The classic calibration boat.",
  "externalId": null,
  "externalProvider": null,
  "folderId": null,
  "totalCogs": 0,
  "createdAt": "2026-09-23T16:05:44.019Z",
  "updatedAt": "2026-09-23T16:05:44.019Z",
  "linkedParts": [
    {
      "id": "l2k8j4h0g6f1d7s3a9p5o1i7",
      "storeId": "k3m9x2p7q8r4t6v1w5y0z3a2",
      "skuId": "s5h1j7k3l9a2s6d0f4g8h2j5",
      "partId": "p8f2k6m1q9w3e7r5t0y4u2i6",
      "label": "Benchy",
      "quantity": 1,
      "parameters": [],
      "exposedParameters": [],
      "materialAssignments": {
        "0": [
          {
            "propertyId": "f1l4m7n0t3p6r9q2w5e8r1t4"
          }
        ]
      },
      "extensions": null,
      "parameterBindings": null,
      "plateQuantitiesBinding": null,
      "createdAt": "2026-09-23T16:05:44.047Z",
      "updatedAt": "2026-09-23T16:05:44.047Z"
    }
  ]
}

Response Schema

SkuLinkedPartsRelation
createdAtrequired
string
format: date-time
customMetadataoptional
Record<string, any>
Construct a type with a set of properties K of type T
descriptionrequired
string
externalIdrequirednullable
string

ID of the matching product in an external system, or null.

externalProviderrequirednullable
"etsy" | "shopify"

Marketplace the externalId belongs to, or null.

etsyshopify
folderIdoptionalnullable
string
pattern: ^[a-z0-9]{24}$
idrequired
string
pattern: ^[a-z0-9]{24}$
linkedPartsrequired
object[]

The parts in one unit of this SKU.

createdAtrequired
string
format: date-time
exposedParametersrequired
string[]

Required. Send [].

extensionsoptionalnullable
object
3mfoptional
object
plateLabelsoptional
Record<string, string>
plateQuantitiesrequired
Record<string, number>
skipObjectsoptional
Record<string, string[]>
Construct a type with a set of properties K of type T
idrequired
string
pattern: ^[a-z0-9]{24}$
labelrequired
string

Label shown on this part's print jobs.

materialAssignmentsoptionalnullable
Record<string, object[]>

Material per filament channel, keyed by channel index. Each value is a list of specs in order of preference: { "variantId" }, { "materialId" }, { "groupId" }, { "materialType" }, or { "propertyId" } to take the material from a variant property.

parameterBindingsoptionalnullable
Record<string, string>

Map of part parameter name to the ID of a text variant property. The value of the selected option drives the parameter.

parametersrequired
object[]

Fixed parameter values for parametric parts, as { "name", "value", "type" } entries. type is string, number, boolean or file.

namerequired
string
typerequired
"number" | "string" | "boolean" | "file"
numberstringbooleanfile
valueoptional
number | string | boolean
partIdrequired
string

ID of the part, from GET /v1/parts.

pattern: ^[a-z0-9]{24}$
plateQuantitiesBindingoptionalnullable
string

ID of a plate_quantities variant property. The selected option value decides how many copies of each 3MF plate to print.

quantityrequired
number

Copies of this part in one unit of the SKU, 0 to 500.

min: 0max: 500
sequenceBindingsoptionalnullable
Record<string, string>
Construct a type with a set of properties K of type T
skuIdrequired
string
pattern: ^[a-z0-9]{24}$
storeIdrequired
string
pattern: ^[a-z0-9]{24}$
updatedAtrequired
string
format: date-time
skurequired
string

The SKU code. Must be unique within your store; this is the code orders refer to.

storeIdrequired
string
pattern: ^[a-z0-9]{24}$
titlerequired
string

Display name of the product.

totalCogsrequired
number
updatedAtrequired
string
format: date-time

Example Response

201 OK — application/json
{
  "sku": "string",
  "title": "string",
  "description": "string",
  "externalId": "string",
  "externalProvider": "etsy",
  "folderId": "string",
  "totalCogs": 1,
  "customMetadata": {},
  "id": "string",
  "storeId": "string",
  "createdAt": "2025-01-15T12:00:00.000Z",
  "updatedAt": "2025-01-15T12:00:00.000Z",
  "linkedParts": [
    {
      "skuId": "string",
      "partId": "string",
      "parameters": [
        {
          "name": "string",
          "type": "number",
          "value": 1
        }
      ],
      "quantity": 0,
      "label": "string",
      "exposedParameters": [
        "string"
      ],
      "materialAssignments": {},
      "extensions": {
        "3mf": {
          "skipObjects": {},
          "plateQuantities": {},
          "plateLabels": {}
        }
      },
      "parameterBindings": {},
      "sequenceBindings": {},
      "plateQuantitiesBinding": "string",
      "id": "string",
      "storeId": "string",
      "createdAt": "2025-01-15T12:00:00.000Z",
      "updatedAt": "2025-01-15T12:00:00.000Z"
    }
  ]
}