Before rendering, confirm the template exists and read its manifest so your data keys bind. Two
canonical, key-authenticated read endpoints make this a fast pre-flight check.
List templates
GET /v1/templates returns every template in your key’s project
with its publish state — lightweight, no manifest.
curl https://api.craftkit.dev/v1/templates \
-H "Authorization: Bearer $CRAFTKIT_API_KEY"
{
"templates": [
{
"id": "…",
"name": "Charter Handover",
"slug": "charter-handover",
"templateType": "document",
"currentVersionNumber": 2,
"published": true,
"createdAt": "2026-05-01T09:00:00.000Z",
"updatedAt": "2026-06-01T12:00:00.000Z"
}
]
}
Read one template’s manifest
GET /v1/templates/:slug returns the template plus its published
manifest and an auto-generated JSON Schema you can use for client-side validation.
curl https://api.craftkit.dev/v1/templates/charter-handover \
-H "Authorization: Bearer $CRAFTKIT_API_KEY"
{
"slug": "charter-handover",
"templateType": "document",
"published": true,
"currentVersionNumber": 2,
"manifest": {
"variables": [
{ "key": "booking.code", "dataType": "text", "required": true },
{ "key": "handover.signedBy", "dataType": "text", "required": true }
],
"loops": [
{ "key": "areas", "label": "Inspection areas",
"itemFields": [
{ "key": "areaKey", "dataType": "text" },
{ "key": "condition", "dataType": "text" }
] }
]
},
"jsonSchema": { "$schema": "http://json-schema.org/draft-07/schema#", "type": "object", "...": "..." }
}
Distinguish “missing” from “unpublished”
| Response | Meaning |
|---|
404 template_not_found | No template with that slug in this key’s project. |
200 with "published": false, "manifest": null | Template exists but has no published version yet. |
200 with a manifest | Ready to render — match your data keys to it. |
Cache the manifest and treat it as a contract. If a render returns invalid_input_data, re-read
the manifest — the published version may have changed which keys or types it expects.