DEV Community

deed.page
deed.page

Posted on

Publish an AI agent's HTML report to a live URL with one curl call

Agents are good at producing HTML: test summaries, research briefs, dashboards, small prototypes. Getting that file onto a URL someone can open usually takes longer than writing it. You have to pick a host, sign up, set up a CLI or connect a repo, then wait for a build.

This walkthrough uses deed.page, a static host built for this case. You can publish without an account, the response is JSON an agent can parse, and updates are versioned, so a script can safely overwrite its own report every night.

Everything below is plain curl. You can run it yourself or give it to an agent as a shell tool.

1. Write the report

cat > report.html <<'HTML'
<!doctype html><html><head><meta charset="utf-8"><title>Nightly test report</title></head>
<body><h1>Nightly test report</h1><p>412 passed, 3 failed.</p></body></html>
HTML
Enter fullscreen mode Exit fullscreen mode

2. Publish it

SLUG=agent-report-$(openssl rand -hex 3)
curl -s -T report.html "https://deed.page/v1/sites?slug=$SLUG" -H "X-Client: report-bot" > first.json
Enter fullscreen mode Exit fullscreen mode

curl -T sends a PUT with the file as the body. No API key is needed. The response looks like this (trimmed):

{
  "ok": true,
  "url": "https://agent-report-87cc65.deed.page/",
  "version": "v1",
  "version_url": "https://v1--agent-report-87cc65.deed.page/",
  "token": "deed_tok_…"
}
Enter fullscreen mode Exit fullscreen mode

The site is live right away, and version_url is a permanent link to this exact version.

The token is only shown once, and it's what lets you update or delete the site later. Save it to a file outside the agent's context instead of printing it:

mkdir -p ~/.config/deed-page && chmod 700 ~/.config/deed-page
python3 -c "import json;print(json.load(open('first.json'))['token'])" > ~/.config/deed-page/token
chmod 600 ~/.config/deed-page/token && rm first.json
export DEEDPAGE_TOKEN=$(cat ~/.config/deed-page/token)
Enter fullscreen mode Exit fullscreen mode

If an LLM is driving the shell, this matters. A token that shows up in tool output ends up in the transcript, the logs and possibly the next prompt. Keep it in a file and let the tool read it.

3. Update it safely

The next night the numbers change. Publish to the same slug with the token. Add If-Match so the write only succeeds if the site is still at the version you expect:

sed -i 's/412 passed, 3 failed/415 passed, 0 failed/' report.html
curl -s -T report.html "https://deed.page/v1/sites?slug=$SLUG" \
  -H "Authorization: Bearer $DEEDPAGE_TOKEN" \
  -H 'If-Match: "v1"'
# -> "version": "v2"
Enter fullscreen mode Exit fullscreen mode

If two agents (or two runs of the same cron job) race, the one holding a stale version gets a 409 instead of silently overwriting the other:

{"code":"version_conflict","message":"Slug agent-report-87cc65 is at v2, not v1. Re-read and retry.","version":"v2"}
Enter fullscreen mode Exit fullscreen mode

The error body tells the agent the current version, so it can re-read the site and retry. If you publish exactly the same bytes again, you get "unchanged": true and no new version.

4. Look back and roll back

Every publish is kept as a version (the free plan keeps the last 10):

curl -s "https://deed.page/v1/sites/$SLUG/versions" -H "Authorization: Bearer $DEEDPAGE_TOKEN"
Enter fullscreen mode Exit fullscreen mode

Each entry has a permalink like https://v2--agent-report-87cc65.deed.page/. If tonight's report is wrong, restore an older one. The restore becomes a new version, so history is never rewritten:

curl -s -X POST "https://deed.page/v1/sites/$SLUG/versions/v1/restore" \
  -H "Authorization: Bearer $DEEDPAGE_TOKEN"
# -> "version": "v3", content equal to v1
Enter fullscreen mode Exit fullscreen mode

5. Clean up

curl -s -X DELETE "https://deed.page/v1/sites/$SLUG" -H "Authorization: Bearer $DEEDPAGE_TOKEN"
# -> {"ok":true,"deleted":"agent-report-87cc65"}
Enter fullscreen mode Exit fullscreen mode

The URL returns 404 a few seconds later.

More than one file

For a folder (HTML plus CSS, images and JS), pack it and upload the tarball the same way:

tar -C ./dist -czf site.tar.gz .
curl -T site.tar.gz "https://deed.page/v1/sites?slug=$SLUG" -H "Authorization: Bearer $DEEDPAGE_TOKEN"
Enter fullscreen mode Exit fullscreen mode

Clean URLs work (/about serves about.html or about/index.html), and a root 404.html is used for missing pages. Single-page apps can send X-Spa: 1 so unknown paths fall back to index.html. A single request is capped at 4 MB, and larger sites use the manifest upload described in the docs.

Letting an agent do this

If your agent runs shell commands, the steps above are all it needs. Two guardrails are worth adding:

  1. Ask before publishing. A URL is public. Have the agent show what it is about to publish (file list and a preview) and wait for an explicit "yes" before running the PUT.
  2. Keep the token out of the conversation. Read it from ~/.config/deed-page/token inside the tool, never echo it.

For agents that speak MCP, deed.page also has an MCP endpoint at https://deed.page/mcp. There's an open-source agent skill that follows both rules at github.com/f-o-x11/deed-page-skill.

Limits worth knowing

The free plan allows 25 sites, 25 MB per site, 60 publishes an hour and 10 versions per site. Free sites show a small "Published with deed.page" badge. The paid plans are listed on deed.page.

Full API reference: deed.page/docs. There's also a plain-text version for LLMs at deed.page/llms.txt.

Top comments (0)