Developer reference
API reference
Read and write Rendra documents from any agent, CLI, or backend. Bearer-token auth, JSON in, JSON out — the same endpoints the app itself uses.
Authentication
Every request carries an Authorization header with a personal access token. Tokens are scoped to a single workspace and carry one or both of these scopes:
docs:read— list, get, search, PDF.docs:write— create, update, delete.
Authorization: Bearer rendra_YOUR_TOKEN_HERE/api/v1/workspaceGet the active workspace
Whoami + handshake. Call this first from an agent to confirm it's connected to the right workspace.
Requires scope: docs:read
Example request
curl https://app.rendra.dev/api/v1/workspace \
-H "Authorization: Bearer rendra_YOUR_TOKEN_HERE"Example response
{
"workspace": {
"slug": "acme",
"name": "Acme",
"plan": "pro",
"createdAt": "2026-01-04T10:22:11.000Z"
},
"docs": {
"total": 42,
"published": 18
},
"auth": {
"kind": "token",
"scopes": [
"docs:read",
"docs:write"
]
}
}Error responses
| Status | Meaning |
|---|---|
| 401 | Missing, malformed, or revoked token. |
| 403 | Token lacks the required scope. |
| 500 | Unexpected server error. |
| 404 | Workspace not found. |
/api/v1/documentsList documents
Returns a page of document summaries (no `html` body — fetch one doc for that).
Requires scope: docs:read
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
| status | query | string | no | active (default) | all | draft | review | published | archived |
| type | query | string | no | guide | playbook | policy | runbook | brief | spec |
| collection | query | string | no | Exact match on collection name. |
| favorite | query | string | no | Pass `1` or `true` to only return favorites. |
| limit | query | integer | no | 1..200 (default 50). |
| offset | query | integer | no | 0..10000 (default 0). |
Example request
curl https://app.rendra.dev/api/v1/documents \
-H "Authorization: Bearer rendra_YOUR_TOKEN_HERE"Example response
{
"documents": [
{
"slug": "onboarding-playbook",
"title": "Onboarding Playbook",
"status": "published",
"docType": "playbook",
"collection": "People ops",
"tags": [
"hiring"
],
"updatedAt": "2026-04-01T09:12:33.000Z"
}
],
"pagination": {
"limit": 50,
"offset": 0,
"returned": 1
}
}Error responses
| Status | Meaning |
|---|---|
| 401 | Missing, malformed, or revoked token. |
| 403 | Token lacks the required scope. |
| 500 | Unexpected server error. |
/api/v1/documentsCreate a document
Creates a new document from raw HTML. Rendra normalizes the markup, computes stats, and generates a collision-free slug from the title.
Requires scope: docs:write
Request body (application/json)
{
"title": "Onboarding Playbook",
"subtitle": "Ship a new hire in week one",
"html": "<h1>Welcome</h1><p>Day one...</p>",
"status": "draft",
"docType": "playbook",
"collection": "People ops",
"tags": [
"hiring",
"week-one"
]
}Example request
curl -X POST https://app.rendra.dev/api/v1/documents \
-H "Authorization: Bearer rendra_YOUR_TOKEN_HERE" \
-H "Content-Type: application/json" \
-d '{ "title": "Onboarding Playbook", "subtitle": "Ship a new hire in week one", "html": "<h1>Welcome</h1><p>Day one...</p>", "status": "draft", "docType": "playbook", "collection": "People ops", "tags": [ "hiring", "week-one" ]}'Example response
{
"document": {
"slug": "onboarding-playbook",
"title": "Onboarding Playbook",
"status": "draft",
"docType": "playbook",
"html": "<h1>Welcome</h1><p>Day one...</p>",
"createdAt": "2026-04-17T08:00:00.000Z",
"updatedAt": "2026-04-17T08:00:00.000Z"
}
}Error responses
| Status | Meaning |
|---|---|
| 400 | Invalid JSON body or validation error. |
| 401 | Missing, malformed, or revoked token. |
| 403 | Token lacks the required scope. |
| 500 | Unexpected server error. |
| 402 | Free plan document cap reached (10 docs). Upgrade to Pro to create more. |
/api/v1/documents/{slug}Get one document
Returns the full document, including the HTML body.
Requires scope: docs:read
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
| slug | path | string | yes | Document slug (unique within the workspace). |
Example request
curl https://app.rendra.dev/api/v1/documents/onboarding-playbook \
-H "Authorization: Bearer rendra_YOUR_TOKEN_HERE"Example response
{
"document": {
"slug": "onboarding-playbook",
"title": "Onboarding Playbook",
"status": "published",
"html": "<h1>Welcome</h1><p>...</p>"
}
}Error responses
| Status | Meaning |
|---|---|
| 401 | Missing, malformed, or revoked token. |
| 403 | Token lacks the required scope. |
| 500 | Unexpected server error. |
| 404 | No document with that slug. |
/api/v1/documents/{slug}Update a document
Partial update — send only the fields you want to change. Status changes are gated by the state machine; invalid transitions return 409. Changing the title regenerates the slug.
Requires scope: docs:write
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
| slug | path | string | yes | Current document slug. |
Request body (application/json)
{
"status": "published",
"tags": [
"hiring",
"week-one",
"people-ops"
]
}Example request
curl -X PATCH https://app.rendra.dev/api/v1/documents/onboarding-playbook \
-H "Authorization: Bearer rendra_YOUR_TOKEN_HERE" \
-H "Content-Type: application/json" \
-d '{ "status": "published", "tags": [ "hiring", "week-one", "people-ops" ]}'Example response
{
"document": {
"slug": "onboarding-playbook",
"status": "published",
"lastReviewedAt": "2026-04-17"
}
}Error responses
| Status | Meaning |
|---|---|
| 400 | Invalid JSON body or validation error. |
| 401 | Missing, malformed, or revoked token. |
| 403 | Token lacks the required scope. |
| 500 | Unexpected server error. |
| 404 | No document with that slug. |
| 409 | Invalid status transition (see state machine above). |
/api/v1/documents/{slug}Delete a document
Hard-deletes the document. Irreversible.
Requires scope: docs:write
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
| slug | path | string | yes | Document slug. |
Example request
curl -X DELETE https://app.rendra.dev/api/v1/documents/onboarding-playbook \
-H "Authorization: Bearer rendra_YOUR_TOKEN_HERE"Example response
(empty body — 204 No Content)Error responses
| Status | Meaning |
|---|---|
| 401 | Missing, malformed, or revoked token. |
| 403 | Token lacks the required scope. |
| 500 | Unexpected server error. |
| 404 | No document with that slug. |
/api/v1/documents/{slug}/pdfGet print-ready HTML
Returns a self-contained HTML page styled for A4. In a browser, it auto-invokes window.print(). Send Accept: application/pdf to skip the auto-print (useful when piping to a headless browser).
Requires scope: docs:read
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
| slug | path | string | yes | Document slug. |
Example request
curl https://app.rendra.dev/api/v1/documents/onboarding-playbook/pdf \
-H "Authorization: Bearer rendra_YOUR_TOKEN_HERE"Example response
<!doctype html> ... (full print-ready HTML)Error responses
| Status | Meaning |
|---|---|
| 401 | Missing, malformed, or revoked token. |
| 403 | Token lacks the required scope. |
| 500 | Unexpected server error. |
| 404 | No document with that slug. |
/api/v1/documents/{slug}/propose-updatePropose a section rewrite
Agent-facing hook for proposing a rewrite of one section. The proposal lands in the Suggested updates queue — the live document is never modified directly. A human approves from the UI before the rewrite is applied.
Requires scope: docs:write
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
| slug | path | string | yes | Document slug. |
Request body (application/json)
{
"section_id": "pricing-table",
"proposed_html": "<section data-rendra-refresh id=\"pricing-table\">…</section>",
"diff_summary": "Bumped Pro tier to $24/mo per the 2026 update."
}Example request
curl -X POST https://app.rendra.dev/api/v1/documents/onboarding-playbook/propose-update \
-H "Authorization: Bearer rendra_YOUR_TOKEN_HERE" \
-H "Content-Type: application/json" \
-d '{ "section_id": "pricing-table", "proposed_html": "<section data-rendra-refresh id=\"pricing-table\">…</section>", "diff_summary": "Bumped Pro tier to $24/mo per the 2026 update."}'Example response
{
"ok": true,
"proposal_id": 142
}Error responses
| Status | Meaning |
|---|---|
| 400 | Invalid JSON body or validation error. |
| 401 | Missing, malformed, or revoked token. |
| 403 | Token lacks the required scope. |
| 500 | Unexpected server error. |
| 404 | No document with that slug. |
/api/v1/documents/{slug}/sections/{sectionId}/refreshRun a section refresh on demand
Same worker as the cron-driven Rendra Refresh tick, kicked off on demand (typically from the MCP `trigger_section_refresh` tool). The section must already have a configured refresh job. Empty body = refresh using the section's configured source + model. Result lands in Suggested updates for human approval.
Requires scope: docs:write
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
| slug | path | string | yes | Document slug. |
| sectionId | path | string | yes | Id of the `<section data-rendra-refresh>` block to refresh. |
Request body (application/json)
{
"source_text": "Pricing changed Apr 2026 — Pro is now $24/mo, Team $48/mo.",
"source_title": "Pricing FAQ — Apr 2026"
}Example request
curl -X POST https://app.rendra.dev/api/v1/documents/onboarding-playbook/sections/{sectionId}/refresh \
-H "Authorization: Bearer rendra_YOUR_TOKEN_HERE" \
-H "Content-Type: application/json" \
-d '{ "source_text": "Pricing changed Apr 2026 — Pro is now $24/mo, Team $48/mo.", "source_title": "Pricing FAQ — Apr 2026"}'Example response
{
"ok": true,
"proposal_id": 143,
"summary": "Updated pricing to match Apr 2026 source."
}Error responses
| Status | Meaning |
|---|---|
| 400 | Invalid JSON body or validation error. |
| 401 | Missing, malformed, or revoked token. |
| 403 | Token lacks the required scope. |
| 500 | Unexpected server error. |
| 404 | Document or refresh job not found. The section needs a configured refresh job before it can be refreshed. |
| 409 | The refresh worker hit an unrecoverable error. |
/api/v1/documents/searchSearch documents
Case-insensitive substring match across title, subtitle, summary, owner, and collection.
Requires scope: docs:read
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
| q | query | string | yes | Search text (non-empty). |
| limit | query | integer | no | 1..100 (default 20). |
| status | query | string | no | Same semantics as on GET /documents. |
Example request
curl https://app.rendra.dev/api/v1/documents/search \
-H "Authorization: Bearer rendra_YOUR_TOKEN_HERE"Example response
{
"query": "onboarding",
"documents": [],
"pagination": {
"limit": 20,
"returned": 0
}
}Error responses
| Status | Meaning |
|---|---|
| 400 | Missing the required `q` query parameter. |
| 401 | Missing, malformed, or revoked token. |
| 403 | Token lacks the required scope. |
| 500 | Unexpected server error. |