---
title: "Create template"
method: POST
path: "/v1/templates"
tags: ["Templates"]
---

# Create template

`POST /v1/templates`

## Request

- Base URL: `https://api.briefgate.dev`
- URL: `https://api.briefgate.dev/v1/templates`
- Auth: HTTP bearer

Save a custom intake template: a reusable set of item definitions plus, optionally, every other create-intake setting (`settings`) applied as defaults when an intake is created from it. Requires a logged-in dashboard session (an API key alone cannot call this) and Solo plan or above — `402 plan_required` on Free. The slug used in `template` on POST /v1/intakes is derived from `name`, not supplied here.

## Request body

- CreateTemplate
  - `name` string, required
  - `description` string
  - `language` 'cs' | 'en' | 'de'
  - `items` object[], required
    - `key` string, required
    - `type` 'text' | 'longtext' | 'file' | 'file_list' | 'image' | 'color_list' | 'select' | 'multiselect' | 'boolean' | 'url' | 'secret' | 'structured', required
    - `assignee` 'client' | 'owner'
    - `label` string, required
    - `help` string
    - `required` boolean
    - `constraints` object
      - `formats` string[]
      - `min_width` integer
      - `min_height` integer
      - `max_width` integer
      - `max_height` integer
      - `max_bytes` integer
      - `min_chars` integer
      - `max_chars` integer
      - `min_count` integer
      - `max_count` integer
      - `transparent_background` boolean
    - `schema` object
    - `options` object[]
      - `value` string, required
      - `label` string, required
    - `pattern` string
    - `proposed` object
      - `value` union, required
        - string
        - string[]
      - `rationale` string
  - `settings` object
    - `due_in_days` integer
    - `chase_schedule` 'default' | 'gentle' | 'aggressive' | 'custom' | 'off'
    - `chase_interval` integer
    - `chase_interval_unit` 'minutes' | 'hours' | 'days'
    - `respect_quiet_hours` boolean
    - `max_reminders` union
      - integer
      - 'unlimited'
    - `chase_at_time` string
    - `email_copy` object
      - `invite_subject` string
      - `invite_intro` string
      - `reminder_subject` string
      - `reminder_intro` string
    - `auto_approve_hours` integer
    - `retention` object
      - `mode` 'days' | 'on_delivery'
      - `days` integer
      - `anonymize` boolean
    - `branding` object
      - `logo_url` string, uri
      - `accent_color` string
      - `sender_name` string
      - `reply_to` string, email
    - `folder_id` string
    - `client_brief` string

## Response `201`

Template created

- object
  - `template` object
    - `id` string, required
    - `accountId` string, nullable, required: null for the three built-in public templates.
    - `slug` string, required: Derived from `name` on creation; use this in `template` on POST /v1/intakes.
    - `name` string, required
    - `description` string, nullable
    - `language` 'cs' | 'en' | 'de', required
    - `items` object[], required: Item definitions, same shape as `items` on POST /v1/intakes.
    - `settings` object, nullable, required: Defaults applied when an intake is created from this template. null for templates that only pin down items.
      - `due_in_days` integer
      - `chase_schedule` 'default' | 'gentle' | 'aggressive' | 'custom' | 'off'
      - `chase_interval` integer
      - `chase_interval_unit` 'minutes' | 'hours' | 'days'
      - `respect_quiet_hours` boolean
      - `max_reminders` union
        - integer
        - 'unlimited'
      - `chase_at_time` string
      - `email_copy` object
        - `invite_subject` string
        - `invite_intro` string
        - `reminder_subject` string
        - `reminder_intro` string
      - `auto_approve_hours` integer
      - `retention` object
        - `mode` 'days' | 'on_delivery'
        - `days` integer
        - `anonymize` boolean
      - `branding` object
        - `logo_url` string, uri
        - `accent_color` string
        - `sender_name` string
        - `reply_to` string, email
      - `folder_id` string
      - `client_brief` string
    - `isPublic` boolean, required
    - `createdAt` string, date-time, required

## Other responses

- `400`: Invalid request — malformed body or query parameters
- `401`: Missing or invalid API key
- `402`: Plan upgrade required
- `409`: A template with the slug derived from `name` already exists in this account.
- `422`: Validation error — the body shape is correct but values are invalid

---

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