API Documentation
Publish static sites in 3 API calls. No account required for temporary sites.
Quick Start
Publish an HTML file to a live URL in under 10 seconds:
# 1. Create a site curl -X POST https://api.sharehammer.com/api/v1/sites \ -H "Content-Type: application/json" \ -d '{"files": [{"path": "index.html", "size": 1024, "contentType": "text/html"}]}' # Response includes presigned upload URLs # { "slug": "abc123", "url": "https://abc123.sharehammer.com", "upload": { "files": [...] } } # 2. Upload your file to the presigned URL curl -X PUT "UPLOAD_URL_FROM_STEP_1" \ -H "Content-Type: text/html" \ --data-binary @index.html # 3. Finalize — your site is live! curl -X POST https://api.sharehammer.com/api/v1/sites/SLUG/finalize # { "slug": "abc123", "url": "https://abc123.sharehammer.com", "status": "active" }
Authentication
Anonymous requests create temporary sites that expire in 24 hours. For permanent sites, authenticate with an API key.
Get an API key
# 1. Request a code curl -X POST https://api.sharehammer.com/api/v1/auth/send-code \ -H "Content-Type: application/json" \ -d '{"email": "you@example.com"}' # 2. Verify the code from your email curl -X POST https://api.sharehammer.com/api/v1/auth/verify \ -H "Content-Type: application/json" \ -d '{"email": "you@example.com", "code": "123456", "grant": "api_key"}' # { "api_key": "sh_live_...", "user": { "id": 1, "email": "you@example.com" } }
Use the API key in all subsequent requests:
curl -H "Authorization: Bearer sh_live_..." ...
Create Site
POST
/api/v1/sites
Public
Create a new site and get presigned upload URLs for each file.
Request body
| Field | Type | Description |
|---|---|---|
files | array | List of files to publish |
files[].path | string | Relative path, e.g. index.html |
files[].size | integer | File size in bytes |
files[].contentType | string | MIME type, e.g. text/html |
Response
{
"slug": "abc123",
"url": "https://abc123.sharehammer.com",
"upload": {
"files": [
{ "path": "index.html", "uploadUrl": "https://...", "contentType": "text/html" }
]
}
}
Upload Files
PUT
{uploadUrl}
Public
Upload each file to its presigned R2 URL from the create response.
Set the Content-Type header to match the contentType from the create response. Send raw file bytes as the body.
Finalize
POST
/api/v1/sites/{slug}/finalize
Public
Finalize the site after all files are uploaded. Makes it live.
Update Site
PUT
/api/v1/sites/{slug}
Auth
Redeploy a site with new files. Unchanged files (by SHA-256 hash) are skipped.
Same request body as create. After uploading changed files, call POST /sites/{slug}/finalize.
Update Metadata
PATCH
/api/v1/sites/{slug}
Auth
Update site title, description, or OG image URL.
| Field | Type | Description |
|---|---|---|
title | string | Site title |
description | string | Site description |
og_image_url | string | Open Graph image URL |
List Sites
GET
/api/v1/sites
Auth
List your sites with pagination.
Get Site
GET
/api/v1/sites/{slug}
Auth
Get site details including file list.
Delete Site
DELETE
/api/v1/sites/{slug}
Auth
Permanently delete a site and its files.
Custom Domains
POST
/api/v1/domains
Auth
Add a custom domain. CNAME it to
proxy.sharehammer.com.{ "hostname": "example.com" }
Domain Links
POST
/api/v1/domains/{id}/links
Auth
Link a site to a domain path.
{ "siteSlug": "abc123", "path": "" }
Limits
| Anonymous | Authenticated | |
|---|---|---|
| Rate limit | 5 req/hour | 60 req/hour |
| Max file size | 10 MB | 50 MB |
| Max total size | 10 MB | 100 MB |
| Max files | 50 | 200 |
| Expiry | 24 hours | Permanent |
| Custom domains | — | 3 |
Errors
All errors return JSON with error and message fields:
{ "error": "invalid_body", "message": "At least one file required", "status": 400 }
| Status | Meaning |
|---|---|
| 400 | Bad request — check request body |
| 401 | Unauthorized — missing or invalid API key |
| 404 | Not found — site or resource doesn't exist |
| 429 | Rate limited — wait and retry |