Custom items
What a custom item is, and how to put one on an order.
There are two ways to put a line item on an order.
| Kind | Use it when |
|---|---|
| Product line item | You built the product in the Pengine app in advance. Name a variant by productVariantId or sku. |
| Custom line item | The design is decided at order time. Name a blank, an artwork and where the artwork goes. |
A custom item combines a catalog product variant (a blank in one color and size), an artwork (your image), and one or more decorations (where and how to print the artwork). It does not create a saved product, making it suitable for designs generated at order time.
The flow
Find a blank
Catalog products are the blanks available to your store. Each one reports the decoration methods it supports and the areas you can print on.
curl "https://api.pengine.io/store-api/2026-08/stores/$STORE_ID/catalog-products?filter[productType]=shirts&filter[decorationMethod]=direct_to_garment" \
-H "X-API-Key: $PENGINE_API_KEY"Use the variant id for the color and size you want. Also record the allowed decorationLocations.
See Catalog products.
Upload the artwork
Provide an HTTPS URL that Pengine can use to download the image. The response contains an artwork you can reuse across orders.
curl -X POST https://api.pengine.io/store-api/2026-08/stores/$STORE_ID/artworks \
-H "X-API-Key: $PENGINE_API_KEY" \
-H "Content-Type: application/json" \
-d '{ "name": "Northbound logo", "image": { "url": "https://cdn.example.com/art/northbound.png" } }'Store the artwork id. Uploading the same image twice creates two separate artworks. See
Artworks.
Create the order
Set isCustom to true, identify the blank with catalogProductVariantId, and define each placement
in decorations.
curl -X POST https://api.pengine.io/store-api/2026-08/stores/$STORE_ID/orders \
-H "X-API-Key: $PENGINE_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"externalOrderId": "web-10483",
"lineItems": [
{
"isCustom": true,
"catalogProductVariantId": "zt1vz7szjeiv64qezrzakzc8",
"quantity": 1,
"decorations": [
{
"decorationLocation": "front",
"decorationMethod": "direct_to_garment",
"artworkId": "sm22mjuo3dk36g1ejurbawjx",
"physicalWidth": 10,
"physicalHeight": 12,
"horizontalOffsetFromCenter": 0,
"verticalOffsetFromTop": 2.5
}
]
}
],
"shippingAddress": {
"firstName": "Ada",
"lastName": "Lovelace",
"address": {
"streetAddress": "1600 Pennsylvania Avenue NW",
"cityOrTown": "Washington",
"stateOrProvince": "DC",
"zipOrPostalCode": "20500",
"country": "US"
}
}
}'Custom and product line items can sit on the same order. The shipping address and externalOrderId
work exactly as they do anywhere else. See Orders.
The response uses the standard order shape. Custom line items have isCustom: true and omit
productId because they are not based on a saved product.
The decoration object
Prop
Type
Placing the artwork
All four measurements are in inches, matching the print area the catalog product reports for that location. The artwork has to fit inside it:
physicalWidthandphysicalHeightmust each be no larger than the area's own dimensions.verticalOffsetFromTopplusphysicalHeightmust not exceed the area's height.- Half of
physicalWidthplus the absolute value ofhorizontalOffsetFromCentermust not exceed half the area's width.
Set horizontalOffsetFromCenter to 0 to center the artwork. The API does not preserve the source
image's aspect ratio automatically, so set a proportional width and height.
Rules for a custom line item
isCustom: truerequirescatalogProductVariantIdand at least one decoration.- A custom line item cannot carry
productVariantId. A product line item cannot carrycatalogProductVariantIdordecorations. - Every decoration on a line item must use the same
decorationMethod. To combine methods, split them into separate line items. - A location can appear only once per line item.
- The method has to be supported by the blank, and also allowed at that specific location. Some locations exclude some methods.
When it fails
Every one of these is a 400. The message names the value that caused it.
| Message | Cause |
|---|---|
A custom line item must have a catalog product variant ID | isCustom is true with no blank named. |
A custom line item must have at least one decoration | decorations is missing or empty. |
A custom line item cannot have a product variant ID | Both isCustom and productVariantId were sent. |
Only a custom line item can have a catalog product variant ID or decorations | Custom fields on a product line item. |
All decorations of a line item must use the same decoration method | Mixed methods in one line item. |
Decoration locations must be unique within a line item | The same location twice. |
No catalog product variant found for a line item: ... | The variant ID is not a catalog product variant. |
Artworks not found in the store: ... | The artwork ID does not belong to this store. |
The print method is not available for the catalog product: ... | The blank does not support that method. |
The print location is not available for the catalog product: ... | The blank has no such print area. |
The print method is not available for the print location: ... | That location excludes that method. |
The design is larger than the print area for the print location: ... | Width or height exceeds the area. |
The design is placed outside the print area for the print location: ... | The offsets push it past an edge. |
These messages say print, the fields say decoration
Several errors use the older "print method" and "print location" wording for the fields now called
decorationMethod and decorationLocation. They refer to the same thing. As always, branch on the
status code rather than the text.
Validate placement while the customer is designing to prevent geometry errors at checkout.