> ## Documentation Index
> Fetch the complete documentation index at: https://docs.framelane.io/llms.txt
> Use this file to discover all available pages before exploring further.

# Templates

> Start a project from a template, save a project as one, or swap a template into an open project.

A template is a project used as a copy source: `kind: "template"` on the project. It opens,
edits, previews and renders like any project. Two kinds reach you:

* **Your templates**: projects in your workspace with `kind: "template"`.
* **Public templates**: the gallery, published by Framelane and readable by every workspace.

## Find one

`GET /v1/templates` lists both, newest first. It needs no API key: without one you get the
public gallery, with one `scope` defaults to `all` and each card says `scope: "public"` or
`scope: "workspace"`. Filter with `category`, `q` (matches the name, title or description),
`aspect` (`landscape`, `portrait` or `square`) and `family` (the size variants of one design,
named by each card's `family`); page with `limit` and `cursor`. Over MCP, the
`list_templates` tool takes the same filters.

`GET /v1/templates/{id_or_slug}` returns one card plus its `render_request`, by project id or
by the gallery slug (`stock-montage`), so you can inspect a template before using it.

## Copy one

`POST /v1/projects` with `source_project_id` copies a head into version 1 of a new project.
Element ids are kept. The same call covers three jobs:

| Body | Result | `source_kind` | Default name |
| - | - | - | - |
| `{"source_project_id": "<project>"}` | a duplicate | `project` | `Copy of {name}` |
| `{"source_project_id": "<project>", "kind": "template"}` | a new template | `project` | `{name} Template` |
| `{"source_project_id": "<template>"}` | a project from a template | `template` or `public_template` | the template's name without ` Template` |

Pass `name` to choose your own. `render_request` and `source_project_id` cannot be sent
together (`422`), and a source you cannot read is a `404`. Templates stay out of
`GET /v1/projects` unless you ask for `kind=template` or `kind=all`; rename any project or
template with `PATCH /v1/projects/{id}`.

## Swap one into a project

The `apply_template` op replaces an open project's composition with a template's, as one
versioned edit:

```json theme={null}
{
  "ops": [{ "op": "apply_template", "template_id": "proj_01J8QR2K5VKDGN2T4FBM3CZYX7" }],
  "if_version": 4
}
```

By default (`keep_output_settings: true`) the project keeps its `frame_rate`,
`output_format`, `output_filename`, `alpha`, `webhook_url` and `metadata`, and takes
everything else from the template: canvas, duration, background, elements, transitions,
groups and animations. Set it to `false` to take the template's head whole. The project's
`source_project_id` and `source_kind` then name the template.

## The public gallery

Admin workspaces curate the gallery with `POST`, `PATCH` and `DELETE /v1/templates` (others
get `403 admin_only`); `GET /v1/workspace` answers `is_admin: true` for one. A listing gives
one template project a slug, a title, copy, a category, tags and an order. Publishing
(`status: "published"`) needs every media URL in the composition to be on the shared CDN, so
a public template never points at one workspace's uploads; anything else is a
`422 template_assets_not_shared` that lists the URLs. The composition may not carry a
`webhook_url` either (`422 template_has_webhook`): a copy takes the head as stored, so every
workspace's renders of it would notify that URL. Deleting a listing unpublishes it and leaves
the project in place.

## Thumbnails

A project's `thumbnail_url` is a PNG poster of its head and `thumbnail_version` the head
version it shows, so it is stale while `thumbnail_version` is below `version`. Gallery cards
carry the same `thumbnail_url`. Saving a template and publishing one ask for a thumbnail when
it is missing or stale; to ask yourself, `POST /v1/projects/{id}/thumbnail` answers `202`:

```json theme={null}
{ "job_id": "render_01J8QR2K5VKDGN2T4FBM3CZYX7", "project_version": 4 }
```

The job is a single-frame preview, not billed, at the first moment the contact-sheet planner
picks after zero. Poll it with `GET /v1/renders/{id}` or read the project again. A second call
while one is in flight for the same version returns the same job.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.