Skip to main content

Documents

Sending document HTML

Send your document HTML in document_html. The AI reads it, makes changes, and returns updated HTML in document_changes.updated_html. The one rule: Render the returned HTML as-is in your editor. When sending it back on the next request, send the full document HTML exactly as your editor has it. Don’t programmatically strip, modify, or reformat the HTML. If your editor or HTML sanitizer removes custom data-* attributes, configure it to preserve them.

Example flow

import requests

API_KEY = "sk_YOUR_API_KEY"
HEADERS = {"Authorization": f"Bearer {API_KEY}", "Content-Type": "application/json"}

# 1. Send a document
response = requests.post("https://api.superdocs.app/v1/chat", headers=HEADERS, json={
    "message": "Add a summary at the top",
    "session_id": "my-doc",
    "document_html": "<h1>Report</h1><p>Q4 revenue increased by 15%.</p>"
})

data = response.json()
updated_html = data["document_changes"]["updated_html"]

# 2. Send the updated HTML back on the next request
response = requests.post("https://api.superdocs.app/v1/chat", headers=HEADERS, json={
    "message": "Make the summary more concise",
    "session_id": "my-doc",
    "document_html": updated_html  # send back exactly as received
})
The returned HTML contains data-chunk-id attributes on elements. These identify document sections and enable the AI to make targeted edits without reprocessing the entire document. These same IDs appear in API responses — for example, chunk_id and insert_after_chunk_id in HITL proposed changes. If you make an edit you want to undo, you can rewind both the chat history and the document state to before any user message — see Revert a session to a previous message.

Loading documents from files

Upload a file to load it as the active document in a session. The file is processed synchronously — the response includes the full document HTML ready for editing. Supported formats: DOCX, PDF, TXT, HTML, MD (Markdown), RTF
curl -X POST https://api.superdocs.app/v1/documents/upload \
  -H "Authorization: Bearer sk_YOUR_API_KEY" \
  -F "file=@contract.docx" \
  -F "session_id=my-session"
Response:
{
  "html": "<div data-chunk-id=\"abc123\"><h1>Contract</h1><p>...</p></div>",
  "session_id": "my-session",
  "filename": "contract.docx",
  "chunks_count": 12,
  "version_id": "v_xyz789"
}
Multiple documents per session. By default an upload replaces the session’s focused document. Pass open_mode=new_focused to open the file as an additional document (and focus it), or open_mode=background to open it without stealing focus. The response also includes the session’s document roster (every open document’s id + title + which is focused) so you can render tabs immediately. See the Multi-Document Sessions guide. Page geometry. For DOCX and PDF uploads, document payloads include a nullable page_setup object — detected page size, orientation, and margins — anywhere a document is returned (upload responses, the session-documents roster, session history). It’s null when the source format carries no geometry (e.g. plain text or HTML).
{
  "page_setup": {
    "paper_size": "a4",
    "orientation": "portrait",
    "margins": {"top": 1.0, "right": 1.0, "bottom": 1.0, "left": 1.0}
  }
}
After uploading, you can immediately send chat messages to edit the document:
# Upload a document
upload = requests.post("https://api.superdocs.app/v1/documents/upload",
    headers={"Authorization": f"Bearer {API_KEY}"},
    files={"file": open("contract.docx", "rb")},
    data={"session_id": "my-session"}
)
doc_html = upload.json()["html"]

# Edit it with AI
response = requests.post("https://api.superdocs.app/v1/chat", headers=HEADERS, json={
    "message": "Simplify the language in section 3",
    "session_id": "my-session",
    "document_html": doc_html
})

Creating documents from scratch

Send a message to an empty session (no document_html, no uploaded file) and the AI will generate a complete document for you.
response = requests.post("https://api.superdocs.app/v1/chat", headers=HEADERS, json={
    "message": "Create a non-disclosure agreement between two companies",
    "session_id": "new-nda"
})

data = response.json()
new_document_html = data["document_changes"]["updated_html"]
Example prompts that work well:
  • “Create a consulting agreement”
  • “Draft a project proposal for a mobile app”
  • “Write a company privacy policy”
  • “Create a meeting minutes template”
