> For clean Markdown of any page, append .md to the page URL.
> For a complete documentation index, see https://docs.lumenia.net/llms.txt.
> For AI client integration (Claude Code, Cursor, etc.), connect to the MCP server at https://docs.lumenia.net/_mcp/server.

# Prompt templates

A **prompt template** is a reusable prompt owned by your company (the partner) — it lives above accounts and organizations. You write the prompt once, with `{{placeholders}}` for the parts that differ per customer, publish it as an immutable **version**, and **assign** that version to any workspace under your key. Each workspace supplies its own variable values, and the prompt is rendered from the template at request time. To roll out a change, create and publish a new version, then assign it to the workspaces that should use it.

Because templates are partner-level, the template routes take **no `X-Account-Id` header** — the API key alone identifies the owner. The assignment routes act on a workspace, so those keep the header as usual.

## Templates and versions

A template is a named container; the content lives in its versions:

| Resource                                                                                                  | What it holds                                                                                                                                                           |
| --------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| **Template** — `/v1/prompt-templates`                                                                     | `name` (unique per partner), `description`, and `type`: `chat` or `voice`. The type is **immutable** — it decides which workspace slot the template can be assigned to. |
| **Version** — `/v1/prompt-templates/{templateId}/versions` and `/v1/prompt-template-versions/{versionId}` | The actual content: `prompt`, `firstMessage` (voice templates only — the spoken greeting), the **variable definitions**, and referenced **tools**.                      |

A `chat` template drives a workspace's base system prompt (what `chat.prompt` does manually); a `voice` template drives the voice assistant's spoken prompt **and** its first message (what `voice.prompt` / `voice.firstMessage` do manually). See [the two prompts](/documentation/core-concepts/workspaces#the-two-prompts) for what each governs.

## Version lifecycle

| Status      | Meaning                                                                                                             |
| ----------- | ------------------------------------------------------------------------------------------------------------------- |
| `draft`     | Editable via `PATCH /v1/prompt-template-versions/{versionId}`. Not assignable yet.                                  |
| `published` | Assignable to workspaces and **immutable** from then on.                                                            |
| `archived`  | No **new** assignments — but workspaces already pinned to it keep working. Archiving never breaks a live workspace. |

How versions move through it:

* Creating a template (`POST /v1/prompt-templates`) creates **version 1 as a draft** in the same call.
* A template holds at most **one draft at a time**. Creating another while a draft exists returns `409` with the existing `draftVersionId` — edit or publish that draft instead.
* `POST /v1/prompt-template-versions/{versionId}/publish` makes a draft live. Publishing validates the version (see below).
* To iterate on a published prompt, create the **next** version: `POST /v1/prompt-templates/{templateId}/versions` duplicates the latest published version (or an explicit `sourceVersionId`, which may be published or archived) into a new draft. Version numbers are assigned automatically.
* `POST /v1/prompt-template-versions/{versionId}/archive` retires a published version. Archived versions cannot be restored, but they can still be duplicated into a new draft.

Workspaces are pinned to a **specific version**, never "latest" — publishing a new version changes nothing until you re-assign workspaces to it, so rollouts are explicit and roll back by re-pinning the previous version.

## Variables

Placeholders use double braces — `{{company}}` — and every placeholder must be backed by a **variable definition** on the version:

| Field          | What it is                                                    |
| -------------- | ------------------------------------------------------------- |
| `key`          | The placeholder name (`{{key}}`).                             |
| `description`  | What the value means — shown to whoever fills it in.          |
| `type`         | `string`, `number`, or `boolean`.                             |
| `required`     | Whether every workspace assignment must supply a value.       |
| `defaultValue` | Used when a non-required variable is not supplied.            |
| `validation`   | Optional constraints: `enum`, `pattern` (regex), `min`/`max`. |

Publishing enforces three rules, so a published version always renders completely:

1. The `prompt` is not empty.
2. Every `{{placeholder}}` used in the prompt or `firstMessage` has a variable definition.
3. Every variable is either `required` or has a `defaultValue` — an optional variable with no default could otherwise render as an empty string mid-sentence.

> **Info**
>
> Template placeholders are written **without spaces** (`{{company}}`) and are rendered server-side when the workspace's prompt is built. They are unrelated to the Liquid aliases of [tools](/documentation/core-concepts/tools#using-a-tools-response-in-the-prompt), which are written with spaces (`{{ orderStatus }}`) and are substituted live during the conversation — a template can contain both.

## Assigning a version to a workspace

A workspace has one template slot per channel — `chat` and `voice`:

```
PUT    /v1/workspaces/{workspaceId}/prompt-templates/{chat|voice}   # pin { versionId, variables }
PATCH  /v1/workspaces/{workspaceId}/prompt-templates/{chat|voice}   # replace the variable values
DELETE /v1/workspaces/{workspaceId}/prompt-templates/{chat|voice}   # unassign
```

* Only **published** versions can be pinned (and the version's template `type` must match the slot). The supplied `variables` are validated against the version's definitions — every required variable needs a value, and types/`validation` constraints are checked.
* While a template is assigned, it **wins** over the manual prompt: the workspace's `chat.prompt` (or `voice.prompt`/`voice.firstMessage`) becomes the fallback used only after you unassign. The manual fields keep their stored values and stay editable throughout.
* The workspace detail and the voice integration read back `promptSource` (`template` or `manual`) and a `promptTemplate` object per channel describing the pinned version and values. Add `?includeRendered=true` to `GET /v1/workspaces/{workspaceId}` or the voice integration GET to also receive the fully rendered `renderedPrompt`/`renderedFirstMessage`.
* A **voice** template can be assigned before the workspace has a [voice integration](/documentation/core-concepts/voice-integration); it lies dormant and takes effect as soon as the integration is created.

A template cannot be deleted while any workspace is pinned to one of its versions — unassign everywhere first.

## Template tools

A version can reference **partner tools** — tools owned by your company rather than by one organization (`GET`/`POST /v1/tools`, no `X-Account-Id`). Assigning the version to a workspace brings those tools along:

* A workspace's effective tool set is the **union** of its directly attached tools and the pinned versions' tools. Inspect it with `GET /v1/workspaces/{workspaceId}/tools/effective` (optionally `?mode=chat|voice`), which also reports any name **shadowing** — on a name collision, a directly attached tool overrides a template-provided one.
* To keep published versions dependable, a tool referenced by a published version (or by an archived version still pinned somewhere) cannot be **renamed or deleted** — but its URL, headers, and schemas stay editable, so rotating a credential never requires republishing.