Transformez tout un site
en données propres.
Pointez Writ vers une URL. Il cartographie le site, répartit le crawl sur toute votre flotte (best-first, en parallèle), et vous rend chaque page en Markdown propre ou en JSON structuré. Scrapez une page ou crawlez-en un million.
Une page en entrée, du Markdown propre en sortie.
Writ retire l’habillage (navigation, bandeaux de cookies, pubs, boilerplate) et garde le contenu, pour qu’un LLM lise la page, pas la mise en page. Appuyez sur Scrape :
Chaque URL découvrable, en quelques secondes.
Map fusionne le sitemap avec les liens que Writ découvre en direct, vous voyez donc toute la surface avant de dépenser un seul crawl de page. Choisissez vos seeds, puis crawlez seulement ce qui compte.
Un crawl, toute votre flotte.
Un crawl, ce n’est pas une seule machine qui écoule une file. Writ partage une frontière unique entre tous les agents (best-first, pour que les pages les plus pertinentes reviennent en premier) et passe à l’échelle linéairement à mesure que vous ajoutez des workers. Ajoutez des agents :
La frontière dépend de qui est connecté.
Un crawler public s’arrête net au mur de connexion. Attachez une persona et la même URL de départ s’ouvre sur les pages que seul votre compte peut voir - historique de commandes, factures, pages membres absentes de tout sitemap - et la carte elle-même s’agrandit. Basculez la session :
Sans session, la frontière s’arrête à /login. Tout ce qui est au-delà est indécouvrable — pas lent à atteindre, indécouvrable : ces URL ne figurent dans aucun sitemap et rien du site public n’y renvoie.
Topologie illustrative. Un vrai Harvest s’exécute dans le périmètre que vous fixez — inclusions, exclusions et plafonds de débit — et respecte robots.txt.
Crawlez ce que vous visez, pas tout.
Décrivez l’intention et Writ note chaque URL en fonction, suivant celles qui correspondent et ignorant le reste. Vous payez les pages voulues, pas tout le site. Choisissez une cible :
HTML, JS, PDF, images : tout devient lisible.
Writ route chaque ressource vers la voie la moins coûteuse qui fonctionne : HTTP direct pour les pages statiques, un vrai navigateur pour les apps JS, doc-extract pour les PDF et fichiers bureautiques, OCR hors ligne pour les images. Vous obtenez du texte dans tous les cas.
Markdown, JSON, ou un jeu de données interrogeable.
Prenez du Markdown propre, ou donnez un schéma à Writ et obtenez du JSON structuré par page. Chaque crawl atterrit dans un jeu de données que vous pouvez interroger, sans re-crawl pour répondre à la question suivante.
Un vingtième de cent par page. Gratuit pour démarrer.
Les crawls s’exécutent sur la flotte Writ - un compte gratuit suffit pour démarrer, sans carte bancaire. Les pages sont facturées depuis votre pool, et les voies navigateur et OCR pèsent plus lourd car elles coûtent plus cher à exécuter. En auto-hébergeant l’open-core, vos propres agents crawlent sans aucun frais de notre part. Faites glisser vos pages mensuelles :
Lancez un crawl en un seul appel.
Lancez un crawl, interrogez son statut, streamez les résultats via REST, un outil MCP ou le SDK. Choisissez :
Un crawl de site complet, c’est un seul POST avec une clé. Writ répartit la graine sur la flotte et livre le résultat comme un jeu de données appelable.
# 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" Aucun compte pour essayer : le palier sans clé crawle quelques pages du même domaine, sur un niveau, dans la limite d’une allocation quotidienne. La portée complète, les logins et un jeu de données appelable demandent une clé.
Pointez votre assistant vers Writ et il peut crawler un site directement, puis relire les lignes sans que vous écriviez un parseur.
claude mcp add writ-cloud \
-e WRIT_API_KEY=wt_your_api_key \
-- npx -y writ-mcp
# then, one line in the session:
writ_crawl_site({ url: "https://example.com",
intent: "product pages with specs",
page_budget: 500, save_as: "example-catalog" })
writ_crawl_status({ crawl_id: 8125 }) Clients à fichier de config — Claude Desktop · Cursor · Windsurf
Avec save_as, le crawl devient réexécutable et appelable : les exécutions suivantes réutilisent les données récentes au lieu de recrawler.
npm install github:usewrit/writ-sdks --workspace typescript
import { CloudApi } from "@usewrit/agent-sdk";
const cloud = new CloudApi({ apiKey: process.env.WRIT_API_KEY });
const job = await cloud.crawl({ url: "https://example.com", max_depth: 3, page_budget: 500 });
const status = await cloud.crawlStatus(job.id);
console.log(status.pages_done, "/", status.pages_discovered); pip install "git+https://github.com/usewrit/writ-sdks#subdirectory=python"
from writ_agent import Cloud
cloud = Cloud(api_key=os.environ["WRIT_API_KEY"])
job = cloud.crawl("https://example.com", max_depth=3, page_budget=500)
status = cloud.crawl_status(job["id"])
print(status["pages_done"], "/", status["pages_discovered"]) go get github.com/usewrit/writ-sdks/go
client := writ.New(writ.WithAPIKey(os.Getenv("WRIT_API_KEY")))
job, err := client.Cloud.Crawl(ctx, writ.CrawlStartParams{
URL: "https://example.com",
MaxDepth: writ.Ptr(int64(3)),
PageBudget: writ.Ptr(int64(500)),
})
status, _ := client.Cloud.CrawlStatus(ctx, job.ID) cargo add writ-client --git https://github.com/usewrit/writ-sdks
use writ_client::{CloudClient, CrawlStartParams};
let cloud = CloudClient::from_env()?;
let job = cloud.crawl(&CrawlStartParams {
url: "https://example.com".into(),
max_depth: Some(3),
page_budget: Some(500),
..Default::default()
}).await?;
let status = cloud.crawl_status(job.id).await?;