The production line, programmable
Everything the workspace does — upload, evaluate, improve, download — driven from your own systems over a simple JSON API.
The loop
The API mirrors the workspace: four steps, repeated per book.
Upload
Declare the file, PUT the bytes to a presigned URL, register the publication. Files never route through the API itself.
Run
Start any tool against the publication's working version. The response is a run you poll — sync tools finish on the first poll.
Read
Fetch the run's JSON report: findings, scores, metadata, or the publication-page description.
Download
Repairs and edits append new file versions. Download the working version via a short-lived link.
Authentication
Every request carries a workspace API key as a Bearer token. The key is bound to one workspace: everything you create and read through it lives there, exactly as if you were working in the app.
Keys are issued per workspace and shown once. Self-serve key management is coming to workspace settings; until then, request a key from your publica.la contact.
curl https://origami.publica.la/api/v1/publications \
-H "Authorization: Bearer ${ORIGAMI_API_KEY}" \
-H "Accept: application/json"
Quickstart
Six requests take a book from your disk to a validation report and back. Replace the token and file name; everything else is copy-paste.
1 · Ask for an upload slot
curl -X POST https://origami.publica.la/api/v1/uploads \
-H "Authorization: Bearer ${ORIGAMI_API_KEY}" \
-H "Content-Type: application/json" \
-d '{"original_filename": "book.epub", "size_bytes": 4180294}'
2 · PUT the bytes to the presigned URL
curl -X PUT "UPLOAD_URL_FROM_STEP_1" \
-H "Content-Type: application/epub+zip" \
--data-binary @book.epub
3 · Register the publication
curl -X POST https://origami.publica.la/api/v1/publications \
-H "Authorization: Bearer ${ORIGAMI_API_KEY}" \
-H "Content-Type: application/json" \
-d '{"publication_id": "ID_FROM_STEP_1", "key": "KEY_FROM_STEP_1", "original_filename": "book.epub", "size_bytes": 4180294}'
4 · Run a tool against it
curl -X POST https://origami.publica.la/api/v1/publications/PUBLICATION_ID/runs \
-H "Authorization: Bearer ${ORIGAMI_API_KEY}" \
-H "Content-Type: application/json" \
-d '{"tool": "epub-check"}'
5 · Poll the run, then read the report
curl https://origami.publica.la/api/v1/runs/RUN_ID \
-H "Authorization: Bearer ${ORIGAMI_API_KEY}"
curl https://origami.publica.la/api/v1/runs/RUN_ID/report \
-H "Authorization: Bearer ${ORIGAMI_API_KEY}"
6 · Download the working version
curl https://origami.publica.la/api/v1/publications/PUBLICATION_ID/files/current \
-H "Authorization: Bearer ${ORIGAMI_API_KEY}"
curl -L -o book-improved.epub \
https://origami.publica.la/api/v1/files/FILE_ID/download \
-H "Authorization: Bearer ${ORIGAMI_API_KEY}"
Endpoints
All endpoints live under /api/v1, speak JSON, and answer errors as {error, reason, detail} with a stable machine reason.
Publications & uploads
/api/v1/tools
The tool catalog as the API exposes it, with metering flags.
/api/v1/uploads
Mint a presigned PUT for a new file (30 minutes).
/api/v1/publications
Register an uploaded object as a publication.
/api/v1/publications
List the workspace's publications (cursor pagination).
/api/v1/publications/{id}
One publication: type, status, title, working file.
File versions
/api/v1/publications/{id}/files
The full version history: the immutable original plus every improved copy.
/api/v1/publications/{id}/files/current
The working version — what the next tool run acts on.
/api/v1/files/{id}/download
302 to a short-lived download link for any version.
Tool runs
/api/v1/publications/{id}/runs
Start a tool run (202). Accepts an options object and an Idempotency-Key header.
/api/v1/publications/{id}/runs
List a publication's runs, filterable by tool.
/api/v1/runs/{id}
Run status, timing and error detail.
/api/v1/runs/{id}/report
The finished run's JSON report.
Conventions
Async by default
Runs answer 202 with a resource you poll. A run is terminal at succeeded, failed or rejected.
Idempotency
Send an Idempotency-Key header on POST /runs; a retry returns the original run instead of spending twice.
Pagination
Lists answer {data, next_cursor, has_more}; pass next_cursor back as ?cursor= until has_more is false.
Limits
Requests are throttled per key. Metered tools share your workspace's daily fair-use allowance — a 429 with reason daily_limit_reached means try again tomorrow, and uploads consume the plan's publication allowance.
Descriptions
The description tool returns the publication-page copy: one style (back_cover) with a long version for the page body and a short one for cards and metadata.
Files move directly
Uploads are presigned PUTs and downloads presigned GETs against storage — the API never proxies file bytes, so transfers are fast at any size.
Building an integration?
Tell us what you're automating — bulk ingestion, a DAM hook, a preflight pipeline — and we'll help you wire it.