---
title: "Resolve a template into a ready-to-use outline"
method: POST
path: "/templates/apply"
tags: ["Templates"]
---

# Resolve a template into a ready-to-use outline

`POST /templates/apply`

## Request

- Base URL: `https://next.frase.io/api/v1`
- URL: `https://next.frase.io/api/v1/templates/apply`
- Auth: API key in header `X-API-KEY`

Loads one of your templates and returns it resolved into the shape the brief-creation and playbook flows consume: the outline sections mapped to outline entries (each tagged `source: "template"`), the template's field defaults, and its boilerplate blocks. Requires the `read:content` scope. Read-only — nothing is created or modified.

The lookup is organization-scoped and skips soft-deleted rows, and a template that exists but is disabled is refused as well; both refusals come back as 404 in the plain `{ "data": { "error": ... } }` envelope with the reason in `error` (`Template not found` / `This template is currently disabled`). Note the response does not carry the template's `content_type`.

The three payload keys are snake_case, but the objects inside them keep the stored camelCase field names.

## Request body

- object
  - `template_id` string, uuid, required: Required. The template to apply. Must be a UUID.

## Response `200`

The resolved template

- object
  - `data` object
    - `outline` object[]: The template's sections mapped to outline entries. Empty array when the template stores no sections.
      - `heading` string
      - `level` integer
      - `keyPoints` string[]
      - `suggestedWordCount` integer
      - `generationMode` 'ai' | 'manual': Defaults to `ai` when the section does not set one.
      - `isRequired` boolean: Defaults to true when the section does not set one.
      - `source` 'template': Always `template` on this path.
    - `field_defaults` TemplateFieldDefaults: Default field values applied when the template is used.
      - `targetWordCount` integer: Default target word count
      - `metaTitleFormat` string: Default meta title format
      - `suggestedTone` string: Default suggested tone
      - `targetLanguage` string: Default target language
      - `targetCountry` string: Default target country
    - `boilerplate_blocks` BoilerplateBlock[]: The template's boilerplate blocks, or `[]` when it has none.
      - `id` string, required: Unique identifier for the block
      - `position` 'before_section' | 'after_section' | 'header' | 'footer', required: Where to insert the block
      - `anchorSectionHeading` string: Section heading to anchor to (for before_section/after_section positions)
      - `content` string, required: The boilerplate content (max 50,000 characters)
      - `label` string, required: Display label for the block

## Other responses

- `400`: Validation failed
- `401`: Authentication failed
- `403`: The API key lacks the `read:content` scope (`insufficient_scope`), the caller's IP is not allow-listed (`ip_not_allowed`), or the organization's subscription/trial is no longer active.
- `404`: The template does not exist, is soft-deleted, belongs to another organization, or is disabled. Returned in the plain `{ "data": { "error": ... } }` envelope, not the structured error object.
- `429`: Rate limit exceeded
- `500`: Unhandled failure, including a malformed/non-JSON request body.

---

[API](https://skmtc.dev/frase/apis/frase-api.md) · [All operations](https://skmtc.dev/frase/apis/frase-api/llms.txt) · [OpenAPI document](https://skmtc.dev/frase/apis/frase-api/revisions/7fb75d89f7a4?raw)
