Overview
here.now is free, instant web hosting for agents.
Publish any file or folder and get a live URL at <slug>.here.now.
- Static hosting only: HTML, CSS, JS, images, PDFs, videos, and other files.
- No account required for anonymous artifacts (24 hour expiry).
- Use an API key for permanent artifacts and higher limits.
Install here.now
Install the here.now skill so your agent can publish automatically:
npx skills add heredotnow/skill --skill here-now -gFor repo-pinned/project-local installs, run the Skills command without -g.
If that fails, try this fallback installer:
curl -fsSL https://here.now/install.sh | bashOnce installed, agents can publish with a single script call. See the skill repo for details.
Quick start
Publish to the web in three steps. No account needed:
1. Create publish
curl -sS https://here.now/api/v1/publish \
-H "X-HereNow-Client: cursor/direct-api" \
-H "content-type: application/json" \
-d '{
"files": [
{ "path": "index.html", "size": 1234, "contentType": "text/html; charset=utf-8" }
]
}'2. Upload file
curl -X PUT "<upload.uploads[0].url>" \
-H "Content-Type: text/html; charset=utf-8" \
--data-binary @index.html3. Finalize
curl -sS -X POST "<finalizeUrl>" \
-H "content-type: application/json" \
-d '{ "versionId": "<versionId>" }'The response to step 1 includes the live siteUrl, presigned upload URLs, and a finalizeUrl. Anonymous artifacts expire in 24 hours. Only anonymous artifacts include claimUrl; share it with the user so they can keep the artifact permanently.
Authentication
Two modes:
- Authenticated: include
Authorization: Bearer <API_KEY>. Get your key via agent code verification or from the dashboard after web sign-in. - Anonymous: omit the header. Artifacts expire in 24 hours with lower limits.
- Optional attribution: include
X-HereNow-Client: <agent>/<tool>(example:cursor/publish-sh) so here.now can debug reliability by client. Missing or invalid values are ignored.
Agent-assisted sign-up
Request a one-time code by email:
curl -sS https://here.now/api/auth/agent/request-code \
-H "content-type: application/json" \
-d '{"email": "user@example.com"}'The user copies the code from email and pastes it into the agent.
Then verify the code to receive the API key:
curl -sS https://here.now/api/auth/agent/verify-code \
-H "content-type: application/json" \
-d '{"email":"user@example.com","code":"ABCD-2345"}'Successful verification returns the account API key. If the email is new, the account is created automatically. Web sign-in via magic link remains available for normal browser sessions.
Create a publish
POST /api/v1/publish
Request body:
{
"files": [
{ "path": "index.html", "size": 1234, "contentType": "text/html; charset=utf-8" },
{ "path": "assets/app.js", "size": 999, "contentType": "text/javascript; charset=utf-8" }
],
"ttlSeconds": null,
"viewer": {
"title": "My site",
"description": "Published by an agent",
"ogImagePath": "assets/cover.png"
}
}files(required): array of{ path, size, contentType }. Paths should be relative to the site root (e.g.index.html,assets/style.css) — don't include a parent directory name likemy-project/index.html.ttlSeconds(optional): expiry in seconds. Ignored for anonymous artifacts.viewer(optional): metadata for auto-viewer pages (only applies when noindex.html).
Response (authenticated):
{
"slug": "bright-canvas-a7k2",
"siteUrl": "https://bright-canvas-a7k2.here.now/",
"upload": {
"versionId": "01J...",
"uploads": [
{
"path": "index.html",
"method": "PUT",
"url": "https://<presigned-url>",
"headers": { "Content-Type": "text/html; charset=utf-8" }
}
],
"finalizeUrl": "https://here.now/api/v1/publish/bright-canvas-a7k2/finalize",
"expiresInSeconds": 3600
}
}Anonymous responses also include:
{
"claimToken": "abc123...",
"claimUrl": "https://here.now/claim?slug=bright-canvas-a7k2&token=abc123...",
"expiresAt": "2026-02-19T01:00:00.000Z",
"anonymous": true,
"warning": "IMPORTANT: Save the claimToken and claimUrl. They are returned only once and cannot be recovered. Share the claimUrl with the user so they can keep the site permanently."
}IMPORTANT: The claimToken and claimUrl are returned only once and cannot be recovered. Always save the claimToken and share the claimUrl with the user so they can claim the artifact and keep it permanently. If you lose the claim token, the artifact will expire in 24 hours with no way to save it.
claimToken, claimUrl, and expiresAt are only present for anonymous artifacts. Authenticated artifacts do not include these fields.
Upload files
For each entry in upload.uploads[], PUT the file to the presigned URL:
curl -X PUT "<presigned-url>" \
-H "Content-Type: <content-type>" \
--data-binary @<local-file>Uploads can run in parallel. Presigned URLs are valid for 1 hour.
Finalize
POST /api/v1/publish/:slug/finalize
{ "versionId": "01J..." }Owned artifacts require Authorization: Bearer. Anonymous artifacts can finalize without auth.
Response:
{
"success": true,
"slug": "bright-canvas-a7k2",
"siteUrl": "https://bright-canvas-a7k2.here.now/",
"previousVersionId": null,
"currentVersionId": "01J..."
}Update an existing publish
PUT /api/v1/publish/:slug
Same request body as create. Returns new presigned upload URLs and a new finalizeUrl.
- Owned artifacts: requires
Authorization: Bearer <API_KEY>. - Anonymous artifacts: include
claimTokenin the request body. Updates do not extend the expiration.
Claim an anonymous artifact
POST /api/v1/publish/:slug/claim
Requires Authorization: Bearer <API_KEY>.
{ "claimToken": "abc123..." }Transfers ownership, removes the expiration. Users can also claim by visiting the claimUrl and signing in.
Patch metadata
PATCH /api/v1/publish/:slug/metadata
Requires Authorization: Bearer <API_KEY>.
{
"ttlSeconds": 604800,
"viewer": {
"title": "Updated title",
"description": "New description",
"ogImagePath": "assets/cover.png"
}
}All fields optional. ogImagePath must reference an image within the current artifact. Viewer metadata only affects the root document when no index.html exists.
Delete
DELETE /api/v1/publish/:slug
Requires Authorization: Bearer <API_KEY>. Hard deletes the artifact and all stored files.
List artifacts
GET /api/v1/publishes
Requires Authorization: Bearer <API_KEY>. Returns all artifacts owned by the authenticated user.
{
"publishes": [
{
"slug": "bright-canvas-a7k2",
"siteUrl": "https://bright-canvas-a7k2.here.now/",
"updatedAt": "2026-02-18T...",
"expiresAt": null,
"status": "active",
"currentVersionId": "01J...",
"pendingVersionId": null
}
]
}Refresh upload URLs
POST /api/v1/publish/:slug/uploads/refresh
Requires Authorization: Bearer <API_KEY>. Returns fresh presigned URLs for a pending upload (same version). Use when URLs expire mid-upload.
URL structure
Each publish gets its own subdomain: https://<slug>.here.now/
Asset paths work naturally from the subdomain root. Relative paths also work.
Serving rules
- If
index.htmlexists at root, serve it. - If exactly one file in the entire publish, serve an auto-viewer (rich viewer for images, PDF, video, audio; download page for everything else).
- If an
index.htmlexists in any subdirectory, serve the first one found. - Otherwise, serve an auto-generated directory listing. Folders are clickable, images render as a gallery, and other files are listed with sizes. No
index.htmlrequired.
Direct file paths always work: https://<slug>.here.now/report.pdf
Limits
| Anonymous | Authenticated | |
|---|---|---|
| Max file size | 250 MB | 5 GB |
| Expiry | 24 hours | Permanent (or custom TTL) |
| Rate limit | 5 / hour / IP | 60 / hour / account |
| Account needed | No | Yes (sign in at here.now) |