DeveloperDeveloper API and MCP

Developer API and MCP

Copy page

API keys, the REST API and the MCP server: manage templates and branding and generate PDF documents from your own code or an AI agent.

What you do in the app, you can also do from your own code or from an AI agent. Workflow Documents has a REST API and an MCP server, both on the Developer page. Use them to manage templates, change your branding, read the document history and generate documents.

API keys

On Developer, tab API keys, select Create API key, give it a name and pick the access level:

  • Read only - list and read templates and documents.
  • Read & write - also create, update and delete templates, and generate documents.

The full key is shown once, together with a test request and ready setup commands for AI clients. Store it securely: only a fingerprint of the key is kept, so a lost key is replaced, not recovered. You can have up to 20 active keys and revoke a key at any time. Give each system its own key, so you can revoke one without touching the others.

Send the key as a Bearer token on every request:

text
Authorization: Bearer wdk_your_key_here

REST API

The base URL is shown on the Developer page as REST API base URL. It ends in /api/v1. The examples below use https://shopify.workflow-documents.app/api/v1.

Method Path Purpose
GET /me Check the key and see its level
GET /plan Your plan, allowance, usage of the last 30 days, what is left of it and the PDF retention
GET /templates List templates, without their HTML
POST /templates Create a template from name, resource and html, or from a ready-made one with starter
GET /templates/:id One template with its HTML and CSS
PATCH /templates/:id Change the given fields of a template
DELETE /templates/:id Delete a template
GET /branding Your branding and the fonts it may choose from
PATCH /branding Change the given branding fields
GET /documents The document history, with status, trigger, templateId, q, page and limit as query parameters
POST /documents Generate a document
GET /documents/:id One document. Add ?link=1 for a fresh 7-day download link while the PDF is stored

A quick check that your key works:

bash
curl https://shopify.workflow-documents.app/api/v1/me \
  -H "Authorization: Bearer wdk_your_key_here"

Generate a document

Send the template, by templateId or templateName, and resourceId: the id of the order, product or customer the template renders. A plain number or a Shopify gid both work. language is optional and picks one of the template's languages. Without it the customer's language is used.

bash
curl -X POST https://shopify.workflow-documents.app/api/v1/documents \
  -H "Authorization: Bearer wdk_your_key_here" \
  -H "Content-Type: application/json" \
  -d '{ "templateName": "Invoice", "resourceId": "gid://shopify/Order/1234567890", "language": "de" }'

The PDF is rendered within the request, which takes a few seconds. The answer carries the document with its download link:

json
{
  "document": {
    "id": "1042",
    "filename": "Invoice-1001.pdf",
    "sizeBytes": 48213,
    "url": "https://...",
    "expiresAt": "2026-10-11T09:30:00.000Z",
    "resourceName": "#1001"
  }
}

The link is valid for 7 days. Errors come back with a message and one of these statuses:

Status Meaning
400 The request is incomplete, for example no id for the resource the template renders
402 Your plan's documents for the last 30 days are used up
404 The template, or the order, product or customer, was not found
409 The template is turned off
422 The document could not be generated, for example a template error
429 Rate limit reached, with a retry time
503 A temporary problem. Retry

Create and update templates

A template takes name, resource (order, product or customer), html, and optionally css, filename, paperSize, landscape, marginMm, enabled, description, defaultLocale and branding. To copy a ready-made template, send only starter with one of invoice, packing-slip, product-sheet, customer-summary or blank.

As in the editor, a template is only stored when it renders with sample data. Otherwise the call is refused with the error and the field it belongs to.

branding on a template is the template's own override of colors, fonts and font size. It replaces the stored override as a whole: send an empty object to go back to your brand.

Templates list their added languages in languages. Languages themselves are added and edited in the app.

Branding

PATCH /branding accepts primaryColor, accentColor, textColor, mutedColor, borderColor, headingFont, bodyFont, fontSize, logoWidth, companyName, address, taxId and footerText. Fonts are ids from the fonts list of GET /branding. The logo and custom font files are uploaded in the app.

MCP server

The MCP server lets an AI agent (Claude, Cursor, VS Code, Gemini CLI, OpenAI Codex and others) manage your templates and generate documents. The MCP tab shows the server URL, which ends in /api/mcp, and a connect command per client. After you create a key, the same commands come with the key already filled in.

The tools mirror the REST API:

Tool Access
list_templates, get_template Read
list_documents, get_document Read
get_branding Read
create_template, update_template, delete_template Read & write
update_branding Read & write
generate_document Read & write

A read-only key only gets the read tools.

API and MCP documents count toward your plan

A document generated through the API or MCP counts toward your plan like one from Shopify Flow, and appears in Documents with the source API. A failed document is not counted. Reading templates, documents and branding is free. When your allowance is used up, generating is refused with 402 until the rolling 30-day window frees up or you change to a larger plan. See Plans and pricing.

Rate limits

A leaky bucket per key, the same model Shopify uses: bursts of up to 300 requests, refilling 5 per second. Generating documents has its own bucket of 60, refilling 1 per second. Over the limit you get 429 with a retry time: back off and retry. Limits are the same on every plan.

The API is versioned in the path (/api/v1). A breaking change would ship as /api/v2 with notice.

Next steps