Appuyez sur / pour rechercher

Toute la documentation
docs Appeler depuis votre logiciel SDK

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

sdk ▸ quatre clients

Quatre SDKs. Un agent.

TypeScript, Python, Go et Rust — publiés, versionnés, légers. Chaque client découvre l’agent Writ qui tourne sur votre machine, et le même client atteint Writ Cloud quand vous lui confiez une clé wt_.

Les SDKs pilotent un logiciel sur votre machine, sur vos comptes. Rien ne téléphone ailleurs.

install ▸ premier run

Installer, découvrir, exécuter.

Chaque quickstart suit les trois mêmes temps : le client trouve l’agent en cours d’exécution (pas d’URL, pas de token à coller), liste vos workflows, en exécute un et relit les lignes extraites. Ces exemples sont les paquets publiés, mot pour mot.

TypeScript typescript/ Depuis le dépôt · Node ≥ 18 · zéro dépendance runtime
Python python/ Depuis le dépôt · Python ≥ 3.10 · import writ_agent
Go github.com/usewrit/writ-sdks/go go get · Go ≥ 1.23 · stdlib uniquement
Rust rust/ Dépendance git · async, tout runtime compatible reqwest

run.ts

import { WritAgent, runRowId } from "@usewrit/agent-sdk";

const client = new WritAgent();              // discovers the running agent + token
const { data: workflows } = await client.workflows.list();
const run = await client.workflows.runAndWait(workflows[0].id, {
  inputs: { city: "Paris" },
});
const { data: rows } = await client.runs.data(runRowId(run));
console.log(run.status, rows);

surfaces ▸ deux

Un client, deux surfaces.

Les SDKs parlent à deux endroits différents, et la doc ne les confond jamais. L’agent local est le logiciel sur votre machine : loopback uniquement, gratuit, avec ses propres familles de tokens. Writ Cloud est la surface hébergée qu’une clé wt_ déverrouille — avec un palier sans clé qui ne demande aucun compte.

SurfaceURL de baseAuth
Agent local (writ-agentd)http://127.0.0.1:8131 · https://127.0.0.1:8132token runtime wlt_ · clé restreinte wlk_ · OAuth wlo_
Writ Cloudhttps://api.usewrit.appclé API wt_ (facturée) · X-Writ-Client-Id (sans clé)

Parlez à 127.0.0.1, pas à localhost — le daemon applique une garde anti DNS-rebind sur le Host et l’Origin acceptés. Le jumeau HTTPS sur :8132 utilise une CA locale par installation dans ~/.writ/tls/ca.pem.

Variables d’environnement

La découverte lit d’abord l’environnement, puis les runtime.json du dossier Writ, en sondant chaque candidat. Noms identiques dans les quatre SDKs :

VariableRôle
WRIT_API_URLRemplace l’URL de base du daemon local
WRIT_TOKENRemplace le token bearer du daemon local
WRIT_HOMEPremier dossier candidat pour runtime.json
WRIT_API_KEYClé API Writ Cloud facturée (wt_)
WRIT_CLOUD_URLRemplace l’URL de base de Writ Cloud
WRIT_CLIENT_IDRemplace l’identifiant d’appareil sans clé

runs ▸ trois façons d’attendre

Exécutez, puis attendez à votre façon.

Chaque SDK expose les trois mêmes postures pour le même run :

  1. Handle async — run() rend la main immédiatement avec un id de run — interrogez ou streamez quand vous voulez.
  2. Attente côté serveur — run avec wait — l’appel HTTP lui-même bloque jusqu’au verdict (timeout en secondes, borné côté serveur).
  3. runAndWait — Le SDK s’abonne au flux d’événements en direct avec un polling de secours, et rend le run une fois réglé.

Un run en échec est un résultat, pas une erreur : vous récupérez le run avec son statut. Seul un budget d’attente expiré lève — et l’erreur porte encore l’id du run, rien n’est perdu.

Les éléments du fil de runs portent un id composite comme workflow-3. Chaque appel runs.* prend l’id numérique de ligne — extrayez-le avec l’assistant du langage : runRowId(run) (TS), run_row_id(run) (Python), item.RowID() (Go), item.row_id() (Rust).

Événements en direct via SSE

La progression étape par étape est diffusée par le daemon ; chaque langage a son idiome natif — itérateur async, générateur, range-over-func, Stream.

events.ts

for await (const ev of client.runs.events(runRowId(run))) {
  console.log(ev.type, ev);
}

surface ▸ services

Tout l’agent, par espaces de noms.

Un seul objet client porte toute la surface : agent, workflows, runs, moniteurs, selectors, extractors, automations, personas, secrets, vault, files, data, crawl, datasets, keys — plus cloud. Les noms sont identiques d’un langage à l’autre ; les idiomes sont natifs :

