Programmatic SEO is simple to describe: take a dataset, a template and a model, and publish one useful page for every row. A city, a product, an integration, a comparison. The hard part is not generating 2,000 pages. It is making page 1,437 read like someone cared about it.
Most programmatic pages fail the same way. Every intro opens with the same throat-clearing line, every section closes with the same summary, and every paragraph has the same rhythm. Readers notice by the second page they open, and they stop trusting the third.
This guide shows where a humanizer step belongs in the pipeline, what it should and should not touch, and how to keep it from quietly breaking the things SEO depends on.
Where the humanizer goes
A typical pipeline looks like this:
- Data: one row per page (name, attributes, numbers, links).
- Draft: a template plus a model writes the prose for each row.
- Humanize: the draft is rewritten to remove the patterns that make it read machine-made.
- Verify: check that every name, number, link and keyword survived.
- Publish: render to HTML or Markdown and ship.
Steps 3 and 4 are the ones most pipelines skip. Step 4 is the one that bites. A rewrite that changes "$49 per month" into "around $50" or drops a qualifier ("in most cases") turns a style improvement into a factual error, multiplied by every page you generate.
What a humanizer should never touch
On a programmatic page, some text is content and some text is structure. The structure has to come back byte-for-byte:
- Target keywords. If the page targets "running shoes for flat feet", a rewrite that turns it into "shoes for flat arches" is a regression, however nice it reads.
- Links and anchors. Internal links are the skeleton of programmatic SEO.
- Numbers, prices, dates and names pulled from your dataset.
- Headings, tables, code and front matter. They are usually generated from the template, not the model.
With the Sounday API you pass the keywords to keep, and everything structural is protected automatically:
curl https://sounday.ai/v1/rewrite \
-H "Authorization: Bearer $SOUNDAY_API_KEY" \
-H "Content-Type: application/json" \
-d '{"text": "...", "keep": ["running shoes for flat feet", "Acme Run 3"], "strength": "standard"}'
Links, code, headings, tables, front matter and keep terms are swapped for placeholders before the model sees the
text, and restored afterwards.
Verify before you publish
Treat the rewrite like any other untrusted transformation: check it, then decide.
Sounday returns facts_preserved with every response. A chunk whose rewrite changed a number, date or name, or that a
second model flags for a changed claim, is retried once and otherwise returned as your original text. In code, the
decision is one line:
result = sounday_rewrite(page.draft, keep=page.keywords)
page.body = result["text"] # verified rewrite, or your original where a check failed
page.needs_review = result["checks"]["chunks_reverted"] > 0
Pages where a chunk was reverted are still safe to publish; they just read a little more like the draft. Send them to a review queue if you want every page polished.
Make every page sound a little different
Humanizing removes the obvious tells, but 2,000 pages from one template can still feel like one page. Three cheap fixes:
- Vary the template, not just the words. Two or three section orders, chosen per row, do more than any synonym swap.
- Feed the model the specific facts. Pages that mention the row's actual details (the opening year, the odd feature, the real price) read as written; pages built from generic attributes read as generated.
- Match a voice. Pass
voice("plain, direct, a bit dry") or up to threevoice_samplesfrom pages you wrote by hand, and every rewrite leans toward that voice.
Check the whole site in CI
Programmatic content usually lives in a repository. Add the free Sounday check to your pull requests and it annotates AI tells on the changed lines, failing the build under a score you choose:
npx -y --package=https://sounday.ai/dl/sounday.tgz sounday check content --min-score 60
See GitHub Actions for the full workflow.
What a humanizer won't fix
A humanizer makes a page read like a person wrote it. It does not make a thin page useful. If a page exists only because a keyword exists, rewriting it will not change what it is, and search engines treat mass-produced pages with nothing to offer as spam however they were written. Start with rows that genuinely deserve a page, give the model real data to work with, and use the humanizer for what it is good at: the last mile between "generated" and "published".
Ready to try it? Get a free API key (10,000 words a month) or check a draft in the free style checker first.