Skip to content
TutujinAPI

Bulk content production

For product descriptions and marketing copy at volume, a cheap chat model writes the drafts and a stronger model checks and polishes a sample of them. For 20,000 descriptions a month with 10% reviewed, at live prices in each model’s cheapest group, model costs are about ¥152 a month. Concurrency, queueing and retries all live in your own code.

Prices updated Nov 13, 2026, 1:33 AM

Monthly cost estimate

Assumptions: 20,000 product descriptions a month, each with about 800 input tokens (attributes, brand voice and one example) and about 400 output tokens; 10% (2,000) reviewed by a stronger model at about 1,200 input and 300 output tokens each.

¥151.68per month

  • Drafting¥134.4
  • Spot-check and polish¥17.28
See the usage assumed

The business problem

New listings, content marketing and ad campaigns all need a lot of text: a description per SKU, a set of titles per channel, dozens of lines per promotion. Writers cannot keep up, and outsourced quality varies.

Getting a model to write one description is easy. Producing tens of thousands reliably is harder: jobs need a queue and concurrency, rate limits and network errors need retries, the tone has to stay consistent, and the copy must not invent features.

The usual approach is to turn product attributes into structured data, generate drafts from a fixed template, then send a sample to a stronger model or a person for review and rerun any batch with repeated problems.

Recommended models

Recommended models are picked from the live catalog; prices are each model's cheapest group, updated Nov 13, 2026, 1:33 AM. Click a model to see every group's price.

Reference architecture

  1. 1

    Prepare inputs

    Turn product attributes (name, material, specs, use cases) and the brand voice guide into structured data, with banned words and claims in a separate list.

  2. 2

    Queue with fixed concurrency

    Put jobs in a queue and call the chat model with a fixed number of concurrent requests, say 8 to 16. Retry 429 and 5xx with exponential backoff; log 400-type errors and fix the input instead of retrying.

  3. 3

    Generate drafts

    Keep the system prompt fixed and put each product’s attributes in the user message. Cap the output length and ask for paragraphs or JSON so results go straight into your database.

  4. 4

    Automatic checks

    Check length, banned words and any numbers or certifications that are not in the attributes; send failures back for a rewrite.

  5. 5

    Review a sample

    Send about 10% to the stronger model for review and polish, rerun batches with repeated problems, and have someone skim before publishing.

Cost estimate

Assumptions: 20,000 product descriptions a month, each with about 800 input tokens (attributes, brand voice and one example) and about 400 output tokens; 10% (2,000) reviewed by a stronger model at about 1,200 input and 300 output tokens each.

ItemModelUsage assumedCost
Draftingdeepseek-v4.1-flash20,000 × (800 input + 400 output tokens)¥134.4
Spot-check and polishClaude Sonnet 5.52,000 × (1,200 input + 300 output tokens)¥17.28
Total (per month)¥151.68

Calculated from live prices in each model's cheapest group, updated Nov 13, 2026, 1:33 AM.

Model usage only. Retries add calls, so a high failure rate raises the cost. Twice the items means roughly twice the cost; longer descriptions raise the output cost.

Sample code

A semaphore caps the requests in flight; 429, 5xx and network errors are retried with exponential backoff, other 4xx errors are logged, and results are written as JSONL for import.

Sample code (Python, async concurrency and retries)
import asyncio
import json
import os
import random

from openai import APIConnectionError, APIStatusError, AsyncOpenAI

client = AsyncOpenAI(base_url="https://www.tutujin.com/v1", api_key=os.environ["TUTUJIN_API_KEY"], max_retries=0)
LIMIT = asyncio.Semaphore(8)  # requests in flight at the same time

PROMPT = (
    "Write a product description for an online store in a friendly, concrete tone. "
    "Use only the facts provided. Do not add awards, certifications or numbers that are not listed. "
    "Return 3 short paragraphs."
)


async def write(product, attempts=4):
    async with LIMIT:
        for i in range(attempts):
            try:
                resp = await client.chat.completions.create(
                    model="deepseek-v4.1-flash",
                    messages=[
                        {"role": "system", "content": PROMPT},
                        {"role": "user", "content": json.dumps(product, ensure_ascii=False)},
                    ],
                    max_tokens=600,
                    temperature=0.8,
                )
                return {"sku": product["sku"], "text": resp.choices[0].message.content}
            except APIConnectionError:
                pass  # network problem or timeout: retry
            except APIStatusError as e:
                if e.status_code != 429 and e.status_code < 500:
                    # 4xx means the request itself is wrong (or no balance): fix it, do not retry
                    return {"sku": product["sku"], "error": e.status_code}
            await asyncio.sleep(2 ** i + random.random())  # back off: ~1s, 2s, 4s, 8s
        return {"sku": product["sku"], "error": "gave up after retries"}


async def main(products):
    results = await asyncio.gather(*(write(p) for p in products))
    with open("descriptions.jsonl", "w", encoding="utf-8") as f:
        for r in results:
            f.write(json.dumps(r, ensure_ascii=False) + "\n")


products = [
    {"sku": "A1001", "name": "Ceramic mug", "material": "stoneware", "capacity_ml": 350, "dishwasher_safe": True},
]
asyncio.run(main(products))
# then send about 10% of the results to claude-sonnet-5-5 for a fact and tone check

Try this with one key

Sign up, create an API key in the console, and put your base_url and key into the code above. For company purchasing or invoices, add our WeChat support JsnonoChat.

Tutujin support WeChat QR code
WeChatJsnonoChat

Scan the code or search the WeChat ID to add us

FAQ

What do 20,000 product descriptions a month cost?

At about 800 input and 400 output tokens each, plus a 10% review by a stronger model, the cheapest groups come to about ¥152 a month. Longer output costs more, so set a length limit in the prompt.

Is there a dedicated bulk endpoint?

No. Bulk jobs are concurrent calls to the regular Chat Completions endpoint, billed by actual usage, with concurrency, queueing and retries handled by your code.

How much concurrency should I use?

Start with 4 to 8 concurrent requests and raise it while watching the share of 429 responses. On a 429, wait before retrying instead of resending immediately. Models and groups handle different loads; see the rate-limit notes in the docs.

How do I stop the model from inventing selling points?

Give the model only the attributes the product has, state in the prompt that it must not add benefits, certifications or numbers beyond them, and check the numbers and keywords in each output against the attributes.

Can generated copy go live directly?

Review a sample first. Product and ad copy are subject to advertising rules the model does not know for your market, so have marketing or legal check it before it goes live.