API referenceTemplates

Publish a new immutable template version

Publishes a new immutable version of the template addressed by idOrSlug and assigns it the next sequential version number.

Endpoint
POST https://api.dairo.app/v1/templates/{idOrSlug}/versions

Publishes a new immutable version of the template addressed by idOrSlug and assigns it the next sequential version number. source is required; subject, variables, and notes take the same shapes and limits as template creation, and the source is dry-rendered before storage — a template that cannot render is rejected with 400 and the renderer's error code, and dangerouslySetInnerHTML adds a non-blocking USES_DANGEROUS_HTML warning. promote defaults to true, advancing the template's currentVersion so new default sends use this version immediately; pass promote: false to publish a draft reachable only by an explicit version, leaving currentVersion unchanged. Publishing is capped at 50 per hour with a shared 60-per-minute mutation limit and requires the templates:write scope; a missing or archived template returns 404. Responds 200 (not 201) with the object: "template" and the new version metadata under version.

Scope: templates:write. Send the API key as a bearer token; Scopes lists what each one reaches.

Request

cURL
curl -X POST "https://api.dairo.app/v1/templates/idOrSlug/versions" \
  -H "Authorization: Bearer $DAIRO_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "source": "string"
  }'

Path parameters

NameTypeRequiredDescription
idOrSlugstringyesTemplate UUID or slug.

Body

Required, application/json: TemplateVersionRequest.

FieldTypeRequiredDescription
sourcestringyesReact Email TSX source for the new version.
subjectstringno
variablesTemplateVariableSchemano
promotebooleannoAdvance currentVersion to this version. Defaults to true.
notesstringno

Response

200 Success. Body: application/json, TemplateVersionResponse.

FieldTypeRequiredDescription
templateTemplateyes
versionTemplateVersionyes
warningsarray of stringyes
200
{
  "template": {
    "id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
    "slug": "welcome",
    "name": "Ada Lovelace",
    "description": null,
    "currentVersion": null,
    "status": "string",
    "createdAt": "2026-10-19T09:30:00Z",
    "updatedAt": "2026-10-19T09:30:00Z"
  },
  "version": {
    "version": 0,
    "subject": "Hello from Acme",
    "variables": {},
    "notes": null,
    "createdAt": "2026-10-19T09:30:00Z"
  },
  "warnings": [
    "string"
  ]
}

Errors

Every error has the same body, {"error": {"type", "code", "message", "param"}}; branch on code. Errors lists every code.

StatusMeaning
400The request is malformed or a value is invalid (invalid_request, invalid_domain, idempotency_key_mismatch).
401The API key is missing or invalid.
403The key lacks the scope this endpoint needs (scope_missing) or may not do this (not_permitted).
404No such resource in this account (resource_not_found).
422The request is well-formed but a field failed validation (validation_failed).
429Rate limit, plan limit, budget or spend cap reached (rate_limited, plan_limit_reached, budget_exceeded, spend_cap_reached).
500An unexpected error; retry with backoff, then contact support (internal_error).

On this page