The Foldkit partner API. Server-to-server, authenticated with a secret API key (`Authorization: Bearer sk_live_…`). Every response is scoped to the tenant the key belongs to; a resource belonging to another tenant is indistinguishable from one that does not exist, so every denial is a 404.
Point a Swagger UI, a Postman import or your language’s codegen at the spec. It carries the security scheme, so “Authorize” with a sandbox key lets you exercise the whole API from the browser.
Paging
List endpoints are cursor-paged. Pass limit (1–200, default 50) and follow nextCursor until it is null. The cursor is opaque — it encodes a keyset position, not an offset, so a page cannot skip or repeat a row when something is created while you are reading.
let cursor = null
do {
const page = await foldkit.designs.list({ limit: 100, cursor })
for (const design of page.items) process(design)
cursor = page.nextCursor
} while (cursor)
Operations
designs
Operation
What it does
Scopes
GET /v1/designs
List designs (active only unless includeArchived is set)
designs:read
POST /v1/designs
Create a design from a style, a template, or a document
designs:write
GET /v1/designs/{id}
Get a design
designs:read
PATCH /v1/designs/{id}
Rename a design or re-attribute it to an end-user
designs:write
DELETE /v1/designs/{id}
Delete a design and its version history
designs:write
GET /v1/designs/{id}/versions
List a design's version history
designs:read
GET /v1/designs/{id}/preview.png
Server-rendered PNG of a design’s flat dieline with artworkA PNG of the **flat dieline with the artwork on it** — a print-shop proof, not a photorealistic folded carton. Rendered once per (design version, width) and cached, so a handful of sizes costs a handful of renders for the life of the version. Send the previous response’s `ETag` back as `If-None-Match` to get a `304` without a render.
designs:read
exports
Operation
What it does
Scopes
POST /v1/designs/{id}/exports
Enqueue an export of a design
designs:read, exports:write
GET /v1/exports
List export jobs
exports:read
GET /v1/exports/{id}
Get an export job, with a download URL once it completes
exports:read
assets
Operation
What it does
Scopes
POST /v1/assets
Presign an artwork upload
assets:write
POST /v1/assets/{id}/confirm
Confirm an upload and run the ingest pipeline
assets:write
GET /v1/assets/{id}
Get an asset
assets:read
catalog
Operation
What it does
Scopes
GET /v1/styles
List the box styles this tenant may offer
templates:read
GET /v1/templates
List this tenant's starter templates
templates:read
GET /v1/quotes
List quote requests captured in this tenant's embeds
quotes:read
usage
Operation
What it does
Scopes
GET /v1/usage
Metered usage for a billing period
usage:read
webhooks
Operation
What it does
Scopes
GET /v1/webhooks
List webhook endpoints
webhooks:manage
POST /v1/webhooks
Create a webhook endpoint (returns the signing secret once)
webhooks:manage
PATCH /v1/webhooks/{id}
Update, pause or resume a webhook endpoint
webhooks:manage
DELETE /v1/webhooks/{id}
Delete a webhook endpoint
webhooks:manage
POST /v1/webhooks/{id}/test
Send a synthetic delivery so a partner can prove their endpoint
webhooks:manage
POST /v1/webhooks/{id}/rotate-secret
Rotate an endpoint signing secret, with an overlap window
webhooks:manage
GET /v1/webhook-deliveries
List webhook deliveries
webhooks:manage
POST /v1/webhook-deliveries/{id}/replay
Re-send a delivery as a new delivery with a new id
webhooks:manage
What is not in the spec
Two routes exist that the generated document does not describe, and both omissions are deliberate.
GET /exports/:id/stream — a server-sent event stream of export progress. OpenAPI cannot model an open stream, so it is documented in prose rather than misdescribed as a request/response. Polling GET /v1/exports/:id carries identical progress and is the supported fallback.
/sandbox/echo/:bucket — the webhook echo. It sits outside /v1 because it takes no credential: our own dispatcher is the caller, and a webhook receiver that demanded an API key could not be a webhook receiver.
Headers
Header
Direction
Meaning
X-Request-Id
Both
Echoed back if you send one, minted if you do not. Quote it to support.
X-RateLimit-Limit
Response
Requests permitted in the current window.
Retry-After
Response
Seconds to wait, on a 429.
ETag
Response
On preview.png. Send it back as If-None-Match for a 304.
Foldkit-Version and an idempotency-key header are accepted and not yet honoured. They are declared so an SDK can send them from day one; today they are inert, and we would rather say so than have you rely on behaviour that is not there.