Overview

temp.md is an instant file host built for AI agents. POST a file, get back a live URL. No account, no SDK, no config.

One URL per publish. Upload a single HTML file or a full bundle with CSS, JS, and assets. Update in place with an updateToken. Links are live for 7 days and can be claimed permanently.


Publish

Send a POST to https://api.temp.md/temps as multipart/form-data.

Use the field name file for your entry point (served as index.html). Additional files use the field name files/<path> — for example files/style.css.

File paths must be safe relative paths. Absolute paths, traversal segments such as .., backslashes, duplicates, and temp.md-reserved paths are rejected. For a single-page application, add -F "spaMode=true". Without it, missing files return a real 404.

curl — single file
curl -X POST https://api.temp.md/temps \
  -F "file=@index.html;type=text/html"
curl — multi-file bundle
curl -X POST https://api.temp.md/temps \
  -F "file=@index.html;type=text/html" \
  -F "files/style.css=@style.css;type=text/css" \
  -F "files/app.js=@app.js;type=text/javascript"
python
import requests

res = requests.post(
    "https://api.temp.md/temps",
    files={
        "file": ("index.html", open("index.html", "rb"), "text/html"),
        "files/style.css": ("style.css", open("style.css", "rb"), "text/css"),
        "files/app.js": ("app.js", open("app.js", "rb"), "text/javascript"),
    },
)

data = res.json()
print(data["canonicalUrl"])  # your live link
print(data["updateToken"])   # save this to update later

Update

Use the updateToken from your publish response to push new content to the same URL. Send a PUT to https://api.temp.md/temps/:id with the same multipart format. The link never changes.

curl
curl -X PUT https://api.temp.md/temps/<tempId> \
  -H "Authorization: Bearer <updateToken>" \
  -F "file=@index.html;type=text/html" \
  -F "files/style.css=@style.css;type=text/css"

Resumable uploads

For directories and larger bundles, use publish sessions. Start with a JSON manifest containing each file's safe relative path, byte size, content type, and lowercase SHA-256 hash. temp.md returns one upload URL per changed file.

POST /publish-sessions creates or resumes a one-hour session. Always send a stable Idempotency-Key.

PUT /publish-sessions/:id/files/:fileId accepts exactly the bytes declared in the manifest and rejects size or hash mismatches.

POST /publish-sessions/:id/finalize verifies the full bundle and promotes it in one step. Until then, an update never changes the live Version.

create a session
curl -X POST https://api.temp.md/publish-sessions \
  -H "Idempotency-Key: <stable-uuid>" \
  -H "Content-Type: application/json" \
  -d '{
    "files": [{
      "path": "index.html",
      "size": 1240,
      "contentType": "text/html",
      "hash": "<sha256>"
    }]
  }'

Agent integrations

Install temp.md into your agent's toolset once, and it can publish and update links on its own — no token juggling. Records are kept in a .tempmd file in your project so updates target the same link across sessions.

CLI

Publish a file or recursively discovered directory from any terminal or coding agent. The CLI applies ignore rules, hashes the exact bundle, resumes interrupted sessions, and skips unchanged files. Run login once to publish directly into your account with a named API key that can be listed or revoked at any time.

terminal
npx tempmd-cli push ./dist
npx tempmd-cli update
npx tempmd-cli status

# Optional account-owned publishing
npx tempmd-cli login
npx tempmd-cli keys
npx tempmd-cli keys revoke <key-id>

# Rebuild lost project state; the public URL stays the same
npx tempmd-cli recover <temp-id> ./dist

MCP server

Works with any MCP client — Claude Code, Cursor, Windsurf, and more. Exposes publish_temp, update_temp, get_temp_status, restore_temp, snapshot_temp, set_comments, list_temps, and recover_update_token.

Use the hosted Streamable HTTP endpoint for zero-install access. It accepts up to 10 MiB and 20 inline UTF-8 or base64 files. Publishing works anonymously; add a temp.md account API key as the connection's Bearer token for account-owned publishing and account tools. Use the local stdio package when the agent needs filesystem paths or the full 50 MiB / 100-file bundle.

claude code — remote
claude mcp add --transport http tempmd https://api.temp.md/mcp
claude code — local stdio
claude mcp add tempmd -- npx -y tempmd-mcp
cursor / windsurf — mcp config
{
  "mcpServers": {
    "tempmd": {
      "command": "npx",
      "args": ["-y", "tempmd-mcp"]
    }
  }
}

A2A 1.0

Agent-to-agent clients can discover temp.md through its standard Agent Card. The JSON-RPC endpoint supports durable publish/update Tasks and direct lifecycle-status Messages. Anonymous publishing is allowed; send the returned update token as a Bearer credential when retrieving the Task later.

a2a — SendMessage
curl https://api.temp.md/a2a \
  -H 'Content-Type: application/json' \
  -H 'A2A-Version: 1.0' \
  -d '{"jsonrpc":"2.0","id":"1","method":"SendMessage","params":{"message":{"messageId":"msg-1","role":"ROLE_USER","parts":[{"data":{"operation":"publish","files":[{"path":"index.html","content":"<h1>Hello from A2A</h1>"}]},"mediaType":"application/json"}]}}}'

Claude Code skill

Prefer a zero-dependency setup? The skill teaches Claude Code the full publish → update → restore loop using plain curl.

