seed ▸ crawl opened 0

Turn a whole site
into clean data.

Point Writ at a URL. It maps the site, spreads the crawl across your whole fleet (best-first, in parallel), and hands every page back as clean Markdown or structured JSON. Scrape one page or crawl a million.

free account to start · $0.0005 / page in cloud · self-host open-core
playground.usewrit.app no key
https://
Markdown + frontmatter structured JSON sitemap + discovered links
fetch ▸ page scraped 1
01
scrape

One page in, clean Markdown out.

Writ strips the chrome (nav, cookie banners, ads, boilerplate) and keeps the content, so an LLM reads the page, not the layout. Press Scrape:

tech.example/article
Raw page
nav · menu linkschrome
cookie consent bannerchrome
▓ sponsored · Surfsharkad
# Tech news & reviewscontent
article body · 1,240 wordscontent
newsletter signupchrome
footer · social · legalchrome
Markdown · 100% tokens
press Scrape to extract clean Markdown
map ▸ urls discovered 12
02
map

Every discoverable URL, in seconds.

Map merges the sitemap with links Writ discovers live, so you see the whole surface before you spend a single page-crawl. Pick your seeds, then crawl only what matters.

map tech.example
0 urlssitemap + discovered0.0s
net ▸ frontier draining 1,240
03
harvest · distributed crawl

One crawl, your whole fleet.

A crawl isn't one machine grinding a queue. Writ shares one frontier across every agent (best-first, so the most relevant pages come back first) and scales linearly as you add workers. Add agents:

agents 4frontier 2,914 · pg/s
auth ▸ wall opened 1,650
04
harvest · behind the login

The frontier depends on who's signed in.

A public crawler dead-ends at the login wall. Attach a persona and the same seed URL opens onto the pages only your account can see - order history, invoices, member pages that appear in no sitemap - and the map itself grows. Toggle the session:

/ /about /pricing /docs /login /account /account/orders /account/invoices /orders/8841 /orders/8842 /invoices/2291 login wall
5 URLs reachable from one seed

Without a session the frontier dead-ends at /login. Everything past it is undiscoverable — not slow to reach, undiscoverable: those URLs appear in no sitemap and nothing links to them from the public site.

Illustrative topology. A real Harvest runs inside the scope you set — includes, excludes and rate caps — and respects robots.txt.

tgt ▸ urls scored 1,980
05
targeting

Crawl what you mean, not everything.

Describe the intent and Writ scores every URL against it, following the ones that match and skipping the rest. You pay for the pages you wanted, not the whole site. Pick a target:

ext ▸ content extracted 2,400
06
render & extract

HTML, JS, PDFs, images: all readable.

Writ routes each resource to the cheapest lane that works: direct HTTP for static pages, a real browser for JS apps, doc-extract for PDFs and office files, offline OCR for images. You get text either way.

What a crawl can read
Static HTML direct http fetched and read natively — the fast, cheap lane
JS-rendered app browser a real browser renders the page when the content only exists after scripts run
PDF documents doc-extract read from the text layer when there is one; scanned pages fall back to OCR. Office files (DOCX, XLSX, PPTX) and JSON/CSV extract natively too
Images & scans ocr offline OCR — no third-party OCR service — with a confidence score reported per page
Behind a login persona needs a Persona: the crawler replays its saved session, and never performs a login itself
Everything else reported a page Writ cannot read comes back labeled with its kind and reason — never silently dropped
Auto by default: each URL is probed and routed to the cheapest lane that works. Browser and OCR pages meter at 2× the base page unit.
out ▸ shaped 2,900
07
output

Markdown, JSON, or a searchable dataset.

Take clean Markdown, or hand Writ a schema and get structured JSON per page. Every crawl lands in a dataset you can query, with no re-crawl to answer the next question.

bill ▸ metered per page 8,900
08
pricing

A twentieth of a cent per page. Free to start.

Crawls run on the Writ fleet — a free account starts you off, no card required. Pages are billed from your pool, with browser and OCR lanes weighted higher since they cost more to run. Self-host the open-core and your own agents crawl at no charge from us. Drag your monthly pages:

pages / mo 50,000
est. $25.00/mo cloud· self-host · your agents · $0 to us
smallest plan that covers it
Freeconcurrency 3 · up to 1,000 pages per crawl$0
Starterconcurrency 5 · up to 10,000 pages per crawl$15
Proconcurrency 10 · up to 25,000 pages per crawl$49
Growthconcurrency 25 · up to 50,000 pages per crawl$199
Scaleconcurrency 75 · up to 50,000 pages per crawl$499
dev ▸ crawl kicked off 8,900
09
developers

Kick off a crawl in one call.

Start a crawl, poll its status, stream results over REST, an MCP tool, or the SDK. Pick one:

A whole-site crawl is one POST with a key. Writ fans the seed across the fleet and lands the result as a callable dataset.

# No account, no key — a few same-domain pages, one level deep.
curl -X POST https://api.usewrit.app/v1/keyless/crawl \
  -H "Content-Type: application/json" \
  -d '{"url": "https://example.com", "limit": 3}'

# With a key: the whole site, as a job you poll.
curl -X POST https://api.usewrit.app/api/crawl \
  -H "Authorization: Bearer $WRIT_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"url": "https://example.com", "max_depth": 3, "page_budget": 500}'

curl https://api.usewrit.app/api/crawl/8125 -H "Authorization: Bearer $WRIT_API_KEY"

No account needed to try it: the keyless tier crawls a few same-domain pages, one level deep, against a daily allowance. Whole-site scope, logins and a callable dataset need a key.