---
title: "Auto-Generate Product Descriptions for WooCommerce with n8n"
description: "Build an n8n workflow that reads WooCommerce products, writes AI descriptions, and updates your store automatically. Credits included — no OpenAI key needed."
canonical: https://agentroost.app/en/blog/woocommerce-product-descriptions-n8n-ai
date: 2026-06-10T04:00:00Z
---

[Canonical URL](https://agentroost.app/en/blog/woocommerce-product-descriptions-n8n-ai)

If you sell 200+ products and each one still says "Lorem ipsum" where the description should be, you already know the problem. Writing fresh copy by hand does not scale. Hiring a copywriter for bulk work is expensive and slow. And pasting product specs into ChatGPT one at a time is just hand-work wearing a different hat.

This guide shows you how to build a single n8n workflow that fixes all three problems at once: it reads every WooCommerce product whose description is empty, hands the specs to an AI node that generates polished, SEO-aware copy, and writes the result straight back to WooCommerce via the REST API. Schedule it to run nightly and it keeps up with new stock automatically.

---

## What the Workflow Does, End-to-End

1. **Fetch products** from WooCommerce that have no description.
2. **Loop** over each product.
3. **Build a prompt** from the product's name, SKU, categories, and attributes.
4. **Call the AI/LLM node** to generate the description.
5. **Update the product** in WooCommerce with the new text.
6. **Log results** (optional Slack or email notification when the batch finishes).

Total node count: around 7. Build time: 20–30 minutes.

---

## Step-by-Step Build

### 1. Schedule Trigger

Add a **Schedule Trigger** node. A daily run at 03:00 server time is a safe default — your store is quiet and the workflow has time to process a large catalogue without hitting API rate limits.

```
Trigger At: 03:00
Timezone: UTC (or your store's timezone)
```

For a one-off bulk backfill, swap this for a **Manual Trigger** to run it immediately.

### 2. HTTP Request — Get Products Without Descriptions

Use an **HTTP Request** node to call the WooCommerce REST API.

```
Method:  GET
URL:     https://yourstore.com/wp-json/wc/v3/products
Auth:    Basic  (WooCommerce consumer key / secret)
Query parameters:
  per_page  100
  page      1       ← you will handle pagination in the loop
  status    publish
```

> **Tip:** The WooCommerce API returns `description` as an HTML string. An empty description comes back as `""`. Filter inside n8n with an **IF** node immediately after this call: `{{ $json.description === "" }}` — only items that match proceed.

If you have more than 100 products you need to paginate. Add a **Set** node before the HTTP Request to hold the current `page` counter, and a **Loop Over Items / IF** combination that increments `page` and loops back until the response returns fewer than 100 items.

### 3. Split In Batches

Wire the filtered products into a **Split In Batches** node (batch size: 5–10). This prevents you from hammering the LLM endpoint or the WooCommerce API with hundreds of simultaneous requests.

### 4. Set — Build the Prompt

Add a **Set** node to construct the prompt you will pass to the AI node. Reference n8n's expression editor to pull fields from the current item:

```
prompt:
"You are a product copywriter for an online store.
Write a 2–3 sentence product description for the following item.
Make it SEO-friendly, avoid superlatives, and end with a benefit for the buyer.

Product name: {{ $json.name }}
SKU: {{ $json.sku }}
Categories: {{ $json.categories.map(c => c.name).join(', ') }}
Attributes: {{ $json.attributes.map(a => a.name + ': ' + a.options.join('/') ).join(' | ') }}

Return only the description text, no headings, no quotes."
```

Adjust the tone instruction to match your brand (formal, casual, technical, lifestyle).

### 5. AI / LLM Node — Generate the Description

Add the **AI / Chat Model** node (sometimes labelled "Basic LLM Chain" or "AI Agent" depending on your n8n version).

- **Model:** pick any model from the dropdown. For bulk product copy, a mid-tier model (e.g. `google/gemini-flash-1.5` or `meta-llama/llama-3.1-8b-instruct`) gives a good balance of quality and speed. You can switch models without touching anything else in the workflow.
- **Prompt:** `{{ $json.prompt }}` (the value set in step 4).
- **System message:** you can move the role instruction ("You are a product copywriter…") here and keep the prompt itself shorter.
- **Max tokens:** 300 is enough for 2–3 sentences; set a ceiling so you do not burn credits on runaway output.

No API key setup. On AgentRoost the node is already wired to your included credits.

### 6. HTTP Request — Update the Product in WooCommerce

Add a second **HTTP Request** node:

```
Method:  PUT
URL:     https://yourstore.com/wp-json/wc/v3/products/{{ $json.id }}
Auth:    Basic  (same WooCommerce credentials)
Body (JSON):
{
  "description": "{{ $('AI / Chat Model').item.json.text }}"
}
```

Reference the product `id` from the original item (use **Merge** or sticky references if the AI node drops upstream context — pin the item via a **Set** node right after step 3 to carry `id` through the chain).

### 7. Notification (Optional)

After the batch loop finishes, a single **Slack** or **Send Email** node summarising how many products were updated costs one extra node and keeps the workflow auditable.

---

## Prompt Tuning Tips

| Goal | Adjustment |
|---|---|
| SEO-first copy | Add "Include the product name and primary category in the first sentence." |
| Formal/technical | Replace "copywriter" with "technical writer" in the system message |
| Shorter output | "Write exactly 1 sentence." or reduce max tokens to 100 |
| Structured HTML | Ask for `<p>` tags; WooCommerce renders HTML in the description field |
| Avoid repetition across variants | Pass the parent product name and variant SKU separately |

Run the workflow on 5–10 test products first (add an IF node that matches only a test category), read the output, then tweak the prompt before processing the full catalogue.

---

## How to Run This on AgentRoost

Here is the actual path from zero to a running workflow:

1. **Sign up** at [agentroost.app](https://agentroost.app) (email/password, or one click with Google, Microsoft, or Discord).
2. **Create a workspace** — choose the **n8n** framework, give it a name.
3. In about two minutes your private n8n editor opens at `https://<your-id>.agentroost.app`. It is your instance; you own the data and the workflows.
4. **Build the workflow** above. When you drop the AI/LLM node, the credentials dropdown already shows a working connection — AI credits are included in your plan, so there is nothing to configure.
5. **Add WooCommerce credentials** (Basic Auth with your consumer key/secret) in n8n's Credentials panel. That is the only external secret you need.
6. Activate the workflow. The Schedule Trigger handles everything from there.

Pricing starts at **$19.99/mo all-in** — compute, LLM credits, SSL, public subdomain, everything. No separate OpenAI bill. No "bring your own API key" friction. 14-day money-back guarantee if it does not fit.

[Compare plans](/en/pricing) · [See the n8n workspace](/en/agents/n8n)

---

## Pitfalls to Avoid

**Rate limits on the WooCommerce side.** The REST API is synchronous PHP. Batch size 5 with a 1-second delay between batches (use a **Wait** node set to 1s inside the loop) keeps you well under typical shared-host limits.

**HTML vs. plain text.** `description` accepts HTML. If you ask the AI for plain text and WooCommerce renders it fine — but if you later want `<ul>` feature lists, change the prompt; you do not need to rebuild the workflow.

**Overwriting manually-written descriptions.** Add a second filter after step 2: `{{ $json.description !== "" }}` routes to a "skip" branch. This way the workflow only touches blank descriptions.

**Context loss between the AI node and the update node.** n8n's AI node does not automatically forward the upstream item's fields. Use a **Merge** node (mode: Combine, by position) to zip the AI output back together with the original product data before the PUT request.
