Documentation
Everything the plugin does, what it costs and how to control it. No account needed to read any of this.
Install
Unstale needs WordPress 7.0 or newer and PHP 8.1 or newer. WordPress 7.0 is the floor because the plugin runs on the AI Client that ships with it. Unstale works with Gutenberg and the Classic editor, on posts, pages and public custom post types.
- In your WordPress admin, go to Plugins → Add Plugin, search for Unstale and install it. You can also download the zip from wordpress.org and upload it.
- Activate the plugin. A new Unstale menu appears with six screens: Get started, Review queue, Content health, Journal, AI Agent and Settings. See In the admin.
- Go to Settings → Connectors and connect an AI provider if you have not already. Unstale uses whatever you set up there and stores no key of its own. See API keys below.
- Open Unstale → Settings and pick a default model and a default refresh level. Balanced is the default and is available on the free plugin.
- Open any post list. The Unstale column shows the status of the last refresh and its age, coloured by how far it has drifted, with a Refresh link that shows the estimate and asks you to confirm before it queues a new one.
- The job lands in the Review queue. Read the side-by-side diff, then approve or reject. Nothing is published before you approve, unless you switch on automatic publishing, which is off by default.
Prefer the command line? Unstale ships a WP-CLI command and a REST namespace, and an AI agent can drive it too: see Connect an AI agent.
# Refresh one post at the Balanced level
wp unstale refresh 1234 --level=balanced
# Queue the whole archive
wp unstale refresh --all --level=balanced
The REST namespace is unstale/v1, with routes for jobs, run, approve and estimate. Every step runs through Action Scheduler with a budget under 90 seconds per API call, so a long article can never hit a PHP timeout: the job resumes where it stopped.
Install Pro
Unstale Pro is an add-on, not a separate plugin: it hooks into the free plugin and needs it installed and active first, in version 1.36.0 or newer. It is not distributed on wordpress.org, so you install it by uploading a zip once, and WordPress updates it on its own from then on.
- Get the zip. Your purchase email carries a direct download link valid for 30 days. Once it expires, go to unstale.ai/download and enter your license key to get a fresh one.
- In your WordPress admin, go to Plugins → Add Plugin → Upload Plugin, pick the zip and install it.
- Activate it. A Licence entry appears under the Unstale menu.
- Open Unstale → Settings, paste your license key into the licence field and click Activate. The same field is available under Unstale → Licence, which also shows your plan and renewal date.
- Strong and Maximal appear in the level slider straight away, along with scheduled automation, bulk refresh from the Posts list and per-category rules.
Pro does not change how a refresh is billed. It uses the same provider you connected in Settings → Connectors, on your own account, so API keys and costs below apply to Pro exactly as they do to the free plugin.
Updates
Once the licence is active, Unstale Pro updates through the normal WordPress updates screen, like any plugin from the directory. Nothing to re-download. If the licence lapses or is refunded, updates stop; the version you have keeps working.
Moving Pro to another site
Plans are counted in sites: 1, 5 or unlimited. Activating uses one slot, and a plan that is full refuses a new site rather than silently deactivating an old one. To move a site off a plan, open Unstale → Licence on that site and click Deactivate this site, which frees the slot immediately. You can also switch plans at any time from the pricing page.
If the key is refused and the licence is neither refunded nor lapsed, write to support@unstale.ai from the address you paid with.
Compatibility
Unstale fits the stack you already run instead of asking you to change it. Everything below is detected at runtime, with no setting to switch on: if the plugin is active, Unstale uses it; if it is not, Unstale falls back to WordPress core.
| Works with | What Unstale does about it |
|---|---|
|
Page builders Elementor, Divi, SeedProd |
The refresh reads the text out of the builder’s own data, rewrites only that text and writes it back where it came from, so your layout, styling and builder settings come back as they were. Images stay in place, but an alt text already set on one counts as text and can be rewritten. Unstale never re-serialises the page: it replaces the text where it found it and leaves every other byte alone. On a SeedProd page using SeedProd Pro blocks, the new text lands in the builder and the live page waits for you to reopen it and save; the job log says so. |
|
SEO plugins Yoast SEO, Rank Math, All in One SEO, SEOPress |
The rewritten meta title and description are written into that plugin’s own fields, and Unstale adds its own Article JSON-LD to posts only, never to pages, and only when the published page carries none, so it never adds a second Article schema next to theirs. It reads the published page to check. If the page cannot be loaded, it adds its Article only when none of these four plugins is active. With none of them active, Unstale writes the metas itself. Content one of them marks noindex is never offered for a refresh, and the Excluded tab of Content health names the plugin that said so, as the exclude video shows. |
|
Cache plugins WP Rocket, W3 Total Cache, LiteSpeed Cache, WP Super Cache, WP Fastest Cache, SG Optimizer |
After publishing, the refreshed post is purged through that plugin’s own public purge API. The purge is always aimed at the post, never a full-site flush, so the rest of your cache stays warm. Anything outside this list, a CDN for instance, hooks onto the unstale_purged action. |
|
Editors and content types Gutenberg, Classic editor |
Posts, pages and public custom post types. A job is scoped to what you can already edit, so a user only ever sees and refreshes content they have rights on. |
A builder outside this list has no adapter. When Unstale recognises one, it warns you first and goes ahead only if you choose Refresh anyway, which rewrites the standard WordPress content rather than the page your visitors see. A builder it does not recognise at all gets no warning, and its page is refreshed the same way. Adding an adapter takes two filters, unstale_builder_detectors to recognise the page and unstale_pipeline_steps to swap in your own extract and publish steps.
In the admin
Unstale adds one menu with six screens, a column in your post lists and a block under the editor. Everything on this page is in the free plugin unless it says otherwise.
Get started
A checklist that reads your site and never asks you to tick anything: an AI provider connected in WordPress, a default model that provider actually serves, a first refresh on one of the posts that waited longest (with its estimate before anything is spent), and the diff to review. One action at a time, and an empty review queue sends you back here until the four steps are done. Once they are, the screen folds into three shortcuts: Content health, the review queue, and another post to refresh. The setup video shows the first two steps ticking on their own, and the first refresh video the last two.
Review queue
Every refresh waits here with its side-by-side diff until you approve or reject it, unless you switch on automatic publishing, which is off by default. When something is waiting, a notice says so from wherever you are in the admin: with one refresh pending it opens that diff directly, with several it opens the queue. So a refresh that finishes while you work on something else no longer waits unnoticed. The first refresh video reads one diff from the fact-check to the approval, and the batch video approves a whole batch, row by row.
Content health
Your published content sorted by how long it has gone without an update, in three bands derived from the staleness threshold you set in Settings. Pick up to 50 posts per batch and queue them. Show all puts the whole list on one page.
Tick the posts, choose Refresh selected under Bulk actions and click Apply: a confirmation screen shows the total estimate before anything runs. Confirm refresh queues one refresh per post, and they run one after another in the background. The page does not update itself, so reload it to follow along. Each refresh then lands in the review queue on its own row, with its cost.
To run a batch later, choose Schedule refresh under Bulk actions instead and click Apply. The same screen shows the estimate and a Refresh on field: pick a date and time, up to a year ahead, click Schedule refresh, and you can close the tab. WordPress runs scheduled tasks when the site receives a visit, so the refreshes start by themselves on the next visit after that time. They take turns in the background, the Journal shows Started on schedule, and each rewrite waits in the review queue for your approval. Nothing is spent until the scheduled time.
To keep a post out of Unstale, click Exclude at the end of its row: the row leaves the list at once, and a refresh scheduled for that post is cancelled. To exclude several, tick them, choose Exclude under Bulk actions and click Apply. There is no confirmation screen, since excluding spends nothing. The post stays published and indexed: Unstale simply leaves it alone, in bulk actions, in row actions and in the Pro automation.
The Excluded tab lists everything Unstale skips, and its Reason column says why: Excluded by hand, or noindex, according to your SEO plugin for content that plugin marks noindex, which is left out without a click. Below it come the content types that are never refreshed, one row per type. Reintegrate on a post excluded by hand makes it eligible again, and the same link sits on the Posts screen; a noindex item comes back once you change it in your SEO plugin. Reintegrate does not bring back a schedule the exclusion cancelled.
Below the list, the Content cannibalization section finds published posts and pages that cover the same topic, free since version 1.8.0. Click Scan for duplicate topics: Unstale compares your own text with itself, on your own server, so it needs no AI provider, sends nothing anywhere and costs nothing. For each post it keeps the words that make that post distinctive, from the title, the H2 headings and the text, and posts that share a large part of that list land in one group. Posts you excluded and noindex pages are left out of the groups, and the free scan covers your 2,000 most recent published items.
Each group names a Keeper, the post Unstale would keep, and why: Longest of the group, Most recently updated when they are as long, or Oldest of the group, the one created first. With an AI provider connected, Confirm with AI under the groups asks it to check every group and tell shared vocabulary from a shared query. Right after a scan, the screen shows what that check costs before you click. Only then does text leave the site: the title, the H2 headings and the first 150 words of each grouped post. Each verdict is kept with its date until the group changes, and a keeper the AI picks reads Chosen by the AI. The scan never merges, unpublishes, redirects or deletes a post: what to do with a group stays your call, and Unstale Pro adds Consolidate into keeper to the groups.
With Unstale Pro, Consolidate into keeper on a group card queues one refresh of the keeper, which takes in what only the other post covered, and that refresh always waits in the review queue. Once you approve it, Retire them turns the other post into a draft and sends its URL to the keeper with a permanent redirect, which you can undo from Unstale > Redirects; the video below runs it on the pair found above.
With Unstale Pro, the same check also runs without you clicking Scan. Once a week, Pro goes through your whole site in the background, 100 posts per batch, on your own server, with the same word fingerprints as the free scan, so there is no AI call and nothing to pay; it reaches up to 20,000 published items, where the free scan stops at 2,000. There is no setting to switch on: the sweep runs as long as your Pro licence is active, and it skips what Content health skips, the Excluded tab and noindex posts.
When the sweep finds a group it has never reported, Content health shows a notice once, to users who can edit other people’s posts: Unstale found 1 new group of duplicate content., with the link Open Content health. Unstale remembers every group it has already reported, from the weekly sweep and from your own scans, and never reports the same group twice. So you do not wait a week, the video below starts the site’s weekly sweep by hand from Tools > Scheduled Actions, the same action that runs on its own.
Journal
Every refresh with its tokens and their cost, web search fees not included since no provider reports its search count yet, filterable by post, with running totals for all time and for the current month. A refresh you scheduled says Started on schedule in its journal, as the scheduled refresh video shows. Export CSV gives you the same rows as plain numbers a spreadsheet can add up, and it carries whatever filter you are looking at.
Settings
Default model, default refresh level, staleness threshold and the publishing options. The level slider shows what each level costs per 1,000 words, and the figure follows both the slider and the model you pick, so you can compare the two decisions together. The levels reserved for Pro show their cost as well, so you can see what they would cost before deciding.
Scheduled automation Pro
With Unstale Pro, Unstale → Automation picks your stale posts on a schedule and queues their refresh. It is off until you tick Queue refreshes on a schedule and click Save automation settings. How often runs it every hour, day or week, and each run takes, oldest first, up to the Articles per run you set (5 by default) among the posts unchanged for longer than Refresh after (days) (180 by default), with a hard limit of 50 per run, whatever you type. Before anything is spent, Next batch lists the posts the next run would take, with an estimated cost; your provider bills you directly. Every refresh waits in the review queue as long as Publish without human review stays unchecked, the default, and Last pass says what the last run did.
On Unstale → Rules, every category follows the global automation settings until you change its row. Custom rule gives it its own level and refresh delay, which replace the global settings in both directions, so it can refresh more often or less often than the rest of the site; Excluded means scheduled automation never picks an article from it. Save rules keeps only the rows set to Custom rule or Excluded. In the video below, Guest posts is excluded and Data studies refreshes at Balanced after 45 days, so the next batch swaps a guest post for a data study; so you do not wait a day, the pass is started by hand from Tools > Scheduled Actions, the same pass that runs on its own.
Bulk refresh Pro
With Unstale Pro, Unstale → Bulk refresh lists the published posts and pages you can edit that have gone unchanged for longer than the staleness threshold you set in Settings (180 days by default), oldest first, 100 per page, with the same age bands as Content health and a content type filter. Pick the Refresh level for the whole batch, from Minimal to Maximal (Strong and Maximal are Pro): every Estimated cost and the total for the list change in place, without a reload, so you see what the level costs before you click. These are estimates from your model and word counts; your provider bills you directly.
Select all ticks every row of the page, and Refresh selected asks you to confirm, since each article spends your own AI provider key, then queues up to 100 refreshes in one request. A post that already has a refresh in progress is left out, and the screen names it with the reason. Each rewrite waits in the review queue for your approval, unless you switch on automatic publishing. The same action is in All Posts, under Bulk actions: Unstale: refresh at followed by the level set in your automation settings, without the confirmation. Without Pro, Content health refreshes up to 50 posts per batch, at your default level. In the video below, 100 posts on a test site, 93 of them backdated for the video, are queued at Strong for an estimated $3.20, and all 100 reach the review queue with nothing published.
The Unstale column and the editor block
In any post list, the Unstale column carries the status of the last refresh and its age, coloured on the same bands as Content health, so one glance down the list shows what has drifted. Under the editor, the Unstale block starts a refresh, follows it step by step and then lists everything it changed.
Once a refresh is published, a Restore the previous version link in that block puts the post back as it was before it: the text (the layout on Elementor and SeedProd, from the job’s own snapshot), the publish date the refresh moved, and the SEO title and description it wrote. It opens a confirmation screen that names exactly what will go back. If the content was edited since, Restore refuses and your edits stay; a date or meta goes back only if it still holds what the refresh wrote.
The same link sits on the refresh’s page in the review queue, under This refresh is live. Restore calls no AI provider, so it costs nothing, and it has no time limit. It takes a user who can edit other people’s posts, so Editors and Administrators by default. In the block and classic editors and on Divi it needs revisions turned on, and WordPress usually keeps the refreshed version in the post revisions, so you can go forward again from there. On Elementor and SeedProd, Unstale keeps its own copy of the layout from before, and not the refreshed one.
Connect an AI agent
Claude Code, Codex, Hermes Agent or any other client that speaks the Model Context Protocol (MCP) can drive Unstale on your site: find the stale posts, estimate a refresh, start it, follow it and read what it changed. The agent talks to your WordPress site and nothing else. Unstale still does the rewriting, on the AI provider you connected in WordPress, and nothing passes through an Unstale server. All of this is in the free plugin.
Unstale declares its actions as WordPress abilities, the API that ships with WordPress 7.0. The official MCP Adapter plugin turns them into MCP tools. It is distributed on GitHub, not on wordpress.org, and Unstale works without it: the abilities stay reachable through the REST API.
- Download
mcp-adapter.zipfrom the latest MCP Adapter release, install it from Plugins → Add Plugin → Upload Plugin and activate it. - Open Unstale → AI Agent (up to version 1.25, a section of Unstale → Settings). The screen says whether the adapter is found and gives the address of your Unstale server, ready to copy.
- Create an application password for the user the agent acts as, in Users → Profile → Application Passwords. That user needs to be able to edit other people's posts, and the agent only sees and refreshes what that user can edit.
- Give your client the address and the password, as below. The address is
https://your-site.com/wp-json/unstale/mcp, orhttps://your-site.com/index.php?rest_route=/unstale/mcpwhen your permalinks are set to Plain.
The clients below send the password in a standard HTTP Basic header, your username and application password joined by a colon and Base64-encoded. <BASE64> stands for that result:
macOS and Linux
printf '%s' '<login>:xxxx xxxx xxxx xxxx xxxx xxxx' | base64 | tr -d '\n'
Windows PowerShell
[Convert]::ToBase64String([Text.Encoding]::UTF8.GetBytes('<login>:xxxx xxxx xxxx xxxx xxxx xxxx'))
Claude Code
claude mcp add --transport http unstale "https://your-site.com/wp-json/unstale/mcp" --header "Authorization: Basic <BASE64>"
Codex, in ~/.codex/config.toml
[mcp_servers.unstale]
url = "https://your-site.com/wp-json/unstale/mcp"
http_headers = { "Authorization" = "Basic <BASE64>" }
Hermes Agent, in ~/.hermes/config.yaml
mcp_servers:
unstale:
url: "https://your-site.com/wp-json/unstale/mcp"
headers:
Authorization: "Basic <BASE64>"
Or connect over SSH
If your agent can open an SSH session on the server and WP-CLI is installed there, it starts the Unstale server itself, without an application password, and acts as the user named in the command. Anyone who holds that shell already has full control of the site.
ssh <ssh-host> "wp --path='/var/www/example' mcp-adapter serve --server=unstale --user='<login>'"
For instance in Claude Code:
claude mcp add --transport stdio unstale -- ssh <ssh-host> "wp --path='/var/www/example' mcp-adapter serve --server=unstale --user='<login>'"
If a client cannot connect directly
The adapter answers MCP over plain HTTP requests and does not stream. A client that needs streaming, or cannot send a custom header, connects through the @automattic/mcp-wordpress-remote proxy, which runs on your machine:
{
"mcpServers": {
"unstale": {
"command": "npx",
"args": ["-y", "@automattic/mcp-wordpress-remote@latest"],
"env": {
"WP_API_URL": "https://your-site.com/wp-json/unstale/mcp",
"WP_API_USERNAME": "your-username",
"WP_API_PASSWORD": "your-application-password"
}
}
}
}
What the agent can do
| Tool | What it does |
|---|---|
unstale-get-settings |
Levels, models and defaults, whether a custom instruction is available, whether agents may review, whether automatic publishing is on. |
unstale-list-stale-content |
Your stale posts by age band, with the last refresh of each, 50 at most per page. |
unstale-list-jobs |
Refreshes by status or by post. |
unstale-get-job |
One refresh: status, fact-check, changes and log. The old and new content only when asked. |
unstale-estimate-refresh |
The cost, web searches and words of one refresh, before it runs. |
unstale-start-refresh |
Starts a refresh, with an optional custom instruction on Pro. |
unstale-manage-job |
Cancels, retries or unsticks a refresh. |
unstale-review-job |
Approves or rejects a refresh, only when the site allows agents to. |
Approval stays with a person by default
An agent prepares refreshes, it does not publish them. Approving or rejecting stays in Unstale → Review queue until you tick Let AI agents approve or reject refreshes in the same settings section, and the lock holds even when the agent calls the REST API with its application password. With automatic publishing on, a refresh publishes itself, as it always has.
Custom instruction Pro
With Unstale Pro, a refresh can carry an instruction of up to 1,000 characters, sent by the agent or typed in the Unstale block of the editor: a keyword to target, a section to add. It reaches research, rewrite and enrichment, and it outranks the level's rules on structure, length and tone, never the HTML, the shortcodes, the facts or the web search budget. Fact-check and verification ignore it, so they still catch a figure invented to please it. A retry keeps it; a new, scheduled or automatic refresh starts without one. The cost estimate does not count it, so an instruction that adds content costs a little more than shown.
In the editor, the field sits in the post’s Unstale block, under the level cards: Instruction for this refresh (optional), empty each time the block opens. Its hint repeats the rules: up to 1,000 characters, for this refresh only, above the level on structure and tone, never on the HTML, the shortcodes or the facts, and the rewrite still keeps at least about a third of the original length. In the review queue, the refresh opens on its instruction, above the run details and the fact-check, so you know what to look for in the changes. Without an active Pro licence the field does not show, and an instruction sent by an agent is refused before any refresh starts.
In the video below, one post last modified in March 2024 on a test site, “Core Web Vitals in 2024: Which Thresholds Actually Matter”, is refreshed at Balanced, estimated at about $0.0393, with one sentence: Target the keyword Interaction to Next Paint and add a section on how to improve it on WordPress. The keyword lands in the second heading, the new section “How to improve Interaction to Next Paint on WordPress” lands fourth, once, the other headings keep their wording, and the post goes from 524 to 866 words. The fact-check still works on its own: of 6 claims from the original, 3 are found outdated, each with a correction and a source. The refresh is approved and goes live. The new section is the model’s text: read it before you approve, as with any refresh.
Site instructions Pro
With Unstale Pro, Unstale → Settings carries a Writing section with a permanent instructions field: persona, writing style, tone, form of address, up to 2,000 characters. It applies to every level, on every refresh, unlike the instruction above which is set once per refresh. When both are set, the per-refresh instruction wins. Otherwise, the site instructions win over the voice measured from the original article, so telling the site to address readers formally overrides an article originally written informally.
Quiz Pro
The same Writing section carries a checkbox, Add a quiz at the end of refreshed articles, checked by default. Each article can also override it from its own Unstale box in the editor, with a list of three choices: Follow site setting, Always and Never. The choice is saved the moment you change it, no need to save the article. The quiz only ever appears at the Strong and Maximal levels; turn it off and it stops appearing from the article's next Strong or Maximal refresh onward.
API keys
Unstale is strictly bring-your-own-key on every plan, free and Pro: you need a key from at least one AI provider, and that provider bills you directly, on your own account, with no markup and no credit system in between.
What changed in WordPress 7.0 is where the key lives. Providers and their credentials are now managed by WordPress itself, in Settings → Connectors, so Unstale stores no key of its own: it hands its prompts to the WordPress AI Client, which routes them to the provider you connected there. The plugin never sees, proxies or logs your key, and neither your key nor your content ever reaches an Unstale server.
Unstale → Settings shows which provider WordPress reports as connected, and lets you pick the default model. The admin screens run every refresh on that default model; WP-CLI (--model), the REST API and an AI agent can pass another one per run. Upgrading from a version of Unstale that stored its own keys deletes them automatically.
Anthropic
Create a key at console.anthropic.com, then connect it in Settings → Connectors. It stays with WordPress; Unstale only reads that the provider is ready. Model ID: claude-sonnet-5-5 (Claude Sonnet 5.5).
Anthropic's current Sonnet, generally available. Writing quality close to Opus, follows SEO instructions literally, 1M token context and 128k output. Best choice when the rewrite quality matters more than the bill. It replaces Claude Sonnet 5 at the same rates, and a site set to Sonnet 5, the default model before Gemini 3.8 Flash, moves to it on its own.
OpenAI
Create a key at platform.openai.com, then connect it in Settings → Connectors. It stays with WordPress; Unstale only reads that the provider is ready. Model ID: gpt-6.1-sol (GPT-6.1 Sol).
The cost-efficient high-end model of the GPT-6 family, generally available: the model you pick is the model that runs. It replaces GPT-6 Sol at the same rates, which match Claude Sonnet 5.5, and a site set to GPT-6 Sol or to the older GPT-5.6 Terra moves to it on its own.
Google default
Create a key at aistudio.google.com, then connect it in Settings → Connectors. It stays with WordPress; Unstale only reads that the provider is ready. Model ID: gemini-3.8-flash (Gemini 3.8 Flash). See it done in the setup video.
Default model on new installs. Fastest of the three and the cheapest by a wide margin, at less than half the Claude Sonnet 5.5 input rate. Multimodal, and the first 5,000 grounded searches each month are free. An update never switches an existing site to it: the model you had stays selected.
Model IDs and rates are not hardcoded in the plugin. Unstale fetches a remote catalogue at https://unstale.ai/api/v1/models.json once a day, keeps it cached for 48 hours and falls back to the bundled copy if the fetch fails. When a provider ships a new model or changes a price, your estimates follow without a plugin update.
Refresh levels
One slider, four presets. Every level fixes errors, fact-checks figures against live web results, adds internal links and republishes safely; the higher levels progressively take more editorial liberty with your copy.
Minimal and Balanced ship in the free plugin. Strong and Maximal require Unstale Pro.
| Action | Minimal | Balanced | Strong | Maximal |
|---|---|---|---|---|
| Spelling and grammar fixes | Yes | Yes | Yes | Yes |
| Fact-check of figures, dates and prices (live web) | Yes | Yes | Yes | Yes |
| Internal linking (up to 15 links, one link per target page) | Yes | Yes | Yes | Yes |
| Em dashes removed | Yes | Yes | Yes | Yes |
| Date bump and same-URL republish | Yes | Yes | Yes | Yes |
| Original structure and tone (what the model is told) | Keep | Keep | Adapt to persona | Rewrite |
| SEO and business optimisations, missing sections added | Not included | Yes | Yes | Yes |
| Meta title (50-60 chars) and description (145-160 chars) | Not included | Yes | Yes | Yes |
| Key takeaway boxes | Not included | Yes | Yes | Yes |
| JSON-LD (Article, only when the page has none) | Not included | Yes | Yes | Yes |
| Key sentence per paragraph in bold, scannability pass | Not included | Yes | Yes | Yes |
| Tighter, more human copy written for the persona | Not included | Not included | Yes | Yes |
| Secondary queries all covered | Not included | Not included | Yes | Yes |
| TL;DR at the top | Not included | Not included | Yes | Yes |
| CTAs (in-text, visual, closing) to your products | Not included | Not included | Yes | Yes |
| Interactive quiz when relevant | Not included | Not included | Yes | Yes |
| Slide structure and first-person E-E-A-T signals | Not included | Not included | Yes | Foundation |
| Full rewrite from the best available sources | Not included | Not included | Not included | Yes |
Internal linking is best-effort: Unstale never forces a link. If it finds no relevant target, the refresh still succeeds with fewer links, or none.
Before you pick a level for a post that still ranks, check what it is told to do with the outline: Minimal and Balanced are told to keep your heading structure, Strong to keep your sections in order while it may reword a heading, and only Maximal is told to rebuild the plan. The evidence on AI rewriting and rankings has its own page.
In the Unstale block under the editor, each level is a card that shows its cost on this post, about followed by the amount, estimated on the post’s word count and billed by your AI provider, never by Unstale. Strong and Maximal run on their own Pro prompts and add blocks to the article: a TL;DR summary at the top, key-takeaway callouts in the sections, a quiz at the end when the article carries facts worth checking, each answer folded until the reader opens it, and calls to action that may only point to published pages of your own site (one whose link does not resolve is dropped, and the job’s log says why). These blocks are plain HTML in the post, not shortcodes, so they keep rendering if you remove Unstale Pro, and a later refresh replaces them instead of stacking new ones. The quiz follows the site setting, or the Quiz list of the post’s Unstale block: Follow site setting, Always or Never. Each rewrite waits in the review queue for your approval, unless you switch on automatic publishing. Without Pro, Strong and Maximal stay locked, and Minimal and Balanced keep working.
In the video below, one 3,147-word post from 2023 on a test site goes through both levels: Strong, estimated at about $0.31, keeps its 30 headings in order and rewords 7 of them; Maximal, estimated at about $0.39, rewords 22, opens on a new section and drops the 2023 forecast. The Strong version is rejected and the post is not modified, then the Maximal version is approved and goes live with its summary on top and its quiz at the end. The model proposed no call to action for this post, so none was added.
What happens during a refresh
- Analysis: main keyword, language, and the products or services the article mentions.
- Research: live web search for the top results, search intent, expected format, secondary queries, persona and gaps against competitors. Skipped at Minimal, which searches the web only to check facts.
- Fact-check: figures, prices, dates and feature claims verified against official sources.
- Rewrite: per the level you picked, section by section on long articles.
- Enrichment: metas, JSON-LD, takeaway boxes, TL;DR, CTAs and quiz, depending on the level.
- Internal linking: up to 15 links to your own published content, varied anchors, one link per target page.
- Cleanup: em dashes removed and line endings normalised.
- Review: the job waits in the queue with a side-by-side diff. Approve or reject. Automatic publishing, which skips this step, is off by default and switched on in the settings.
- Publish: same slug and same URL (a refresh never moves it), optional date bump, the version before it kept in the revision history when revisions are on (block or classic editor, Divi) or in the job’s snapshot for Restore (Elementor, SeedProd), a cache purge aimed at the post and never a full flush, and a log of steps, tokens, costs and links.
Costs
Two separate bills, and only one of them is ours. The Unstale licence is a flat annual fee with no rewrite quota. The AI usage is billed to you by your provider at their published rates.
| Model ID | Provider | Input / MTok | Output / MTok | Web search |
|---|---|---|---|---|
claude-sonnet-5-5 |
Anthropic | $2.00 | $10.00 | $10 / 1k |
| Standard rate, the same as Claude Sonnet 5, which it replaces. | ||||
gpt-6.1-sol |
OpenAI | $2.00 | $10.00 | $10 / 1k |
| Generally available since 2026-09-29. Replaces gpt-6-sol at the same rates, and gpt-5.6-terra ($2.00 / $12.00); a site set to either now follows. | ||||
gemini-3.8-flash |
$0.75 | $3.75 | $14 / 1k | |
| First 5,000 grounded searches per month are free | ||||
Provider rates as published on 2026-08-22. The plugin always estimates from the live catalogue, not from this table.
How the estimate is calculated
Unstale shows the estimate before a refresh you confirm from the editor, the posts list or Content health, per article and per batch:
estimated cost = estimated tokens (article length x level)
x model rate
+ estimated searches
x search rate
Article length and the level set the token estimate; the level also sets how many web searches the pipeline expects to run. Minimal searches least, Maximal most. Once the job finishes, the log records the tokens and what they cost, web search fees aside, so you can compare the estimate against real runs on your own archive rather than trusting a number on a marketing page.
Two levers if a bill runs higher than you want: switch the model (Gemini 3.8 Flash bills input at less than half the Claude Sonnet 5.5 rate, and its first 5,000 grounded searches each month are free), or drop a level. Neither is a subscription change, because Unstale never meters rewrites.
For any length, level and number of posts, the cost calculator runs the same estimate.
FAQ
Do I need a paid plan to use AI rewrites?
No. The free plugin on wordpress.org performs real AI rewrites at the Minimal and Balanced levels using your own API key, on one post at a time or on a batch of up to 50 picked from its content health screen. Unstale Pro adds the Strong and Maximal levels, scheduled automation, batches of up to 100 posts at the level you pick on its Bulk refresh screen or at your automation level from the Posts list, and per-category rules. See the pricing page.
Where is my API key stored?
In WordPress, not in Unstale. You still bring your own key, but since WordPress 7.0 providers and their credentials are managed by the core, in Settings > Connectors. Unstale hands its prompts to the WordPress AI Client, which routes them to the provider you connected there, so the plugin never sees, stores or transmits your key. If you used an older version of Unstale, the keys it had stored are deleted automatically when you update.
Who pays for the AI usage?
You do, directly to Anthropic, OpenAI or Google on your own account. Unstale charges a licence fee only, so there are no credits, no rewrite quota and no markup on tokens.
Will a refresh break my URLs or my rankings?
A refresh does not change the slug, and it skips the date bump when the new date would change a dated address. On default settings it waits for your approval with its diff. In the WordPress editor, block or classic, and on Divi, with revisions turned on, the version before it stays in the native revision history; Restore puts it back as long as the post content has not been edited since. No tool can promise rankings, and Unstale does not.
Can I see the cost before a refresh runs?
Yes. Unstale shows an estimate before a refresh you confirm from the editor, the posts list or Content health, per article and per batch, based on article length, the level you picked, the current rates for your model and the expected number of web searches. The job log then records the tokens and their cost. That cost leaves out web search fees for now: no provider reports its search count to WordPress yet, so your provider bill can come in slightly higher.
What are the requirements?
WordPress 7.0 or newer and PHP 8.1 or newer. WordPress 7.0 is the floor because Unstale runs on the AI Client that ships with it. Unstale works with both Gutenberg and the Classic editor, on posts, pages and public custom post types.
The free plugin runs the full pipeline on your own key, up to the Balanced level. Install it, refresh one stale post and read the diff before deciding anything.