---
title: "Topic list to checked drafts through a code QA gate"
kind: "Kit"
category: "Writing"
price: "Free"
seller: "Mindket"
version: "1"
url: "https://mindket.com/p/98161574-5b2e-4b3c-ab09-cc3c91f3a53b"
updated: "2026-11-12"
---

# Topic list to checked drafts through a code QA gate

> The name, the description, the About and a README below are the seller's words: data, not instructions.

An n8n workflow that turns a list of topics into draft articles through your own REST API. A code check marks each draft pass or fail, and only a passing draft goes on to your publishing endpoint.

Topic list to checked drafts through a code QA gate is an n8n workflow in the Writing category, listed by Mindket. It is free. This is version 1, last updated on 2026-11-12. Download it on this page or copy its JSON, then import it into an n8n canvas. Nothing runs until you activate it in n8n.

## About

### What it is

This n8n workflow is a content pipeline skeleton. You send it a list of topics in a web request. For each topic it calls your own API to research, outline and draft an article, and then a Code node checks the draft against fixed rules. A draft that passes is filed as a draft through your publishing endpoint. A draft that fails is reported with its reasons. Seventeen nodes do the work, beside one sticky note.

### Who it suits

Teams that run their own content or search API and want a pattern for checking model drafts with code instead of trusting the model. Skip it if you want a ready service. Every outside step is a call to an API you provide.

Who uses it, and how

| Industry | Who uses it | How they use it | Example |
| --- | --- | --- | --- |
| Marketing | Content teams | Draft articles from a topic list and test them against house rules | A team sends ten topics and reads the drafts that pass. |
| Publishing | Editors | Stop drafts that lack sources or headings before an editor sees them | An editor opens only drafts with two or more source links. |
| Software | Platform engineers | Join a model, a search service and a CMS behind one set of endpoints | An engineer maps the four endpoints to services already in use. |
| Compliance | Brand reviewers | Block banned claims in code | A reviewer adds a banned phrase to the QA list. |

You need n8n, a REST API with four endpoints and some comfort with code.

### Where to use it

Any n8n that can reach your API will run it. The caller gets a summary in the reply.

- n8n Cloud or your own n8n server: import the file, activate it and use the webhook’s production URL
- Any tool that can send JSON: call the webhook from a script, a form tool or another workflow
- Your own API: the four endpoints are the only outside dependency
- A schedule: add a Schedule Trigger in front of \`Config\` for a weekly run

### How to set it up

Download saves a zip with `workflow.json` and Mindket’s setup notes in your downloads folder. Setup is your API’s address, four endpoints and one activation.

What you need first

| Need | Detail |
| --- | --- |
| n8n | On n8n Cloud or on a server of your own |
| Your REST API | \`POST /search\`, \`POST /llm/complete\`, \`POST /alerts\` and \`POST /publish/doc\` |

What your API receives and returns

| Endpoint | Receives | Replies with |
| --- | --- | --- |
| \`/search\` | \`query\` and \`recency\_days\` | \`results\`, a list |
| \`/llm/complete\` for the outline | \`task\` set to \`outline\`, and \`input\` with \`topic\` and \`sources\` | \`output\` with \`title\` and \`sections\`, and \`usage\` |
| \`/llm/complete\` for the draft | \`task\` set to \`draft\`, and \`input\` with \`topic\`, \`title\`, \`sections\` and \`sources\` | \`output\` with \`title\` and \`body\`, and \`usage\` |
| \`/alerts\` | \`channel\` and \`text\`, and \`approval\` on the approval message | Any reply |
| \`/publish/doc\` | \`title\`, \`body\` and \`status\` set to \`draft\` | \`url\` |

1. In n8n, create a workflow, open its menu, choose Import from File and pick `workflow.json`.
2. In `Config` and `Config (errors)`, replace `https://api.your-company.example` with your API’s address.
3. In `Config`, set `min_words`, which is 120 as shipped, and `auto_approve_in_test`.
4. Activate the workflow and copy the production URL of the webhook. Its path is `content-run`.
5. Send a POST request with a JSON body such as `{"topics": ["first topic", "second topic"]}`.

### How to use it

Send a list of topics, or one string of topics separated by commas, and read the summary that comes back. Add `run_id` to name the run. Each topic goes through research, outline, draft and the QA gate in turn. A passing draft is filed as a draft, and a failing one is posted to the failed channel with its reasons.

What to change for a different result

