AI for Word documents: create and edit DOCX through an API
A model cannot save a file into Word, but it can return structure and text. A practical python-docx plus API pipeline for creating and editing documents.
4 min · · автоматизация · development
If you are looking for a neural network for Word documents, it helps to understand the shape of the task first. A language model returns text, not a .docx file. Your code builds the file: the model handles content and structure, and the python-docx library handles formatting. Below is a working pipeline for creating and editing documents that you can run in an evening, plus a cost estimate. Prices are as of October 18, 2026.
How the model and Word fit together
A DOCX file is a zip archive of XML files. Asking a model to "produce a docx" makes no sense: it will describe a file, not create one. A more reliable split looks like this:
- The model receives the task and returns a structure as JSON: headings, paragraphs, lists, tables.
- Your script turns the JSON into a document with
python-docx, applying styles from the company template. - The script validates the result: is the JSON valid, are there empty sections, are any
[TO CONFIRM]placeholders left.
This way formatting does not depend on the model's mood: fonts, margins and headings are always identical because the template defines them. For editing existing files the flow is reversed: code extracts paragraph text, the model returns corrected versions, and code writes them back.
Installation:
pip install python-docx openaiCreate a key in the dashboard; Python client examples are in the documentation.
Creating Word documents with a model: JSON and python-docx
First, a function that asks the model for a structure and parses the answer carefully:
import json
from docx import Document
from openai import OpenAI
client = OpenAI(base_url="https://api.zukko.pro/v1", api_key="fetch_your_key")
MODEL = "claude-sonnet-5-5"
SYSTEM = """You prepare the structure of a business document.
Return only JSON, with no explanations and no code fence:
{"title": "...", "sections": [{"heading": "...", "paragraphs": ["..."],
"bullets": ["..."], "table": {"header": ["..."], "rows": [["..."]]}}]}
The bullets and table fields are optional.
Do not invent details, amounts or dates: if data is missing, write [TO CONFIRM]."""
Now the file builder. The style names Heading 1, List Bullet and Table Grid exist in the default python-docx template:
def build_docx(data, path, template=None):
doc = Document(template) if template else Document()
doc.add_heading(data["title"], level=0)
for s in data["sections"]:
doc.add_heading(s["heading"], level=1)
for p in s.get("paragraphs", []):
doc.add_paragraph(p)
for b in s.get("bullets", []):
doc.add_paragraph(b, style="List Bullet")
t = s.get("table")
if t:
table = doc.add_table(rows=1, cols=len(t["header"]))
table.style = "Table Grid"
for i, h in enumerate(t["header"]):If your company has its own template, pass its path as template. Styles are then taken from it, but the style names must match: if the template has no List Bullet style, the library raises an error. Check the style names in your file before running.
Editing an existing document
For editing, code numbers the paragraphs and sends them to the model with an instruction. The model returns JSON containing only the numbers that need to change:
EDIT_SYSTEM = """You receive document paragraphs as JSON {"number": "text"} and an instruction.
Return JSON only with the numbers whose text must change: {"number": "new text"}.
Do not add or remove numbers. Do not change facts, figures or names."""
def edit_docx(src, dst, instruction):
doc = Document(src)
items = {str(i): p.text for i, p in enumerate(doc.paragraphs) if p.text.strip()}
user = f"Instruction: {instruction}\n\nParagraphs:\n" + json.dumps(items, ensure_ascii=False)
changes = ask_json(EDIT_SYSTEM, user)
for key, new_text in changes.items():
if key not in items:
continue # the model invented a number: skip it
p = doc.paragraphs[int(key)]
if p.runs:This approach has honest limits:
- Formatting inside a paragraph (a bold fragment in the middle of a line) is lost: the style of the first run remains.
- Text in tables, headers, footers and footnotes is not in
doc.paragraphs; walk those separately. python-docxworks only with.docx. Re-save an old.docfirst.- There is no review mode here: edits replace text. Keep the original and compare versions with the built-in document comparison in Word.
Validating the result
Do not open every file by eye when there are many documents. Add automatic checks:
- the JSON parsed, and every section has a heading and at least one paragraph;
- no
[TO CONFIRM]leftovers remain, or the list of them is passed to a person; - when editing, the paragraph count did not change, and the numbers and dates from the original are still in the text (a regular expression over digits);
- every table row has the same number of columns.
For legal and financial documents the model gives only a draft. A person still does the final read, and it is better to insert details and amounts from your own database in code than to ask the model to "recall" them.
What it costs
Suppose a three-page document: about 6000 tokens in (the task and a sample structure) and about 6000 tokens of JSON out. These are assumptions for the calculation; real values depend on the text. Prices as of October 18, 2026, $ per 1M tokens:
claude-sonnet-5-5(0.4 input, 2 output): 6000 × 0.4 / 1,000,000 + 6000 × 2 / 1,000,000 = 0.0024 + 0.012 = $0.0144 per document;gpt-6.1-sol(0.27 / 1.32): 0.00162 + 0.00792 = $0.00954;deepseek-v4.1-flash(0.013 / 0.038): 0.000078 + 0.000228 = $0.000306.
A hundred such documents on claude-sonnet-5-5 come to about $1.44. Cheaper models suit standard template paperwork, but check the quality of the wording on your own examples: compare two or three results blind before launching a batch. Current prices are at GET https://api.zukko.pro/v1/models or on the "Models" page in the dashboard. Payment from Russia: SBP (the payment page adds an 8.5% fee on top), a MasterCard, or cryptocurrency.
If the volume grows, see the articles on translating files without broken placeholders and extracting data from documents.
FAQ
Can a neural network create a Word file by itself?
Not by itself: a model returns text. Your code creates the file, for example with python-docx, while the model supplies the content and a JSON structure.
How do I keep the corporate document style?
Prepare a .docx template with the styles you need and open it with Document("template.docx"). The model controls only the content; the formatting comes from the template.
Can I edit a document without losing formatting?
Partly. Headings, paragraph styles and tables survive, but formatting inside a paragraph (individual bold words) is lost when the text is replaced. For targeted edits, send the model only the paragraphs you need.
Which model should I use for documents?
Inexpensive models from the catalog are enough for standard paperwork; for complex texts take a stronger one. Compare by price, context and the strength index in the model list, and test on your own documents.
zukko
Pay 25×
less
for Claude Code & ChatGPT
One fetch_* key and base URL api.zukko.pro — for Cursor, Claude Code, Codex, and any SDK.
Related articles
- Translating subtitles with a neural network: SRT without broken timecodesThe main risk when translating SRT with a neural network is a broken file structure. A scheme where timecodes never reach the model, and a Python script with validation.
- Editing texts with a neural network: proofreading, style and cuttingDifferent kinds of editing need different prompts. Wording for proofreading, style and cutting, how to get edits with explanations and how not to lose the author's voice.
- A neural network for writing scripts: Bash, PowerShell and PythonA model writes scripts for routine fast, but running them blindly is risky. How to state the task, demand a safe dry-run mode and check the result before launch.
- Dify in Docker: installation, first-run setup and connecting modelsInstall Dify with Docker Compose, create the admin account and connect Claude, GPT and DeepSeek models on one key. Plus what to do when containers will not start.