JitWord Document Processing Open APIs
Built for enterprise integration, business middle platforms, OA workflows, contract management and knowledge bases: DOCX import, parsing, online editing and export capabilities. Convert local Word files into collaborative online documents via API, then keep viewing, editing and exporting them in the editor.
Quick Start
From uploading a DOCX to opening the online editor, follow these steps for your first integration.
Environment Setup
Settings are saved to browser localStorage for repeated testing. When the static page runs on port 5500, you must explicitly configure the backend URL.
token and api parameters so the editor talks to the same backend as the import API.Authentication
APIs that require user identity expect a JWT in the request header; the server binds the document owner to the token.
| Location | Format | Notes |
|---|---|---|
| Header | Authorization: Bearer <token> | Required by import, export, document list, document info, open document data, version list, revision and comment APIs. |
| Login allowlist | IP / CIDR / Domain | Admins can restrict register/login sources in the portal's Open Access panel; disabled or empty rules mean allow-all. |
| Same-origin session | localStorage.jwt_token | When this page is deployed on the same origin as the editor and no token is set manually, the editor session is reused automatically. |
| Editor link | ?token=<token>&api=<apiBase> | The editor stores the session locally after opening and cleans the URL parameters. |
Register & Login
The open auth APIs reuse the existing user system. A successful login returns a JWT used by all subsequent APIs.
| API | Request body | Notes |
|---|---|---|
| /api/v1/user/register | { "username": "demo", "password": "123456" } | Returns a token on success; may be limited by the login allowlist. |
| /api/v1/user/login | { "username": "demo", "password": "123456" } | Returns data.token on success. |
curl -X POST "http://localhost:3002/api/v1/user/register" \
-H "Content-Type: application/json" \
-d '{"username":"demo","password":"123456"}'
curl -X POST "http://localhost:3002/api/v1/user/login" \
-H "Content-Type: application/json" \
-d '{"username":"demo","password":"123456"}'
My Documents
Fetch documents owned by the current logged-in user. Regular users can only query their own documents.
curl -X GET "http://localhost:3002/api/v1/documents?filter=active&scope=mine" \ -H "Authorization: Bearer <token>"
DOCX Import & Create
Recommended integration API. After uploading a DOCX, the server parses it, creates a document, writes content, persists comments and returns a documentId.
| Field | Type | Required | Notes |
|---|---|---|---|
| file | file | Yes | DOCX file; the field name must be file. |
| publicPermission | string | No | private/read/edit. This test page defaults to edit. |
| name | string | No | Document name; defaults to the file name. |
curl -X POST "http://localhost:3002/api/v1/parse/docx-v2-import" \ -H "Authorization: Bearer <token>" \ -F "file=@demo.docx" \ -F "publicPermission=edit"
Excel Import & Create
After uploading an XLSX, the server parses it into a sheet snapshot, creates a sheet document and returns a link that opens the Excel editor directly.
| Field | Type | Required | Notes |
|---|---|---|---|
| file | file | Yes | Excel file; the field name must be file, .xlsx recommended. |
| publicPermission | string | No | private/read/edit. This test page defaults to edit. |
| name | string | No | Sheet name; defaults to the file name. |
curl -X POST "http://localhost:3002/api/v1/parse/excel-v2-import" \ -H "Authorization: Bearer <token>" \ -F "file=@demo.xlsx" \ -F "publicPermission=edit"
High-fidelity DOCX Parsing
Parses without creating a document. Returns JitWord JSON, a parsing summary, a diagnostics report and Word comment info.
| Capability | Notes |
|---|---|
| Structure parsing | Body text, headings, tables, lists, tab stops, styles and more. |
| Formula parsing | Supports OMML formula conversion. |
| Best for | Callers that store document content themselves or run parsing quality checks. |
DOCX to HTML
Basic HTML parsing for lightweight previews or legacy integrations.
| API | Notes | Auth |
|---|---|---|
| /api/v1/parse/doc2html | Returns full HTML. | No login |
| /api/v1/parse/doc2html2 | Paginated HTML parsing; returns docId and page count. | No login |
Export DOCX by Doc ID
Export an existing online document as a Word file by its ID.
Export DOCX from JSON
Submit editor JSON content directly; the server generates and returns a Word file.
{
"content": { "type": "doc", "content": [] },
"filename": "demo.docx",
"documentId": "optional, used to load comments"
}
Export PDF by Doc ID
Render and export an existing online document as a PDF on the server.
| Key point | Notes |
|---|---|
| Response | application/pdf byte stream; Content-Disposition carries a file name based on the document name. |
| Rendering | A server-side headless browser reuses the editor print pipeline; output matches the front-end “Print → Save as PDF”. |
| Latency | Synchronous response, usually a few seconds; large documents up to ~90s. Requires the rendering service (browser-service) online; behind a gateway, set read timeout ≥120s. |
| Common errors | 404 document not found | 403 no permission | 429 export busy | 503 rendering service down | 504 rendering timeout. |
curl -X GET "http://localhost:3002/api/v1/export/pdf/<documentId>" \ -H "Authorization: Bearer <token>" \ -o export.pdf
Document Info
Fetch document metadata, header/footer, content presence and the current token's permission for a document by ID.
| Field | Notes |
|---|---|
| id / name / type | Unique document ID, name and type; for regular documents type can be empty or doc. |
| ownerId / ownerName | Owner info, useful for ownership mapping in business systems. |
| publicPermission | private, read or edit. |
| headerFooter | Header/footer configuration; null if not configured. |
| hasContent | Whether real body content is stored on the server. |
| _userPermission | Current token's view, edit and comment permission for this document. |
curl -X GET "http://localhost:3002/api/v1/documents/<documentId>" \ -H "Authorization: Bearer <token>"
Document Content Data
Unified content reading for documents, sheets and mind maps, reusing the existing document permission checks.
| Field | Notes |
|---|---|
| document | Trimmed document metadata: id, name, type, owner, permission and timestamps. |
| permission | Current token's access permission for this document. |
| contentType | doc, sheet or mindmap. |
| content | Body data; null with an explicit message when there is no content yet. |
curl -X GET "http://localhost:3002/api/v1/open/documents/<documentId>/data" \ -H "Authorization: Bearer <token>"
Version List
Fetch historical versions of a document (metadata only, no content), reusing the existing document permission checks.
| Field | Notes |
|---|---|
| document | Trimmed document metadata (id, name, type, owner, permission, timestamps). |
| permission | Current token's access permission for this document. |
| versions | Versions in the current page, each with id, title, description, isAutoSave, author, createdAt, size; version body content is not included. |
| total / page / limit | Total count and pagination parameters. |
curl -X GET "http://localhost:3002/api/v1/open/documents/<documentId>/versions?page=1&limit=20" \ -H "Authorization: Bearer <token>"
Revisions & Comments
Read review-related data of a document: the revisions API returns tracked-change marks in the document body (insertions/deletions/format changes, same scope as the editor review panel), and the comments API returns inline comment data; the live test requests both in parallel and merges the display.
| API | Parameters | Notes |
|---|---|---|
/api/v1/open/documents/{documentId}/revisions | None | Fetch tracked changes: multiple text fragments of the same revision are merged into one record with type, author, time, text fragments and a summary. Note this is different data from the version list or edit history. |
/api/v1/comments | documentId | Fetch comments and replies for the document, including content, quoted text, author and extension fields. |
curl -X GET "http://localhost:3002/api/v1/open/documents/<documentId>/revisions" \ -H "Authorization: Bearer <token>" curl -X GET "http://localhost:3002/api/v1/comments?documentId=<documentId>" \ -H "Authorization: Bearer <token>"
Document Diff & Compare
Upload files, pass file URLs, or reference internal document IDs. The server parses both sides and returns structured differences: similarity, added/removed/modified counts, and a per-change "original → difference" list with anchors for both sides. left = original (red), right = compared (green).
POST {server base URL}/api/v1/compare
# {server base URL} is the "Server URL" from the Environment section above (default http://localhost:3002)
# Full example (local deployment): POST http://localhost:3002/api/v1/compare
# No query parameters; all inputs go in the multipart body (see "Request Parameters" below)
| Header | Value | Required | Description |
|---|---|---|---|
Authorization | Bearer <token> | Yes | JWT from login (see "Register & Login"; this page auto-syncs the same-origin session token) |
Content-Type | multipart/form-data | Yes | Set automatically by curl -F or the browser FormData API (boundary included) — do not set it manually |
| Field | Type | Required | Example | Description |
|---|---|---|---|---|
leftFile | file | left: pick one | @v1.docx | Original document: upload a .docx/.doc file (≤50MB) |
leftUrl | string | left: pick one | /uploads/a.docx or http://…/a.docx | Original document: file URL (site-relative path or external http(s) address; SSRF-checked) |
leftDocId | string | left: pick one | mvd33lxfcm4nf1d6vw | Original document: internal document ID (from "My Documents") |
rightFile | file | right: pick one | @v2.docx | Compared document: upload a .docx/.doc file (≤50MB) |
rightUrl | string | right: pick one | http://…/b.docx | Compared document: file URL, same rules as the left side |
rightDocId | string | right: pick one | mvd33lxfcm4nf1d6vw | Compared document: internal document ID, same rules as the left side |
format | string | No | full / summary | full (default) returns the complete change list; summary returns similarity and counts only (lighter for large documents) |
# 1) Two uploaded files curl -X POST "http://localhost:3002/api/v1/compare" \ -H "Authorization: Bearer <token>" \ -F "leftFile=@v1.docx" -F "rightFile=@v2.docx" # 2) Two file URLs (site-relative on the left, absolute on the right — mixing is fine) curl -X POST "http://localhost:3002/api/v1/compare" \ -H "Authorization: Bearer <token>" \ -F "leftUrl=/uploads/a.docx" \ -F "rightUrl=http://172.30.239.32:3002/uploads/b.docx" # 3) Two internal documents, similarity and counts only curl -X POST "http://localhost:3002/api/v1/compare" \ -H "Authorization: Bearer <token>" \ -F "leftDocId=<id1>" -F "rightDocId=<id2>" -F "format=summary"
| Field | Description |
|---|---|
| similarity | Text similarity (integer) = 100 - changed percentage. |
| stats | added/removed/modified/total are change counts; tokensAdded/tokensRemoved/changePercentage use the token metric. |
| changes | Change list (omitted when format=summary). Each item has type (added/removed/modified), kind, label, oldText/newText (original/diff snippets) and oldAnchors/newAnchors (blockIndex + from/to; -1 = whole block, from=to = insertion point, [] = no content on that side). |
| left / right | Source receipts: source, fileName, contentHash, blockCount; url/docId sources also return sourceUrl/docId. |
| warnings | Parse-degradation notes (if any); results may be incomplete. |
| meta | generatedAt, engineVersion, format, elapsedMs. |
{
"state": 200,
"data": {
"similarity": 79,
"stats": { "added": 321, "removed": 9, "modified": 0, "total": 330,
"tokensAdded": 12375, "tokensRemoved": 394, "changePercentage": 21 },
"changes": [
{ "id": 0, "type": "added", "kind": "text", "label": null,
"oldText": "", "newText": "Table of Contents",
"oldTextFull": "", "newTextFull": "Table of Contents",
"oldTextTruncated": false, "newTextTruncated": false,
"oldAnchors": [],
"newAnchors": [{ "blockIndex": 16, "from": 0, "to": 2 }] },
{ "id": 1, "type": "modified", "kind": "text", "label": null,
"oldText": "apple and banana", "newText": "apple and pear",
"oldTextFull": "apple and banana", "newTextFull": "apple and pear",
"oldTextTruncated": false, "newTextTruncated": false,
"oldAnchors": [{ "blockIndex": 0, "from": 7, "to": 9 }],
"newAnchors": [{ "blockIndex": 0, "from": 7, "to": 8 }] }
],
"left": { "source": "url", "sourceUrl": "/uploads/a.docx", "fileName": "a.docx",
"contentHash": "d2f47fd191b4… (64 hex chars, truncated)", "blockCount": 5289 },
"right": { "source": "file", "fileName": "b.docx",
"contentHash": "…", "blockCount": 5579 },
"warnings": [],
"meta": { "generatedAt": "2026-10-18T00:24:17.383Z", "engineVersion": 1,
"format": "full", "elapsedMs": 10493 }
}
}
HTTP 400
{ "state": 400, "data": null, "msg": "原文档只能提供一种来源,当前同时提供了:文件 + URL" }
HTTP 401
Authentication Error (missing or invalid token)
HTTP 403
{ "state": 403, "data": null, "msg": "原文档无权访问此文档: 合同模板" }
curl -X POST "http://localhost:3002/api/v1/compare" \ -H "Authorization: Bearer <token>" \ -F "leftDocId=<documentId>" \ -F "rightUrl=/uploads/demo.docx" \ -F "format=full"
Create Document
Create a new document with optional initial content (ProseMirror JSON). Returns the document ID for subsequent save, export, or delete operations.
| Field | Type | Required | Description |
|---|---|---|---|
name | string | Yes | Document name |
type | string | No | Document type: doc (default) / sheet / mindmap |
content | object | No | Initial body (ProseMirror JSON, only effective when type=doc), e.g. {"type":"doc","content":[...]} |
publicPermission | string | No | Document permission: private (default) / read (public read-only) / edit (public editable) |
GET /api/v1/open/documents/{id}/data to read the full content, or PUT /api/v1/open/documents/{id}/content to update it.curl -X POST "http://localhost:3002/api/v1/open/documents" \
-H "Authorization: Bearer <token>" \
-H "Content-Type: application/json" \
-d '{"name":"Open API Test Doc","type":"doc"}'
Save Document Content
Write document body directly via REST (ProseMirror JSON). Suitable for programmatic content generation and bulk import scenarios.
| Field | Type | Required | Description |
|---|---|---|---|
content | object | Yes | Standard ProseMirror JSON; top-level type must be "doc", content is an array of nodes |
409 Conflict to prevent overwriting real-time edits. Ensure no users are editing before calling this endpoint.curl -X PUT "http://localhost:3002/api/v1/open/documents/<documentId>/content" \
-H "Authorization: Bearer <token>" \
-H "Content-Type: application/json" \
-d '{"content":{"type":"doc","content":[{"type":"paragraph","content":[{"type":"text","text":"Hello"}]}]}}'
Set Document Permission
Change the public permission of a document. Supports three levels: private (owner/admin only), public read-only, and public editable. Only the document owner or an admin can perform this action.
| Field | Type | Required | Description |
|---|---|---|---|
publicPermission | string | Yes | Target permission: private / read (public read-only) / edit (public editable) |
| Value | Effect |
|---|---|
private | Only the owner and admins can view and edit |
read | Any logged-in user can view; only owner/admin can edit |
edit | Any logged-in user can view and edit |
publicPermission parameter in the Create Document API, without needing this endpoint.curl -X PUT "http://localhost:3002/api/v1/open/documents/<documentId>/permission" \
-H "Authorization: Bearer <token>" \
-H "Content-Type: application/json" \
-d '{"publicPermission":"edit"}'
Delete Document
Soft-delete a document (move to trash). Only the document owner or an admin can perform this action. Template documents cannot be deleted via this endpoint.
| Field | Type | Description |
|---|---|---|
documentId | string | The document ID to delete |
curl -X DELETE "http://localhost:3002/api/v1/open/documents/<documentId>" \ -H "Authorization: Bearer <token>"
Template Batch Generation · Overview
Generate contracts, notices, certificates and reports in bulk with "one template + rows of variable data". Auth reuses the existing JWT — no extra integration cost.
output=doc persists the document and returns a docId with an editor link; output=json returns the merged ProseMirror JSON without persisting./api/v1/open/templates namespace and are automatically protected by JWT. First fill in the backend URL and access token in "Environment Setup" (you can grab a token in "Register & Login").Template List
List templates the current token can use for generation. Filter by scope and optionally include the variable schema.
| Parameter | Type | Required | Notes |
|---|---|---|---|
| scope | string | No | Omit = all visible templates; official = public templates; mine = templates you created. |
| withVariables | string | No | Pass 1 to include the full variables schema per item — handy for building input skeletons. |
| Field | Notes |
|---|---|
| id / title / category / desc | Template ID, title, category and description. |
| variableCount / hasVariables | Number of variables and whether the template has any. |
| public | Whether the template is public. |
| updatedAt / variablesUpdatedAt | Last update time of the template and its variables. |
curl -X GET "http://localhost:3002/api/v1/open/templates?withVariables=1" \ -H "Authorization: Bearer <token>"
Template Variable Schema
Inspect a template's variable definitions (field name, type, required, enum options) and organize generation data accordingly.
| Field | Notes |
|---|---|
| templateId / title | Template ID and title. |
| variables | Array of variable definitions; each has key, label, type, required, defaultValue, options, etc. (flat, backward compatible). |
| schema | Structured description: scalars (top-level scalar variables), tables (repeating tables grouped by tableId with column lists and sample rows), example (a values skeleton ready to submit). |
| variablesUpdatedAt | Last update time of the variable schema. |
text, number, date, select, image, signature, seal, tableColumn.values fields; they are keyed by the table's tableId with an array of row objects — one object per row, field names matching column keys. Follow schema.example / schema.tables to organize the data.curl -X GET "http://localhost:3002/api/v1/open/templates/<templateId>/variables" \ -H "Authorization: Bearer <token>"
Single Generation
Generate one document from a set of variable values. By default it creates an online document and returns a docId with an editor link; it can also return the merged JSON only.
| Field | Type | Required | Notes |
|---|---|---|---|
| values | object | Yes | Variable key-value pairs. Scalar variables use their key directly; repeating table variables use the tableId as key with an array of row objects (see schema.example in the variable schema). |
| unfilledStrategy | string | No | How to handle unfilled variables: default (use default value), empty (leave blank), keepPlaceholder (keep the placeholder). |
| name | string | No | Generated document name; defaults to the template title. |
| output | string | No | doc (default; persists and counts against quota) or json (content only; no persistence, no quota). |
output=doc consumes the current user's document quota (admins are exempt); if you only need content for server-side rendering/export, prefer output=json.curl -X POST "http://localhost:3002/api/v1/open/templates/<templateId>/generate" \
-H "Authorization: Bearer <token>" \
-H "Content-Type: application/json" \
-d '{"values":{},"output":"doc"}'
Batch Generation
Generate multiple documents from one template + rows of data. Up to 200 items per request; a single failed item does not affect the others.
| Field | Type | Required | Notes |
|---|---|---|---|
| items | array | Yes | Array of data rows, each { name?, values, unfilledStrategy? }, up to 200 items. |
| output | string | No | doc (default) or json. |
| stopOnError | boolean | No | When true, stop after the first failure; defaults to false (best-effort processing of all items). |
| Field | Notes |
|---|---|
| summary | { total, success, failed } statistics. |
| results | Per-item result: { index, status, docId?, name?, url?, content?, message? }. |
const res = await fetch(`${API}/api/v1/open/templates/${templateId}/batch-generate`, {
method: 'POST',
headers: { 'Authorization': `Bearer ${token}`, 'Content-Type': 'application/json' },
body: JSON.stringify({
output: 'doc',
items: [
{ name: 'Alice-Offer Letter', values: { Name: 'Alice' } },
{ name: 'Bob-Offer Letter', values: { Name: 'Bob' } },
],
}),
});
const { data } = await res.json();
console.log(data.summary, data.results);
curl -X POST "http://localhost:3002/api/v1/open/templates/<templateId>/batch-generate" \
-H "Authorization: Bearer <token>" \
-H "Content-Type: application/json" \
-d '{"output":"doc","items":[{"values":{}}]}'
Core Fields
The most frequently used data fields during integration.
| Field | Meaning | Recommendation |
|---|---|---|
| documentId | Unique ID of the online document. | Store it in your business system for opening, export and collaboration. |
| publicPermission | Access level: private/read/edit. | Use private in production; edit is fine for demos and testing. |
| ownerId | User ID of the document owner. | Should match the id in the import token. |
| api | Runtime API URL used by the editor. | Must match the upload backend in cross-origin / standalone deployments. |
FAQ
The most common errors during integration and how to troubleshoot them.