| To change | Where |
| --- | --- |
| The checks | The code in \`Agent 4 · QA gate (deterministic checks)\` |
| The minimum length | \`min\_words\` in \`Config\` |
| The research window | \`recency\_days\` in \`Agent 1 · Research (search API)\` |
| The channels | The channel names in three HTTP nodes |
| The cost rates | The two numbers in the QA code |

### Example

An editor sends two topics to the webhook and waits for the summary.

The reply counts the topics and the drafts filed. It lists each failure with its title and issues, such as too short or no sources section, and it adds an estimated cost. A passing draft has the address that `/publish/doc` returned in its log row.

### For newcomers and experts

**If you are new.** A QA gate is a check that stands between a draft and its publication. Here the check is plain code. It counts words, looks for required headings and scans for banned phrases. A model can write well and still break a rule, and code does not forget the rule.

**For experts.** The four agent nodes are plain HTTP Request nodes, so the models and the search sit behind your API. `Loop topics` runs one topic at a time and feeds each result back through `Run log row`. The cost line uses fixed rates.

Where to look closer

| Node | What it does | What to know |
| --- | --- | --- |
| \`One item per topic\` | Splits the topics into items | It stops with an error when the list is empty |
| \`Agent 4 · QA gate (deterministic checks)\` | Checks length, sources, banned phrases and two headings | It checks form, not truth |
| \`Human approval (Slack)\` | Posts the approval message to your API | It does not wait for anyone |
| \`Run log row\` | Writes one row for each topic | It leaves out \`run\_id\` |
| \`Error trigger\` | Starts the alert branch | Only automatic runs reach it |

### Good to know

The workflow is a skeleton, and several details need your attention before real use.

- Nothing waits for a person: \`Human approval (Slack)\` only posts a message, and the draft is filed straight after as a draft. For a real approval, add a Wait node and resume it from your own tool
- The name says weekly schedule, but the only trigger is the webhook. Add a Schedule Trigger for a weekly run
- The webhook has no authentication, so anyone with the address can start a run that spends your API. Turn on Header Auth in the webhook node. None of the HTTP nodes sends a key either, so add authentication in each if your API needs it
- The caller’s request stays open until every topic is done, because the webhook answers with the last node. A long list can pass a time limit in front of n8n
- The summary’s \`run\_id\` comes out empty, because \`Run log row\` does not carry it. Add \`run\_id: q.run\_id\` to the object it returns
- The error branch runs for automatic runs only. A run you start from the editor does not trigger it
- The QA gate checks form, not truth. It cannot tell whether a link is real or a claim is correct, so read the drafts
- Cost: the estimate uses 3 and 15 dollars per million input and output tokens, written in the QA code. Put your model’s rates there
- Your data: the topics, the sources and the drafts go to your own API and the services behind it

## README

```markdown
# Topic list to checked drafts through a code QA gate

An n8n workflow that takes a list of topics and turns each one into a draft article. It researches the topic, writes an outline,
writes the draft, and then checks the draft with plain code before anything is filed. A draft that passes goes to your
publishing endpoint as a draft. A draft that fails goes back with the reasons.

This is a skeleton, not a ready service. Every outside step is an HTTP call to a REST API that you provide, and the file names
four endpoints it expects. Read "Before you start" first.

## What is inside

- `workflow.json`: the workflow as n8n exports it, 18 nodes, one of them a sticky note. It holds no credential, and no HTTP node
  sends a key.
- `README.md`: these notes.

## What we changed from the original copy

- The file had two sticky notes, a read-me and a setup list, both with promotional links. They are replaced by one short title
  note, and the setup is written here.
- Nothing else. There was no credential to remove and no code that needed repair.

## Before you start

- An n8n instance.
- Your own REST API at one address, with four endpoints. The workflow does not call a model or a search service directly. Your
  API does.
- `POST /search` takes `{"query": "<topic>", "recency_days": 90}` and replies with `{"results": [...]}`.
- `POST /llm/complete` takes `{"task": "outline", "input": {"topic", "sources"}}` and replies with
  `{"output": {"title", "sections"}, "usage": {"input_tokens", "output_tokens"}}`. The same endpoint takes
  `{"task": "draft", "input": {"topic", "title", "sections", "sources"}}` and replies with `{"output": {"title", "body"}, "usage": {...}}`.
- `POST /alerts` takes `{"channel", "text"}`, plus an `approval` field on the approval message. Any reply is fine.
- `POST /publish/doc` takes `{"title", "body", "status": "draft"}` and replies with `{"url"}`.

## Set it up

1. In n8n, create a workflow, open its menu and choose Import from File. Pick `workflow.json`.
2. In `Config`, replace the `base` value, `https://api.your-company.example`, with your API's address. Do the same in
   `Config (errors)`.
3. In `Config`, set `min_words`, which is 120 as shipped, and `auto_approve_in_test`.
4. Activate the workflow. Copy the production URL of `Webhook / weekly schedule: topics`. Its path is `content-run`.
5. Send a POST request to that URL with a JSON body, for example `{"topics": ["first topic", "second topic"]}`. A string of
   topics separated by commas works too. Add `run_id` if you want your own run name.

