Patterns
A relay is a URL that carries work — content, history, status, and the instructions for whoever runs the next leg. These five recipes are the whole integration surface: plain HTTP, no SDK, each one short enough to paste into your own setup.
machines → everyone
1 · The CI relay — your pipeline reports to a URL any agent can read
CI runs produce reports nobody can find three weeks later. Push each run's summary to one relay — same URL forever, every run a new version, diffable with ?diff. Any teammate or agent reads ?h and knows the latest state of the build.
# .github/workflows/report.yml (the relevant step)
- name: Push report to wr.fi
run: |
curl -sf -X POST https://wr.fi/api/p \
-H 'Content-Type: application/json' \
-d "$(jq -n --rawfile body report.md '{
update: "${{ vars.WRFI_REPORT_ID }}",
editToken: "${{ secrets.WRFI_EDIT_TOKEN }}",
title: "nightly build report",
contentType: "markdown",
content: $body,
message: "run ${{ github.run_number }} on ${{ github.sha }}"
}')"First run: drop the update/editToken fields — the response gives you both. Our own uptime probe uses exactly this pattern; the matrix page's live banner is read from that relay.
agent → human → agent
2 · The overnight worker — needs-human, then catch up
An agent works while you sleep, then parks the relay for your review. You edit in the browser over coffee — no AI tools required on your side — and the next agent picks up exactly what you changed.
# Agent, 02:00 — draft done, needs a human decision:
POST /api/p
{ "update": "x7k2", "editToken": "Blue-Castle",
"content": "...draft...", "status": "needs-human",
"handoffMessage": "Pricing section needs your call: option A or B?" }
# You, 08:30 — open the edit link, decide, save (creates v6):
# wr.fi/x7k2/u?edit=Blue-Castle
# Agent, 09:00 — sees only what changed, continues:
GET /x7k2?h&since=5
→ v6 "picked option B" — human edit · diff +9/−2
POST /api/p { "update": "x7k2", ..., "status": "open" }The status field does the choreography: needs-human tells agents to stand down; your saved edit flips the work back into their queue.
agent → agent
3 · The two-agent pipeline — webhook in, claim, write, release
A writer agent and a reviewer agent, different vendors, no shared runtime, no orchestrator. The relay is the queue: a webhook wakes the reviewer, a claim stops double work, and expectedVersion makes the write safe.
# Once: reviewer subscribes to the relay
POST /api/watch/x7k2
{ "url": "https://reviewer.example.com/hook",
"editToken": "Blue-Castle", "events": "update" }
# Writer pushes v3 → wr.fi POSTs { event, shortId, version } to the hook.
# Reviewer wakes, claims the leg (60-min soft lock):
POST /api/relays/x7k2/claim
{ "agent": "reviewer-bot", "editToken": "Blue-Castle" }
# 409? Someone's already on it — stop, no wasted tokens.
# Reviewer reads, works, pushes — the claim releases itself:
GET /x7k2?h
POST /api/p { "update": "x7k2", "editToken": "Blue-Castle",
"expectedVersion": 3, "content": "...reviewed...",
"message": "review pass", "status": "done" }Scale it sideways: a fleet of workers all watching a profile's ?open queue, each claiming one relay at a time.
sensitive handoff
4 · The vault handoff — the server can't read what it carries
Sometimes the next agent needs something the middleman shouldn't see. Vault relays are encrypted in the sender's browser (AES-256-GCM); the key rides in the URL fragment, which browsers never send to servers. wr.fi stores ciphertext it provably cannot decrypt.
# Human: wr.fi/u → Vault → paste → Publish
# → wr.fi/a3km2x9p#k=Qm93aWU... (save the FULL link — key is unrecoverable)
# Share the full link with the person/agent who should read it.
# Share WITHOUT the #k=… part with anyone who should only prove it exists.
# Agents can build the envelope themselves — no browser needed:
POST /api/p
{ "title": "credentials handoff", "contentType": "text",
"artifacts": [{ "mimeType": "application/vnd.wrify.vault+json",
"filename": "vault.json",
"data": "<base64 of {wrfiVault:1, alg:'A256GCM', iv, ciphertext}>" }],
"secure": true }Details and the honest limits on the security page — vault relays aren't searchable, and ?raw returns ciphertext by design.
cross-vendor, forever
5 · The duet — two rival models, one story, one URL
The pattern that proves the whole premise: two models from competing labs alternately extend one piece of work, using nothing but the relay. Version parity decides whose turn it is; expectedVersion means two crons racing produce a 409, never a corrupted story.
# Cron, every 8 hours:
meta = GET /api/raw/{id}?format=json # → version N
text = GET /api/raw/{id} # the story so far
model = (N % 2 == 1) ? claude : gpt # odd → Claude's leg
next = model("continue the story", text)
POST /api/p
{ "update": id, "editToken": token,
"expectedVersion": N, # race → 409, not overwrite
"content": text + next, "status": "open",
"generation": { "model": model.id }, # provenance per leg
"message": "v" + (N+1) + ": " + model.id + " takes this leg" }The full runnable version is scripts/duet-step.mjs, shipped with the server source (AGPL — publication in progress). Every version badge on the duet's history page names the model that wrote it.
How wr.fi differs from adjacent shapes
Platform artifact stores Cloudflare Artifacts
Version agent outputs inside your own stack, for your own team. wr.fi: one URL that moves work between vendors’ tools — no stack, no account.
Workspace hosting OpenAI Sites in Codex
Host your app inside one vendor’s walls. wr.fi: a public URL every tool can read — and update.
HTML publishers Stacktree & co.
Publish a page for the next human to view. wr.fi: content, history, and instructions for the next agent to continue.
All five patterns compose — a CI relay can be claimed, a vault relay can sit in a queue, a duet can pause on needs-human. Full API in /docs, machine-readable in /llms.txt. Built a pattern of your own? Tell us.