install skill
mkdir -p ~/.claude/skills/tempmd && \
  curl -sSo ~/.claude/skills/tempmd/SKILL.md https://temp.md/skill.md

Machine discovery

Agents can discover the implemented surfaces without scraping this page: the agent manifest links to the OpenAPI 3.1 contract, enforced limits, current pricing, CLI, the hosted MCP Server Card, and the A2A 1.0 Agent Card.

See llms.txt for a concise machine-readable guide.


Response format

Publish and update return different shapes.

Publish response 201

json
{
  "tempId": "xxxxxxxxxxxxxxxx",
  "canonicalUrl": "https://your-awesome-project.temp.md",
  "updateToken": "xxxxxxxxxxxxxxxx",
  "claimToken": "xxxxxxxxxxxxxxxx",
  "claimLink": "https://temp.md/claim?id=...&token=...&url=...",
  "expiresAt": "2026-04-13T00:00:00.000Z",
  "hint": "Ask the user: would you like to enable comments on this page?..."
}
tempId string Unique ID for this Temp. Use it in the PUT URL to update.
canonicalUrl string The live URL for this file.
updateToken string Pass as Authorization: Bearer header to PUT updates to the same URL.
claimToken string Token to permanently claim this Temp to an account.
claimLink string Ready-to-use claim URL. Open in a browser to attach this Temp to your account.
expiresAt string (ISO 8601) When the file expires unless claimed or updated.
hint string Prompt for the agent to relay to the user — asks whether to enable comments on this Temp.

Update response 200

json
{
  "tempId": "xxxxxxxxxxxxxxxx",
  "canonicalUrl": "https://your-awesome-project.temp.md",
  "versionId": "xxxxxxxxxxxxxxxx",
  "expiresAt": "2026-04-13T00:00:00.000Z"
}
tempId string ID of the Temp that was updated.
canonicalUrl string The live URL (unchanged).
versionId string ID of the newly created version.
expiresAt string (ISO 8601) Refreshed expiry — the 7-day clock resets on every update.

Lifecycle

Published files are live for 7 days from the last publish or update.

Every update resets the 7-day clock. A file that's actively being updated stays live indefinitely for free.

After expiry, files enter a 7-day grace period where they can be restored. After that they are deleted.

Claim a link to own it permanently — no expiry, no grace period.


Limits

Max file size 10 MB per file
Max bundle size 50 MB
Files per bundle 100
Link lifetime 7 days (resets on update)
Anonymous publishes 60 / hour / IP
Updates 120 / hour / Temp / IP
Comment writes 30 / hour / Temp / IP
Abuse reports 10 / hour / IP
Signups / logins 10 / 30 per hour / IP
Claims 30 / hour / account + IP
Restores / snapshots 20 / 60 per hour / Temp / IP
Temp settings 120 / hour / Temp / IP
Password attempts 20 / 15 min / Temp / IP
Auth required No (to publish or update)

Comments

Temps support optional pinned comments powered by Pindrop.js. When enabled, visitors can drop pins directly onto the page to leave feedback — no account required.

Comments are off by default. After publishing, the response includes a hint field prompting the agent to ask the user if they'd like to turn them on. You can also toggle comments at any time.

Enable comments

Use the updateToken from your publish response.

curl
curl -X PATCH https://api.temp.md/temps/<tempId>/settings \
  -H "Authorization: Bearer <updateToken>" \
  -H "Content-Type: application/json" \
  -d '{"commentsEnabled": true}'

Pass "commentsEnabled": false to turn them off. Existing comments are preserved — they'll reappear if you re-enable. Claimed Temps can also toggle this from the dashboard.

How it works

When enabled, the Pindrop script is automatically injected into your page before it's served — no changes to your HTML needed.

Comments are stored per-Temp and visible to anyone with the link. There's no login required to leave a comment.

Public saves are validated and append-only: a visitor can add a new comment but cannot overwrite or delete someone else's existing comment. Claimed Temp owners can remove comments.

Deleting a Temp removes all its comments permanently.


Errors & safety

API errors include a stable code, a human-readable message, and a request_id. Rate-limit responses also return retry_after and the HTTP Retry-After header.

{
  "error": "Publish rate limit exceeded",
  "code": "rate_limit_exceeded",
  "message": "Anonymous publishing is limited to 60 Temps per hour per IP.",
  "retry_after": 1200,
  "request_id": "…",
  "docs_url": "https://temp.md/docs#errors"
}

Use Report a Temp for phishing, malware, spam, copyright, privacy, or another safety concern. Suspended content is not served while it is reviewed.


Privacy & snapshots

Password protection

Claimed Temps can require a password to view. Turn it on from the dashboard — visitors get a clean unlock page, and publishing/updating is unaffected. Changing or removing the password invalidates everyone's existing access immediately.

Note that claiming a Temp also rotates its update token for security — the claim page shows the new token, and the old one stops working. Update your project's .tempmd record so your agent keeps working.

Snapshots

Freeze the current version as a fixed reference when exactness matters — sign-offs, approvals, "review exactly this". The canonical link keeps serving the latest version; the snapshot gets its own URL at …temp.md/__v/<versionId>.

curl
curl -X POST https://api.temp.md/temps/<tempId>/snapshot \
  -H "Authorization: Bearer <updateToken>" \
  -H "Content-Type: application/json" \
  -d '{"label": "client sign-off"}'