S’exécute surWrit CloudDesktopAuto-hébergé
Sur cette page
Dans votre réseau. Appelable de l’extérieur.
Un système interne sans API devient un endpoint HTTPS. L’agent appelle vers l’extérieur et reste connecté ; une requête vers votre endpoint descend cette connexion, et le workflow s’exécute sur votre machine, contre un système que lui seul voit.
connexion ▸ un seul sens
L’agent appelle vers l’extérieur. Rien n’entre.
Tout repose sur une propriété : la connexion part de l’intérieur de votre réseau, vers l’extérieur, et reste ouverte. Le travail descend une connexion que vous avez déjà ouverte.
- 01 L’agent se connecte vers l’extérieur
Vous installez l’agent sur une machine qui atteint déjà le système interne. Il ouvre une connexion sortante vers Writ et la maintient.
- 02 L’appel y descend
Une requête vers votre endpoint publié passe par cette connexion existante. Writ n’ouvre pas de connexion vers votre réseau.
- 03 Le workflow s’exécute à l’intérieur
Le navigateur pilote le système interne depuis cette machine : l’exécution voit exactement ce que verrait quelqu’un assis à ce poste.
Aucun port entrant à ouvrir, aucune adresse publique à donner au système interne. Ce dont l’agent a besoin, c’est le HTTPS sortant que votre réseau autorise déjà.
pièces ▸ quatre
Ce qu’il faut.
Quatre éléments, chacun documenté sur sa propre page. Cette page donne l’ordre dans lequel les assembler.
| Une machine dans le réseau | Writ Desktop ou un agent auto-hébergé, sur un hôte qui atteint déjà le système que vous voulez appeler. |
| Un workflow | Enregistré une fois contre ce système — ou décrit en mots — puis pointé vers votre propre agent pour qu’il s’y exécute. |
| Un endpoint publié | La porte d’entrée sur Writ Cloud : une méthode et un chemin que vous choisissez, servis sous /v1/{slug}/{path}. |
| Une clé consommateur | Ce que présentent vos appelants. Restreignez-la à un endpoint, donnez-lui une limite de débit, faites-la tourner avec une période de grâce. |
mise en place ▸ dans l’ordre
Assemblez-le.
Chaque étape est du travail produit ordinaire — rien ici n’est propre aux systèmes internes, sauf l’endroit où se trouve l’agent.
- 01 Installez et liez l’agent
Sur une machine dans le réseau. Une fois lié, il apparaît dans votre liste d’agents et maintient sa connexion sortante.
- 02 Apprenez le workflow
Enregistrez la tâche contre le système interne, ou décrivez-la et laissez la session IA l’enregistrer. Les identifiants sont résolus depuis le coffre à l’exécution.
- 03 Pointez-le vers votre agent
Réglez le workflow pour qu’il s’exécute sur votre agent plutôt que dans le cloud, afin que chaque exécution ait lieu sur une machine qui voit le système.
- 04 Publiez l’endpoint
Choisissez la méthode et le chemin. Ce chemin devient l’API que le système interne n’a jamais eue.
- 05 Distribuez une clé consommateur
Une clé par appelant. Limitez-la aux endpoints nécessaires, révoquez-la ou faites-la tourner sans toucher au workflow.
appel ▸ de n’importe où
Appelez-le comme n’importe quelle API.
Les appelants ne savent pas — et n’ont pas besoin de savoir — où l’exécution a lieu. Ils postent sur votre chemin avec leur clé et lisent le résultat.
call.sh
curl -X POST https://api.usewrit.app/v1/acme/price-check \
-H "Authorization: Bearer $WRIT_CONSUMER_KEY" \
-H "Content-Type: application/json" \
-d '{"url": "https://example.com/product/42"}' call.py
import os, requests
res = requests.post(
"https://api.usewrit.app/v1/acme/price-check",
headers={"Authorization": f"Bearer {os.environ['WRIT_CONSUMER_KEY']}"}, # csk_...
json={"url": "https://example.com/product/42"},
timeout=120,
)
res.raise_for_status()
payload = res.json()
print(payload["run_id"], payload["data"]) call.ts
const res = await fetch("https://api.usewrit.app/v1/acme/price-check", {
method: "POST",
headers: {
Authorization: `Bearer ${process.env.WRIT_CONSUMER_KEY}`, // csk_...
"Content-Type": "application/json",
},
body: JSON.stringify({ url: "https://example.com/product/42" }),
});
if (!res.ok) throw new Error(`Writ call failed: ${res.status}`);
const { run_id, data } = await res.json();
console.log(run_id, data); call.go
package main
import (
"bytes"
"encoding/json"
"fmt"
"net/http"
"os"
)
func main() {
body, _ := json.Marshal(map[string]string{"url": "https://example.com/product/42"})
req, _ := http.NewRequest("POST", "https://api.usewrit.app/v1/acme/price-check", bytes.NewReader(body))
req.Header.Set("Authorization", "Bearer "+os.Getenv("WRIT_CONSUMER_KEY")) // csk_...
req.Header.Set("Content-Type", "application/json")
res, err := http.DefaultClient.Do(req)
if err != nil {
panic(err)
}
defer res.Body.Close()
var out struct {
RunID string `json:"run_id"`
Data json.RawMessage `json:"data"`
}
json.NewDecoder(res.Body).Decode(&out)
fmt.Println(out.RunID, string(out.Data))
} call.rs
use serde_json::{json, Value};
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
let key = std::env::var("WRIT_CONSUMER_KEY")?; // csk_...
let res: Value = reqwest::Client::new()
.post("https://api.usewrit.app/v1/acme/price-check")
.bearer_auth(key)
.json(&json!({ "url": "https://example.com/product/42" }))
.send()
.await?
.error_for_status()?
.json()
.await?;
println!("{} {}", res["run_id"], res["data"]);
Ok(())
} Les appels sont synchrones par défaut. Demandez un 202 et un identifiant d’exécution avec Prefer: respond-async, et servez un résultat récent au lieu d’une nouvelle exécution avec Cache-Control: max-age=N. Les formes de réponse, les codes de statut et le chemin de polling sont sur la page des endpoints gérés.
partage ▸ qui fait quoi
Ce qui s’exécute où.
La séparation mérite d’être précise, car c’est elle qui rend l’exposition sûre.
| Côté | Ce qu’il détient |
|---|---|
| Votre machine | Le navigateur, la connexion au service, les identifiants et chaque octet lu depuis le système interne. L’exécution a lieu ici. |
| Writ Cloud | La porte d’entrée : authentification, limites de débit, quotas et journal d’exécution. Elle retient la requête de l’appelant pendant que votre agent travaille. |
Les exécutions sur votre propre agent sont gratuites et non facturées. La porte d’entrée cloud applique toujours les limites de débit et le quota mensuel de votre plan.
limites ▸ ce qui plafonne
Les limites à connaître.
Voici les nombres qui décident du nombre de portes et de la force avec laquelle on peut y frapper.
| Agents liés | Free, Starter et Pro en incluent un. Growth en permet 5, Scale 20, Enterprise est sans plafond. |
| Endpoints publiés | Plafonnés par plan. Publier un chemin en consomme un. |
| Limite de débit | Par clé consommateur, 60 requêtes par minute sauf si vous fixez la vôtre, plus le quota mensuel d’appels de votre organisation. |
| Délai | 5 à 300 secondes par endpoint, 120 par défaut. Au-delà, un 504 est renvoyé avec un identifiant d’exécution à interroger. |
référence ▸ le détail
Où chaque pièce est documentée.
Cloud, desktop et auto-hébergé — et ce qui est facturé dans chaque cas.
→ Endpoints gérésChemins, asynchrone, fraîcheur, enveloppes, codes de statut et quotas.
→ Clés consommateurCréation, restriction, limites de débit, rotation avec période de grâce.
→ WorkflowsEnregistrer, décrire, entrées et sorties, états d’exécution.
→questions ▸ posées
Uplink, en clair.
Dois-je ouvrir un port ?
Le système interne doit-il avoir une API ?
Deux machines peuvent-elles servir un endpoint ?
Est-ce facturé ?
fin ▸ ouvrir une porte
Mettez un système interne derrière un endpoint.
Commencez par la mécanique des endpoints, puis décidez où l’exécution doit avoir lieu.