Skip to main content
This is the reference for a headless integration: your backend holds one project API key (ck_live_…), calls Craftkit server-to-server, and gets back a shareable PDF with no embed session and no browser involved. It is written for flows like an offline-first mobile app that reconnects at sign-off and renders a document on the server.
One key is enough. A single project ck_live_ key can render, read templates, poll renders, and create share links for its project — with no per-org provisioning. See Authentication.

The end-to-end flow

1

Confirm the template (once)

Author the charter-handover (or your) template in the dashboard and publish it. Note the slug and read its manifest with GET /v1/templates/:slug so your data keys bind. See Verify before you render.
2

Render server-to-server

POST /v1/templates/:slug/render with your data and an Idempotency-Key header. Craftkit validates against the manifest and enqueues the job. See Render a template.
3

Get the result

Poll GET /v1/renders/:id until succeeded, or receive a webhook. Return downloadUrl to your client, or mint a durable share link.

Requirement coverage

Every capability a backend integration typically asks for, and where it is answered. Available means it works against the current API today; By design means the behavior is intentional and documented; Roadmap means it is not built yet and the workaround is linked.
NeedStatusWhere
A stable, published template reachable by slugAvailableVerify before you render
Read a template’s manifest before rendering (fail fast)AvailableGET /v1/templates/:slug
Bind scalar variables by dot-path (booking.code)AvailableVariables & loops
Iterate an array (areas[]) into a repeating tableAvailable (pipeline-dependent)Render pipelines
Bind a signature / dynamic imageAvailable (pipeline-dependent)Images & signatures
One ck_live_ key renders headlessly, no provisioningBy designAuthentication
Synchronous render (options.sync)By design: not honored — poll insteadRender lifecycle
downloadUrl durability / expiryBy design: permanent public URL (or private download)Render lifecycle
Authoritative status enumBy designRender lifecycle
Re-fetch a render later (offline replay)AvailableGET /v1/renders/:id
Durable, revisitable share linkAvailableSharing
Idempotent renders (dedupe retries)AvailableIdempotency
Render-complete webhook (drop polling)Available (dashboard-configured)Webhooks
Host + namespace for headless callsBy designHosts & environments
Private (non-public-bucket) PDF downloadAvailable (partner-key stream)Download a render
Programmatic template create / publish via APIAvailableCreate a template
Published typed server SDKRoadmap (call the REST API directly)API reference
Render-only / read-only scoped keysRoadmapAuthentication
Presigned / expiring downloadUrlRoadmapRender lifecycle

Worked example

A complete server-to-server render, with idempotency and polling.
# 1. Verify the template exists and read its manifest.
curl https://api.craftkit.dev/v1/templates/charter-handover \
  -H "Authorization: Bearer $CRAFTKIT_API_KEY"

# 2. Render (idempotent on the booking + handover identity).
curl -X POST https://api.craftkit.dev/v1/templates/charter-handover/render \
  -H "Authorization: Bearer $CRAFTKIT_API_KEY" \
  -H "Idempotency-Key: handover-BK-12345-checkout" \
  -H "Content-Type: application/json" \
  -d '{
    "data": {
      "booking": { "code": "BK-12345", "activityName": "Sunset Charter" },
      "handover": { "kind": "checkout", "date": "2026-06-04", "signedBy": "Jane Doe" },
      "areas": [
        { "areaKey": "hull", "condition": "damage", "severity": "cosmetic", "location": "port bow" },
        { "areaKey": "engine", "condition": "ok" }
      ]
    },
    "options": { "filename": "charter-handover-BK-12345.pdf" }
  }'
# → 202 { "id": "…", "status": "queued", "pollUrl": "…/v1/renders/…", "downloadUrl": null }
areas[] is the substance of a handover — confirm the pipeline first. Array iteration and dynamic images only render on the loop-capable pipeline. Read Render pipelines before you commit a template, and note the loop-key rule — a loop key must be a dot-free top-level key, or the array silently validates to empty.

Next

Authentication

What one ck_live_ key can and cannot do.

Render pipelines

Three pipelines, three capability sets — pick the right one.

Idempotency

Make offline-replay retries safe.

Render lifecycle

Sync, status enum, and download durability.