Multiple placements

Print different artwork on each area of a product — front, back, sleeve — as one buyable item.
frontback
A design
The product's placements
×2
One buyable item

How it works

A product is configured on two axes, and you pass a value for each. You pick a variant — size, color — with one opt.<attr> param per attribute (opt.size=m); see Options. And you supply a design — your artwork — by filling each printable placement with asset.<key> (asset.front=…).

Both are readable params any language builds by hand — no ids to look up, no SDK required. The server resolves price, print geometry, and composites the design into one mockup. One design is one buyable item; a single-image product (get started) is just one placement with bare asset=.

Discover the product

Read the product once from the catalog. Placements are the design axis — each has an addressable key — a URL-safe slug of the label (lowercase, non-alphanumerics collapsed to _, so “Left sleeve” → left_sleeve) — a human label, and a type (image or color). Attributes and attributesList are the variant axis — build pickers from them; combinations carries each price. You pass your picks as opt.<attr>; you never pass an internal id.

json
{
  "id": "KMYKUK",
  "name": "Women's Tee",
  "placements": [
    { "key": "front",        "label": "Front",        "type": "image" },
    { "key": "back",         "label": "Back",         "type": "image" },
    { "key": "left_sleeve",  "label": "Left sleeve",  "type": "image" },
    { "key": "right_sleeve", "label": "Right sleeve", "type": "image" },
    { "key": "collar",       "label": "Collar",       "type": "image" }
  ],
  "options": {
    "attributesList": ["Size"],
    "attributes": {
      "Size": { "choices": [{ "label": "S" }, { "label": "M" }, { "label": "L" }] }
    },
    "combinations": [
      { "Size": "S", "price": 2799 },
      { "Size": "M", "price": 2799 },
      { "Size": "L", "price": 2799 }
    ]
  }
}

Render a mockup

It’s a URL: a product code, your opt.<attr> picks, one asset.<key> per placement, and your shop. Build it in any language — it’s just a query string.

<img src="https://img.snowcone.app/KMYKUK?opt.size=m&asset.front=https%3A%2F%2Fcdn.example.com%2Ffront.png&asset.back=https%3A%2F%2Fcdn.example.com%2Fback.png&shop=YOUR_SHOP_ID" />

Prefer JavaScript? The optional SDK builds the same URL:

tsx
import { getMockupUrl } from "@snowcone-app/sdk";

const src = getMockupUrl("KMYKUK", {
  shop: "YOUR_SHOP_ID",
  options: { size: "m" },
  design: { front: "https://…/front.png", back: "https://…/back.png" },
});

Adjust each placement

A placement is filled by an image (asset.<key>) or, for a color placement like a cap’s crown, a solid color (color.<key>) — plus optional modifiers, keyed the same way.

html
<!-- Tile the front, top-align the back — modifiers are more params, same placement key. -->
<img src="https://img.snowcone.app/KMYKUK?opt.size=m&asset.front=…&tile.front=2&asset.back=…&align.back=top&shop=YOUR_SHOP_ID" />
asset.<key>url
Image to print on an image placement.
color.<key>hex
Solid color for a color placement (type "color") — e.g. a cap’s crown or strap.
tile.<key>0.25 | 0.5 | 1 | 2 | 4
Repeat the image as a tiled pattern; the number is the tile scale.
align.<key>center | top | bottom | left | right | far-*
How the image sits within the placement. Defaults to center.

Sell it

Swap imgbuy and the same params become a hosted checkout for one line item carrying every placement. A self-contained HTML form needs no JavaScript; price resolves server-side from your Shop ID.

<form action="https://buy.snowcone.app/KMYKUK" method="POST">
  <input type="hidden" name="asset.front" value="https://cdn.example.com/front.png" />
  <input type="hidden" name="asset.back"  value="https://cdn.example.com/back.png" />
  <input type="hidden" name="shop"        value="YOUR_SHOP_ID" />
  <select name="opt.size">
    <option value="s">S</option>
    <option value="m" selected>M</option>
    <option value="l">L</option>
  </select>
  <button type="submit">Buy now — $28</button>
</form>

Bring your own checkout

Running your own checkout? The Orders API line item takes the same two maps as JSON — options and design, keyed by key. Modifiers become fields on the fill ({ src, tile }) instead of a bare URL.

bash
curl https://api.snowcone.app/orders -X POST \
  -H "x-api-key: sk_your_orders_add_key" \
  -H "Content-Type: application/json" \
  -d '{
    "json": {
      "reference": "order-123",
      "items": [
        {
          "product": "KMYKUK",
          "options": { "size": "m" },
          "design": {
            "front": "https://cdn.example.com/front.png",
            "back":  "https://cdn.example.com/back.png"
          },
          "quantity": 1
        }
      ],
      "shipTo": {
        "name": "Ada Lovelace", "address1": "5 Bell Yard",
        "city": "London", "postalCode": "WC2A", "country": "GB"
      }
    }
  }'