TypeScriptEspaces de noms en Promises ; enveloppes Page<T> ; run() surchargé pour wait et dry-run.
PythonJumeaux WritAgent sync et AsyncWritAgent ; réponses en dicts ; Page itérable.
GoChaque méthode prend ctx en premier ; erreurs typées compatibles errors.As ; zéro dépendance.
RustAsync uniquement ; listes filtrées via variantes *_with ; Cloud = CloudClient séparé ; un seul enum WritError.

cloud ▸ facturé + sans clé

Le palier cloud est intégré.

Confiez une clé wt_ au client et scrape, map et crawl cloud sont décomptés de votre pool de crédits. Sans clé, le palier keyless scrape des pages publiques identifié par un simple id d’appareil — avec un endpoint de quota qui dit ce qui reste.

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"

Le client expose son palier (« metered » ou « keyless ») pour que votre code puisse bifurquer. Le sans-clé répond 429 quand l’allocation est épuisée ; le facturé répond 402 quand le pool est vide — deux erreurs typées.

clés ▸ erreurs

Clés restreintes, échecs typés.

Fabriquer une clé wlk_ restreinte (scopes : read, run, admin) exige le token runtime à accès complet — une clé CI qui fuite ne peut donc jamais s’élargir elle-même.

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

Taxonomie des erreurs

Le même échec est le même type dans chaque langage — attrapez ce que vous savez gérer, le reste porte status, code et body :

ApiErrorTout non-2xx avec un code stable : bad_request, unauthorized, forbidden, not_found, vault_locked (423), too_many_requests, internal.
RunTimeoutUn budget d’attente a expiré — porte l’id du run, toujours valide.
RateLimitedAllocation sans clé épuisée — porte l’heure de reset et les compteurs restants.
InsufficientCreditsPool facturé vide (402). Rechargez ou repassez en local.
ApiKeyRequiredAppel cloud facturé sans clé wt_.
Connection / DiscoveryAucun agent vivant trouvé, ou daemon injoignable.

rest ▸ sans sdk

Pas de SDK ? L’endpoint est du REST pur.

Un endpoint de workflow publié est un POST HTTPS ordinaire avec un Bearer wt_ — ces wrappers sont toute l’intégration si vous préférez posséder le HTTP vous-même.

writ.py

import os, requests

WRIT_BASE = "https://api.usewrit.app"

def run_workflow(slug: str, path: str, inputs: dict) -> dict:
    res = requests.post(
        f"{WRIT_BASE}/v1/{slug}/{path}",
        headers={"Authorization": f"Bearer {os.environ['WRIT_CONSUMER_KEY']}"},
        json=inputs,
        timeout=120,
    )
    res.raise_for_status()
    return res.json()

payload = run_workflow("acme", "price-check", {"url": "https://example.com/product/42"})
print(payload["data"])

faq

Questions SDK, répondues.

Ai-je besoin d’un SDK pour utiliser Writ ?
Non. Les endpoints publiés sont du REST pur avec un Bearer wt_, et le palier cloud sans clé est un appel curl. Les SDKs gagnent leur place quand vous pilotez l’agent local : découverte, événements SSE, erreurs typées et toute la surface de services sans HTTP artisanal.
Quels langages sont publiés ?
TypeScript, Python, Go et Rust, tous dans github.com/usewrit/writ-sdks. Go s’installe avec go get ; les autres s’installent depuis le dépôt pour l’instant — les paquets de registre ne sont pas encore publiés. Des clients générés pour d’autres langages se construisent depuis la même spec OpenAPI.
Comment les SDKs trouvent-ils mon agent ?
L’environnement d’abord (WRIT_API_URL / WRIT_TOKEN), puis les candidats runtime.json du dossier Writ, chacun sondé avec un budget de deux secondes. Vous pouvez toujours passer URL et token explicitement.
Comment gérer les workflows longs ?
Trois façons : prendre l’id de run async et revenir ; demander au serveur d’attendre (l’appel bloque jusqu’au verdict) ; ou runAndWait, où le SDK streame les événements avec un polling de secours. Un run en échec revient comme un résultat avec son statut, pas comme une exception.
Les SDKs fonctionnent-ils dans un navigateur ?
La découverte lit le système de fichiers, donc côté desktop uniquement. Dans un navigateur, passez baseUrl et token explicitement — ou appelez votre endpoint cloud publié, du REST pur fait exactement pour ça.

fin ▸ livrer

Installez-en un et faites le premier appel.

Le quickstart exécute votre premier workflow en quelques minutes, en local et gratuitement.