The AI generates structured, formatted HTML that you can then continue editing with follow-up messages.

Exporting documents

Export the current document as a downloadable file. Three input modes:
  • Mode A — send HTML content inline (use when you have the document HTML in your app, up to 20 MB)
  • Mode B — send a session ID (the API retrieves the document from the session)
  • Mode C — upload the HTML to a pre-signed URL first, then send upload_id (use for documents between 20 MB and 100 MB — see Large documents below)
Five output formats:
  • docx (default) — Microsoft Word (Open XML), preserves tables, formatting, embedded images
  • pdf — paginated, print-ready PDF
  • html — standalone HTML file with inlined CSS
  • markdown — Markdown (.md) with ATX headings
  • txt — plain text
A sixth value, doc (Word-compatible HTML wrapper), is accepted as a legacy alias and will be removed in a future release. New integrations should use docx.

Mode A: Export from HTML

curl -X POST https://api.superdocs.app/v1/documents/export \
  -H "Authorization: Bearer sk_YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "html": "<h1>My Document</h1><p>Content here...</p>",
    "format": "docx",
    "options": { "filename": "my-document" }
  }' \
  --output my-document.docx

Mode B: Export from session

curl -X POST https://api.superdocs.app/v1/documents/export \
  -H "Authorization: Bearer sk_YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "session_id": "my-session",
    "format": "pdf"
  }' \
  --output exported-document.pdf

Export in Python

response = requests.post("https://api.superdocs.app/v1/documents/export",
    headers=HEADERS,
    json={
        "session_id": "my-session",
        "format": "docx",
        "options": {
            "paper_size": "A4",
            "margins": "normal",
            "filename": "final-contract"
        }
    }
)

with open("final-contract.docx", "wb") as f:
    f.write(response.content)

Request parameters

ParameterTypeRequiredDescription
htmlstringOne of html / session_id / upload_id requiredHTML content to convert (Mode A)
session_idstringOne of html / session_id / upload_id requiredSession to export from (Mode B)
upload_idstringOne of html / session_id / upload_id requiredPre-signed URL upload reference (Mode C)
formatstringNo"docx" (default), "pdf", "html", "markdown", or "txt". "doc" accepted as a legacy alias.
optionsobjectNoCustomisation block — see Export options below.
filenamestringNoLegacy top-level filename. Prefer options.filename.

Export options

Pass an options object to customise the rendered output. Defaults are sensible for English-language documents; override only what you need.
FieldTypeDefaultDescription
paper_sizestring"Letter""Letter", "A4", "A3", or "Legal". Applies to DOCX/PDF.
orientationstring"portrait""portrait" or "landscape". Applies to DOCX/PDF.
marginsstring"normal""narrow" (0.5 in), "normal" (1 in), "wide" (1.5 in), or "custom".
custom_margins_inchesobjectRequired when margins="custom". Object with top, right, bottom, left floats between 0.25 and 3.0.
filenamestringFile name without extension. Auto-detected from the first heading if unset.
embed_imagesbooleanfalseHTML export only. When true, images are base64-embedded for offline portability. Raises the size cap from 100 MB to 150 MB.
watermark_textstringPDF only. Optional text watermark overlaid on every page (max 64 chars).
watermark_opacitynumber0.3PDF watermark opacity, between 0.05 and 1.0.
options = {
    "paper_size": "A4",
    "orientation": "landscape",
    "margins": "wide",
    "filename": "Q4-Report",
    "watermark_text": "DRAFT",
    "watermark_opacity": 0.15,
}
The response is a binary file download with the appropriate Content-Type header. The Content-Disposition header carries the filename (RFC 5987 encoded for non-ASCII characters).

Non-fatal warnings

