Templates
Search the public template catalogue of ~50,000 image and video templates by keyword, topic, tags, and model.
The template catalogue holds roughly 50,000 approved, public templates — the same ones the web catalogue shows — projected down to a narrow shape that is safe for an API-key client. Search and filter them, then use a template's prompt (when present) to seed a generation.
Both endpoints require a valid API key, like the rest of
/v1. Templates are public data, so — unlike the generation endpoints — these routes charge no credits. They are subject to the same per-key rate limiting as every other API-key route.
GET /v1/templates
Search and filter the public template catalogue. Returns only live, approved, public rows.
Auth: API Key
| Query param | Type | Required | Description |
|---|---|---|---|
q |
string |
No | Free-text search over title, description, and prompt. |
media_type |
string |
No | Restrict to image or video. |
topic |
string |
No | Topic/niche keyword bucket, e.g. aesthetic, dating, fashion. Matches by keyword; see the note below on the topic response field. |
tags |
string |
No | Tag filter, any-match. Repeatable — pass tags multiple times to match any of several tags. |
target_model |
string |
No | Filter to templates built for one target model. |
featured |
boolean |
No | Only featured templates. |
trending |
boolean |
No | Sort by recency-weighted popularity instead of the default order. Default false. |
limit |
number |
No | Page size, 1 to 100. Default 30. |
offset |
number |
No | Row offset, ≥ 0. Default 0. |
Response 200 OK
{
"templates": [
{
"id": "10423",
"title": "Golden hour portrait",
"prompt": "a portrait bathed in warm golden-hour light, shallow depth of field",
"media_type": "image",
"topic": null,
"tags": ["portrait", "aesthetic"],
"target_model": "gemini-3.1-flash-image-preview",
"preview_url": "https://cdn.picxstudio.com/templates/10423/preview.jpg",
"thumbnail_url": "https://cdn.picxstudio.com/templates/10423/thumb.jpg",
"is_featured": true,
"likes": 1284
}
],
"total": 31,
"limit": 30,
"offset": 0
}
Each entry in templates is a TemplateInfo:
| Field | Type | Description |
|---|---|---|
id |
string |
Template id. Pass it to GET /v1/templates/{template_id}. |
title |
string |
Human-readable template name. |
prompt |
string | null |
The sample prompt for free templates. null on premium/gated rows by design — the exact premium prompt is the paid asset and is never returned here. null means gated, not missing. |
media_type |
string |
image or video. |
topic |
null |
Always null. Topic is a query-time keyword bucket, not a per-row column — there is no stored topic to return. Filter by topic with the topic query param; do not expect it echoed back on a row. |
tags |
string[] |
The template's tags. |
target_model |
string | null |
The model this template was built for, when set. |
preview_url |
string | null |
Richest available preview — the video URL for video templates, otherwise the still image. null when neither exists. |
thumbnail_url |
string | null |
A still image (never a video file), suitable for an <img>. |
is_featured |
boolean |
Whether the template is featured. |
likes |
number | null |
Like count, when available. |
totalis an estimate, not a count. To keep search fast over ~50,000 rows, an exactCOUNTis deliberately never run.totalis computed asoffset + (rows on this page) + 1when more rows exist, so it only tells you "there is at least one more page". Do not use it to compute a page count or a progress bar. Instead, page until a short page returns: keep requesting with a growingoffsetuntil you get back fewer thanlimittemplates — that page is the last one.
curl
# Search "golden hour", image only, first page
curl "https://api.picxstudio.com/v1/templates?q=golden%20hour&media_type=image&limit=30&offset=0" \
-H "Authorization: Bearer $PICX_API_KEY"
# Topic bucket + repeatable tags (any-match) + trending sort
curl "https://api.picxstudio.com/v1/templates?topic=fashion&tags=portrait&tags=studio&trending=true" \
-H "Authorization: Bearer $PICX_API_KEY"
# Featured video templates for one target model
curl "https://api.picxstudio.com/v1/templates?media_type=video&featured=true&target_model=fal-ai/bytedance/seedance/v2" \
-H "Authorization: Bearer $PICX_API_KEY"
Page until a short page returns
# limit=30. Keep bumping offset by 30 until a response has fewer than 30 templates.
curl "https://api.picxstudio.com/v1/templates?q=aesthetic&limit=30&offset=0" -H "Authorization: Bearer $PICX_API_KEY"
curl "https://api.picxstudio.com/v1/templates?q=aesthetic&limit=30&offset=30" -H "Authorization: Bearer $PICX_API_KEY"
curl "https://api.picxstudio.com/v1/templates?q=aesthetic&limit=30&offset=60" -H "Authorization: Bearer $PICX_API_KEY"
# ...when a page returns < 30 templates, you have reached the end.
GET /v1/templates/{template_id}
Fetch a single public template by id.
Auth: API Key
Returns the same TemplateInfo shape as one entry of the list response.
Response 200 OK
{
"id": "10423",
"title": "Golden hour portrait",
"prompt": "a portrait bathed in warm golden-hour light, shallow depth of field",
"media_type": "image",
"topic": null,
"tags": ["portrait", "aesthetic"],
"target_model": "gemini-3.1-flash-image-preview",
"preview_url": "https://cdn.picxstudio.com/templates/10423/preview.jpg",
"thumbnail_url": "https://cdn.picxstudio.com/templates/10423/thumb.jpg",
"is_featured": true,
"likes": 1284
}
Returns 404 when the template does not exist, or exists but is not live, approved, and public (archived, pending, or private). A non-public row is never leaked.
curl
curl https://api.picxstudio.com/v1/templates/10423 \
-H "Authorization: Bearer $PICX_API_KEY"
Seed a generation from a template
A free template's prompt is ready to drop straight into a generation call:
# 1. Find a template
curl "https://api.picxstudio.com/v1/templates?q=golden%20hour&media_type=image&limit=1" \
-H "Authorization: Bearer $PICX_API_KEY"
# 2. Use its prompt to generate an image
curl -X POST https://api.picxstudio.com/v1/images/generate \
-H "Authorization: Bearer $PICX_API_KEY" \
-H "Content-Type: application/json" \
-d '{"prompt":"a portrait bathed in warm golden-hour light, shallow depth of field","size":"2K","aspect_ratio":"16:9"}'
When a template's
promptisnull, it is a premium/gated template and its exact prompt is withheld. Pick a free template, or write your own prompt guided by the template'stitleandtags.
FAQ
Why is total smaller than the real number of matches?
total is an estimate, not a count. To keep search fast across ~50,000 rows, the API never runs an exact COUNT. It returns offset + (rows on this page) + 1 whenever more rows exist, which only signals "there is at least one more page". Page through by increasing offset until a page comes back with fewer than limit templates — that is the last page.
Why is the topic field always null even when I filter by topic?
Because topic is a query-time keyword bucket, not a stored per-row column. The topic query param filters the catalogue, but no template carries a single canonical topic value, so the topic field on every row is null. This is expected — filter by topic, don't read topic back.
Why is prompt null on some templates?
Those are premium/gated templates. Their exact prompt is the paid asset and is never returned on the public API surface. null means gated, not missing — the template still exists and its title, tags, and preview are all returned.
Do template requests cost credits?
No. Templates are public data, so /v1/templates and /v1/templates/{template_id} charge no credits. Only the generation and edit endpoints consume credits.
How do I match several tags at once?
Repeat the tags param: ?tags=portrait&tags=studio. It is any-match — a template matching any of the listed tags is returned.