Outrank is an AI SEO content mill with a publishing pipe attached: it picks keywords for a site, writes the articles, generates the images, and pushes them live to WordPress, Webflow, Shopify or Ghost on a schedule, thirty a month without anyone opening an editor. The $99 plan also buys entry to a backlink exchange, where subscribers host links for each other's sites and spend earned credits to get links back. Add-ons scale output to ninety articles a month, or put human editors in front of every piece for $1,399.
Build me a content pipeline that replaces Outrank: keywords in, finished articles out, published to my CMS on a schedule, with the numbers to say afterwards whether any of it worked. Read this before you write a line. The writing is the easy half — an agent and an LLM API get you thirty articles a month in an afternoon. The hard half is that thirty thin articles a month is precisely how a site gets classified as scaled content abuse and loses the rankings it already had. So the gate comes before the mill: build the thing that refuses to publish first, and the scheduler last. STACK - Node 20+ with Fastify, server-rendered HTML for the admin. No client framework - SQLite through better-sqlite3, one file, WAL mode - One LLM provider behind one module and one model constant, so swapping it is a line - An image model, local or API, writing files to disk and converting to webp with sharp - node-cron inside the same process. No queue service until one process demonstrably is not enough - Caddy in front THE DATA MODEL - sites: id, name, base_url, cms, credentials_ref, default_author, sitemap_url, voice_notes, banned_phrases - keywords: id, site_id, phrase, volume, difficulty, intent, source, cluster_id, status, rejected_reason - clusters: id, site_id, name, pillar_keyword_id — supporting articles link up to the pillar, which is most of what internal linking means - briefs: id, keyword_id, target_words, headings_json, questions_json, entities_json, competitor_urls_json, created_at - articles: id, keyword_id, title, slug, markdown, meta_title, meta_description, word_count, model, prompt_version, status, internal_links_json, published_url, published_at - article_revisions: id, article_id, field, old_value, new_value, changed_by, at — append-only, because a rewrite that made things worse is only diagnosable if the old one still exists - publish_attempts: id, article_id, target, external_id, http_status, error, at — append-only - rankings: id, keyword_id, url, position, impressions, clicks, checked_at — append-only - Credentials never sit in the database. Store a reference; the secret lives in the environment THE KEYWORD LIST - Real volume and difficulty are bought, not computed. Wire one paid source behind an interface — DataForSEO is pay-per-call and cheap enough to run monthly — and make the whole system work without it - The free source that beats it for an existing site is Search Console: the queries you already get impressions for and rank eleventh on are worth more than anything a keyword tool suggests - Free supplements: autocomplete, related searches, People Also Ask, and the questions your competitors' headings answer - If no data source is configured, leave volume null and show it as unknown. Never invent a number and never let the model guess one — a fabricated volume is how a site ends up with sixty articles about a phrase nobody searches - Cluster before you queue: one intent per article, and if two keywords have the same intent they are one article, not two THE BRIEF - Fetch the top ten results for the phrase and extract their headings, their length, and the questions they answer. Store the URLs - Target length comes from what ranks, not from a setting. If the top ten average 900 words, a 2,500-word article is padding - Build an entity list — the specific things that must be mentioned for the piece to look informed - The brief is a stored row, reviewable and editable, not a string thrown at the model and forgotten WRITING, IN PASSES - Never one prompt for a whole article. Outline first as its own call, then each section as its own call with the outline and the neighbouring sections as context. Coherence comes from the structure, not from a longer prompt - Ban the register: no "in today's fast-paced world", no "it's important to note", no section that restates the heading before saying anything. Keep the banned list per site and reject drafts that contain them - Require at least one thing the model cannot know — a price, a measurement, a screenshot, a first-hand result. The model must mark these [VERIFY] rather than invent them, and an article containing an uncleared [VERIFY] cannot reach published. This is the single line of code that separates this from the tools it replaces - Generate meta title and description explicitly, to length, and reject the ones that overflow - Store prompt_version on the article. When output quality moves, you need to know which prompt produced which batch INTERNAL LINKING, WHERE AUTOMATION ACTUALLY WINS - The database knows every article you have ever published, which a human writer does not. Use it: link the new article to the relevant older ones, and go back and edit the older ones to link forward - Match on cluster and entity overlap, not on string similarity. Cap it — five links in, five out — and never link the same anchor twice on a page - Every backward edit writes an article_revisions row and republishes that post. Untracked silent edits to live pages are how a site drifts IMAGES - One header image plus one per major section, generated to a consistent style per site - Alt text is the part that matters and it is written from the section, not from the image prompt - Convert to webp, cap the long edge, and check the byte size. A page carrying four two-megabyte PNGs is slower than every competitor and that is measurable PUBLISHING - One adapter interface — create, update, unpublish — and one implementation per target: WordPress REST with an application password, Ghost Admin API with a JWT, Webflow CMS v2, Shopify, and a plain signed webhook for anything else - Every adapter is idempotent. Send your own external id and check for it before creating, because the failure mode you will actually hit is a timeout after the post was created, and a naive retry publishes it twice - Retry with backoff on 5xx and 429 only, honouring Retry-After. Never retry a 4xx: it will fail identically forever - Record every attempt with its status and body. When a CMS starts rejecting posts you want the date it began - Schedule across the month, not thirty posts on the first. A site that publishes nothing for four weeks and then a book looks exactly like what it is MEASURING WHETHER IT WORKED - Pull Search Console daily: impressions, clicks, average position, per URL and per query. Append rows, never overwrite - The only honest question is whether an article got impressions eight to twelve weeks after publication. Nothing before that means anything, so do not build a dashboard that implies otherwise - Show the failures loudly: articles published more than six months ago with fewer than ten impressions. Those get deleted or rewritten. A pile of dead pages is a liability, not an archive BACKLINKS — DO NOT BUILD THIS - The exchange is the one thing here you are actually paying for, and it is other people's domains. You cannot write it. A link network with one member in it is worth nothing, and building a reciprocal exchange yourself is a link scheme by the plain definition - If you want that, keep paying someone who already has the network, and know what you are buying - The thin layer that is worth building instead: a prospects table — site, contact, why they would link, what you sent, what came back, and the date. That is outreach tracking, it is fifty lines, and it is the only part of link building that code can honestly help with WHAT THIS COSTS TO RUN - Thirty articles a month of real length is a few dollars of tokens, plus images, plus whatever the keyword data source charges. Print the per-article cost in the admin after every run, from the actual token counts - Put that number in the README. The reason this build is worth doing is that the arithmetic is not close, and the reader should be able to see it OPERATIONS - .env: DATABASE_PATH, LLM_API_KEY, IMAGE_API_KEY, KEYWORD_API_KEY, GSC_CREDENTIALS_PATH, SESSION_SECRET, and per-site CMS tokens - Migrations applied in order on boot, each once, recorded in a table - Nightly VACUUM INTO, gzip, off-machine. The markdown is regenerable; the rankings history is not - A dry-run mode that produces the article and the publish payload and posts nothing WHAT MATTERS MOST The review step. Build the queue that holds finished articles until a person clicks approve, and resist every temptation to add an auto-publish flag. The tools in this category compete on how little you have to look at the output, and that is exactly the property that makes them dangerous to the site they are pointed at. Give me the repository, the CMS adapters with their idempotency and retry tests, the [VERIFY] gate wired into the publish path, migrations, .env.example, a dry-run script, and a README that opens with the cost per article and the review step.
What you lose
- The backlink exchange, which is other subscribers' websites — a link network with one member in it is worth nothing
- Live search volume and difficulty figures, which come from a paid data vendor and are not free to reproduce
- Publishing integrations for eight content systems, already written and repaired every time one of them changes its API
- The option to pay humans to fact-check every article before it goes out
- Someone else carrying the blame when a site publishing thirty machine-written articles a month gets demoted
If you would rather not build
- SEObot — the same auto-publishing article pipeline, sold per site
- Surfer SEO — briefs and on-page scoring, you still write the article
- Frase — SERP-derived briefs and drafting
- Koala AI — bulk AI articles with a WordPress plugin
- A cron job calling an LLM API and the WordPress REST API, which is what all of these are
What it costs
read from their page 24 Aug 2026
| Plan | Billed monthly | Billed yearly | Last read |
|---|---|---|---|
| Basic | $99/mo | — | 23 Aug 2026 |
Their pricing page is where these came from. Seeing a different price? Tell us.
The escape hatch
open source · no votes, no paid placement
n8n
$0Workflow automation that wires a keyword list through an LLM call and into a CMS on a schedule.
n8n-io/n8nfree · open source
SerpBear
$0Self-hosted rank tracker with Search Console data, so you can see whether anything published actually ranked.
towfiqi/serpbearfree · open source
Dify
$0Builds the generation chain — outline, section drafts, metadata — with prompts you can version.
langgenius/difyfree · open source
Ghost
$0The publishing end: a CMS with an admin API that accepts posts programmatically.
TryGhost/Ghostfree · open source
Why this verdict
our own opinion · changed only by a person
58/100
No note on this one yet.
History
tracked since 23 Aug 2026 · nothing is ever overwritten
Questions about Outrank
answered from the record above
Is Outrank free?
No — the plan we track is $99 a month.
Can you replace Outrank by building your own?
ALMOST. A weekend of work, and real gaps remain. Replacement score 58 out of 100, build time a weekend. Read what you lose before you decide.
How much does Outrank cost?
$99 a month on Basic — $1,188 a year. Recorded 23 Aug 2026.
What do you lose by replacing Outrank?
The backlink exchange, which is other subscribers' websites — a link network with one member in it is worth nothing; Live search volume and difficulty figures, which come from a paid data vendor and are not free to reproduce; Publishing integrations for eight content systems, already written and repaired every time one of them changes its API; The option to pay humans to fact-check every article before it goes out; Someone else carrying the blame when a site publishing thirty machine-written articles a month gets demoted. If any of those carry weight for you, keep paying.
Is there an open-source alternative to Outrank?
Yes: n8n, SerpBear, Dify, Ghost. The prompt on this page is for when you want it your way instead.
Related entries
same category first, most replaced first
Every week, something stops being worth paying for.
New verdicts, prices that moved, entries added. One email a week. Unsubscribe in one click. Nothing is being sent yet — your address is kept here, and the first issue is the first thing it is used for.
free forever · no tracking pixel · stored here, never passed to anyone

