---
title: "Start a long-running or HITL-approved AI edit; returns a job_id to poll for results."
method: POST
path: "/v1/chat/async"
tags: ["v1", "mcp", "chat"]
---

# Start a long-running or HITL-approved AI edit; returns a job_id to poll for results.

`POST /v1/chat/async`

## Request

- Base URL: `https://api.superdocs.app`
- URL: `https://api.superdocs.app/v1/chat/async`
- Auth: HTTP bearer

Use instead of chat when (a) the edit is large or multi-step, (b) you need human approval on each proposed change before it applies (set approval_mode='ask_every_time'), or (c) you can't afford to block on a synchronous response. To replace the whole document with EXACT content you already hold, pass that content in document_html (a verbatim load — the AI never re-types it) or upload it via upload_document_base64; describing the content only in `message` makes the AI author it, which can drift from your text. Returns a job_id immediately. Poll get_job to track progress and retrieve the final document. Approve or deny pending changes via approve_change. Job state is durable and survives server restarts. Optional: model_tier (core/turbo/pro/max), thinking_depth (fast/balanced/deep), image_attachments for multimodal vision. RECOMMENDED for AI agents working with large documents (>20 pages): set response_mode='compact' so the job result skips the full HTML and surfaces only per-section diffs in chunk_diffs, saving thousands of tokens per poll. To read sections in compact mode, just send a natural-language chat request ('show me the pricing section') — the AI returns the content in the reply text. Always use natural language; the AI handles all internal section lookups. HITL workflow (approval_mode='ask_every_time'): 1) poll get_job until status=awaiting_approval, 2) read metadata.pending_changes for proposed edits, 3) call approve_change per change, 4) continue polling until status=completed.

## Headers

- `authorization` string, nullable

## Request body

- AsyncChatRequest: Start an async chat request that processes in the background.
  - `message` string, required: Your message to the AI assistant.
  - `session_id` string, required: Unique session identifier. Reuse to continue a conversation.
  - `document_html` string, nullable: Current document HTML. OMIT this when the session already holds the document — the server persists it across turns, so you don't re-send it every turn; pass it only to load new content or replace the document wholesale (a verbatim load — the AI never re-types content passed here). Include data-chunk-id attributes on elements to enable targeted AI edits.
  - `user_id` string, nullable: User identifier. Automatically set from authentication — typically omit this.
  - `image_attachments` ImageAttachmentData[], nullable: Inline images for vision-based analysis (base64-encoded).
    - `id` string, required: Unique identifier for this image.
    - `name` string, required: Original filename of the image.
    - `base64Data` string, required: Base64-encoded image data.
    - `mimeType` string, required: MIME type (e.g., 'image/png', 'image/jpeg').
    - `size` integer, required: File size in bytes.
  - `async_mode` boolean: Must be true for async processing. Included for backward compatibility.
  - `model_tier` string, nullable: AI model to use: 'core' (default, fast), 'turbo' (fastest), 'pro' (advanced reasoning), 'max' (most capable).
  - `thinking_depth` string, nullable: Reasoning depth: 'fast', 'balanced' (default), or 'deep'. Controls how much analysis the AI performs.
  - `approval_mode` string, nullable: Change review mode: 'approve_all' (default, auto-applies changes) or 'ask_every_time' (pauses for your review).
  - `response_mode` 'full' | 'compact', nullable: Response shape control. 'full' (default) puts the complete updated document HTML in the job result — required by web app editors and recommended for small documents. 'compact' (recommended for AI agents editing large documents) suppresses the full HTML and stores only per-section diffs (chunk_diffs), saving thousands of tokens when polling get_job. To read sections in compact mode, send a natural-language request to chat ('show me the pricing section') — the AI returns the content in the reply text.
  - `cursor_context` object, nullable: Editor cursor context at message time, used to default the insert location for new images, diagrams, or sections when the user's prompt doesn't name a position. Shape: {chunk_id: str, pos_in_chunk?: int, text_before?: str, text_after?: str}. Omit when the user typed in chat without focusing the editor first.
  - `document_id` string, nullable: Target a specific open document by id (ids come from /v1/sessions/{session_id}/documents). Omit to target the focused document (default — unchanged single-document behaviour). When set, that document becomes the focus for this turn.
  - `window_id` string, nullable: Optional identifier for the client window (set by the web app) so concurrent edits from two windows of the same chat are merged rather than overwritten. Agents/API may omit.
  - `cross_session_memory` boolean, nullable: When true, the AI carries a private rolling memory of context across THIS account's chats (off by default). Per-request override of your saved Settings default.
  - `cross_session_search` boolean, nullable: When true, the AI may search your PAST chats and documents on demand to reuse prior work and open a found document (off by default). Per-request override of your saved Settings default; never affects the always-on search of the open document.
  - `cross_session_memory_key` string, nullable: Optional per-request id of YOUR end-customer so the cross-session memory note is kept in a separate file per end-customer. Omit for one account-level note (the default / B2C).
  - `cross_session_scope` string[], nullable: Optional list of session ids to restrict cross-session SEARCH to (e.g. one end-customer's sessions). Omit to search all of this account's sessions. Only narrows within the API-key owner; ignored unless cross_session_search is on.
  - `touched_chunk_ids` string[], nullable: Optional list of chunk ids (data-chunk-id values) the user actually edited since the last sync, sent alongside document_html. When present, a chunk NOT in this list whose text is unchanged keeps its stored formatting byte-for-byte even if the client serialized it differently (protects styling from editor round-trip loss). Chunks in the list — and any chunk whose text changed — always take the submitted content. Omit for the default behavior (any differing chunk is treated as an edit).
  - `deleted_part_chunk_ids` string[], nullable: Optional list of chunk ids (data-chunk-id values) of OUT-OF-FLOW part sections (page headers/footers, footnote/endnote bodies, comments) to delete explicitly, sent alongside document_html. Out-of-flow parts absent from document_html are always KEPT — an editor view not containing them is their normal state, never a deletion — so removing one requires naming its id here. Ids that are not stored out-of-flow parts are ignored (in-flow content keeps the default behavior). Omit when deleting nothing.

## Response `200`

Successful Response

- AsyncChatResponse: Response from starting an async chat request.
  - `job_id` string, required: Job identifier. Poll GET /v1/jobs/{job_id} for status and results.
  - `session_id` string, required: Session identifier for this conversation.
  - `status` string, required: Initial job status (always 'pending').
  - `message` string: Human-readable status message.

## Other responses

- `422`: Validation Error

---

[API](https://skmtc.dev/superdocs/apis/universal-document-ai-api.md) · [All operations](https://skmtc.dev/superdocs/apis/universal-document-ai-api/llms.txt) · [OpenAPI document](https://skmtc.dev/superdocs/apis/universal-document-ai-api/revisions/37d03122940b?raw)
