curl and the HTTP API
The CLI and the MCP tool both call the HTTP API at https://app.tmphost.io/api/v1. An agent with only curl can call it directly: with a Bearer token, or, with tight limits, without signing in.
LLM-friendly version (Markdown): https://tmphost.io/docs/api.md
If the agent can install the CLI, use it instead of curl. tmphost file upload dist/ uploads a whole directory in one command, keeps its token fresh, checks paths and credits before sending anything, and prints the URLs. With curl the agent does each of those by hand, one request per file. Install it with one line (install), then run tmphost login.
Use curl only when installing a binary is not an option, or for a quick one-file upload without signing in. Like the CLI, curl sends files from disk, so their bytes never pass through the model's context.
With or without a token
| With a token | Without a token | |
|---|---|---|
| How | Authorization: Bearer <token> | Origin: https://tmphost.io, and no Authorization header |
| TTL | Default 30 minutes; the maximum is in /limits | At most 10 minutes |
| File size | The account's maxUploadBytes | 1 MB per file |
| Quota | Credits: 250 every 30 days | Per IP address, per 30 minutes: 5 new folders, 5 file writes, 4 MB in all |
| Calls | All of them | Only /limits, create a folder, write a file |
| Cost | Credits per file written | Free |
Get a token
Tokens come from the OAuth sign-in at app.tmphost.io, which needs a browser once. The simplest way to get one is the CLI: tmphost login saves an access token to its config file, and tmphost whoami refreshes it when it is about to expire.
$ tmphost login --server https://app.tmphost.io $ tmphost whoami > /dev/null $ TOKEN=$(jq -r .accessToken ~/.config/tmphost/config.json) $ API=https://app.tmphost.io/api/v1
The config file is $TMPHOSTIO_CONFIG, or tmphost/config.json in the user config directory: ~/.config on Linux, ~/Library/Application Support on macOS, %AppData% on Windows. An access token lasts 1 hour. When a call answers 401, run tmphost whoami again and re-read the token; don't trade the refresh token yourself, or the CLI's saved one may stop working.
With a token
Every call below sends -H "Authorization: Bearer $TOKEN". Responses are JSON; ids, times and sizes here are examples.
Check the limits
$ curl -sS -H "Authorization: Bearer $TOKEN" $API/limits
Returns defaultTtlMinutes, maxTtlMinutes, maxUploadBytes, billingBlockMinutes and billingUnitBytes for the account.
Create a folder
$ curl -sS -X POST -H "Authorization: Bearer $TOKEN" $API/folders {"folder":{"id":"k7q2m9xa","createdAt":"2026-10-21T07:15:20Z","expiresAt":"2026-10-21T07:45:20Z","url":"https://k7q2m9xa.file.tmphost.io/","title":"","defaultTitle":"k7q2m9xa","agent":"tmphost CLI"}}
Without a body the folder lives 30 minutes, the recommended default: send {"ttlMinutes":N} only when the agent knows it needs longer. agent is the app the token was issued to.
Upload a file
$ curl -sS -X PUT -H "Authorization: Bearer $TOKEN" \ --data-binary @dist/index.html $API/folders/k7q2m9xa/files/index.html {"file":{"path":"index.html","size":1342,"updatedAt":"2026-10-21T07:15:21Z","url":"https://k7q2m9xa.file.tmphost.io/index.html","agent":"tmphost CLI"},"creditsSpent":1} $ curl -sS -X PUT -H "Authorization: Bearer $TOKEN" \ --data-binary @dist/assets/app.js $API/folders/k7q2m9xa/files/assets/app.js {"file":{"path":"assets/app.js","size":20480,"updatedAt":"2026-10-21T07:15:22Z","url":"https://k7q2m9xa.file.tmphost.io/assets/app.js","agent":"tmphost CLI"},"creditsSpent":1}
One PUT per file; the raw request body is the file and the URL path after /files/ is its path in the folder. Use --data-binary @file: -d strips newlines and would change the file. A file already at that path is replaced in place, same URL, same expiry. Each write costs 1 credit per started MB per started 30 minutes left in the folder.
List a folder, and all folders
$ curl -sS -H "Authorization: Bearer $TOKEN" $API/folders/k7q2m9xa {"folder":{"id":"k7q2m9xa",...,"openUrl":"https://k7q2m9xa.file.tmphost.io/"},"files":[{"path":"assets/app.js","size":20480,...},{"path":"index.html","size":1342,...}]} $ curl -sS -H "Authorization: Bearer $TOKEN" $API/folders {"folders":[{"id":"k7q2m9xa","expiresAt":"2026-10-21T07:45:20Z","url":"https://k7q2m9xa.file.tmphost.io/",...}]}
openUrl is what to share: the folder URL when index.html sits at its root, else the URL of its only file.
TTL: 30 minutes, then extend
Start every folder with the 30 minute default and extend it while it is still needed, instead of guessing a long TTL up front. Credits are charged by lifetime, so a folder that turns out to be needed for 10 minutes costs a quarter of one created for 2 hours, and nothing stays public longer than it has to. Before expiresAt, add time with POST /folders/{id}/extend; once a folder has expired it is gone, so extend a few minutes early.
Download, extend, rename, delete
$ curl -sS -H "Authorization: Bearer $TOKEN" -o app.js $API/folders/k7q2m9xa/files/assets/app.js $ curl -sS -X POST -H "Authorization: Bearer $TOKEN" \ -H 'Content-Type: application/json' -d '{"minutes":60}' $API/folders/k7q2m9xa/extend {"folder":{"id":"k7q2m9xa","expiresAt":"2026-10-21T08:45:20Z",...},"creditsSpent":4} $ curl -sS -X PATCH -H "Authorization: Bearer $TOKEN" \ -H 'Content-Type: application/json' -d '{"title":"build preview"}' $API/folders/k7q2m9xa $ curl -sS -X DELETE -H "Authorization: Bearer $TOKEN" $API/folders/k7q2m9xa/files/assets/app.js $ curl -sS -X DELETE -H "Authorization: Bearer $TOKEN" $API/folders/k7q2m9xa
A download is always sent as an attachment (application/octet-stream); the public URL serves the file with its real type. extend charges each file for the added time. The deletes answer 204 with no body.
Without a token
The upload box on the home page works without signing in, and curl can make the same calls. An anonymous request must carry Origin: https://tmphost.io (or https://app.tmphost.io) and no Authorization header. This is a real session, run on 2026-10-21:
$ API=https://app.tmphost.io/api/v1 $ curl -sS -H 'Origin: https://tmphost.io' $API/limits {"defaultTtlMinutes":10,"maxTtlMinutes":10,"maxUploadBytes":1048576,"billingBlockMinutes":30,"billingUnitBytes":1048576,"anonymous":true,"fileOps":5,"fileBytes":4194304,"fileOpsWindowMinutes":30} $ curl -sS -X POST -H 'Origin: https://tmphost.io' \ -H 'Content-Type: application/json' -d '{"ttlMinutes":10}' $API/folders {"folder":{"id":"g7znawfm","createdAt":"2026-10-21T07:15:20Z","expiresAt":"2026-10-21T07:25:20Z","url":"https://g7znawfm.file.tmphost.io/","title":"","defaultTitle":"g7znawfm","agent":"Web"}} $ curl -sS -X PUT -H 'Origin: https://tmphost.io' \ --data-binary @index.html $API/folders/g7znawfm/files/index.html {"file":{"path":"index.html","size":12,"updatedAt":"2026-10-21T07:15:20Z","url":"https://g7znawfm.file.tmphost.io/index.html","agent":"Web"},"creditsSpent":0}
Keep the folder id and the URLs from these responses: without a token there is no call to look them up again.
Pitfalls without a token
- No Origin header, no access. Plain
curl $API/limitsanswers401 {"error":"unauthorized"}. Every call needsOrigin: https://tmphost.ioorhttps://app.tmphost.io(aRefereron one of them also works). Any other origin is 401 too. - A bad token does not fall back. An expired or wrong
Authorizationheader is 401 even with the Origin header. Send no Authorization header at all. - 10 minutes, at most. The folder and its URLs are gone after 10 minutes, and
{"ttlMinutes":60}answers400 {"error":"invalid ttl: must be between 1 and 10 minutes"}. A folder cannot be extended without a token. - 1 MB per file. A bigger file answers
413 {"error":"upload too large: \"big.bin\" is over the 1 MB file limit"}. - A small quota per IP address. In any 30 minutes: 5 new folders, 5 file writes and 4 MB written. Retries and replacements count. Past it, calls answer
429, such as{"error":"anonymous quota exceeded: at most 5 files per 30 minutes"}. A 5-file site uses the whole window. - Write-only. Listing, reading, downloading, renaming, extending and deleting all need a token (401 without one). A file stays public until its folder expires; there is no way to take it down early.
- The IP address is the account. Everyone behind the same address (an office NAT, a VPN, a shared CI runner) shares one quota and one set of folders, so anyone there who knows a folder id can overwrite its files. If the agent's IP address changes, it can no longer add files to its folders.
- Meant for the web upload box. Anonymous access exists for people dropping files on the site; its limits may tighten. For anything an agent does repeatedly, install the CLI and sign in, or send a token with curl.
Errors
Errors are JSON, {"error":"<message>"}, except a malformed request, which answers a plain Bad Request. Use curl -sS without -f to see the message.
| Status | Meaning |
|---|---|
| 400 | A TTL out of range, an invalid path or title, or a malformed body or folder id. |
| 401 | unauthorized: no valid token, and not an anonymous request from an allowed Origin; or the call needs a token. |
| 402 | insufficient credits: N needed: the account can't pay for the write or the extension. |
| 404 | not found: the folder or file doesn't exist, has expired, or belongs to someone else. |
| 413 | upload too large: the file is over maxUploadBytes. |
| 429 | anonymous quota exceeded: wait for the 30 minute window, or sign in. |
Endpoints
All under https://app.tmphost.io/api/v1.
| Call | Without a token | Description |
|---|---|---|
| GET /limits | Yes | TTL, size and billing limits for the caller. |
| POST /folders | Yes | Create a folder. Body {"ttlMinutes":N}, optional. |
| PUT /folders/{id}/files/{path} | Yes | Write a file; the raw body is its content. |
| GET /folders | No | List live folders. |
| GET /folders/{id} | No | A folder and its files. |
| PATCH /folders/{id} | No | Rename a folder. Body {"title":"..."}. |
| POST /folders/{id}/extend | No | Make a folder live longer. Body {"minutes":N}. |
| DELETE /folders/{id} | No | Delete a folder and its files. |
| GET /folders/{id}/files/{path} | No | Download a file. |
| DELETE /folders/{id}/files/{path} | No | Delete one file. |
| GET /users/me | No | The account, its credits and renewal time. |
Paths are at most 5 directories deep, with no . or .. segments and no backslashes; percent-encode spaces and other special characters in the URL.