Exports may complete successfully but with non-fatal issues — an image URL that 404’d, a diagram that exceeded the render timeout, an unsupported field code that was skipped. The response carries these in the X-Export-Warnings header as a base64-encoded JSON list. The header is always present alongside Content-Disposition in Access-Control-Expose-Headers, so browser clients can read it via fetch.
const response = await fetch('/v1/documents/export', { ... });
const warningsHeader = response.headers.get('X-Export-Warnings');
if (warningsHeader) {
  const warnings = JSON.parse(atob(warningsHeader));
  // [{ code: "image_download_failed", message: "...", detail: { src: "..." } }, ...]
}
Warning codeMeaning
image_download_failedAn embedded image URL could not be fetched. The image is omitted from the output.
mermaid_render_failedA Mermaid diagram could not be rendered. The diagram source is kept in the output as a code block.
mermaid_timeoutA Mermaid diagram took too long to render. Same fallback as above.
excalidraw_corruptAn Excalidraw drawing’s JSON payload could not be parsed.
footnote_orphanA footnote reference has no matching footnote body.
track_change_unmatchedA tracked change anchor could not be placed inline; the change is appended at the end of the document.
field_code_unsupportedA citation or other field code could not be re-emitted in the output format.
watermark_skippedA requested PDF watermark could not be applied.
embed_image_skippedAn image could not be inlined into an HTML export with embed_images=true.
size_cap_warningThe document is close to the per-format size limit.

Large documents

Direct POSTs to /v1/documents/export are capped at 25 MB on the hosted plan. For larger documents, use the upload-then-export pattern (Mode C) instead. Three-tier flow:
Document HTML sizePath
Up to 20 MBDirect POST to /v1/documents/export with inline html.
20 MB – 100 MBRequest a pre-signed upload URL via POST /v1/uploads (purpose: "export-html"), PUT the HTML to it, then call /v1/documents/export with upload_id.
Over 100 MBUse the email-fallback endpoint.
# 1. Request a pre-signed PUT URL
upload = requests.post("https://api.superdocs.app/v1/uploads",
    headers=HEADERS,
    json={
        "filename": "export.html",
        "content_type": "text/html",
        "size_bytes": len(html.encode()),
        "purpose": "export-html",
    }
).json()

# 2. PUT the HTML directly to storage
requests.put(upload["upload_url"],
    headers={"Content-Type": "text/html"},
    data=html)

# 3. Export, referencing the upload_id
response = requests.post("https://api.superdocs.app/v1/documents/export",
    headers=HEADERS,
    json={
        "upload_id": upload["upload_id"],
        "filename": "export.html",
        "format": "docx",
    }
)

with open("output.docx", "wb") as f:
    f.write(response.content)
The signed URL is valid for 5 minutes; the uploaded blob is retained for 24 hours.

Email fallback for very large documents

For documents over 100 MB, render asynchronously and deliver via email. The endpoint accepts a session ID, queues a background job, and emails a 7-day signed download link to the recipient.
curl -X POST https://api.superdocs.app/v1/documents/export/email-request \
  -H "Authorization: Bearer sk_YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "session_id": "my-session",
    "format": "docx",
    "recipient_email": "user@example.com",
    "options": { "paper_size": "A4" }
  }'
Response:
{
  "job_id": "9c2f...e3a",
  "recipient_email": "user@example.com",
  "status": "queued",
  "eta": "24h",
  "message": "Your file will be emailed to user@example.com within 24 hours."
}
recipient_email falls back to the email on file for the authenticated user account when omitted. The job appears in /v1/jobs/{job_id} with job_type: "large_export". See Async jobs for the polling pattern.

Size and error responses

FormatCap
docx, pdf, html, doc100 MB
html with embed_images=true150 MB
markdown, txt50 MB
Direct POST requests above 25 MB return 413 Request Entity Too Large from the hosted infrastructure before reaching the renderer; use Mode C instead. Requests above the format-specific cap return a structured 413 with a JSON body explaining the limit and pointing to the email-fallback endpoint — see Error codes.

Supported formatting

The AI can apply the following formatting when creating or editing documents:
  • Text styling — bold, italic, underline, strikethrough
  • Headings — H1 through H6
  • Lists — ordered, unordered, and nested
  • Text highlighting — with color options (e.g., yellow, green, red)
  • Text color — change the color of specific text
  • Links — clickable hyperlinks
  • Tables — with rows and columns
  • Blockquotes — indented quotation blocks
  • Code blocks — for code snippets
  • Horizontal rules — section dividers
Ask for formatting in plain language: “highlight the key terms in yellow”, “make the title bold and larger”, “add a table comparing the two options”.