# Template tools

Templates (a.k.a. presets) are pre-built input bundles for ZenCreator generation. Each template pairs a specific generation tool (the `tool_name` you pass to [`zencreator_create_task`](../tools/generation.md)) with a ready-to-submit `input` object plus tags describing the use case. Recommending a template is usually faster and more reliable than asking the user to fill out a raw tool input from scratch.

There are two ways to find a template:

- **List + filter** — [`zencreator_list_templates`](#zencreator_list_templates), when the user's intent maps to a tool or a tag.
- **Semantic search** — [`zencreator_search_templates`](#zencreator_search_templates), when the user describes what they want in free-form language. This is part of an **optional** subsystem that may not be enabled on every deployment.

Either way, the recommended chain is the same:

> **search / list → `get_template` (or `get_template_card`) → `use_template`**

All tools accept a `response_format` argument (`"markdown"` default, or `"json"`) and always return a full machine-readable `structuredContent` object. List tools use the standard pagination envelope. See [Workflows](../workflows.md) for end-to-end examples.

---

## zencreator_list_templates

Return a paginated list of public generation templates, summary fields only (no `input`/`output` payloads — fetch those with [`zencreator_get_template`](#zencreator_get_template)).

**Parameters**

| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
| `tool_name` | string | no | — | Filter to templates for one generation tool (e.g. `flux`). Use [`zencreator_list_tools`](../tools/generation.md) for valid names. |
| `tags` | string[] | no | — | Filter by tag overlap. Matches against BOTH `tool_tags` (model/tech tags like `flux`, `sdxl`, `kling`) AND `purpose_tags` (use-case tags like `avatar`, `product`, `anime`, `photoreal`, `video`, `lipsync`). Logical OR — any template touching any provided tag is returned. Tags are free-form strings, not a fixed enum. |
| `sort_by` | string | no | `popularity` | One of `default`, `popularity`, `new_first`, `new_first_popularity`. `popularity` surfaces battle-tested presets first; `new_first_popularity` is best when the user wants something fresh. |
| `is_nsfw` | boolean | no | — | Filter by the NSFW flag. Omit unless the user has explicitly opted in to NSFW content. |
| `limit` | number | no | `20` | Page size, 1–100. |
| `offset` | number | no | `0` | Items to skip, ≥0. Prefer offsets that are multiples of `limit` for clean page boundaries. |
| `response_format` | string | no | `markdown` | `markdown` or `json`. |

**Returns** — the standard pagination envelope; each item is a template summary.

```jsonc
{
  "total":  number,
  "count":  number,
  "offset": number,
  "items": [
    {
      "id":           string,       // pass to get_template / use_template
      "name":         string|null,
      "tool_name":    string,       // the generation tool the template drives
      "version":      string,       // template version (NOT tool version)
      "tool_tags":    string[]|null,
      "purpose_tags": string[]|null,
      "uses_count":   number,       // popularity signal
      "likes_count":  number,
      "is_new":       boolean,      // freshly added in the last week
      "is_nsfw":      boolean
    }
  ],
  "has_more":    boolean,
  "next_offset": number   // present only when has_more is true
}
```

To page, pass `next_offset` back as `offset`.

**Errors**

- No matches: returns an empty `items` list (not an error) — relax `tags`, drop `tool_name`, or try [`zencreator_search_templates`](#zencreator_search_templates).
- Unsure which tags exist: call with `sort_by="popularity"` and inspect the tags on the top results to discover live vocabulary.

**Example** — "Show me the most popular anime avatar presets." → the agent calls `zencreator_list_templates` with `tags: ["anime", "avatar"]` and `sort_by: "popularity"`.

---

## zencreator_get_template

Return the full template by id, including the ready-to-submit `input` payload and an example `output`.

The `input` field is a complete payload for the template's `tool_name`. Pass it (optionally merged with user overrides) as `inputs[0]` to [`zencreator_create_task`](../tools/generation.md), or let [`zencreator_use_template`](#zencreator_use_template) do it in one shot. The `output` field is an EXAMPLE of what generation returns — useful for showing the user a reference before they commit credits.

**Parameters**

| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
| `template_id` | string (UUID) | yes | — | Template UUID, e.g. from `zencreator_list_templates` or `zencreator_search_templates`. |
| `response_format` | string | no | `markdown` | `markdown` or `json`. |

**Returns** — the full template:

```jsonc
{
  "id":              string,
  "name":            string|null,
  "tool_name":       string,        // pass to zencreator_create_task
  "version":         string,        // template version, NOT tool version
  "input":           object,        // ready-to-submit payload (see above)
  "output":          unknown,       // example output (asset ids, urls, etc.)
  "tool_tags":       string[]|null,
  "purpose_tags":    string[]|null,
  "uses_count":      number,
  "likes_count":     number,
  "is_liked":        boolean,
  "is_new":          boolean,
  "is_nsfw":         boolean,
  "registered_only": boolean,
  "website_only":    boolean,
  "new_badge_set_at": string|null,
  "trust_access":    string
}
```

**Errors**

- `404` — `template_id` not found, not public, or the user lacks access (NSFW / trusted gating). List with [`zencreator_list_templates`](#zencreator_list_templates) first.
- `401` — an NSFW template was requested by a user whose account has `nsfw_allowed` off. Enable adult content in ZenCreator account settings, then retry.
- Stale version: if the template's `version` is older than the current tool schema, a later `zencreator_create_task` may return `422`. Fall back to [`zencreator_get_tool_schema`](../tools/generation.md) and ask the user which fields to update.

**Example** — "What does template `…` actually do, and what will it cost?" → the agent calls `zencreator_get_template` to inspect the `input`, then [`zencreator_estimate_price`](../tools/generation.md) on that input before confirming the cost.

---

## zencreator_use_template

One-shot: fetch a template, shallow-merge optional overrides into its `input`, submit a single-call generation task with the template's `tool_name`, and bump the template's `uses_count`. This is the "generate me something like THIS" shortcut — prefer it over manually orchestrating `get_template` → `create_task` when the user has picked a template.

What it does, in order:

1. Fetch the template (read its `tool_name` + `input`).
2. Shallow-merge `overrides` over `template.input` (overrides win on top-level keys).
3. Submit a single-call task with `tool_name = template.tool_name`.
4. Increment the template's use counter (best-effort; a failure here does NOT fail the call).
5. Return the task id — poll with [`zencreator_get_task`](../tools/generation.md).

**Overrides are a SHALLOW merge.** Top-level fields in `overrides` REPLACE the matching top-level fields in `template.input`; nested objects are replaced wholesale, not deep-merged. If you need a deep edit, fetch with [`zencreator_get_template`](#zencreator_get_template), edit the input client-side, and call [`zencreator_create_task`](../tools/generation.md) directly.

**This tool is NOT idempotent** — every call creates a new task and spends credits. Confirm with the user before retrying on a transient error, and estimate the cost first (see [Credits](../workflows.md)).

**Parameters**

| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
| `template_id` | string (UUID) | yes | — | Template UUID to run. |
| `overrides` | object | no | — | Top-level fields that REPLACE the matching fields in `template.input`. Shallow merge. Common use: `{ "prompt": "…" }` or `{ "num_images": 4 }`. |
| `comment` | string | no | `via template <name or id>` | Free-form note attached to the task. Max 500 characters. |
| `response_format` | string | no | `markdown` | `markdown` or `json`. |

**Returns**

```jsonc
{
  "template_id":       string,
  "task_id":           string,       // poll with zencreator_get_task
  "tool_name":         string,
  "status":            "created" | "processing" | "partial" | "completed" | "failed",
  "total":             number,
  "done":              number,
  "created_at":        string,
  "comment":           string|null,
  "overrides_applied": string[]      // top-level override keys that were merged
}
```

**Errors**

- `404` (fetch phase) — `template_id` not found / not public / NSFW gated. List with [`zencreator_list_templates`](#zencreator_list_templates).
- `402` (submit phase) — insufficient credits. The error result carries a structured `out_of_credits` signal (`error_code: "insufficient_credits"`, `purchase_url`, `message`). Relay the message and link to the user verbatim, then have them top up at <https://app.zencreator.pro/billing>.
- `422` (submit phase) — the merged input does not satisfy the tool's current `input_schema` (the template version may be stale). Inspect with [`zencreator_get_template`](#zencreator_get_template) + [`zencreator_get_tool_schema`](../tools/generation.md).
- `429` — rate-limited. Back off and retry.

**Example** — "Use that product-photo preset but with my prompt 'matte black headphones on concrete'." → the agent calls `zencreator_use_template` with `overrides: { "prompt": "matte black headphones on concrete" }`, then polls the returned `task_id`.

---

## Optional: template search (not enabled on every deployment)

The three tools below belong to the optional preset-search subsystem. They are only registered when the server is configured for it; on deployments without it, these tools are simply absent from the tool list. Everything above (`list` / `get` / `use`) is always available. If a search tool isn't present, fall back to [`zencreator_list_templates`](#zencreator_list_templates).

These tools read a synthesized catalog directly and bypass the live ZenCreator API. Use them to find and understand templates; then continue with the always-available [`zencreator_get_template`](#zencreator_get_template) / [`zencreator_use_template`](#zencreator_use_template) to submit.

Recommended chain when search is available:

> `search_templates` → `get_template_card` (understand) and/or `get_template` (raw payload) → `use_template` (submit)

---

### zencreator_search_templates

Semantic + keyword hybrid search over the synthesized template catalog. Use this when the user describes what they want in free-form language and the intent is too fuzzy for tag-based filtering with [`zencreator_list_templates`](#zencreator_list_templates).

**Parameters**

| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
| `query` | string | yes | — | Free-form natural-language description of what to produce. |
| `available_inputs` | string[] | no | — | Assets the user already has. Allowed values: `face_photo`, `body_photo`, `image`, `audio_clip`, `video_clip`. Templates whose `input_requirements` aren't satisfied are filtered out (e.g. lipsync templates need `audio_clip`). |
| `output_type` | string | no | inferred from query | Override the auto-detected output type. One of `image`, `image_set`, `video`. |
| `max_nsfw` | string | no | `explicit` | NSFW ceiling. One of `none`, `suggestive`, `explicit`. Lower this if the user hasn't opted into adult content. |
| `top_k` | number | no | `6` | How many top hits to return after rerank, 1–24. |
| `response_format` | string | no | `markdown` | `markdown` or `json`. |

**Returns**

```jsonc
{
  "hits": [
    {
      "template_id":        string,   // pass to get_template / get_template_card / use_template
      "name":               string|null,
      "tool_name":          string|null,  // which generation tool this drives
      "output_type":        string|null,
      "nsfw_level":         "none"|"suggestive"|"explicit",
      "input_requirements": string[],
      "what_it_creates":    string,
      "what_you_provide":   string,
      "best_for":           string,
      "style_tags":         string[],
      "uses_count":         number,
      "previews":           [{ "url": string, "kind": string }],
      "cosine":             number    // raw cosine similarity (0..1, higher = closer)
    }
  ],
  "top_score":            number,      // best cosine in the result set
  "confident":            boolean,     // true iff top cosine is strong enough
  "detected_output_type": string|null,
  "intended_tools":       string[],    // tools the query implies via intent rules
  "requested_acts":       string[],    // adult-act tags the query mentioned (if any)
  "act_coverage":         { "<act>": number }  // how many surviving hits cover each requested act
}
```

When `confident` is `false`, the catalog has no strong match — be honest with the user. Ask a clarifying question or surface the closest one or two hits as approximate rather than overselling weak results.

**Errors**

- Not registered: if the search subsystem isn't configured on this deployment, the tool is absent from the tool list — use [`zencreator_list_templates`](#zencreator_list_templates) instead.
- Empty / weak results: check the index with [`zencreator_search_index_status`](#zencreator_search_index_status), or relax `max_nsfw` / `available_inputs`.

**Example** — "Find me a preset that animates my photo into a short dancing clip." → the agent calls `zencreator_search_templates` with `query: "animate my photo into a short dancing video"` and `available_inputs: ["image"]`.

---

### zencreator_get_template_card

Return one template's synthesized card — the distilled semantic representation used by search. This complements (does NOT replace) [`zencreator_get_template`](#zencreator_get_template), which returns the raw `input`/`output` JSON. Use the card to UNDERSTAND a template before deciding to fetch and submit it.

**Parameters**

| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
| `template_id` | string (UUID) | yes | — | Template / preset UUID. |
| `response_format` | string | no | `markdown` | `markdown` or `json`. |

**Returns**

```jsonc
{
  "template_id":          string,
  "name":                 string|null,
  "tool_name":            string|null,
  "output_type":          string|null,
  "nsfw_level":           "none"|"suggestive"|"explicit",
  "meaning":              string,      // what the preset is, in plain language
  "what_it_creates":      string,
  "what_you_provide":     string,
  "best_for":             string,
  "searchable_paragraph": string,      // longer prose used by the index
  "tags":                 string[],
  "input_requirements":   string[],    // slot names like 'face_photo', 'audio_clip'
  "uses_count":           number,
  "public":               boolean,
  "previews":             [{ "url": string, "kind": string }],
  "status":               "ready"|"described",  // 'described' = present but not yet indexed
  "described_at":         string|null,
  "embedded_at":          string|null
}
```

**Errors**

- `template_id` not in the synthesized catalog (e.g. brand new or never ingested): returns an error result. Fall back to [`zencreator_get_template`](#zencreator_get_template), which reads the live ZenCreator API and always works.
- Not registered: tool absent when the search subsystem isn't configured.

**Example** — "Explain what template `…` does before I run it." → the agent calls `zencreator_get_template_card` to read `meaning`, `what_you_provide`, and `best_for`.

---

### zencreator_search_index_status

Diagnostic. Report the current state of the search index: how many templates are indexed, when it was last refreshed, embedding dimensionality, the configured embedding model, and whether rerank is enabled. Use it when [`zencreator_search_templates`](#zencreator_search_templates) returns weak or empty results to confirm the index has data and is configured as expected.

**Parameters**

| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
| `response_format` | string | no | `markdown` | `markdown` or `json`. |

**Returns**

```jsonc
{
  "n_ready":        number,      // indexed templates (status='ready' AND embedding present)
  "vectors_built":  string|null, // timestamp of the latest 'ready' row's update
  "dim":            number,      // embedding vector dimensionality
  "embed_model":    string,      // configured embedding model (must match the index)
  "rerank_enabled": boolean
}
```

**Errors**

- Not registered: tool absent when the search subsystem isn't configured.

**Example** — "Search keeps coming back empty — is the index actually loaded?" → the agent calls `zencreator_search_index_status` and checks `n_ready` and `vectors_built`.

---

## See also

- [Generation tools](../tools/generation.md) — `zencreator_create_task`, `zencreator_use_template`'s downstream tool, plus `zencreator_estimate_price`, `zencreator_get_tool_schema`, `zencreator_get_task`.
- [Workflows](../workflows.md) — end-to-end examples that wire templates into a full generation flow.
