Document Generation API
The Document Generation API powers Ema's long-form document workflows — proposals, RFP responses, and other structured documents an AI Employee writes and a person edits. It stores documents and their full version history, generates content by triggering a workflow run, supports an inline chat assistant for editing and Q&A, and manages a reusable template library. The docgen service is mounted at /api/v1/docgen, so every path below is that prefix plus the path shown.
All requests require a JWT or tenant API key. Examples use https://your-tenant.ema.co as the host.
Documents are scoped to the caller. Each document belongs to the user and tenant that created it. A document that belongs to another tenant returns 404 — there is no existence leak across tenants.
Documents
A document holds a title, HTML content, and JSON metadata, and tracks a current version number.
- List:
GET /api/v1/docgen/documents— ordered byupdated_atdescending, paginated withlimitandoffset. Filter by metadata withtypeandparent_document_id. Passinclude_content=trueto includecontent_htmlin each item; omit it for lightweight poll responses. - Create:
POST /api/v1/docgen/documents— requirestitle; optionally seedcontent_html, bind aworkflow_id, attach asession_id, and setmetadata. - Get / update / delete:
GET,PATCH,DELETE /api/v1/docgen/documents/{id}.PATCHupdates thetitleand/or shallow-merges ametadatapatch;DELETEis a soft delete.
POST https://your-tenant.ema.co/api/v1/docgen/documents
Authorization: Bearer eyJhbGciOiJSUzI1Ni...
Content-Type: application/json
{
"title": "Acme RFP response",
"workflow_id": "3f7a...",
"metadata": { "type": "rfp_section" }
}
Bulk create
POST /api/v1/docgen/documents/bulk creates a parent document plus N child sections in one transaction. Provide title and children to create a new parent; provide parent_document_id instead to add children to an existing parent (a missing or cross-tenant parent returns 404).
Versions
Every change to a document is recorded as a version, so you can review history and roll back.
- List versions:
GET /api/v1/docgen/documents/{id}/versions(without content). - Get one version:
GET /api/v1/docgen/documents/{id}/versions/{versionNumber}(withcontent_html). - Save a manual version:
POST /api/v1/docgen/documents/{id}/versions. If the document changed since you loaded it, the save returns409 Conflictso you don't overwrite a newer edit. - Restore:
POST /api/v1/docgen/documents/{id}/restore/{versionNumber}writes the chosen version's content back as the latest version.
Each Version records a source (ai_create, ai_edit, manual_save, or restore) and a change_description, plus the user or workflow run that produced it.
Generate content
POST /api/v1/docgen/documents/{id}/generate starts a workflow run scoped to a document and returns immediately — the workflow writes content back as a new version.
POST https://your-tenant.ema.co/api/v1/docgen/documents/a1b2.../generate
Authorization: Bearer eyJhbGciOiJSUzI1Ni...
Content-Type: application/json
{
"section_title": "Executive summary",
"instructions": "Summarize our proposed approach in two paragraphs.",
"knowledge_base_ids": ["9b2c..."]
}
The body is optional. The workflow to run is resolved in order: the request body's workflow_id, then the document's bound workflow_id, otherwise a 422. Your JWT or API key is forwarded to the workflow service, so the run inherits your tenant and role. The response is 202 Accepted:
{
"run_id": "5e6f...",
"workflow_id": "3f7a...",
"stream_url": "/runs/5e6f.../stream"
}
Tail progress on the Workflow API SSE stream at the returned stream_url.
Outlines. POST /api/v1/docgen/generate-document-outline turns a user-supplied HTML outline (input_type: MANUAL) or the markdown of an uploaded document (input_type: UPLOAD) into a structured list of sections you can then create with bulk create. The AI-generated outline path is not yet available in this platform.
Export
POST /api/v1/docgen/export enqueues an export job for an ordered list of document IDs, then you poll for the result.
POST https://your-tenant.ema.co/api/v1/docgen/export
Authorization: Bearer eyJhbGciOiJSUzI1Ni...
Content-Type: application/json
{
"document_ids": ["a1b2...", "c3d4..."],
"format": "html"
}
The response is 202 Accepted with a job. Poll GET /api/v1/docgen/export/{jobId} until status is complete (then read download_url) or error. The format field currently supports html; pdf and pptx return 501.
Chat assistant
Each document has an inline assistant for editing and questions. There is also a document-less Q&A assistant scoped to a tenant's knowledge bases.
- Document sessions:
GET,POST /api/v1/docgen/documents/{docId}/chat/sessions, plusGET,PATCH,DELETE .../chat/sessions/{id}. - Document messages:
GET,POST /api/v1/docgen/documents/{docId}/chat/sessions/{id}/messages. Sending a message returns the assistant's reply synchronously. - Tenant-KB Q&A sessions: the same shapes under
/api/v1/docgen/chat/sessionsand.../chat/sessions/{id}/messages, with no document context.
POST https://your-tenant.ema.co/api/v1/docgen/documents/a1b2.../chat/sessions/7d1e.../messages
Authorization: Bearer eyJhbGciOiJSUzI1Ni...
Content-Type: application/json
{
"content": "Tighten this paragraph and remove the jargon.",
"mode": "edit",
"selected_html": "<p>...</p>"
}
mode is edit (the default in-document writing assistant) or qa (knowledge-base Q&A, no rewrite). For an edit request that rewrites a selection, the assistant message carries a replacement_text. On the document-less Q&A path, set mode: qa and a workflow_id to scope the knowledge-base search.
Comments
Documents support threaded comments for review.
- Threads:
POST,GET /api/v1/docgen/documents/{docId}/comments/threads; resolve or reopen withPATCH .../comments/threads/{threadId}, and delete a thread (and its replies) withDELETE. - Replies:
POST .../comments/threads/{threadId}/replies; edit withPATCHand soft-delete withDELETE .../replies/{commentId}. - Across documents:
GET /api/v1/docgen/comments/threadsbatch-lists threads across several documents.
Template library
Templates standardize the look of generated documents. A template is DOCX or PPTX and carries a generation mode (slot_fill or html_rewrite).
- List / create:
GET,POST /api/v1/docgen/templates; upload a source file withPOST /api/v1/docgen/templates/upload. - Get / update / delete:
GET,PATCH,DELETE /api/v1/docgen/templates/{id}. - Render assets:
GET /api/v1/docgen/templates/{id}/htmland.../thumbnail. - Manage: set the tenant default with
PUT .../templates/{id}/set-default, duplicate withPOST .../duplicate, and re-run extraction withPOST .../re-extract. - PPTX slides: list, reorder, fetch, edit, and delete slides under
/api/v1/docgen/templates/{id}/slides.
Section profiles describe how a tenant labels document sections. Manage them with GET, POST /api/v1/docgen/section-profiles (and GET, PATCH, DELETE .../section-profiles/{id}), and classify a set of section titles against them with POST /api/v1/docgen/section-profiles/classify.
What's next
- Workflow API — the workflow that document generation triggers, and how to stream its run.
- Knowledge & Ingestion API — the knowledge bases a generation or Q&A request searches.