Templates
A template is a pre-designed mockup scene with designated frame(s) for your artwork, plus metadata like frame ratio and blending mode. When you generate a mockup via the API, your artwork is placed into the frame(s) and rendered into the scene.
Template IDs never change, so existing integrations keep working.
Library and your templates
There are two kinds of template, and every template in the API says which it is with source:
- Library (
"source": "library"): our ready-made scenes. A library ID always renders the scene exactly as we ship it, so you can use one straight away. - Yours (
"source": "custom"): templates in your account, either added from the library or created from your own photo. You can edit these in the dashboard, and edits save onto the same ID, so your API calls render the new version without any change on your side.
To customize a library template, add it to your templates first, in the dashboard or with POST /api/v1/templates. You get a copy with its own ID. The library ID keeps rendering the original, so nothing you already call ever changes under you.
Finding Templates
Browse in the dashboard
Each template has a unique ID. Use it as template_id when generating mockups. Your templates and their IDs are in the dashboard, where you can also add new ones from the library.
List via API
Fetch templates programmatically. The response includes the full library plus your own templates (those of the account that owns the API key). Pass source to list only one of the two.
curl -X GET "https://www.mockupanda.com/api/v1/templates?q=beige%20bedroom" \
-H "Authorization: Bearer YOUR_API_KEY"Query parameters
| Parameter | Type | Default | Description |
|---|---|---|---|
source | string | - | "library" for our ready-made scenes, "custom" for your own templates. Omit to return both. |
type | string | - | Filter by template type: "print" for wall-art/poster templates, "product" for apparel, mugs, and other 3D product templates. Omit to return all types. |
category | string | - | Filter by category (e.g., "Wall Art", "Devices"). Custom templates usually use the category "My templates". |
q | string | - | Hybrid search over the library and your own templates. Matches meaning as well as words, e.g. "beige bedroom" or "shop front" find relevant scenes even when those words are not in the template name. Results are ranked by relevance. |
search | string | - | Legacy substring match on name and category only. Prefer q for new integrations. |
ratio | string | - | Aspect ratio filter, written the way you would say it: "2:3", "4:5", "square", "portrait", "landscape", "A4", a print size like "8x10", or a decimal like 0.667. Comma-separate to accept several. Print templates only. |
artwork_url | string | - | Public URL of the artwork you are about to render. Its shape becomes the filter, so you get back only the templates it fits. |
artwork_width + artwork_height | integer | - | The same matching without the download, when you already know the artwork's pixel size. |
ratio_tolerance | number | 3 | How far from the target ratio still counts as a match, in percent. Raise it to accept templates that will crop the artwork slightly (max 25). |
page | integer | 1 | Page number |
limit | integer | 50 | Items per page (max 1000) |
Response
{
"templates": [
{
"id": "bedroom-poster-01",
"name": "Bedroom Poster",
"category": "poster",
"frame_count": 1,
"thumbnail_url": "https://pub-2702811b4e0b4173a4fd7e0de9e0b474.r2.dev/thumbnails/bedroom-poster-01.jpg",
"aspect_ratio": 0.67,
"aspect_ratio_name": "2:3",
"orientation": "portrait",
"blending_mode": "normal",
"render_mode": "corners",
"surface_type": null,
"is_product_template": false,
"is_user_template": false,
"source": "library"
},
{
"id": "wall-diptych-01",
"name": "Wall Diptych",
"category": "wall-art",
"frame_count": 2,
"thumbnail_url": "https://pub-2702811b4e0b4173a4fd7e0de9e0b474.r2.dev/thumbnails/wall-diptych-01.jpg",
"aspect_ratio": 0.67,
"aspect_ratio_name": "2:3",
"orientation": "portrait",
"blending_mode": "normal",
"render_mode": "corners",
"surface_type": null,
"is_product_template": false,
"is_user_template": false,
"source": "library"
},
{
"id": "tshirt-flat-01",
"name": "T-Shirt Flat Lay",
"category": "apparel",
"frame_count": 1,
"thumbnail_url": "https://pub-2702811b4e0b4173a4fd7e0de9e0b474.r2.dev/thumbnails/tshirt-flat-01.jpg",
"aspect_ratio": 1.0,
"aspect_ratio_name": "Square",
"orientation": "square",
"blending_mode": "multiply",
"render_mode": "uvmap",
"surface_type": "fabric",
"is_product_template": true,
"is_user_template": false,
"source": "library"
},
{
"id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"name": "My Living Room Mockup",
"category": "My templates",
"frame_count": 1,
"thumbnail_url": "https://pub-2702811b4e0b4173a4fd7e0de9e0b474.r2.dev/user-templates/thumb.jpg",
"aspect_ratio": 0.67,
"aspect_ratio_name": "2:3",
"orientation": "portrait",
"blending_mode": "normal",
"render_mode": "corners",
"surface_type": null,
"is_product_template": false,
"is_user_template": true,
"source": "custom"
}
],
"pagination": {
"page": 1,
"limit": 50,
"total": 121,
"total_pages": 3
},
"categories": ["apparel", "devices", "My templates", "poster", "wall-art"],
"ratios": [
{ "name": "A4", "orientation": "portrait", "label": "A4 portrait", "aspect_ratio": 0.707, "count": 49 },
{ "name": "3:4", "orientation": "portrait", "label": "3:4 portrait", "aspect_ratio": 0.75, "count": 30 },
{ "name": "2:3", "orientation": "portrait", "label": "2:3 portrait", "aspect_ratio": 0.667, "count": 11 },
{ "name": "Square", "orientation": "square", "label": "Square", "aspect_ratio": 1, "count": 8 }
],
"ratio_filter": null,
"artwork": null,
"relevance_ranked": false
}Response fields
Each template in the response includes:
| Field | Type | Description |
|---|---|---|
id | string | Unique template identifier |
name | string | Display name |
category | string | Template category |
frame_count | integer | Number of artwork frames |
thumbnail_url | string | null | Thumbnail image URL |
aspect_ratio | number | Expected artwork aspect ratio as a decimal (e.g., 0.67 for portrait 2:3, 1.0 for square, 1.5 for landscape 3:2) |
aspect_ratio_name | string | The same ratio in the words the editor uses: "2:3", "Square", "A4". Falls back to a reduced fraction for unusual shapes. |
orientation | string | "portrait", "landscape" or "square" |
blending_mode | string | Blend mode used when compositing artwork: "normal", "multiply", "screen", etc. |
render_mode | string | How the artwork is rendered: "corners" (perspective warp) or "uvmap" (UV-mapped product surface) |
surface_type | string | null | Material hint for product templates (e.g., "fabric"). Null for print templates. |
is_product_template | boolean | True for apparel, mugs, and other 3D product templates. False for flat print/poster templates. |
supports_product_color | boolean | True for templates that accept product_color when generating. Today that is garment templates (t-shirts, hoodies, totes). |
source | string | "library" for our ready-made scenes, "custom" for templates in your account. |
is_user_template | boolean | Same as source === "custom". Kept for existing integrations. |
The response also includes a pagination object (page, limit, total, total_pages), a categories array listing all available category names, and relevance_ranked: true when results were ordered by search relevance (i.e. you passed q), so clients know not to re-sort by date.
It also carries a ratios array: every shape present in the print library for the current query, as name, orientation, label, aspect_ratio and count. Use it to build a ratio picker, or to tell a seller what their artwork could fit when nothing matched exactly. ratio_filter and artwork echo what you asked for and what we measured; both are null when you did not filter by ratio.
Add a library template
Adds a library template to your templates and returns the copy, with its own ID. Use that ID in your calls if you plan to customize the template: edits you make in the dashboard save onto it.
curl -X POST https://www.mockupanda.com/api/v1/templates \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{ "from_template_id": "LIBRARY_TEMPLATE_ID" }'| Field | Type | Description |
|---|---|---|
from_template_id | string | Required. The ID of a library template ("source": "library"). |
name | string | Optional. A name for the copy. Defaults to the library template's name. |
Returns 201 with { "template": { ... } } in the same shape as the listing, with "source": "custom". Adding is free. An ID that is not a library template returns 404 with TEMPLATE_NOT_FOUND: your own templates are already yours, and you can edit them in the dashboard.
Using Templates
Single-frame
Most templates have one frame. Pass artwork_url:
curl -X POST https://www.mockupanda.com/api/v1/mockups/generate \
--http1.1 \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"template_id": "bedroom-poster-01",
"artwork_url": "https://example.com/art.jpg"
}'Multi-frame
Some templates have multiple frames (diptych, triptych). Use artwork_urls to map frame indices to artwork:
curl -X POST https://www.mockupanda.com/api/v1/mockups/generate \
--http1.1 \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"template_id": "wall-diptych-01",
"artwork_urls": {
"0": "https://example.com/art1.jpg",
"1": "https://example.com/art2.jpg"
}
}'Frame indices start at 0. If a template has 3 frames, use "0", "1", and "2".
Aspect ratios
Each print template expects a specific artwork aspect ratio. Artwork that does not match it is cropped or stretched to fill the frame, which is exactly the thing that makes a mockup look wrong. Rather than checking that yourself, ask for the templates that fit.
Match templates to an artwork
Pass the artwork you are about to render and the response comes back narrowed to the print templates shaped for it:
curl -X GET "https://www.mockupanda.com/api/v1/templates?artwork_url=https://example.com/art.png&q=bedroom" \
-H "Authorization: Bearer YOUR_API_KEY"Only the image header is downloaded, so a large file costs no more than a small
one. If you already know the artwork's pixel size, send it instead and skip the
download entirely: ?artwork_width=4000&artwork_height=6000.
{
"templates": [
{
"id": "bedroom-poster-01",
"name": "Bedroom Poster",
"category": "wall-art",
"frame_count": 1,
"thumbnail_url": "https://pub-2702811b4e0b4173a4fd7e0de9e0b474.r2.dev/thumbnails/bedroom-poster-01.jpg",
"aspect_ratio": 0.667,
"aspect_ratio_name": "2:3",
"orientation": "portrait",
"blending_mode": "normal",
"render_mode": "corners",
"surface_type": null,
"is_product_template": false,
"is_user_template": false,
"source": "library"
}
],
"pagination": { "page": 1, "limit": 50, "total": 11, "total_pages": 1 },
"ratio_filter": {
"requested": ["2:3"],
"tolerance_percent": 3,
"applied_to": "print"
},
"artwork": {
"width": 4000,
"height": 6000,
"format": "png",
"ratio": 0.667,
"name": "2:3",
"orientation": "portrait",
"label": "2:3 portrait"
},
"relevance_ranked": false
}This is the reliable way to bulk-render a catalogue: for each artwork, list the
templates that fit it, then pass those IDs to POST /api/v1/mockups/generate.
Filter by a named ratio
When you know the shape you want, name it. All of these work:
- Ratios:
2:3,3:2,4:5,16:9 - Print sizes:
8x10,11x14,18x24,24x36 - Paper:
A4,US Letter - Orientation:
portrait,landscape,square - Decimals:
0.667
Comma-separate to accept more than one, e.g. ?ratio=2:3,4:5. A ratio counts as
a match when it is within ratio_tolerance (3% by default) of the target, which
absorbs the small differences between hand-traced frames without letting a 3:4
template answer a 2:3 request. Raise the tolerance when you would rather have a
slight crop than no mockup at all.
Prints only
Ratio filtering applies to print templates. A poster frame has one correct
artwork shape, so matching is meaningful there. Product templates (apparel,
mugs, tote bags) warp artwork onto a curved surface with no fixed artwork
ratio, so any ratio or artwork parameter implicitly narrows the results to
type=print, and combining one with type=product returns a 400.