Runs onWrit CloudDesktop
On this page
Describe the job. Scribe drives.
Scribe is Writ’s own AI. You say what you want in plain words; it opens a real browser, finds the page, validates a selector on it, and builds the monitor, the workflow or the crawl. It works in turns, and it pauses before anything that costs you money or touches your accounts.
approval ▸ it pauses
It stops and asks. That is the design.
A mission runs in turns. When it needs something from you, it stops: the session goes to awaiting_input and carries a pending_request describing what it is waiting for. There are three shapes of pause:
| Pause | What you see |
|---|---|
| A question | One or more fields it needs answered — a threshold, a choice, a confirmation, a login identity. |
| A monitor-batch review | Every site it discovered, all preselected and individually deselectable, with an estimated setup cost — shown before a single monitor is created. |
| A connect-setup review | The live endpoint URLs it just published, plus the offer to create an API key for them. |
An approved purchase has a hard precondition, not a soft one. A persona, a payment method, an explicit confirmation and a threshold must all be collected before it will draft anything. Missing any one of them, it asks instead of proceeding.
Two ways to stop. interrupt breaks the current turn and parks the mission — it is resumable. cancel ends it. And a reply to a turn that has already moved on answers 409: re-read the session and answer the current turn rather than the one you were looking at.
capabilities ▸ one tool a turn
What you can ask it to do.
Scribe picks exactly one tool per turn, from a fixed set. It cannot invent a tool, so the list below is the whole of what a mission can do:
| Find and read a page | Land on the right page, then propose a selector and validate it against the live page before using it. |
| Create a monitor | Watch a price against a numeric threshold, or watch content for any text change. Mode: a selector, or a visual pixel-diff of a screenshot zone — which is how charts, images, canvas/SVG and logos get watched. Render: auto, http or js. |
| Watch several sites at once | Discover candidate sites, propose a ranked batch for your review, and create one monitor per kept site in a single turn. |
| Ask you for input | text, value, choice, confirm, secret, persona or payment_method. |
| Sign in as you | Link a saved login identity and handle 2FA, so login-gated pages are reachable. |
| Build a workflow | Draft an approved-action workflow, run an autonomous session that signs in and builds one, or persist a workflow from steps you state explicitly. Add a named callable. |
| Test it and schedule it | Run the workflow and report PASS or FAIL with sample data, then configure a schedule. |
| Publish it | Expose the workflow as REST, as an OpenAI-compatible surface, or as MCP — then pause to show you the live URLs. |
| Wire an automation | Connect a detected change to a notification. |
| Crawl and answer | Run a whole-site crawl with live progress, fold a finished crawl into a single answer, and arm a recurring or reactive crawl. |
| Use what you already have | List, search and answer from datasets you have already collected. This is the cheapest path, and it is preferred before crawling anything. |
| Finish | Close the mission with a summary of what was built. |
The set is fixed on purpose. An AI that can only pick from a known list is an AI whose worst turn is still a tool you can read about on this page — so “what could it possibly do?” has an answer with a finite length.
venues ▸ two, not one
Cloud Scribe and desktop Scribe are not the same.
There are two implementations, and they differ in what they are allowed to build. Read the row that matches where you are running before you plan a mission around it.
| Where | Base | What it can build |
|---|---|---|
| Writ Cloud | /api/ai-concierge | The full set — including approved-action drafting and multi-site batch monitors. |
| Writ Desktop | /v1/ai-concierge | Watch and notify. No approved-action drafting, no multi-site batch monitors. |
| Self-hosted | — | Not available. Scribe is not part of the self-hosted coordinator. |
| Call | What it does |
|---|---|
POST /api/ai-concierge/start | Start a mission. Answers {session_id, status, poll_url} immediately; the work continues in the background. |
GET /api/ai-concierge/{id} | The full session state. This is what you poll. |
POST /api/ai-concierge/{id}/respond | Answer the current pause. |
POST /api/ai-concierge/{id}/ask | Ask a follow-up about what it built. |
POST /api/ai-concierge/{id}/persona | Attach or clear the login identity. |
POST /api/ai-concierge/{id}/interrupt | Stop the current turn and park the mission. |
POST /api/ai-concierge/{id}/cancel | End the mission. |
GET /api/ai-concierge | Your missions, newest first. |
On the desktop agent
The same shape, on loopback, against the agent running on your own machine — and free, because the browser is yours:
POST /v1/ai-concierge/start | Start a mission. |
GET /v1/ai-concierge | List missions. |
GET /v1/ai-concierge/{id} | The session state to poll. |
POST /v1/ai-concierge/{id}/respond | Answer the current pause. |
POST /v1/ai-concierge/{id}/interrupt · /cancel | Park it, or end it. |
Say it plainly: Scribe is not part of the self-hosted coordinator. A self-hosted deployment runs workflows, monitors, automations and crawls — it does not ship Scribe. If a mission-driven build is what you want, that is Writ Cloud or Writ Desktop.
session ▸ what you poll
The mission runs in the background. You poll it.
Start answers straight away with a session id and a poll URL — a browser mission outlives an HTTP request, so a handle is the honest answer. Every poll returns the same projection:
| Field | What it holds |
|---|---|
session_id · goal · platform | What you asked for, and where it is running. |
status | planning, browsing, building, proposing, awaiting_input, armed — plus the terminal states. |
phase · progress_message | Where it is, in words you can show a user. |
transcript | The conversation so far. |
thoughts | The tool it chose and a short thought, per step. |
plan | What it has decided so far. Payment references are stripped. |
pending_request | The pause it is waiting on, when status is awaiting_input. |
resources | What it has created — the monitor, the workflow, the endpoints. |
turn_seq | The optimistic lock you echo back when you respond. |
tokens | input, output and the credits spent so far. |
error_message · created_at · completed_at | Why it stopped, and when. |
Its visible reasoning is deliberately narrow: the tool it chose and a short thought. Tool arguments and tool results are never streamed — which is also why nothing you typed into a secret field can appear in the reasoning feed.
Start, poll, answer
A mission end to end, over plain HTTP.
start.sh
# Describe the job. goal is 3-2000 characters; url is an optional seed.
curl -X POST https://api.usewrit.app/api/ai-concierge/start \
-H "Authorization: Bearer $WRIT_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"goal": "Watch the price of the 15-inch model and alert me under $1,200",
"url": "https://example.com/laptops/15"
}' 200 — start
{
"session_id": 4021,
"status": "planning",
"poll_url": "/api/ai-concierge/4021"
}
// The mission runs in the background from here. Poll poll_url.
// Every poll answers the same projection:
{
"session_id": 4021,
"status": "awaiting_input",
"phase": "proposing",
"goal": "...",
"platform": "cloud",
"progress_message": "Found the price on the page.",
"transcript": [],
"thoughts": [ { "tool": "propose_selectors", "thought": "The price sits in the buy box.", "ts": "..." } ],
"plan": {},
"pending_request": { "kind": "text", "requests": [] },
"resources": {},
"turn_seq": 3,
"tokens": { "input": 8120, "output": 940, "credits": 29 },
"error_message": null
} answer.sh
# Poll until status is awaiting_input, then answer the CURRENT turn.
curl https://api.usewrit.app/api/ai-concierge/4021 -H "Authorization: Bearer $WRIT_API_KEY"
# turn_seq is an optimistic lock: send back the one you just read.
# A stale turn_seq answers 409 — re-read and answer the current turn.
curl -X POST https://api.usewrit.app/api/ai-concierge/4021/respond \
-H "Authorization: Bearer $WRIT_API_KEY" \
-H "Content-Type: application/json" \
-d '{"turn_seq": 3, "answers": {"threshold": "1200"}}'
# Ask it a follow-up about what it just built.
curl -X POST https://api.usewrit.app/api/ai-concierge/4021/ask \
-H "Authorization: Bearer $WRIT_API_KEY" \
-H "Content-Type: application/json" \
-d '{"question": "How do I call this endpoint from my own code?"}'
# Attach a saved login identity. null clears it.
curl -X POST https://api.usewrit.app/api/ai-concierge/4021/persona \
-H "Authorization: Bearer $WRIT_API_KEY" \
-H "Content-Type: application/json" \
-d '{"persona_id": 12}'
# Stop mid-turn (the mission parks, resumable) — or end it.
curl -X POST https://api.usewrit.app/api/ai-concierge/4021/interrupt -H "Authorization: Bearer $WRIT_API_KEY"
curl -X POST https://api.usewrit.app/api/ai-concierge/4021/cancel -H "Authorization: Bearer $WRIT_API_KEY"
# Every mission you have run.
curl https://api.usewrit.app/api/ai-concierge -H "Authorization: Bearer $WRIT_API_KEY" respond ▸ answering a pause
Answering the turn in front of you.
A response carries turn_seq and an answers object keyed by the fields the pause asked for. turn_seq is an optimistic lock: send back the one you read. If the mission has moved on, you get 409 — refresh and answer the current turn instead of overwriting a newer one.
| Input kind | What it asks for |
|---|---|
text | Free text. |
value | A number — a price threshold, a quantity. |
choice | One of a set it offers. |
confirm | A yes or no, before something happens. |
secret | A credential. Sealed to the vault on arrival. |
persona | Which saved login identity to use. |
payment_method | How a purchase would be paid, if you are building one. |
A secret answer is sealed into the vault as it arrives. What reaches a run afterwards is a placeholder that resolves at run time — the value itself does not travel through the plan, the transcript or the model.
There is one more field a response can carry, and Scribe never asks for it. Payment is collected as a choice — the model cannot request a card number at all. But if you take the advanced path and type one, those fields ride in their own card_fields object rather than in answers, and they are sealed into the vault as they arrive. Only placeholders reach the plan, payment_mode becomes vault_card, and the references are stripped back out of the plan you poll — the number itself never travels through the transcript or the model. If it cannot be stored, the answer is refused with 400: the pause stays open, and nothing is kept.
The same, on your own machine
Loopback, a local token, and the desktop’s narrower scope — watch and notify.
desktop.sh
curl -X POST http://127.0.0.1:8131/v1/ai-concierge/start \
-H "Authorization: Bearer $WRIT_TOKEN" \
-H "Content-Type: application/json" \
-d '{"goal": "Tell me when this page changes", "url": "https://example.com/status"}'
curl http://127.0.0.1:8131/v1/ai-concierge -H "Authorization: Bearer $WRIT_TOKEN"
curl http://127.0.0.1:8131/v1/ai-concierge/7 -H "Authorization: Bearer $WRIT_TOKEN"
curl -X POST http://127.0.0.1:8131/v1/ai-concierge/7/respond \
-H "Authorization: Bearer $WRIT_TOKEN" \
-H "Content-Type: application/json" \
-d '{"turn_seq": 2, "answers": {"confirm": true}}'
curl -X POST http://127.0.0.1:8131/v1/ai-concierge/7/interrupt -H "Authorization: Bearer $WRIT_TOKEN"
curl -X POST http://127.0.0.1:8131/v1/ai-concierge/7/cancel -H "Authorization: Bearer $WRIT_TOKEN" limits ▸ plainly
What Scribe will not do.
Worth reading before you plan around it. None of these are settings you can change:
- It does not place the order — For a purchase, it drafts the checkout up to the pay button and stops there. The last click is yours.
- It never asks for a card number — Payment is collected as a choice — a card already saved on the merchant, your browser’s own autofill on your own machine, or a virtual card. The model cannot ask for a number. If you take the advanced path and enter one yourself, it is sealed into the vault as it arrives and only a placeholder reaches the plan.
- It cannot invent a tool — One tool per turn, from the fixed set on this page. There is no free-form action.
- It does not run self-hosted — Scribe is not part of the self-hosted coordinator.
- Desktop Scribe is narrower — No approved-action drafting, and no multi-site batch monitors.
- It does not stream its arguments or results — The visible reasoning is the tool it chose and a short thought. Nothing more.
plan ▸ what it costs
What it needs, and what it spends.
Scribe needs a plan that includes AI assist. Token spend is metered and shown inside the session itself — the tokens field carries input, output and the credits consumed so far, so a long mission is never a surprise at the end of it. A mission on your own machine drives your own browser, so the browser time is free; the AI tokens are still metered.
reference ▸ next
What Scribe builds for you
The watch it creates: check types, modes and cadence.
→ WorkflowsThe recorded steps a mission persists.
→ Crawl a whole siteThe crawl it can run and re-arm.
→ AI sessionsThe autonomous browsing session, on its own.
→ Managed endpointsThe REST, OpenAI-compatible and MCP doors it publishes.
→ Personas, secrets and agentsThe login identity it signs in with.
→faq
Scribe questions, answered.
Will Scribe buy something without asking me?
Does Scribe ever see my card number?
Can I run Scribe on a self-hosted deployment?
What is different about desktop Scribe?
My respond call returned 409. What happened?
How much of its reasoning can I see?
end ▸ ask it
Describe one job and watch it pause.
The fastest way to understand the approval model is to start a mission and read the first pending_request it stops on.