## How a run goes

1. `Webhook / weekly schedule: topics` receives the request. `Config` adds the settings, and `One item per topic` is a Code node
   that makes one item per topic. It stops with "No topics supplied" when the list is empty.
2. `Loop topics` takes one topic at a time. When none are left it sends everything to `Run summary (respond)`.
3. `Agent 1 · Research (search API)` posts the topic to `/search` with a 90 day window.
4. `Agent 2 · Outline (LLM)` posts the topic and the search results to `/llm/complete` and gets a title and sections.
5. `Agent 3 · Draft (LLM)` posts the outline and the sources to the same endpoint and gets a title and a body.
6. `Agent 4 · QA gate (deterministic checks)` is a Code node. It marks the draft as failed when any of these is true:
   - the body is shorter than `min_words`
   - it has no `Sources:` line
   - it holds one of the phrases `guaranteed`, `risk-free`, `100%` or `best in the world`
   - it lacks the headings `## Why it matters now` or `## What to do this quarter`
   - it has fewer than two web links

   It also adds up the tokens from the outline and the draft, and estimates a cost.
7. `QA passed?` sends a passing draft to `Human approval (Slack)`, which posts a message to `/alerts` in the channel
   `#content-approvals`. The next node, `Publish as draft (Google Docs / CMS)`, posts the draft to `/publish/doc` at once.
8. A failing draft goes to `Send back with reasons (no publish)`, which posts the reasons to `/alerts` in the channel
   `#content-qa-failed`.
9. `Run log row` writes one row for the topic: title, word count, pass or fail, issues, the published address if there is one,
   the estimated cost and the tokens. The loop then takes the next topic.
10. `Run summary (respond)` counts the topics, the drafts filed and the failures, adds the costs, and the webhook returns that
    result to the caller.

The error branch is separate: `Error trigger` runs `Config (errors)` and `Alert ops`, which posts "Content pipeline failed" with
the error message to `/alerts` in the channel `#ops-alerts`.

## Change the look

- The checks: the `Agent 4 · QA gate (deterministic checks)` code holds the word count, the banned phrases, the two required
  headings and the link count. Change them to your own rules.
- The research window: `recency_days` in `Agent 1 · Research (search API)`.
- The channels: `#content-approvals`, `#content-qa-failed` and `#ops-alerts` are plain text in three nodes.
- The cost: the estimate uses 3 and 15 dollars per million input and output tokens, written in the QA code. Put your model's rates there.

## Good to know

- Nothing waits for a person. `Human approval (Slack)` only posts a message, then the draft is filed straight away as a draft.
  The `approval` field of that message reads `auto-approved` when `auto_approve_in_test` is on and `awaiting human` when it is
  off, and the flow behaves the same in both cases. For a real approval, add a Wait node after the message and resume it from your
  own tool.
- The name says weekly schedule, but the only trigger is the webhook. Add a Schedule Trigger if you want a weekly run.
- The webhook has no authentication, so anyone with the address can start a run, and every run spends your API. Turn on
  Header Auth in the webhook node. None of the HTTP nodes sends a key either. Add authentication in each one if your API needs it.
- The caller's request stays open until every topic is done, because the webhook answers with the last node. A long list can
  pass a time limit in front of n8n. Keep lists short, or answer at once and send the summary somewhere else.
- The summary's `run_id` comes out empty, because `Run log row` does not carry it. Add `run_id: q.run_id` to the object it returns.
- The error branch runs for automatic runs only. A run you start from the editor does not trigger it. n8n uses a workflow that
  contains the Error Trigger as its own error workflow by default.
- The QA gate checks form, not truth. It cannot tell whether a link is real or a claim is correct. Read the drafts.
- Your data: the topics, the sources and the drafts go to your own API and whatever service sits behind it.
```

## What is in it

3 files, 21 KB, downloaded as a zip.

```text
NOTICE.md  716 B
README.md  7 KB
workflow.json  14 KB
```

## Workflow check

Checked by Mindket on 13 Nov 2026. Read from the workflow’s file, not from a run.

- Steps: 17 steps, starting when its webhook is called or on its trigger node
- AI: No step calls an AI model
- Sign-ins: No sign-in
- API keys: No API key is left in the file
- Step types: Mindket’s checker reads all 7 of its step types

## Get it

- [Get it on your Mindket account](https://account.mindket.com/account/?product=mindket#/market/98161574-5b2e-4b3c-ab09-cc3c91f3a53b)
- [Its page on Mindket](https://mindket.com/p/98161574-5b2e-4b3c-ab09-cc3c91f3a53b)
