Generate product descriptions for Wildberries and Ozon via AI
A Python script that takes product specs from a CSV, generates descriptions via Zukko, flags texts with violations, and saves the result.
5 min · · бизнес · автоматизация
When your catalog has hundreds of items, writing a description for each Wildberries and Ozon card by hand takes a long time, and supplier descriptions often boil down to a list of specs. Generating product descriptions with an AI model solves this in a single run: a script takes the specs from a table, the model writes coherent text, and an automatic check filters out obvious violations. Below are a ready-made Python script, a cost estimate, and how to upload the results to the marketplaces.
How the process works
- Data preparation — a CSV with SKU, category, name, and specs.
- Generation — for each product, the specs go to the model along with a detailed brief.
- Validation — length, banned phrases, contacts, and links in the text.
- Export — a CSV with descriptions and a check status; then upload via the seller dashboard or the marketplace API.
The model writes only from what you give it. The more precise the specs, the less filler in the text and the lower the risk that the model "invents" properties the product doesn't have.
Preparing the CSV
A UTF-8 file products.csv:
product_id,category,name,characteristics
A-1001,Electronics,X15 Smartphone,"6.5-inch screen, 5000 mAh battery, 50 MP main camera, 128 GB storage"
A-1002,Electronics,LP12 Headphones,"Bluetooth 5.3, active noise cancellation, up to 30 hours of playback"
A-1003,Home and Garden,LED bulb 10 W,"E27 base, cool white 6500 K, 900 lm"Fields:
product_id— your SKU, used to match results later;category— product category;name— product name;characteristics— everything known about the product: dimensions, materials, contents, features.
A Python script for generating descriptions
There's one dependency: pip install requests. The key goes in the ZUKKO_API_KEY environment variable. Since Wildberries and Ozon are Russian-language marketplaces, the brief in PROMPT is in Russian; here it's shown in English for readability — keep the language your cards need.
import csv
import os
import re
import sys
from concurrent.futures import ThreadPoolExecutor
import requests
API_URL = "https://api.zukko.pro/v1/chat/completions"
MODEL = "glm-5.3-flash"
MIN_LEN, MAX_LEN = 800, 2000 # length bounds in characters, set your own
FORBIDDEN = ["best", "no. 1", "guaranteed", "100%", "unmatched"]
CONTACTS_RE = re.compile(What matters in it:
- Concurrency. A
ThreadPoolExecutorprocesses up to four products at a time instead of one by one. If429responses start appearing, lowermax_workers. - Errors don't stop the run. A failure on one product lands in the
statuscolumn aserror: ..., and the rest keep going. - Validation doesn't replace a human. A
check: ...status means the text needs a look. Anokstatus means no obvious violations were found, but the script won't catch factual mistakes. - Token tracking. The
tokenscolumn comes from the response'susagefield, so you can see the real usage.
Running it
pip install requests
export ZUKKO_API_KEY=fetch_your_key
python generate_descriptions.pyThe result is descriptions.csv with the columns product_id, name, description, status, tokens. Open it in a spreadsheet, filter rows whose status isn't ok, and fix them by hand or rerun generation for them.
Cost estimate
Russian text usually takes more tokens than words, so estimate with a margin: about 300 input tokens (brief plus specs) and about 600 output tokens per product. For 1,000 products that's 0.3M input and 0.6M output tokens.
| Model | Price in/out per 1M | Calculation | 1,000 products | 10,000 products |
|---|---|---|---|---|
glm-5.3-flash | $0.04 / $0.04 | 0.3 × 0.04 + 0.6 × 0.04 | $0.036 | $0.36 |
gpt-5.6-luna | $0.1 / $0.1 | 0.3 × 0.1 + 0.6 × 0.1 | $0.09 | $0.90 |
claude-sonnet-5 | $0.3 / $0.3 | 0.3 × 0.3 + 0.6 × 0.3 | $0.27 | $2.70 |
After the first run, replace the estimate with real numbers from the tokens column. Test which model writes acceptable texts for your categories yourself: generate descriptions for 20 products with two or three models and compare them side by side. The current model list is at GET https://api.zukko.pro/v1/models or on the "Models" page in the dashboard; request parameters are in the Chat Completions docs.
Uploading to Wildberries and Ozon
For the first batches, the most reliable route is uploading descriptions through the seller dashboard (bulk card editing via a spreadsheet template): you see exactly what changes.
For automated uploads, both marketplaces have APIs: the Wildberries Content API (docs at dev.wildberries.ru) and the Ozon Seller API (docs.ozon.ru/api/seller). Method names, versions, and attribute IDs change there, so take them only from the current documentation, not from examples in articles. Before a bulk update, check two things:
- whether the method overwrites the whole card — if so, fetch the current card first and change only the description;
- whether the updated card passes moderation — start with a few products.
Marketplace requirements
Wildberries and Ozon each have their own description rules, and they change periodically: allowed length, a ban on contacts and links, limits on promotional wording. Check them against the current rules in the seller dashboard and carry them into the script: length bounds into MIN_LEN and MAX_LEN, banned words into FORBIDDEN, and the requirements themselves into the PROMPT brief.
FAQ
The descriptions come out similar to each other — what can I do?
Give the model more specifics. Instead of "smartphone with a large screen", write "6.5-inch screen, 5000 mAh battery, 185 g, black". The more unique specs in the CSV, the more the texts differ. You can also add a column with product features or the target audience and insert it into the brief.
How do I process 10,000 products?
The script above can handle it, but run it in parts of 500–1,000 rows: that makes it easier to review results and rerun errors. Set a daily spend limit on the key in the dashboard — it protects you from unexpected overspending if something goes wrong.
The marketplace rejected a description — why?
Common reasons: the text is longer than allowed, or it contains banned wording, contact details, or claims the specs don't support. Add the offending words to FORBIDDEN and the requirement to the brief.
Can I generate descriptions from a product photo?
That's a separate task: it needs a model with image support and a different request format — check the docs for which models support it. For descriptions, relying on the supplier's specs is more dependable: the model has less room to guess.
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
- AI for testers: test cases, checklists and bug reportsHow a QA engineer can use a model for test cases, checklists and bug reports, check coverage, and avoid requirements the model made up.
- Anonymizing data before sending it to a neural network: a practical wayYou do not have to send personal data to a model for it to process a document. How to replace it with labels, restore it in the answer and check that nothing leaked.
- A neural network for HR: job posts, candidate emails and resume reviewA model can draft job posts and emails and do a first-pass resume review. What to hand over, how to treat candidates' personal data and how to prevent biased decisions.
- Generating an FAQ with a neural network from tickets and a knowledge baseA good FAQ is built on what customers really ask. A pipeline: group the tickets, answer from the knowledge base with a source reference, and verify the result.