WorkloomDevelopers
v1Get an API key
Reference/Documents, videos and designs

Documents, videos and designs

Documents, videos and designs, made the way the app makes them. Start a document from a team template with its gaps filled, export it as an accessible PDF, apply the video editor’s operations, or start a design. Each runs the app’s own checks, and a problem comes back in words.

Scopes: creative:read to read, creative:write to change.

Endpoints

GET/documents

List documents

Your workspace’s documents. templates=true lists only team templates, the ones POST /documents can start from.

Scope: creative:read
Query parameters
templatesboolean

Only team templates.

qstring

Titles containing this.

Errors
400

invalid_request, unknown_fields, reason_required or unsupported_version.

401

authentication_required or invalid_key.

403

missing_scope, forbidden, seat_inactive or organisation_inactive.

429

rate_limited. Wait Retry-After seconds.

500

internal_error.

List documents
curl "https://api.useworkloom.com/api/public/v1/documents" \
  -H "Authorization: Bearer $WORKLOOM_KEY"
const res = await fetch("https://api.useworkloom.com/api/public/v1/documents", {
  method: "GET",
  headers: {
    Authorization: `Bearer ${process.env.WORKLOOM_KEY}`
  }
});
const data = await res.json();
import os, requests

res = requests.get(
    "https://api.useworkloom.com/api/public/v1/documents",
    headers={"Authorization": f"Bearer {os.environ['WORKLOOM_KEY']}"},
)
data = res.json()
Response
{
  "object": "list",
  "data": [
    {
      "id": "6700a1b2e4b0a1b2c3d4d001",
      "title": "Proposal for [COMPANY]",
      "kind": "proposal",
      "template": true,
      "gaps": 3,
      "updated_at": "2026-10-08T15:20:00.000Z"
    }
  ]
}
200 OKsample
POST/documents

Make a document

From a team template with its gaps filled by fields, or a new one of a kind. It shows in Documents as “Made with the API · key …”.

Scope: creative:writeTakes Idempotency-Key
Header parameters
Idempotency-Keystring

Any unique string, up to 255 characters. Send the same key when you retry and the request runs once; the first answer comes back with Idempotent-Replayed: true. Kept 24 hours.

Body parameters
template_idstring, nullable

A team template (a document marked as a template in Workloom).

kindstring

The kind, when there is no template.

titlestring, nullable

Its title.

fieldsobject

Values for its gaps, by name.

Errors
400

invalid_request, unknown_fields, reason_required or unsupported_version.

401

authentication_required or invalid_key.

403

missing_scope, forbidden, seat_inactive or organisation_inactive.

409

duplicate, conflict or idempotency_key_in_use.

422

idempotency_key_reused.

429

rate_limited. Wait Retry-After seconds.

500

internal_error.

Make a document
curl -X POST "https://api.useworkloom.com/api/public/v1/documents" \
  -H "Authorization: Bearer $WORKLOOM_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: $(uuidgen)" \
  -d '{
  "template_id": "6700a1b2e4b0a1b2c3d4d001",
  "fields": {
    "COMPANY": "Brightline",
    "FIRST NAME": "Priya"
  }
}'
const res = await fetch("https://api.useworkloom.com/api/public/v1/documents", {
  method: "POST",
  headers: {
    Authorization: `Bearer ${process.env.WORKLOOM_KEY}`,
    "Content-Type": "application/json",
    "Idempotency-Key": crypto.randomUUID()
  },
  body: JSON.stringify({
    "template_id": "6700a1b2e4b0a1b2c3d4d001",
    "fields": {
      "COMPANY": "Brightline",
      "FIRST NAME": "Priya"
    }
  })
});
const data = await res.json();
import os, uuid, requests

res = requests.post(
    "https://api.useworkloom.com/api/public/v1/documents",
    headers={"Authorization": f"Bearer {os.environ['WORKLOOM_KEY']}", "Idempotency-Key": str(uuid.uuid4())},
    json={
      "template_id": "6700a1b2e4b0a1b2c3d4d001",
      "fields": {
        "COMPANY": "Brightline",
        "FIRST NAME": "Priya"
      }
    },
)
data = res.json()
Response
{
  "data": {
    "id": "6700a1b2e4b0a1b2c3d4d0a7",
    "title": "Proposal for Brightline",
    "kind": "proposal",
    "gaps_left": [
      "DATE"
    ]
  },
  "livemode": true
}
201 Createdsample
POST/documents/{id}/export

