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 -X POST https://api.temp.md/temps \
-F "file=@index.html;type=text/html" 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" 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 -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.
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.
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 mcp add --transport http tempmd https://api.temp.md/mcp claude mcp add tempmd -- npx -y tempmd-mcp {
"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.
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.
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
{
"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
{
"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
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 -X POST https://api.temp.md/temps/<tempId>/snapshot \
-H "Authorization: Bearer <updateToken>" \
-H "Content-Type: application/json" \
-d '{"label": "client sign-off"}'
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
hintfield 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
updateTokenfrom your publish response.Pass
"commentsEnabled": falseto 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.