API guides
Agent runs
Start an agent run from your own code over the REST API and poll it for the drafts.
An agent, like the Changelog, turns a source into a package of content: an article, social posts, and a video, all drafted together. Your team sets one up in the app and presses Run when there's something worth writing about.
The /v1/agents endpoints let something else press it. A CI job can draft an article when a release ships, or an internal tool can fill a publication on its own schedule. The same actions are in the CLI and the MCP server.
A run creates drafts. Nothing is posted, emailed, or scheduled until someone approves it, in the app or with the publish and approve endpoints.
Agents were called Playbooks when this API launched. The /v1/playbooks endpoints still work and return the same data, with the list under playbooks, but they're deprecated: use /v1/agents. Each agent is identified by its key, like changelog.
See what you can run
Ask what's available rather than hard-coding settings. Each agent describes its own, so a client built from this keeps working as agents change.
curl https://api.paragraph.com/api/v1/agents \
-H "Authorization: Bearer your-api-key"{
"agents": [
{
"key": "changelog",
"name": "Changelog",
"summary": "Turn what your team ships into an article and posts.",
"fields": [
{ "key": "audience", "label": "Audience", "type": "string",
"required": true, "helperText": "Who the articles are written for." }
],
"deliverables": [
{ "key": "article", "label": "Article", "required": false },
{ "key": "x_post", "label": "X posts", "required": false },
{ "key": "newsletter", "label": "Newsletter", "required": false }
],
"installed": false,
"setup": null
}
]
}Set it up
curl -X PUT https://api.paragraph.com/api/v1/agents/changelog \
-H "Authorization: Bearer your-api-key" \
-H "Content-Type: application/json" \
-d '{
"repository": "acme/widget",
"values": { "audience": "Developers evaluating the SDK" },
"deliverables": ["article", "x_post", "linkedin_post"]
}'values is keyed by the field keys from the list above, and is checked the same way the app checks them, so a bad value comes back as a 400 explaining itself.
deliverables is the full list of what the agent makes: one you leave out is turned off, including article, and at least one has to stay on.
repository must be public. A private one needs a GitHub connection made in the app. A repository GitHub doesn't show publicly is refused with a 400, and the setup stays as it was. If GitHub can't be reached or is rate limiting requests, setup returns a 503 without saving changes; try again shortly.
Only what you send changes, and it changes what your team sees in the app. values merge by field key. Sending repository replaces the agent's GitHub source, including a private one connected in the app, so leave it out unless you mean to change it.
Start a run
A run takes several minutes, so this returns as soon as the work is queued.
curl -X POST https://api.paragraph.com/api/v1/agents/changelog/runs \
-H "Authorization: Bearer your-api-key" \
-H "Content-Type: application/json" \
-d '{ "idempotencyKey": "release-2.4.0" }'{ "runId": "0f2c...", "status": "queued" }idempotencyKey is yours to choose. Sending the same one again returns the run you already started rather than starting a second one, so a retried request is safe. Use something stable for the thing you're writing about, like a release tag.
instructions is optional and steers a single run, the same as the note you can add when pressing Run in the app.
Check on it
curl https://api.paragraph.com/api/v1/agents/changelog/runs/0f2c... \
-H "Authorization: Bearer your-api-key"{
"runId": "0f2c...",
"status": "succeeded",
"startedAt": "2026-10-09T09:00:00.000Z",
"finishedAt": "2026-10-09T09:04:12.000Z",
"deliverables": [
{ "export": "article", "item": null, "status": "ready" },
{ "export": "x_post", "item": "1", "status": "ready" }
]
}status is queued or running while it works, then succeeded, completed_with_warnings, failed, blocked, or canceled. Poll every 30 seconds or so; most runs finish in a few minutes.
deliverables fills in as pieces are written, so a run that is still running shows what it has so far.
List recent runs
curl "https://api.paragraph.com/api/v1/agents/changelog/runs?limit=5" \
-H "Authorization: Bearer your-api-key"Launch a run
Once a run has finished, approve its pieces together, the same as Launch on the run in the app:
curl -X POST https://api.paragraph.com/api/v1/agents/changelog/runs/0f2c.../launch \
-H "Authorization: Bearer your-api-key" \
-H "Content-Type: application/json" \
-d '{"start": "launch_now", "timeZone": "America/New_York"}'start picks when they go out:
start | What goes out |
|---|---|
suggested (default) | Each piece at its suggested time |
now | Starting now, with the spacing between them kept |
all_now | Everything now |
launch | The article at its time, with its launch posts |
launch_now | The article and its launch posts now, the rest after |
With no entries, it launches every piece of the run that's waiting for approval and isn't on hold. Pass entries (ids from GET /v1/schedule) to launch only some. The response lists what was approved, what failed and why, and the run's entries as they now stand. Launching counts the same as approving in the app.
Where the drafts go
Everything a run makes lands in the publication's library, under Content in the app. Read it with the content endpoints, and approve what goes out in the app, with a launch, or with the schedule endpoints.