Templates
Templates are reusable record sets that you can apply to new or existing zones. Use them to bootstrap common patterns — mail records (MX + SPF + DKIM + DMARC), Google Workspace setup, load-balanced web frontends — without copy-pasting records each time.
Base path: /api/v1/templates/
Required permission: records:create on the target zone
When to use templates
- Standard mail configuration applied to every new customer zone.
- Per-provider setups (Google Workspace, Microsoft 365, Cloudflare front-end) where the record list is well-known.
- Internal zone scaffolding — organizations with strict naming conventions.
- Onboarding automation — your provisioning pipeline applies a template immediately after validation.
List templates
| curl https://scaidns.scailabs.ai/api/v1/templates/ \
-H "X-API-Key: $SCAIDNS_API_KEY"
|
System templates (shipped with the platform) appear alongside custom templates you create. Filter by ?template_type=system or ?template_type=custom if needed.
Template anatomy
A template is a JSON document describing:
- A list of records with placeholders for variables.
- A list of variables that must be provided at apply time.
Example — a minimal mail template:
1
2
3
4
5
6
7
8
9
10
11
12
13 | {
"name": "google-workspace-mail",
"description": "MX, SPF, and DMARC for Google Workspace",
"records": [
{"name": "@", "type": "MX", "content": "1 aspmx.l.google.com.", "ttl": 3600},
{"name": "@", "type": "MX", "content": "5 alt1.aspmx.l.google.com.", "ttl": 3600},
{"name": "@", "type": "TXT", "content": "\"v=spf1 include:_spf.google.com -all\"", "ttl": 3600},
{"name": "_dmarc", "type": "TXT", "content": "\"v=DMARC1; p=quarantine; rua=mailto:${dmarc_contact}\"", "ttl": 3600}
],
"variables": [
{"name": "dmarc_contact", "description": "Email address for DMARC reports", "required": true}
]
}
|
Variables use ${variable_name} syntax in the content field. The template engine substitutes values at apply time.
Built-in variables
Some variables are always available:
| Variable |
Value |
${domain} |
The zone apex name (e.g., example.com) |
${subdomain} |
The subdomain portion if creating on a subdomain zone |
${tenant_slug} |
The tenant's slug |
${tenant_name} |
The tenant's display name |
Retrieve the full list from GET /api/v1/templates/variables.
Create a template
1
2
3
4
5
6
7
8
9
10
11
12
13
14 | curl -X POST https://scaidns.scailabs.ai/api/v1/templates/ \
-H "X-API-Key: $SCAIDNS_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"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 of the web server", "required": true}
]
}'
|
Custom templates are scoped to your tenant. Other tenants don't see them.
Preview before applying
See what records a template would create without making any changes:
| curl -X POST https://scaidns.scailabs.ai/api/v1/templates/$TEMPLATE_ID/preview/$DOMAIN_ID \
-H "X-API-Key: $SCAIDNS_API_KEY" \
-H "Content-Type: application/json" \
-d '{"variables": {"web_ip": "192.0.2.10"}}'
|
Returns the fully-substituted record list:
| {
"records": [
{"name": "example.com", "type": "A", "content": "192.0.2.10", "ttl": 300},
{"name": "www.example.com", "type": "CNAME", "content": "example.com.", "ttl": 300}
]
}
|
Apply a template
| curl -X POST https://scaidns.scailabs.ai/api/v1/templates/ \
-H "X-API-Key: $SCAIDNS_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"template_id": "tpl_abc123",
"domain_id": "d_xyz789",
"variables": {"web_ip": "192.0.2.10"}
}'
|
| resp = httpx.post(
"https://scaidns.scailabs.ai/api/v1/templates/",
headers={"X-API-Key": os.environ["SCAIDNS_API_KEY"]},
json={
"template_id": TEMPLATE_ID,
"domain_id": DOMAIN_ID,
"variables": {"web_ip": "192.0.2.10"},
},
)
result = resp.json()
print(f"Created: {len(result['created_records'])}, skipped: {len(result['skipped_records'])}")
|
1
2
3
4
5
6
7
8
9
10
11
12
13 | const resp = await fetch("https://scaidns.scailabs.ai/api/v1/templates/", {
method: "POST",
headers: {
"X-API-Key": process.env.SCAIDNS_API_KEY!,
"Content-Type": "application/json",
},
body: JSON.stringify({
template_id: templateId,
domain_id: domainId,
variables: { web_ip: "192.0.2.10" },
}),
});
const result = await resp.json();
|
Conflict handling
If a record already exists with the same name/type/content, it's skipped rather than duplicated. The response distinguishes created records from skipped ones:
| {
"created_records": [...],
"skipped_records": [
{"name": "example.com", "type": "A", "reason": "already exists"}
]
}
|
To overwrite, delete the conflicting records first, then apply the template.
Required variables
Check what a template needs before you apply it:
| curl https://scaidns.scailabs.ai/api/v1/templates/$TEMPLATE_ID/required-variables \
-H "X-API-Key: $SCAIDNS_API_KEY"
|
Useful when building UIs or pipelines that apply templates dynamically.
Apply at zone creation
You can apply a template as part of the domain creation call:
| curl -X POST https://scaidns.scailabs.ai/api/v1/domains/ \
-H "X-API-Key: $SCAIDNS_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"name": "customer42.example.com",
"domain_type": "primary",
"template_id": "tpl_standard_customer",
"template_variables": {"web_ip": "192.0.2.42"}
}'
|
Template application is deferred until the zone completes validation — records are created on transition to active.
Update and delete
| # Update metadata / records / variables
curl -X PATCH https://scaidns.scailabs.ai/api/v1/templates/$TEMPLATE_ID \
-H "X-API-Key: $SCAIDNS_API_KEY" \
-H "Content-Type: application/json" \
-d '{"description": "Updated copy"}'
# Delete a custom template
curl -X DELETE https://scaidns.scailabs.ai/api/v1/templates/$TEMPLATE_ID \
-H "X-API-Key: $SCAIDNS_API_KEY"
|
System templates are read-only — you can't edit or delete them.
What's next