Runs onWrit Cloud
On this page
Someone already built it.
A listing is a workflow or an automation that someone else got working, shared as something you can run. You install it — free — bind your own logins and inputs into the slots it declares, and run it: POST /api/marketplace/listings/{slug}/run. You run a listing; you do not read it.
browse ▸ filters
Find one that already works.
GET /api/marketplace/listings takes the filters below, and GET /api/marketplace/listings/{slug} reads one in full. Results carry measured performance, not adjectives.
| Filter | Values |
|---|---|
q · category · tag | Free text, category, tag. |
asset_type | workflow | automation |
sort | rank | fastest | success | on_time | newest | most_used |
capability_key · target_site | What it does, and which site it does it on. |
min_success_rate | Floor on measured success. |
max_p50_latency_ms · max_p95_latency_ms | Ceilings on measured latency. |
min_on_time_rate | How often it finishes inside its promised baseline. |
min_reputation_tier | rising | trusted | top |
verified_only · established_only | Narrow to verified or long-standing creators. |
limit · offset | limit 1–100, default 24. |
What a listing card tells you
Every card carries the same measured signals, so two listings for the same job are directly comparable:
- Latency, success rate and on-time rate — measured from real runs.
- A failure-spike flag when recent runs have got worse.
- The creator’s reputation tier.
- Its rank inside the capability set it competes in.
install ▸ free
Installing is free, and it is idempotent.
POST /api/marketplace/listings/{slug}/install puts the listing on your account. Calling it twice does not install it twice — an install is idempotent per account and listing. What lands is a frozen, data-less snapshot: the steps plus the manifest of slots it needs, with the creator’s credentials stripped at publish.
Nothing in the marketplace is for sale. Installing costs nothing, the creator charges nothing, and a run costs only Writ platform compute — free and unmetered on your own machine, metered by running time on the managed cloud fleet.
bindings ▸ the seam
You bind your own credentials. That is the whole design.
A listing declares slots: the login it needs, the secret it needs, the inputs it takes. It does not ship the creator’s. You fill the slots with things you own, and a run resolves them from your bindings and from nowhere else. Read the slots with GET /api/marketplace/installs/{slug}/manifest before or after you install.
| slot_kind | What goes in it |
|---|---|
persona | A saved login identity. Workflow and automation installs. |
secret | A reference to a secret in your vault, never the value itself. |
input | A plain value the workflow takes. |
monitor_url | Automation installs: the page to watch. |
notify_recipient | Automation installs: where the alert goes. |
Setting and clearing one
PUT /api/marketplace/installs/{slug}/bindings sets a slot; DELETE with ?slot_kind= and ?slot_key= clears it. The body is five fields:
slot_kind · slot_key | Which slot. Both are required, on set and on clear. |
persona_id | For a persona slot. |
vault_secret_ref | For a secret slot — the name, not the secret. |
input_value | For an input, a monitor_url or a notify_recipient slot. |
A persona binding may only point at a persona you own. There is no way to bind someone else’s login identity, and no way for a listing to arrive carrying one.
Install, bind, run
The four calls in the order you make them.
install-bind-run.sh
# 1. See what slots this listing needs before you install it.
curl https://api.usewrit.app/api/marketplace/installs/invoice-puller/manifest \
-H "Authorization: Bearer $WRIT_API_KEY"
# 2. Install. Free, and idempotent per account + listing.
curl -X POST https://api.usewrit.app/api/marketplace/listings/invoice-puller/install \
-H "Authorization: Bearer $WRIT_API_KEY"
# 3. Bind YOUR persona and YOUR secret into the slots it declared.
curl -X PUT https://api.usewrit.app/api/marketplace/installs/invoice-puller/bindings \
-H "Authorization: Bearer $WRIT_API_KEY" \
-H "Content-Type: application/json" \
-d '{"slot_kind": "persona", "slot_key": "login", "persona_id": 12}'
curl -X PUT https://api.usewrit.app/api/marketplace/installs/invoice-puller/bindings \
-H "Authorization: Bearer $WRIT_API_KEY" \
-H "Content-Type: application/json" \
-d '{"slot_kind": "input", "slot_key": "account_number", "input_value": "88213"}'
# 4. Run it. Everything it signs in with came from step 3.
curl -X POST https://api.usewrit.app/api/marketplace/listings/invoice-puller/run \
-H "Authorization: Bearer $WRIT_API_KEY" slot kinds
// A workflow install declares these slot kinds:
{ "slot_kind": "persona", "slot_key": "login", "persona_id": 12 }
{ "slot_kind": "secret", "slot_key": "api_key", "vault_secret_ref": "acme-key" }
{ "slot_kind": "input", "slot_key": "region", "input_value": "eu-west" }
// An automation install adds two more:
{ "slot_kind": "monitor_url", "slot_key": "watch", "input_value": "https://example.com/pricing" }
{ "slot_kind": "notify_recipient", "slot_key": "alerts", "input_value": "[email protected]" }
// Clearing one is a DELETE with the same two identifiers:
// DELETE /api/marketplace/installs/{slug}/bindings?slot_kind=input&slot_key=region after-the-run.sh
# Where this install sits against the creator's caps.
curl https://api.usewrit.app/api/marketplace/installs/invoice-puller/usage \
-H "Authorization: Bearer $WRIT_API_KEY"
# Everything you have installed.
curl https://api.usewrit.app/api/marketplace/installs -H "Authorization: Bearer $WRIT_API_KEY"
# A run went wrong — open a report.
curl -X POST https://api.usewrit.app/api/marketplace/installs/invoice-puller/report \
-H "Authorization: Bearer $WRIT_API_KEY" \
-H "Content-Type: application/json" \
-d '{"reason": "The run signed in but returned no rows."}'
# Your own reports: open | reviewing | resolved | dismissed.
curl https://api.usewrit.app/api/marketplace/reports -H "Authorization: Bearer $WRIT_API_KEY" run ▸ what is guaranteed
What a run promises.
POST /api/marketplace/listings/{slug}/run executes the listing on your account. Four things hold on every run:
- It uses your bindings, and only your bindings — Personas, credentials, secrets and inputs are resolved from what you bound. Nothing arrives from the creator.
- It runs the snapshot you installed — Install captures the recipe as it was that day. A creator editing their live workflow does not change what your install runs.
- A missing required slot blocks it — The run answers 422 rather than starting and failing halfway. Bind the slot, run again.
- The listing itself is free — There is no listing charge and no creator fee on a run. What a run can cost is Writ platform compute: nothing on your own machine, metered running time on the managed cloud fleet.
The rest of the lifecycle
Everything else you can do with an install:
| Call | What it does |
|---|---|
GET /api/marketplace/installs | Everything you have installed. |
GET /api/marketplace/installs/{slug}/usage | status and last_run_at, plus the creator’s caps with used, remaining and reset per window. |
POST /api/marketplace/installs/{slug}/sync | Move your install onto the creator’s newer recipe. It needs your consent — it never happens on its own. |
DELETE /api/marketplace/listings/{slug}/install | Uninstall. Cascades to your bindings. |
An install keeps working even if the listing is later unpublished. You installed a snapshot, not a live link to the creator’s workspace.
reviews ▸ verified runs
Reviews come from people who ran it.
Only someone who installed a listing and accumulated enough successful runs can review it, and an organization gets one review. That is why the ratings track the measured signals instead of drifting from them.
| Call | What it does |
|---|---|
GET /api/marketplace/listings/{slug}/reviews | Reviews from accounts that actually ran it, plus the rating summary. |
GET /api/marketplace/listings/{slug}/reviews/eligibility | Whether you may review it yet, and what is missing. |
POST /api/marketplace/listings/{slug}/reviews | Leave yours. One per organization. |
DELETE /api/marketplace/listings/{slug}/reviews/me | Withdraw it. |
problems ▸ reports
When it does not deliver.
Report the run that went wrong. The creator and the platform admins are notified, and a listing that collects unresolved reports is flagged for review.
| Call | What it does |
|---|---|
POST /api/marketplace/installs/{slug}/report | Raise a problem with an install, optionally pinned to the run that failed. |
GET /api/marketplace/reports | Your own reports, each with status: open | reviewing | resolved | dismissed. |
publish ▸ creators
Publishing your own.
POST /api/marketplace/publish needs a verified account and accept_creator_agreement: true. Any plan, Free included, may publish, and what you publish is a free recipe: your personas, secrets and sessions are stripped at publish, so what anyone installs can never contain them. The body describes the asset and the guardrails you want on every run of it.
| Field | What it does |
|---|---|
asset_type | workflow | automation. |
workflow_id · automation_id | What you are publishing. |
title · summary · category | title up to 140 characters. |
keywords[] · tags[] · icon · cover_image_url | How it is found and how it looks. |
intent | Up to 60 characters — the job it does, in one line. |
visibility | Who can see the listing. |
baseline_duration_ms | The speed you are promising. On-time rate is measured against it. |
marketplace_exec_policy | customer | cloud | local | creator — where a run of it is allowed to execute. |
usage_limits | Per-install, global and concurrency caps, each with its own window and mode. |
input_rules | A regex per input, enforced on every run of your listing. |
Publish a recipe
The publish call, and the guardrails that ride with it.
publish.sh
curl -X POST https://api.usewrit.app/api/marketplace/publish \
-H "Authorization: Bearer $WRIT_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"accept_creator_agreement": true,
"asset_type": "workflow",
"workflow_id": 41,
"title": "Invoice puller",
"summary": "Signs in and pulls every invoice since a date you pass in.",
"category": "finance",
"keywords": ["invoices", "accounting"],
"tags": ["billing"],
"intent": "Pull invoices from a billing portal",
"baseline_duration_ms": 18000,
"marketplace_exec_policy": "cloud",
"usage_limits": {
"per_buyer": { "count": 200, "window": "day", "mode": "enforce" },
"global": { "count": 20000, "window": "month", "mode": "enforce" },
"max_concurrent_per_buyer": { "count": 4, "mode": "enforce" }
},
"input_rules": {
"rules": {
"account_number": { "pattern": "^[0-9]{4,8}$", "message": "4 to 8 digits" }
}
}
}' limits + rules
// usage_limits — three independent caps, each with its own mode.
// mode: "off" | "warn" | "enforce"
// window: per_buyer "day" | "month" · global "day" | "month" | "lifetime"
{
"per_buyer": { "count": 200, "window": "day", "mode": "enforce" },
"global": { "count": 20000, "window": "month", "mode": "enforce" },
"max_concurrent_per_buyer": { "count": 4, "mode": "enforce" }
}
// input_rules — one regex per input or secret slot, checked on every run.
// flags: any subset of "i", "m", "s". message is what the runner is shown.
{
"rules": {
"account_number": { "pattern": "^[0-9]{4,8}$", "flags": "", "message": "4 to 8 digits" }
}
} ip ▸ run, not read
People run a listing. They do not read it.
If you publish a recipe you spent weeks getting right, sharing it should not mean handing it over. That is a design constraint, not a promise — so here is exactly how it is arranged:
- Install captures a data-less snapshot — What lands on someone else’s account is the shape of the recipe, without the data it was built against.
- No install-side endpoint returns the steps — There is no read path for the recipe. Not on the listing, not on the install, not on a run.
- The desktop path receives a sealed recipe — When a run executes on a machine, that machine receives a form only it can open.
reference ▸ next
Around the marketplace
Every marketplace endpoint in one place.
→ AuthenticationKeys, scopes and what a partner key can reach.
→ WorkflowsBuild the thing you are going to publish.
→ Sign-ins and secretsPersonas and vault references — what a binding points at.
→ Billing and usageHow runs, pages and AI tokens are metered.
→ Account and teamWho in your organization can install and publish.
→faq
Marketplace questions, answered.
Does the creator get my login when I install their listing?
If the creator changes their workflow, does my install change?
What does a listing cost?
What does it take to publish something?
Can anyone see my workflow steps?
Where does an installed listing run?
end ▸ install one
Install one and bind your own login.
The manifest tells you which slots a listing needs before you install it. Read it first, then install.