HTML
curl -sS -X POST \
"https://tabucom.vps.mark-thebault.pro/api/v1/publish?ttl=72h" \
-H "Content-Type: text/html; charset=utf-8" \
--data-binary @index.htmlTabucom · internal temporary static hosting
Send one POST with HTML, Markdown, or a ZIP of a prebuilt static site. Set an optional ttl query parameter to choose the lifetime, or omit it to keep the default 30-day retention.
npm install, Node.js servers, SSR, APIs, databases, or uploaded source code. Build on your machine or in CI, then publish the resulting dist/ or build/ directory.One request
These commands use this page's current origin automatically. The explicit localhost forms remain valid for local development.
curl -sS -X POST \
"https://tabucom.vps.mark-thebault.pro/api/v1/publish?ttl=72h" \
-H "Content-Type: text/html; charset=utf-8" \
--data-binary @index.htmlcurl -sS -X POST \
"https://tabucom.vps.mark-thebault.pro/api/v1/publish?ttl=72h" \
-H "Content-Type: text/markdown; charset=utf-8" \
--data-binary @report.mdcurl -sS -X POST \
"https://tabucom.vps.mark-thebault.pro/api/v1/publish?spa=1&ttl=72h" \
-H "Content-Type: application/zip" \
--data-binary @site.zipcurl -sS -X POST "http://localhost:8080/api/v1/publish?ttl=72h" -H "Content-Type: text/html" --data-binary @index.html{
"id": "019f2a56-7f0d-73c3-89ef-8f0d8c499f26",
"url": "https://publish.tools.company/p/019f2a56-7f0d-73c3-89ef-8f0d8c499f26/",
"createdAt": "2026-06-19T14:30:00Z",
"expiresAt": "2026-06-22T14:30:00Z",
"files": 37,
"bytes": 1842032,
"spa": true
}Every successful request creates a new immutable deployment. There is no update operation and the expiry cannot be extended after publication.
Agent instruction: publish the build output, then return the deployment URL and expiry timestamp to the user.
Complete project workflow
Vite, React, Vue, Svelte and similar projects are supported when they produce static browser files.
npm ci
npm run buildFind the generated output, commonly dist/ or build/.
(cd dist && zip -qr ../site.zip .)ZIP the directory's contents, not the parent directory.
curl -sS -X POST \
"https://tabucom.vps.mark-thebault.pro/api/v1/publish?spa=1&ttl=72h" \
-H "Content-Type: application/zip" \
--data-binary @site.zipUse spa=1 only when client-side routing needs fallback.
Archive contract
index.html must be at the ZIP rootCSS, JavaScript, images, fonts, JSON, WASM, media, source maps, and nested asset directories are served as static files.
site.zip ├── index.html ├── assets/ │ ├── app.js │ └── app.css └── images/logo.svg
site.zip
└── dist/
├── index.html
└── assets/…Fix with (cd dist && zip -qr ../site.zip .).
Serving behavior
The response's url is authoritative. Follow it rather than constructing a URL yourself.
Deployments are served at /p/{id}/. Build apps with relative asset paths or the matching base path. Root-relative URLs such as /assets/app.js point at the service root and may fail.
Path-mode deployments share the same browser origin as this documentation page and the publish API. Do not treat path mode as an isolation boundary for untrusted HTML or JavaScript.
When PREVIEW_DOMAIN and wildcard DNS/TLS are configured, the service can return https://{id}.preview.tools.company/. This gives each deployment a separate browser origin and supports root-relative assets.
Publish with ?spa=1 for React Router or another client router. Add &ttl=72h or another positive duration when the deployment should expire sooner or later than the default 30 days. Existing files are served normally; an unknown route returns the deployment's index.html. Without SPA mode, unknown paths return 404.
Operational contract
Limits protect a no-sign-in internal service from accidental overload and hostile archives.
| Rule | Default |
|---|---|
| Lifetime | Client-selected via ttl; defaults to 30 days (720 hours) |
| Compressed request | 100 MB maximum |
| Expanded ZIP | 500 MB maximum |
| ZIP entries | 10,000 maximum, including directories |
| Publish rate | 60 requests/hour/network peer |
ZIPs with absolute paths, traversal, NUL bytes, symlinks, device files, duplicate normalized paths, conflicting file and directory paths, excessive nesting, or expansion beyond the limit are rejected. Partial uploads never become visible.
Machine-readable failures
Check the HTTP status and error.code; display error.message to the user.
{
"error": {
"code": "missing_index",
"message": "site must contain index.html at its root"
}
}unsupported_media_type, empty_body, invalid_spa, invalid_ttl — fix the request shape.upload_too_large / too_many_files — reduce the artifact.invalid_archive / missing_index — fix ZIP structure.rate_limited — retry after the response delay.method_not_allowed, internal_error, service_unavailable — correct the caller or retry later.HTTP API
Machine clients can use the OpenAPI 3.1 document, llms.txt, or agent discovery document.
/api/v1/publishPublish HTML, Markdown, or ZIP. Optional spa=1 and ttl=<duration>. Returns 201 after atomic publication.
/healthzReadiness endpoint for container and ingress health checks.