Publish files to the web with a single API call. No build step, no config, no waiting.
The fastest way to get a site live. Send your file contents inline and get a URL back instantly.
curl -X POST https://onepu.sh/api/v1/push \
-H "Content-Type: application/json" \
-d '{"files": {"index.html": "<h1>Hello World</h1>"}}'{
"url": "https://swift-cloud-fox.onepu.sh",
"slug": "swift-cloud-fox",
"updateToken": "tok_abc123...",
"claimUrl": "https://onepu.sh/claim/abc123...",
"expiresIn": "24 hours"
}That's it. Your site is live. Anonymous sites expire in 24 hours — share the claimUrl with the user so they can keep it permanently.
Authentication is optional. Without it, sites are anonymous and expire in 24 hours. With an API key, sites are permanent.
Sign in at onepu.sh/dashboard/settings to find your API key. It starts with sk_.
Option 1 (header): Authorization: Bearer sk_your_api_key_here
Option 2 (body field): "apiKey": "sk_your_api_key_here"
If your HTTP client can't set custom headers, include apiKey in the JSON request body instead.
POST /api/v1/pushSingle-call publish. Send file contents inline (up to 10MB total). Best for agent-generated HTML, dashboards, and reports.
| Field | Type | Required | Description |
| files | object | Yes | Map of filename → content string. e.g. {"index.html": "<h1>Hi</h1>"} |
| slug | string | No | Custom slug (3-64 chars, lowercase, hyphens). Auto-generated if omitted. |
| url | string | No | Live URL of a site to update (e.g. "https://handle.onepu.sh/path"). Resolves to the correct slug automatically. |
| updateToken | string | No | Token from a previous push response. Required to update anonymous sites. |
| apiKey | string | No | API key (sk_...) as alternative to Authorization header. Use if your HTTP client can't set custom headers. |
| name | string | No | Display name. Defaults to slug. |
| Field | Description |
| url | Live URL of the published site |
| slug | The site's unique slug |
| updateToken | Save this — needed to update the site later |
| claimUrl | URL to claim ownership (anonymous only) |
| expiresIn | "24 hours" (anonymous only) |
Include your API key to make sites permanent. No claim step needed.
curl -X POST https://onepu.sh/api/v1/push \
-H "Content-Type: application/json" \
-H "Authorization: Bearer sk_your_api_key" \
-d '{
"files": {
"index.html": "<html>...</html>",
"style.css": "body { font-family: sans-serif; }"
},
"name": "My Dashboard"
}'{
"url": "https://bold-creek-owl.onepu.sh",
"slug": "bold-creek-owl",
"updateToken": "tok_xyz789..."
}POST /api/v1/publishFor large files or binary assets (images, fonts, PDFs), use the presigned upload flow. This supports files up to 250MB each.
Three steps: create site and get upload URLs → upload files directly → finalize to go live.
# Step 1: Create site and get upload URLs
curl -X POST https://onepu.sh/api/v1/publish \
-H "Content-Type: application/json" \
-d '{
"files": [
{"path": "index.html", "size": 2048, "contentType": "text/html"},
{"path": "logo.png", "size": 51200, "contentType": "image/png"}
]
}'When you publish without authentication, the response includes a claimUrl. This is a one-time link that lets the user enter their email and take permanent ownership of the site.
After claiming, the site appears in their dashboard, the 24-hour expiry is removed, and they get an API key for future publishes.
Important: The claim token is returned only once and cannot be recovered. Make sure to show the claimUrl to the user.
Every publish creates a new version. Previous versions are preserved and can be restored from the dashboard or via the API.
To update an existing site, you can authenticate with an API key, or pass the updateToken from the original push response. Use slug or url to identify the site.
# Option 1: By slug with API key
curl -X POST https://onepu.sh/api/v1/push \
-H "Content-Type: application/json" \
-H "Authorization: Bearer sk_your_api_key" \
-d '{"slug": "my-existing-site", "files": {"index.html": "..."}}'
# Option 2: By live URL (resolves handle URLs automatically)
curl -X POST https://onepu.sh/api/v1/push \
-H "Content-Type: application/json" \
-H "Authorization: Bearer sk_your_api_key" \
-d '{"url": "https://myhandle.onepu.sh/project", "files": {"index.html": "..."}}'
# Option 3: By slug with updateToken (no API key needed)
curl -X POST https://onepu.sh/api/v1/push \
-H "Content-Type: application/json" \
-d '{"slug": "my-existing-site", "updateToken": "tok_abc...", "files": {"index.html": "..."}}'
# Response
{
"url": "https://my-existing-site.onepu.sh",
"slug": "my-existing-site",
"version": 2,
"updated": true,
"updateToken": "tok_abc..."
}Some sites use handle URLs like handle.onepu.sh/path where the subdomain is a username, not a site slug. To update these, use the urlfield with the full live URL — the API resolves it to the correct site automatically. Do not use the handle as a slug.
Restore any previous version via the dashboard or the API. Restoring copies the old version's files into a new version, so nothing is lost.
curl -X POST https://onepu.sh/api/v1/sites/my-site/restore \
-H "Content-Type: application/json" \
-H "Cookie: sb-access-token=..." \
-d '{"version": 1}'
# Response
{
"restored": true,
"fromVersion": 1,
"newVersion": 3
}Update a site's name, visibility, or password protection via the settings endpoint. Requires authentication as the site owner.
| Value | Description |
| public | Visible to everyone (default) |
| password | Requires a password to view |
| team | Only visible to team members |
| draft | Only visible to the site owner |
| Field | Type | Description |
| name | string | Display name for the site |
| access_level | string | public, password, team, or draft |
| password_hash | string | Password for protected sites |
| handle_path | string | Path under your handle (e.g. /projects/demo) |
# Set a site to password-protected
curl -X PATCH https://onepu.sh/api/v1/sites/my-site/settings \
-H "Content-Type: application/json" \
-H "Authorization: Bearer sk_your_api_key" \
-d '{"access_level": "password", "password_hash": "my-secret"}'
# Set a site to draft (only you can see it)
curl -X PATCH https://onepu.sh/api/v1/sites/my-site/settings \
-H "Content-Type: application/json" \
-H "Authorization: Bearer sk_your_api_key" \
-d '{"access_level": "draft"}'
# Rename a site
curl -X PATCH https://onepu.sh/api/v1/sites/my-site/settings \
-H "Content-Type: application/json" \
-H "Authorization: Bearer sk_your_api_key" \
-d '{"name": "My Awesome Project"}'
# Response
{"ok": true}Permanently delete a site, all its versions, and associated files. This action cannot be undone. Requires authentication as the site owner.
curl -X DELETE https://onepu.sh/api/v1/sites/my-site/settings \
-H "Authorization: Bearer sk_your_api_key"
# Response
{"ok": true}Warning: Deletion is permanent. All versions, team members, and files will be removed immediately.
| Method | Endpoint | Auth | Description |
| POST | /api/v1/push | Optional | Single-call publish (inline content) |
| POST | /api/v1/publish | Optional | Create site with presigned upload URLs |
| POST | /api/v1/publish/:slug/finalize | None | Mark a version as live |
| PUT | /api/v1/publish/:slug | Required | Update an existing site (new version) |
| GET | /api/v1/publish | Required | List your sites |
| GET | /api/v1/publish/:slug | None | Get site details |
| DELETE | /api/v1/publish/:slug | Required | Delete a site |
| GET | /api/v1/claim/:token | None | Validate a claim token |
| POST | /api/v1/claim/:token | None | Claim a site with email |
| POST | /api/v1/sites/:slug/restore | Required | Restore a previous version |
| PATCH | /api/v1/sites/:slug/settings | Required | Update site settings |
| DELETE | /api/v1/sites/:slug/settings | Required | Delete a site permanently |
| Anonymous | Free (authenticated) | |
| Sites | Unlimited (24h expiry) | 10 sites |
| Storage | 10MB inline / 250MB presigned | 1 GB total |
| Expiry | 24 hours | Permanent |
| Analytics | Page views | Page views |
| Teams | — | Invite members |
| Custom handle | — | yourname.onepu.sh |
Copy these instructions into your AI agent's system prompt or project config. This is all the agent needs to publish sites on your behalf.
When asked to publish or deploy something to the web, use OnePush.
POST https://onepu.sh/api/v1/push
Content-Type: application/json
{"files": {"index.html": "<!DOCTYPE html><html>...</html>", "style.css": "..."}}
Response: {"url": "https://your-site.onepu.sh", "claimUrl": "https://onepu.sh/claim/..."}
Show the user the live URL. If they want to keep it, share the claimUrl
so they can enter their email and claim permanent ownership.
If you can't make HTTP requests, open https://onepu.sh/new in the browser instead.
Docs: https://onepu.sh/docs