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

  1. Data preparation — a CSV with SKU, category, name, and specs.
  2. Generation — for each product, the specs go to the model along with a detailed brief.
  3. Validation — length, banned phrases, contacts, and links in the text.
  4. 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:

bash
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.

bash
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 ThreadPoolExecutor processes up to four products at a time instead of one by one. If 429 responses start appearing, lower max_workers.
  • Errors don't stop the run. A failure on one product lands in the status column as error: ..., and the rest keep going.
  • Validation doesn't replace a human. A check: ... status means the text needs a look. An ok status means no obvious violations were found, but the script won't catch factual mistakes.
  • Token tracking. The tokens column comes from the response's usage field, so you can see the real usage.

Running it

bash
pip install requests
export ZUKKO_API_KEY=fetch_your_key
python generate_descriptions.py

The 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.

ModelPrice in/out per 1MCalculation1,000 products10,000 products
glm-5.3-flash$0.04 / $0.040.3 × 0.04 + 0.6 × 0.04$0.036$0.36
gpt-5.6-luna$0.1 / $0.10.3 × 0.1 + 0.6 × 0.1$0.09$0.90
claude-sonnet-5$0.3 / $0.30.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.

Get API keyDocumentation

api.zukko.pro · fetch_*

Wildberries and Ozon product descriptions with AI · Zukko