Export a document as PDF

Makes the PDF (accessible by default) and keeps it with the workspace’s PDFs. Returns a link to download it, valid for a few hours.

Scope: creative:write
Path parameters
idstringRequired

The document’s id.

Body parameters
modestring

Accessible (tagged) by default; plain where the document engine is not installed.

Errors
400

invalid_request, unknown_fields, reason_required or unsupported_version.

401

authentication_required or invalid_key.

403

missing_scope, forbidden, seat_inactive or organisation_inactive.

404

not_found.

409

duplicate, conflict or idempotency_key_in_use.

429

rate_limited. Wait Retry-After seconds.

500

internal_error.

Export a document as PDF
curl -X POST "https://api.useworkloom.com/api/public/v1/documents/6700a1b2e4b0a1b2c3d4d001/export" \
  -H "Authorization: Bearer $WORKLOOM_KEY" \
  -H "Content-Type: application/json" \
  -d '{
  "mode": "accessible"
}'
const res = await fetch("https://api.useworkloom.com/api/public/v1/documents/6700a1b2e4b0a1b2c3d4d001/export", {
  method: "POST",
  headers: {
    Authorization: `Bearer ${process.env.WORKLOOM_KEY}`,
    "Content-Type": "application/json"
  },
  body: JSON.stringify({
    "mode": "accessible"
  })
});
const data = await res.json();
import os, requests

res = requests.post(
    "https://api.useworkloom.com/api/public/v1/documents/6700a1b2e4b0a1b2c3d4d001/export",
    headers={"Authorization": f"Bearer {os.environ['WORKLOOM_KEY']}"},
    json={
      "mode": "accessible"
    },
)
data = res.json()
Response
{
  "data": {
    "mode": "accessible",
    "pages": 4,
    "bytes": 182344,
    "url": "https://files.useworkloom.com/pdfs/6700a1b2e4b0a1b2c3d4d0a7.pdf?sig=…",
    "warnings": [],
    "gaps_left": []
  },
  "livemode": true
}
200 OKsample
POST/videos/{id}/edit

Edit a video

Applies the editor’s operations, checked as the editor checks them, and saves a new version, which Workloom renders. A problem comes back as a problem in words; nothing half-applied is saved.

Scope: creative:writeTakes Idempotency-Key
Path parameters
idstringRequired

The video’s id.

Header parameters
Idempotency-Keystring

Any unique string, up to 255 characters. Send the same key when you retry and the request runs once; the first answer comes back with Idempotent-Replayed: true. Kept 24 hours.

Body parameters
opsarray of objectRequired

Operations, for example { "op": "cut", "from": 12.5, "to": 18 } or { "op": "add_text", "at": 0, "end": 3, "kind": "title", "text": "Your rollout plan" }.

base_revisioninteger, nullableRequired

The version you are changing.

Errors
400

invalid_request, unknown_fields, reason_required or unsupported_version.

401

authentication_required or invalid_key.

403

missing_scope, forbidden, seat_inactive or organisation_inactive.

404

not_found.

409

duplicate, conflict or idempotency_key_in_use.

422

idempotency_key_reused.

429

rate_limited. Wait Retry-After seconds.

500

internal_error.

Edit a video
curl -X POST "https://api.useworkloom.com/api/public/v1/videos/6700b2c3e4b0a1b2c3d4b001/edit" \
  -H "Authorization: Bearer $WORKLOOM_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: $(uuidgen)" \
  -d '{
  "ops": [
    {
      "op": "cut",
      "from": 12.5,
      "to": 18
    },
    {
      "op": "add_text",
      "at": 2,
      "end": 6,
      "kind": "title",
      "text": "Rollout plan for Brightline"
    }
  ],
  "base_revision": 3
}'
const res = await fetch("https://api.useworkloom.com/api/public/v1/videos/6700b2c3e4b0a1b2c3d4b001/edit", {
  method: "POST",
  headers: {
    Authorization: `Bearer ${process.env.WORKLOOM_KEY}`,
    "Content-Type": "application/json",
    "Idempotency-Key": crypto.randomUUID()
  },
  body: JSON.stringify({
    "ops": [
      {
        "op": "cut",
        "from": 12.5,
        "to": 18
      },
      {
        "op": "add_text",
        "at": 2,
        "end": 6,
        "kind": "title",
        "text": "Rollout plan for Brightline"
      }
    ],
    "base_revision": 3
  })
});
const data = await res.json();
import os, uuid, requests

