---
title: Templates Reference
path: reference/templates
status: published
---

# Templates Reference

Reusable record sets that can be applied to zones. For the guide, see [Templates](../tutorials/templates.md).

**Base path:** `/api/v1/templates/`

## GET /api/v1/templates/

List templates visible to the caller. Includes both system (shared) and tenant-custom templates.

**Query parameters:**

| Param | Type | Notes |
|-------|------|-------|
| `page`, `page_size` | integer | Standard pagination |
| `template_type` | string | `system` or `custom` |

**Response:**

```json
{
  "data": [
    {
      "id": "tpl_abc123",
      "name": "google-workspace-mail",
      "description": "MX, SPF, and DMARC for Google Workspace",
      "template_type": "custom",
      "record_count": 4,
      "variable_count": 1,
      "created_at": "2026-03-15T14:00:00Z"
    }
  ],
  "total": 12,
  "page": 1,
  "page_size": 50
}
```

## POST /api/v1/templates/

Create a custom template or apply an existing one. The endpoint is overloaded — distinguish by payload shape:

- With `records[]` and `variables[]`: creates a template.
- With `template_id` and `domain_id`: applies the template to a domain.

### Create

**Request:**

```json
{
  "name": "basic-web",
  "description": "Web apex with www CNAME",
  "records": [
    {"name": "@", "type": "A", "content": "${web_ip}", "ttl": 300},
    {"name": "www", "type": "CNAME", "content": "${domain}.", "ttl": 300}
  ],
  "variables": [
    {"name": "web_ip", "description": "Public IP", "required": true}
  ]
}
```

**Response:** Created template.

### Apply

**Request:**

```json
{
  "template_id": "tpl_abc123",
  "domain_id": "d_xyz789",
  "variables": {"web_ip": "192.0.2.10"}
}
```

**Response:**

```json
{
  "created_records": [
    {"id": "r_1", "name": "example.com", "type": "A", "content": "192.0.2.10"}
  ],
  "skipped_records": [],
  "total_created": 1,
  "total_skipped": 0
}
```

## GET /api/v1/templates/{template_id}

Get a single template.

**Response:**

```json
{
  "id": "tpl_abc123",
  "name": "basic-web",
  "description": "Web apex with www CNAME",
  "template_type": "custom",
  "records": [...],
  "variables": [...],
  "created_at": "...",
  "updated_at": "..."
}
```

## PATCH /api/v1/templates/{template_id}

Update a custom template. System templates are read-only.

**Request:** Partial fields — `name`, `description`, `records`, `variables`.

**Response:** Updated template.

## DELETE /api/v1/templates/{template_id}

Delete a custom template.

**Response:** `204 No Content`.

## GET /api/v1/templates/variables

Return built-in variables available in all templates.

**Response:**

```json
{
  "variables": [
    {"name": "domain", "description": "Zone apex name"},
    {"name": "subdomain", "description": "Subdomain portion"},
    {"name": "tenant_slug", "description": "Tenant slug"},
    {"name": "tenant_name", "description": "Tenant display name"}
  ]
}
```

## GET /api/v1/templates/{template_id}/required-variables

Return the variables a specific template requires.

**Response:**

```json
{
  "variables": [
    {"name": "web_ip", "description": "Public IP", "required": true}
  ]
}
```

## POST /api/v1/templates/{template_id}/preview/{domain_id}

Preview the records that would be created without actually creating them.

**Request:**

```json
{"variables": {"web_ip": "192.0.2.10"}}
```

**Response:**

```json
{
  "records": [
    {"name": "example.com", "type": "A", "content": "192.0.2.10", "ttl": 300}
  ]
}
```

## Schemas

### Template

| Field | Type |
|-------|------|
| `id` | string (UUID) |
| `name` | string |
| `description` | string |
| `template_type` | string (`system` or `custom`) |
| `records` | array of record templates (supports `${var}` substitution) |
| `variables` | array of `{name, description, required}` |
| `tenant_id` | string or null (null for system templates) |

## Error codes

| Status | Meaning |
|--------|---------|
| `400` | Malformed template (invalid record, unresolved `${var}`) |
| `403` | Can't modify system template; can't apply without records permission |
| `404` | Template or domain not found |
| `409` | Template name already exists in tenant |
| `422` | Variable value missing or wrong type |

## Related

- [Templates guide](../tutorials/templates.md) — walkthrough.
- [Records reference](./records.md) — record shapes used inside templates.
