Designs catalog
Why pre-made designs
Every personalization site starts its users from a design, not a blank canvas. The designs catalog is that supply: every published, remixable design on the Snowcone marketplace, each already paired with a real product from the product catalog. It’s the same public Meilisearch surface as products — a second index, snowcone-designs, readable with the same public search key.
Catalog designs render from every shop — including fresh sandbox shops — with no allowlist configuration, and the renders are free: a design= mockup never counts against your usage budget. Billing starts only when your user personalizes a design (their artwork, your shop’s render). Search, pick one, and your first mockup works in the same minute.
Search the catalog
Search is semantic: every design carries an AI-generated visual caption and the index blends keyword + embedding matching, so descriptive queries like “pink cowgirl boots on the moon” find the right designs even when the publisher never tagged those words. The SDK and MCP send the hybrid blend by default; on raw Meilisearch calls pass hybrid as shown below. Facets compose with it: tags, occasion, style, productId, minPriceCents, and curated (first-party picks: curated = true).
curl "https://search.snowcone.app/indexes/snowcone-designs/search" \
-H "Authorization: Bearer eee819b849798ad9091228c486ec05d0931e5292" \
-H "Content-Type: application/json" \
-d '{ "q": "pink cowgirl boots on the moon", "limit": 10, "hybrid": { "embedder": "default", "semanticRatio": 0.5 }, "filter": "occasion = '\''christmas'\''" }'import { searchDesigns } from "@snowcone-app/sdk";
const { items } = await searchDesigns("pink cowgirl boots on the moon", {
filter: "occasion = 'christmas'",
});
// or on a client: client.catalog.designs.search("christmas card")// MCP (npx @snowcone-app/mcp): the snowcone_search_designs tool
{
"query": "pink cowgirl boots on the moon",
"shop": "YOUR_SHOP_ID"
}
// → each result includes a ready-to-render mockup_urlThe design document
A design document carries the components of a mockup URL — never an assembled URL — so you compose it with your own shop and any variant picks, exactly like the rest of the URL grammar.
{
"id": "9b2f6c3e-…",
"pairingId": "9b2f6c3e-…",
"slug": "watercolor-christmas-card",
"title": "Watercolor Christmas Card",
"description": "Hand-painted holiday scene.",
"tags": ["holiday", "watercolor"],
"occasion": "christmas",
"style": "watercolor",
"productId": "KMYKUK",
"variant": "e92f40",
"asset": "https://…storage.snowcone.app/exports/full.png",
"assets": { "front": "https://…/front.png", "back": "https://…/back.png" },
"previewThumbnail": "https://…/thumb.png",
"minPriceCents": 1999,
"caption": "Pink cowgirl boots standing on a cratered moon surface…",
"license": { "remixable": true },
"curated": true,
"slots": null
}Props
id / pairingIdstringtitle / description / tagsstring | string[]occasion / stylestring | nullproductIdstringvariantstring | nullasseturl | nullassets{ [placementKey]: url } | nullpreviewThumbnailurl | nullminPriceCentsnumber | nulllicense{ remixable: true }captionstring | nullcuratedbooleanslotsnull (RESERVED)Render one
Take the doc’s id (or slug), put it in design= on the doc’s productId path, add your shop, and it’s an <img> — rendered server-side from the published components, for free. The asset/assets components stay in the doc for canvas and remix flows; you never need them just to render. Variant picks via opt.<attr> and per-placement layout via tile/align work the same as any other mockup.
<!-- Render by reference: the doc's id (or slug) + your shop = a FREE mockup. -->
<img src="https://img.snowcone.app/KMYKUK?design=9b2f6c3e-…&shop=YOUR_SHOP_ID" />
<!-- The slug works too: -->
<img src="https://img.snowcone.app/KMYKUK?design=watercolor-christmas-card&shop=YOUR_SHOP_ID" />
<!-- Variant picks compose like any mockup (still free): -->
<img src="https://img.snowcone.app/KMYKUK?design=watercolor-christmas-card&opt.color=sage&shop=YOUR_SHOP_ID" />
