Documentation
Print your first document
Composa prints documents from a template. Your AI agent designs the template over MCP, you look it over in the editor, and your code prints one copy — or five hundred — per HTTP call, each with its own data.
Connect your agent
Add Composa’s MCP server to your agent. In Claude Code:
claude mcp add --transport http --scope user composa https://mcp.composa.dev/mcpThe first time it connects, your browser opens: sign in to Composa (or create an account), choose the team, and Allow. There is no key to paste. Cursor, VS Code, Codex, Claude Desktop and any other MCP client: MCP server → Connect.
Design a template
Ask your agent for the document, and name what changes from one copy to the next:
Make a one-page A4 certificate in Composa. The recipient's name and the course
change per copy: make them variables called customer_name and course.It answers with a link to the editor, where you watch the page being built and can change anything by hand. A variable prints as {{customer_name}} until your data fills it. When it looks right, ask the agent to publish it — or press Publish in the editor. The API prints the published version, never the draft you are still editing.
The project’s id is in its editor link, /typeset/<project id>, and in the agent’s list_projects. That id is the template_id below.
Create an API key
Open Press Room → API keys, name the key after where it will live (“billing server”), and copy it: it is shown once. Keep it on your server, never in a browser or an app.
export COMPOSA_API_KEY="cmp_live_…"Print it
One call, one document. The answer is the PDF itself:
curl -X POST https://composa.dev/api/v1/run \
-H "Authorization: Bearer $COMPOSA_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"template_id": "YOUR_PROJECT_ID",
"data": { "customer_name": "Alice Moreau", "course": "Typography I" }
}' \
--fail-with-body --output certificate.pdfA name you send that the template does not have is ignored; one you leave out prints the sample the template was designed with. Every field, format and answer: HTTP API.
Print many at once
Send items instead of data and each item becomes its own document, returned together as JSON (base64):
{
"template_id": "YOUR_PROJECT_ID",
"items": [
{ "name": "alice", "data": { "customer_name": "Alice Moreau" } },
{ "name": "bruno", "data": { "customer_name": "Bruno Lima" } }
]
}- Up to 500 items per call.
- An item that fails carries its own
error; the others still print, and the call answers 200. - Ask for compression (
curl --compressed,Accept-Encoding: gzip): copies of one template compress very well.