Appuyez sur / pour rechercher

Toute la documentation
docs Appeler depuis votre logiciel Référence de l’API REST

S’exécute surWrit CloudDesktopAuto-hébergé

api ▸ toute la surface

Référence API

Toute la surface, endpoint par endpoint.

Writ répond à deux endroits : writ-agentd, le daemon agent sur votre propre machine à http://127.0.0.1:8131, et Writ Cloud à https://api.usewrit.app. Même grammaire JSON et même en-tête Bearer des deux côtés — familles de tokens différentes, et un seul des deux est facturé.

Writ s’exécute sur vos propres comptes, avec vos propres identifiants et données, sur les sites que vous êtes autorisé à utiliser.

surfaces ▸ local + cloud

Deux surfaces.

Le daemon local est le logiciel que l’app de bureau (ou l’agent auto-hébergé) fait tourner : loopback uniquement, gratuit. Writ Cloud est la surface hébergée qu’une clé wt_ déverrouille. Les SDKs découvrent le premier et peuvent porter la seconde.

SurfaceURL de baseAuth
Agent local (writ-agentd)http://127.0.0.1:8131Bearer wlt_ · wlk_ · wlo_
Writ Cloudhttps://api.usewrit.appBearer wt_ · en-tête X-Writ-Client-Id (sans clé)

Utilisez 127.0.0.1, pas localhost — le daemon vérifie Host et Origin contre le DNS rebinding. Un jumeau HTTPS écoute sur https://127.0.0.1:8132 avec une CA locale par installation dans ~/.writ/tls/ca.pem, et WRIT_PORT remplace le port.

Un workflow publié est une porte à part : POST /v1/{slug}/{path} sur Writ Cloud, authentifié par une consumer key csk_ que vous fabriquez pour ses appelants, documentée sur les endpoints gérés. Le serveur MCP (JSON-RPC sur /mcp) et les livraisons webhook signées ont aussi leurs propres pages : serveur MCP, webhooks.

auth ▸ cinq préfixes

Familles de tokens.

Un seul en-tête partout : Authorization: Bearer …. Ce qui change, c’est la famille du token — chaque préfixe est cantonné à sa surface. Rotation et détail des scopes : authentification.

TokenSurfaceRôle
wlt_LocalToken runtime — toute la surface. La seule famille qui peut fabriquer des clés restreintes.
wlk_LocalClé restreinte fabriquée via POST /v1/keys ; les scopes sont un CSV de read|run|admin.
wlo_LocalToken OAuth 2.1 portant le scope run.
wt_CloudClé API pour les appels cloud facturés sur api.usewrit.app.
X-Writ-Client-IdCloudPas un token — un en-tête d’identifiant d’appareil pour les routes sans clé et leur allocation fixe.

Fabriquer une clé wlk_ exige le token runtime wlt_ — une clé restreinte qui fuite ne peut donc jamais s’élargir elle-même :

const key = await client.keys.create({ name: "ci-runner", scopes: "read,run" });

erreurs ▸ codes stables

Une seule forme d’erreur.

Les erreurs sont de petits objets JSON : {"error": "…", "code": "…"} — une phrase lisible et un code stable. Les codes :

CodeHTTPSignification
bad_request400JSON malformé, champ manquant ou paramètre hors de sa plage autorisée.
unauthorized401Pas de token Bearer, ou un token que le daemon ne reconnaît pas.
captcha_required402L’opération a rencontré une étape de vérification qui demande un humain.
forbidden403Le token est valide mais ses scopes ne couvrent pas cette opération.
not_found404Aucune ressource à cet id ou ce chemin.
device_capacity409L’appareil est à sa limite de capacité pour cette ressource.
vault_locked423Le vault chiffré est verrouillé ; déverrouillez-le puis réessayez.
too_many_requests429Trop de requêtes en peu de temps ; espacez-les puis réessayez.
internal500Défaillance inattendue à l’intérieur du daemon.

Quelques chemins 4xx répondent en text/plain plutôt qu’en JSON. En lisant un corps d’erreur, tolérez le non-JSON.

runs ▸ le contrat

Sémantique des exécutions.