res = requests.post(
    "https://api.useworkloom.com/api/public/v1/videos/6700b2c3e4b0a1b2c3d4b001/edit",
    headers={"Authorization": f"Bearer {os.environ['WORKLOOM_KEY']}", "Idempotency-Key": str(uuid.uuid4())},
    json={
      "ops": [
        {
          "op": "cut",
          "from": 12.5,
          "to": 18
        },
        {
          "op": "add_text",
          "at": 2,
          "end": 6,
          "kind": "title",
          "text": "Rollout plan for Brightline"
        }
      ],
      "base_revision": 3
    },
)
data = res.json()
Response
{
  "data": {
    "id": "6700b2c3e4b0a1b2c3d4b001",
    "revision": 4,
    "changes": [
      "Cut 0:12 to 0:18 · 6 s shorter",
      "Added “Rollout plan for Brightline”"
    ],
    "status": "rendering"
  },
  "livemode": true
}
200 OKsample
POST/designs

Make a design

A blank design of a format or size, with a link to open it in Workloom’s image editor.

Scope: creative:writeTakes Idempotency-Key
Header parameters
Idempotency-Keystring

Any unique string, up to 255 characters. Send the same key when you retry and the request runs once; the first answer comes back with Idempotent-Replayed: true. Kept 24 hours.

Body parameters
formatstring, nullable

A format id, for example beam_thumbnail or linkedin_post.

widthinteger, nullable

Width in pixels, 16 to 4096.

heightinteger, nullable

Height in pixels, 16 to 4096.

namestring, nullable

Its name.

Errors
400

invalid_request, unknown_fields, reason_required or unsupported_version.

401

authentication_required or invalid_key.

403

missing_scope, forbidden, seat_inactive or organisation_inactive.

409

duplicate, conflict or idempotency_key_in_use.

422

idempotency_key_reused.

429

rate_limited. Wait Retry-After seconds.

500

internal_error.

Make a design
curl -X POST "https://api.useworkloom.com/api/public/v1/designs" \
  -H "Authorization: Bearer $WORKLOOM_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: $(uuidgen)" \
  -d '{
  "format": "linkedin_post",
  "name": "Brightline case study"
}'
const res = await fetch("https://api.useworkloom.com/api/public/v1/designs", {
  method: "POST",
  headers: {
    Authorization: `Bearer ${process.env.WORKLOOM_KEY}`,
    "Content-Type": "application/json",
    "Idempotency-Key": crypto.randomUUID()
  },
  body: JSON.stringify({
    "format": "linkedin_post",
    "name": "Brightline case study"
  })
});
const data = await res.json();
import os, uuid, requests

res = requests.post(
    "https://api.useworkloom.com/api/public/v1/designs",
    headers={"Authorization": f"Bearer {os.environ['WORKLOOM_KEY']}", "Idempotency-Key": str(uuid.uuid4())},
    json={
      "format": "linkedin_post",
      "name": "Brightline case study"
    },
)
data = res.json()
Response
{
  "data": {
    "id": "6700c3d4e4b0a1b2c3d4c001",
    "name": "Brightline case study",
    "width": 1200,
    "height": 1200,
    "open_url": "https://app.useworkloom.com/designs/6700c3d4e4b0a1b2c3d4c001"
  },
  "livemode": true
}
201 Createdsample

From an AI assistant (MCP)

The same four actions are an MCP server at https://api.useworkloom.com/api/public/v1/mcp (JSON-RPC over HTTP), with the same keys: creative:read to connect, creative:write for a tool that makes or changes something. Its tools are workloom.document.create, workloom.document.export, workloom.video.edit and workloom.design.create; tools/list describes their inputs. A problem comes back as the tool’s result with isError: true and the reason in words.

tools/call
{
  "jsonrpc": "2.0",
  "id": 1,
  "method": "tools/call",
  "params": {
    "name": "workloom.document.create",
    "arguments": {
      "template_id": "6700a1b2e4b0a1b2c3d4d001",
      "fields": {
        "COMPANY": "Brightline"
      }
    }
  }
}
Was this page useful?