JSON · markdown · public reads, no key

Scrape any site.
Then search everything.

10 endpoints over 405 pages from 10 companies. Point it at a domain and it crawls, cleans and scores every page; ask it a question and it searches across all of them at once, by meaning and by exact words.

  • Hybrid search over sections, not pages. You get the paragraph that answers, with its heading path.
  • Clean markdown for any page or any whole company, as a file rather than a JSON envelope.
  • Filters are columns scored at index time. Technicality is measured, not tagged.
  • Coverage is declared. A response that has 300 of 1,100 pages says so, and says why.

curl https://stealpage.com/api/content?technicality_min=4

Building an agent? Skip the HTTP.

The same corpus as 7 MCP tools. One command and Claude, Cursor or Codex reads it directly — no client, no keys, no plumbing.

claude mcp add --transport http stealpage https://stealpage.com/api/mcp
MCP server

What you can filter on

None of these is a text search. Every one is a value written when the page was indexed, which is the difference between asking for technical articles and asking for pages containing the word “technical”.

type
article, docs, pricing, landing, case-study, changelog, comparison — what the page is for, not what section of the site it sits in.
format
tutorial, teardown, research, listicle, announcement, interview, reference, opinion.
audience
developer, marketer, founder, designer, exec, general. Who the page is written at.
technicality
1–5, measured from code fences, term density and paragraph-length variance over the PROSE, never the raw markdown. A URL is not a sentence.
promotional
1–5. Set promotional_max=2 and the marketing goes away. The word “technical” appears in almost no technical article and in every landing page that wants to sound like one.
originality & depth
Whether the argument is the author's own, and how far it goes. The two axes that separate a reference guide from a rewrite of one.

The 10 endpoints

Parameters and a runnable curl for each of them are in the reference. Every row here links straight at its entry.

Questions

Do I need a key?

Not for reads. Everything the public website shows is readable over the API without one, because a key on public data buys nothing and costs anonymous discovery.

How is this different from a scraping API?

A scraper hands back one page and forgets it. This crawls the site's own link graph, converts every page to markdown, scores what each one is, keeps every version, and lets you search across all 10 companies at once. The scrape is the first step, not the product.

Can I just get the markdown?

Yes. /api/content/:id.md returns one page with a frontmatter block, and /api/domains/:root/content.md returns a company as a single file — headings inside each page demoted one level so the bundle is a real tree.

What happens to a filter you do not recognise?

It comes back in the response. Every list declares what it filtered on, so a misspelled parameter is visible rather than silently ignored — and the two quality gates nobody asked for are named in `qualityGates` with a count of what they removed.

What if you only have part of a site?

The response says so, and says which bucket the rest is in. Coverage is a view with no write path, so it cannot drift from what was actually fetched.

Can I make you index something?

POST /api/crawl with a domain. It returns a job id straight away because a crawl is minutes to hours, and /api/jobs/:id reports progress per page rather than per wave.

Every response is what the public website already shows, and every page in it carries the URL it came from — attribution is in the markdown, not in a licence nobody reads. llms.txt says the same thing to the thing most likely to be reading it.