Instant static site hosting. Publish files and get a live URL at <slug>.shipsite.co.
Inspired by and API-compatible with here.now — whose elegant design made instant static hosting accessible to agents everywhere. ShipSite builds on that foundation with additional features: version history, instant rollback, ZIP export, and built-in analytics.
No account needed. Create an anonymous site in three steps:
curl -sS https://shipsite.co/api/v1/publish \
-H "content-type: application/json" \
-d '{"files":[{"path":"index.html","size":42,"contentType":"text/html"}]}'
Returns presigned upload URLs and a finalizeUrl.
# PUT each file to its presigned URL
curl -X PUT "$UPLOAD_URL" \
-H "Content-Type: text/html" \
--data-binary "<h1>Hello world</h1>"
curl -sS -X POST "$FINALIZE_URL" \
-H "content-type: application/json" \
-d '{"versionId":"$VERSION_ID"}'
Your site is now live at https://<slug>.shipsite.co/
Passwordless via email OTP. Two steps to get an API key:
POST/api/auth/agent/request-code
{"email": "you@example.com"}
POST/api/auth/agent/verify-code
{"email": "you@example.com", "code": "ABCD-EFGH"}
Returns: {"apiKey": "sk_..."}
Use it in requests:
Authorization: Bearer sk_your_api_key_here
POST/api/v1/publish
Request body:
{
"files": [
{"path": "index.html", "size": 1024, "contentType": "text/html"},
{"path": "style.css", "size": 512, "contentType": "text/css", "hash": "sha256:..."}
],
"viewer": {
"title": "My Project",
"description": "A demo site",
"ogImagePath": "og.png"
}
}
Response:
{
"slug": "bright-canvas-a7k2",
"siteUrl": "https://bright-canvas-a7k2.shipsite.co/",
"upload": {
"versionId": "01ABC...",
"uploads": [
{"path": "index.html", "method": "PUT", "url": "https://...", "headers": {"Content-Type": "text/html"}}
],
"skipped": ["style.css"],
"finalizeUrl": "https://shipsite.co/api/v1/publish/bright-canvas-a7k2/finalize",
"expiresInSeconds": 3600
}
}
hash (SHA-256) for each file to enable incremental deploys. Files with matching hashes are skipped and copied server-side.PUT each file to its presigned URL from the create/update response. Uploads go directly to S3 — the server never proxies file bytes.
curl -X PUT "$UPLOAD_URL" \
-H "Content-Type: text/html" \
--data-binary @index.html
Presigned URLs expire after 1 hour. Use the uploads/refresh endpoint to get new ones.
POST/api/v1/publish/:slug/uploads/refresh
Requires auth. Returns fresh presigned URLs for the pending version.
POST/api/v1/publish/:slug/finalize
{"versionId": "01ABC..."}
Activates the uploaded version. The site is now live. For incremental deploys, hash-matched files are copied server-side during finalization.
PUT/api/v1/publish/:slug
{"files": [...], "claimToken": "..." }
Same format as create. For authenticated sites, use your API key. For anonymous sites, include the claimToken.
GET/api/v1/publish/:slug
Returns site metadata, current/pending version IDs, and the file manifest.
GET/api/v1/publishes
Returns all sites for the authenticated user.
PATCH/api/v1/publish/:slug/metadata
{
"viewer": {"title": "New Title", "description": "Updated desc"},
"ttlSeconds": 86400,
"password": "secret"
}
Set password to a string to enable password protection. Set to null to remove.
Set ttlSeconds to auto-expire the site. Set to null to remove expiry.
POST/api/v1/publish/:slug/claim
{"claimToken": "abc123..."}
Converts an anonymous site to your account. Removes the 24-hour expiry. Requires auth + the claim token from the original create response.
POST/api/v1/publish/:slug/duplicate
Server-side copy to a new slug. Files are copied in S3 without re-upload.
DELETE/api/v1/publish/:slug
Permanently deletes the site and all its files.
GET/api/v1/publish/:slug/versions
List all deployed versions with timestamps and file counts. Each publish or update creates a new version.
{
"slug": "bright-canvas-a7k2",
"versions": [
{"versionId": "01DEF...", "createdAt": "2026-03-29T...", "fileCount": 5, "current": true},
{"versionId": "01ABC...", "createdAt": "2026-03-28T...", "fileCount": 3, "current": false}
]
}
POST/api/v1/publish/:slug/rollback
{"versionId": "01ABC..."}
Instantly revert to any previous version. No re-upload needed — the files are already in S3.
{
"success": true,
"slug": "bright-canvas-a7k2",
"previousVersionId": "01DEF...",
"currentVersionId": "01ABC..."
}
GET/api/v1/publish/:slug/download
Download the current version of a site as a ZIP archive. Useful for backups or migrating to another host.
curl -OJ -H "Authorization: Bearer sk_..." \
https://shipsite.co/api/v1/publish/bright-canvas-a7k2/download
GET/api/v1/publish/:slug/analytics?days=30
View traffic analytics for your site. Returns daily breakdowns of views, unique visitors, top paths, and top referrers.
Query params: days (1–90, default 30)
{
"slug": "bright-canvas-a7k2",
"period": {"startDate": "2026-02-27", "endDate": "2026-03-29", "days": 30},
"daily": [
{
"date": "2026-03-29",
"views": 142,
"uniqueVisitors": 89,
"topPaths": [["/", 98], ["/about.html", 44]],
"topReferrers": [["google.com", 34], ["twitter.com", 12]]
}
],
"totals": {"views": 4210, "uniqueVisitors": 1893}
}
| Feature | Anonymous | Authenticated |
|---|---|---|
| Max file size | 25 MB | 5 GB |
| Max files per site | 20 | 500 |
| Site expiry | 24 hours | Permanent |
| Rate limit | 5/hour per IP | 200/hour |
| Version history | — | Full |
| Rollback | — | Any version |
| ZIP download | — | Current version |
| Analytics | — | 90-day retention |
When a request hits <slug>.shipsite.co/:
index.html exists, serve itSubdirectory paths resolve to <path>/index.html if present.