Le contrat à comprendre avant de câbler quoi que ce soit :

  • Asynchrone par défaut. POST /v1/workflows/{id}/run répond dès que l’exécution est dispatchée, avec son id.
  • Ou bloquez jusqu’au résultat. Ajoutez ?wait=true — l’appel attend le verdict. timeout est en secondes, borné à 1–3600, 120 par défaut.
  • Un run en échec est un résultat, pas une erreur. Vous récupérez l’exécution avec status: "failed" ; réservez la gestion d’erreurs au transport et à l’auth.
  • Deux formes d’id. Le fil des runs renvoie des ids composites comme workflow-3 ; chaque appel /v1/runs/{id}/* prend l’id numérique de ligne.

référence ▸ 98 opérations

La surface locale.

Chaque opération du daemon local, exactement comme la description OpenAPI l’énonce — 98 opérations en 16 groupes, toutes sous /v1 en loopback, toutes authentifiées par Bearer.

Chaque appel a cette forme — un en-tête Bearer, JSON en entrée, JSON en sortie :

monitor.sh

# Local agent daemon — loopback, wlt_/wlk_ token (use 127.0.0.1, not localhost)
curl -X POST http://127.0.0.1:8131/v1/monitors \
  -H "Authorization: Bearer $WRIT_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"url": "https://example.com/pricing"}'

Les enveloppes de liste varient à dessein. La plupart répondent {"data": [...], "count": n} ; /v1/runs ajoute "total" ; moniteurs, selectors, extractors, automations et /v1/changes/recent répondent des tableaux nus.

Agent

MéthodeCheminRésumé
GET/v1/agentÉtat léger de l’agent
GET/v1/healthSonde de santé approfondie

Workflows

La sémantique ci-dessus s’applique à POST /v1/workflows/{id}/run. La paire session gère la session de la voie HTTP sans navigateur qu’un workflow peut détenir.

MéthodeCheminRésumé
GET/v1/workflowsLister les workflows
POST/v1/workflowsCréer un workflow
GET/v1/workflows/{id}Lire un workflow
PATCH/v1/workflows/{id}Modifier un workflow
DELETE/v1/workflows/{id}Supprimer un workflow
POST/v1/workflows/{id}/runExécuter un workflow (asynchrone par défaut, ou attendre le résultat)
POST/v1/workflows/{id}/cancelAnnuler l’exécution vivante la plus récente d’un workflow
GET/v1/workflows/{id}/sessionÉtat de la session de la voie HTTP sans navigateur
DELETE/v1/workflows/{id}/sessionEffacer la session persistée

Exécutions

GET /v1/runs/{id}/events diffuse la progression en direct via SSE. Annuler une exécution déjà réglée répond 409 — avec l’exécution elle-même en corps.

MéthodeCheminRésumé
GET/v1/runsLister les exécutions (fil enrichi)
GET/v1/runs/{id}Lire une exécution
GET/v1/runs/{id}/resultsCharge utile brute du résultat d’une exécution
GET/v1/runs/{id}/dataDonnées extraites d’une exécution
GET/v1/runs/{id}/eventsFlux d’événements d’exécution en direct (SSE)
POST/v1/runs/{id}/cancelAnnuler une exécution vivante par son id

Moniteurs

MéthodeCheminRésumé
GET/v1/monitorsLister les moniteurs
POST/v1/monitorsCréer un moniteur
GET/v1/monitors/capacityJauge de capacité de vérification de l’appareil
GET/v1/monitors/{id}Lire un moniteur
PATCH/v1/monitors/{id}Modifier un moniteur
DELETE/v1/monitors/{id}Supprimer un moniteur
POST/v1/monitors/{id}/runLancer une vérification maintenant
GET/v1/monitors/{id}/changesHistorique des changements et de disponibilité d’un moniteur
GET/v1/changes/recentChangements récents, tous moniteurs confondus

Sélecteurs

MéthodeCheminRésumé
GET/v1/monitors/{id}/selectorsLister les sélecteurs d’un moniteur
POST/v1/monitors/{id}/selectorsAjouter un sélecteur à un moniteur
GET/v1/monitors/{id}/selectors/{selector_id}Lire un sélecteur
PATCH/v1/monitors/{id}/selectors/{selector_id}Modifier un sélecteur
DELETE/v1/monitors/{id}/selectors/{selector_id}Supprimer un sélecteur
POST/v1/monitors/{id}/selectors/{selector_id}/toggleBasculer l’état actif d’un sélecteur
POST/v1/monitors/{id}/selectors/{selector_id}/testSonder un sélecteur contre la page réelle
POST/v1/monitors/{id}/selectors/{selector_id}/set-baselineCapturer la référence du sélecteur
POST/v1/monitors/{id}/selectors/{selector_id}/clear-baselineEffacer la référence enregistrée

Extracteurs

Notez le toggle : PATCH, et non POST comme côté sélecteurs.

MéthodeCheminRésumé
GET/v1/selectors/{selector_id}/extractorsLister les extracteurs d’un sélecteur
POST/v1/extractorsCréer un extracteur
GET/v1/extractors/{extractor_id}Lire un extracteur
PATCH/v1/extractors/{extractor_id}Modifier un extracteur
DELETE/v1/extractors/{extractor_id}Supprimer un extracteur
PATCH/v1/extractors/{extractor_id}/toggleBasculer l’état actif d’un extracteur
POST/v1/extractors/{extractor_id}/testTester un extracteur enregistré

Automatisations

MéthodeCheminRésumé
GET/v1/automationsLister les automatisations
POST/v1/automationsCréer une automatisation
GET/v1/automations/{id}Lire une automatisation
PATCH/v1/automations/{id}Modifier une automatisation
DELETE/v1/automations/{id}Supprimer une automatisation
POST/v1/automations/{id}/enableActiver / désactiver une automatisation
POST/v1/automations/{id}/runDéclencher une automatisation maintenant

Personas

MéthodeCheminRésumé
GET/v1/personasLister les personas
POST/v1/personasCréer un persona
GET/v1/personas/{id}Lire un persona
PATCH/v1/personas/{id}Modifier un persona
DELETE/v1/personas/{id}Supprimer un persona
GET/v1/personas/{id}/runsExécutions récentes ayant agi comme ce persona
POST/v1/personas/validate-totpValider un secret TOTP
POST/v1/personas/{id}/test-2faTester la 2FA du persona

Secrets

Métadonnées uniquement — aucun endpoint ne renvoie jamais la valeur d’un secret.

MéthodeCheminRésumé
GET/v1/secretsLister les secrets (métadonnées uniquement)
POST/v1/secretsCréer un secret
GET/v1/secrets/{key}Lire les métadonnées d’un secret
DELETE/v1/secrets/{key}Supprimer un secret

Vault

MéthodeCheminRésumé
GET/v1/vault/statusÉtat du verrou d’application
POST/v1/vault/lockVerrouiller le vault maintenant
POST/v1/vault/unlockDéverrouiller le vault

Fichiers

MéthodeCheminRésumé
GET/v1/filesLister les descripteurs de fichiers
POST/v1/filesImporter un fichier (multipart)
POST/v1/files/from-dataExporter des données de workflow vers un fichier
GET/v1/files/{id}Lire un descripteur de fichier
DELETE/v1/files/{id}Supprimer un fichier
GET/v1/files/{id}/contentTélécharger les octets du fichier

Données

MéthodeCheminRésumé
GET/v1/dataSélecteur de workflow de l’explorateur de données
GET/v1/workflows/{id}/dataTable agrégée des données extraites
DELETE/v1/workflows/{id}/dataSupprimer des lignes de données extraites
GET/v1/workflows/{id}/data/runsIndex des snapshots de données
GET/v1/workflows/{id}/data/facetsFacettes par colonne
GET/v1/workflows/{id}/data/exportExporter la table des données extraites

Jeux de données

?format=json|csv|markdown|html — tout format non-json répond du texte rendu plutôt qu’un corps JSON.

MéthodeCheminRésumé
GET/v1/datasetsLe catalogue unifié des datasets
GET/v1/datasets/searchRecherche plein texte globale sur tous les datasets
GET/v1/datasets/{id}Métadonnées du dataset + schéma inféré
GET/v1/datasets/{id}/recordsParcourir les enregistrements d’un dataset
GET/v1/datasets/{id}/exportTélécharger tous les enregistrements d’un dataset
GET/v1/datasets/{id}/searchRecherche plein texte dans un seul dataset

Crawl

Les définitions sont des crawls enregistrés et rappelables. POST /v1/crawl/definitions/{ref}/run accepte max_age — un crawl précédent assez récent est réutilisé au lieu d’être rechargé.

MéthodeCheminRésumé
GET/v1/crawlLister les crawls
POST/v1/crawlDémarrer un crawl
GET/v1/crawl/{id}Lire un crawl
POST/v1/crawl/{id}/cancelDemander l’annulation d’un crawl
GET/v1/crawl/definitionsLister les crawls enregistrés
POST/v1/crawl/definitionsEnregistrer une configuration de crawl
GET/v1/crawl/definitions/{ref}Lire un crawl enregistré
PATCH/v1/crawl/definitions/{ref}Modifier un crawl enregistré
DELETE/v1/crawl/definitions/{ref}Supprimer un crawl enregistré
POST/v1/crawl/definitions/{ref}/runExécuter un crawl enregistré (réutilisation de fraîcheur en option)
GET/v1/crawl/definitions/{ref}/dataLire ce qu’un crawl enregistré a déjà collecté

Clés

La fabrication exige le token runtime wlt_.

MéthodeCheminRésumé
GET/v1/keysLister les clés API
POST/v1/keysFabriquer une clé API restreinte
GET/v1/keys/{id}Lire la fiche d’une clé
DELETE/v1/keys/{id}Supprimer la fiche d’une clé

Tickets WebSocket

MéthodeCheminRésumé
POST/v1/ws-ticketFabriquer un ticket WebSocket à usage unique

cloud ▸ facturé + sans clé

La surface cloud.

Writ Cloud est la surface hébergée et facturée à https://api.usewrit.app. La spec y déclare quatre opérations REST : le Scrape d’une page avec une clé wt_, plus un palier sans clé identifié par un simple id d’appareil. Tout le reste de l’hôte cloud — endpoints publiés, MCP, webhooks — est documenté sur sa propre page.

MéthodeCheminRésumé
POST/api/v1/website-to-apiTransformer un site en API
GET/api/v1/website-to-api/{id}Interroger un build site-vers-API
POST/api/crawl/scrapeScrape d’une page (facturé)
POST/api/crawlLancer un crawl de site complet
GET/api/crawl/{id}Interroger un crawl
GET/api/targetsLister les moniteurs
POST/api/targetsCréer un moniteur
GET/api/targets/{id}Récupérer un moniteur
PATCH/api/targets/{id}Modifier un moniteur
DELETE/api/targets/{id}Supprimer un moniteur
PATCH/api/targets/{id}/toggleMettre en pause ou relancer un moniteur
POST/api/targets/{id}/runVérifier un moniteur maintenant
GET/api/targets/{id}/changesHistorique des changements d’un moniteur
GET/api/targets/changes/recentChangements récents sur tous les moniteurs
POST/v1/keyless/crawlCrawler quelques pages (sans clé)
POST/v1/keyless/scrapeScrape d’une page (sans clé)
POST/v1/keyless/mapCartographier les URLs d’un site (sans clé)
GET/v1/keyless/quotaAllocation sans clé restante

Le sans-clé répond 429 keyless_rate_limited quand l’allocation est épuisée ; le facturé répond 402 insufficient_credits quand le pool de crédits est vide.

cloud.ts

const cloud = new CloudApi({ apiKey: process.env.WRIT_API_KEY }); // wt_…
const page = await cloud.scrape("https://example.com");
const site = await cloud.map("https://example.com", { search: "pricing", limit: 20 });
console.log(cloud.tier); // "metered" | "keyless"

faq

Questions API, répondues.

Est-ce l’API que les SDKs appellent ?
Oui. Les quatre SDKs publiés sont des clients légers au-dessus d’exactement ces opérations, générés depuis la même description OpenAPI (writ-agent.yaml). Tout ce que listent les tableaux, les SDKs le font — et un simple curl aussi.
Comment attendre la fin d’une exécution ?
POST /v1/workflows/{id}/run répond immédiatement par défaut. Ajoutez ?wait=true pour bloquer jusqu’au verdict — timeout en secondes, borné à 1–3600, 120 par défaut. Ou prenez l’id et abonnez-vous à GET /v1/runs/{id}/events (SSE). Un run qui échoue revient comme un résultat avec son statut, pas comme une erreur HTTP.
Pourquoi cette liste renvoie-t-elle un tableau nu ?
À dessein. La plupart des listes répondent {"data": [...], "count": n} et /v1/runs ajoute "total" ; moniteurs, selectors, extractors, automations et /v1/changes/recent répondent des tableaux nus. Chaque forme est stable — lisez chaque liste selon son enveloppe documentée.
Quel token va où ?
Daemon local : un Bearer des familles wlt_ (runtime), wlk_ (restreinte) ou wlo_ (OAuth 2.1), envoyé à 127.0.0.1. Writ Cloud : une clé Bearer wt_ pour les appels facturés, ou l’en-tête X-Writ-Client-Id sur les routes sans clé. Les endpoints publiés forment une voie distincte, authentifiée par des consumer keys csk_.
Appeler l’API locale coûte-t-il quelque chose ?
Non. Le daemon local, c’est votre propre machine — exécutions, moniteurs, crawls et lectures de données n’y portent aucun frais de calcul. Seuls les appels Writ Cloud sont facturés, depuis votre pool de crédits.

fin ▸ livrer

Branchez quelque chose dessus.

Le quickstart vous mène du compte au premier appel en quelques minutes ; les SDKs enveloppent toute cette page dans des clients typés.