Skip to main content
POST
/
v1
/
templates
Create a template
curl --request POST \
  --url https://api.craftkit.dev/v1/templates \
  --header 'Authorization: Bearer <token>' \
  --header 'Content-Type: application/json' \
  --data '
{
  "name": "Invoice",
  "slug": "invoice",
  "description": "Standard customer invoice",
  "manifest": {
    "variables": [
      {
        "key": "customer.name",
        "label": "Customer name",
        "dataType": "text",
        "required": true
      }
    ],
    "loops": []
  },
  "pageConfig": {
    "format": "A4",
    "orientation": "portrait",
    "margin": "20mm",
    "printBackground": true
  }
}
'
{
  "id": "7c9f0b2e-2b1a-4f3d-9c8e-1a2b3c4d5e6f",
  "slug": "invoice",
  "currentVersionNumber": 1,
  "manifest": {
    "variables": [
      {
        "key": "customer.name",
        "label": "Customer name",
        "dataType": "text",
        "required": true
      }
    ],
    "loops": []
  }
}

Authorizations

Authorization
string
header
required

Project API key (ck_live_… or ck_test_…) presented as a bearer token. For embed partner endpoints this is the partner secret key, which is the same credential type.

Body

application/json

Create/upsert body. manifest and pageConfig are validated against the shared schema package; layout is an optional explicit CanvasDocument.

name
string
required
Required string length: 1 - 120
manifest
object
required
slug
string

Optional on create (auto-derived from name); ignored by PUT (URL is canonical).

Maximum string length: 120
Pattern: ^[a-z0-9]+(?:-[a-z0-9]+)*$
description
string
Maximum string length: 280
layout
object

Optional CanvasDocument contentJson; synthesized from the manifest when omitted.

pageConfig
object

Response

Template created and version 1 published.

id
string<uuid>
required
slug
string
required
currentVersionNumber
integer
required
manifest
object
required