DropWeb API
Static site hosting in one curl. Deploy a zip, get a live URL.
Quick Start
Create a directory with an index.html, zip it, deploy it:
mkdir mysite && echo "<h1>Hello!</h1>" > mysite/index.html cd mysite && zip -r ../mysite.zip . curl -F "site=@../mysite.zip" https://api.dropweb.app/deploy
Response:
{
"siteId": "gentle-amber-fox",
"url": "https://gentle-amber-fox.dropweb.app",
"screenshot": "https://screenshot.dropweb.app/gentle-amber-fox.jpg",
"expiresAt": "2026-02-19T12:00:00.000Z",
"files": 1,
"sizeBytes": 22,
"key": "sk_a1b2c3d4e5f6...",
"account": {
"tier": "anonymous",
"email": null,
"sites": 1,
"sitesLimit": 3,
"expiryDays": 7
},
"hint": "Your site is live at https://gentle-amber-fox.dropweb.app — ..."
} POST /account/email.Deploy a Site
POST /deploy
Upload a ZIP or TAR.GZ archive containing your static site. The archive root must contain an index.html. Only static web files are allowed (HTML, CSS, JS, images, fonts, media).
Request
# Anonymous deploy (returns a new API key)
curl -F "[email protected]" https://api.dropweb.app/deploy
# Authenticated deploy (uses existing account)
curl -F "[email protected]" \
-H "Authorization: Bearer sk_yourkey" \
https://api.dropweb.app/deploy
# Key as form field (alternative to header)
curl -F "[email protected]" \
-F "key=sk_yourkey" \
https://api.dropweb.app/deploy
# With email — deploys + sends confirmation email
curl -F "[email protected]" \
-F "[email protected]" \
https://api.dropweb.app/deploy Response 201
{
"siteId": "gentle-amber-fox",
"url": "https://gentle-amber-fox.dropweb.app",
"screenshot": "https://screenshot.dropweb.app/gentle-amber-fox.jpg",
"expiresAt": "2026-02-19T12:00:00.000Z",
"files": 12,
"sizeBytes": 48210,
"key": "sk_...",
"account": {
"tier": "anonymous",
"email": null,
"sites": 1,
"sitesLimit": 3,
"expiryDays": 7
},
"hint": "Your site is live at https://gentle-amber-fox.dropweb.app — ..."
} | Field | Description |
|---|---|
siteId | Unique site identifier, used in the URL and for management |
url | Live URL where the site is accessible |
screenshot | Screenshot URL — visual preview of the deployed site |
expiresAt | When the site will be automatically deleted |
files | Number of files extracted from archive |
sizeBytes | Total size of extracted files in bytes |
key | API key — only returned on anonymous deploy, shown once |
account | Current account state: tier, email, site count, limits, expiry |
hint | Suggested next action (useful for AI agents) |
email sends a confirmation email but does not upgrade the account inline. The deploy proceeds at anonymous tier. The account upgrades when the user clicks the confirmation link.Redeploy / Update a Site
POST /deploy/:siteId
Replace a site's files with a new archive. Requires authentication. The site ID stays the same, the version increments, and expiry resets.
curl -F "[email protected]" \
-H "Authorization: Bearer sk_yourkey" \
https://api.dropweb.app/deploy/gentle-amber-fox Response 200
{
"siteId": "gentle-amber-fox",
"url": "https://gentle-amber-fox.dropweb.app",
"screenshot": "https://screenshot.dropweb.app/gentle-amber-fox.jpg",
"version": 2,
"files": 15,
"sizeBytes": 61440,
"account": {
"tier": "free",
"email": "[email protected]",
"sites": 2,
"sitesLimit": 5,
"expiryDays": 30
},
"hint": "Your site is live at https://gentle-amber-fox.dropweb.app — ..."
} List Sites
GET /sites
List all sites owned by your account.
curl -H "Authorization: Bearer sk_yourkey" \
https://api.dropweb.app/sites Response 200
{
"sites": [
{
"siteId": "gentle-amber-fox",
"url": "https://gentle-amber-fox.dropweb.app",
"files": 12,
"sizeBytes": 48210,
"version": 1,
"createdAt": "2026-02-12T12:00:00.000Z",
"expiresAt": "2026-02-19T12:00:00.000Z"
}
]
} Get Site Details
GET /sites/:siteId
Get details for a specific site, including its deploy history.
curl -H "Authorization: Bearer sk_yourkey" \
https://api.dropweb.app/sites/gentle-amber-fox Response 200
{
"siteId": "gentle-amber-fox",
"url": "https://gentle-amber-fox.dropweb.app",
"files": 15,
"sizeBytes": 61440,
"version": 2,
"createdAt": "2026-02-12T12:00:00.000Z",
"expiresAt": "2026-02-19T12:00:00.000Z",
"deploys": [
{ "version": 1, "files": 12, "sizeBytes": 48210, "createdAt": "2026-02-12T12:00:00.000Z" },
{ "version": 2, "files": 15, "sizeBytes": 61440, "createdAt": "2026-02-12T14:30:00.000Z" }
]
} Delete a Site
DELETE /sites/:siteId
Permanently delete a site and all its files.
curl -X DELETE \
-H "Authorization: Bearer sk_yourkey" \
https://api.dropweb.app/sites/gentle-amber-fox Response 200
{
"message": "Site deleted",
"siteId": "gentle-amber-fox"
} Account Status
GET /account
View your current account status, tier, limits, and site count.
curl -H "Authorization: Bearer sk_yourkey" \
https://api.dropweb.app/account Response 200
{
"tier": "anonymous",
"email": null,
"sites": 1,
"sitesLimit": 3,
"expiryDays": 7,
"createdAt": "2026-02-12T12:00:00.000Z"
} | Field | Description |
|---|---|
tier | anonymous or free |
email | Confirmed email, or null |
sites | Number of active sites |
sitesLimit | Max sites for your tier |
expiryDays | How long new sites last before auto-deletion |
createdAt | When the account was created |
Attach Email
POST /account/email
Start the email confirmation process. A confirmation link is sent to the provided email. Once confirmed, your account upgrades to the free tier (more sites, longer expiry, key recovery).
curl -X POST \
-H "Authorization: Bearer sk_yourkey" \
-H "Content-Type: application/json" \
-d '{"email": "[email protected]"}' \
https://api.dropweb.app/account/email Response 200
{
"message": "Confirmation email sent. Check your inbox."
} Confirm Email
GET /account/confirm?token=...
Called when the user clicks the confirmation link in the email. Validates the token, upgrades the account to the free tier, extends all site expiry dates, and redirects.
Response 302
Redirects to the configured landing page. On invalid or expired tokens, returns a 400 error.
Recover Account
POST /account/recover
Lost your API key? If you confirmed an email, request a new key. A recovery email is sent with a fresh key. The old key is invalidated immediately.
curl -X POST \
-H "Content-Type: application/json" \
-d '{"email": "[email protected]"}' \
https://api.dropweb.app/account/recover Response 200
{
"message": "If this email exists, a new key has been sent."
} Authentication
Most endpoints require an API key. Pass it in one of two ways:
Authorization Header (recommended)
curl -H "Authorization: Bearer sk_yourkey" https://api.dropweb.app/sites
Form Field
curl -F "[email protected]" -F "key=sk_yourkey" https://api.dropweb.app/deploy
How Keys Work
When you deploy anonymously, the response includes a key field starting with sk_. It is shown only once and cannot be recovered without a confirmed email on file.
Keys are hashed server-side. We never store your plaintext key.
Public Endpoints (no key required)
POST /deploy | Anonymous deploy (creates account + returns key) |
POST /account/email | Attach email (key passed in body) |
GET /account/confirm | Email confirmation link |
POST /account/recover | Key recovery |
Authenticated Endpoints
POST /deploy | Deploy with existing key |
POST /deploy/:siteId | Redeploy |
GET /account | Account status |
GET /sites | List sites |
GET /sites/:siteId | Site details |
DELETE /sites/:siteId | Delete site |
Tiers
Accounts start as anonymous and upgrade to free after confirming an email.
| Anonymous | Free (confirmed email) | |
|---|---|---|
| Sites | 3 | 5 |
| Expiry | 7 days | 30 days (renewable on redeploy) |
| Key recovery | Not possible | Via email |
| Deploy rate | 5/hr per IP | 10/hr per account |
Upgrading extends all existing site expiry dates to 30 days.
Rate Limits & Quotas
| Action | Limit |
|---|---|
| Deploy (anonymous, per IP) | 5 per hour |
| Deploy (authenticated, per account) | 10 per hour |
| All API calls (per IP) | 120 per hour |
| Upload size (compressed) | 50 MB |
| Upload size (uncompressed) | 50 MB |
| Files per archive | 1,000 |
Rate-limited requests return 429 with a Retry-After header indicating seconds until the next allowed request. The response body also includes a retryAfter field:
{
"error": {
"code": "RATE_LIMITED",
"message": "Too many requests. Wait a moment and try again.",
"retryAfter": 120
}
} Error Codes
All errors follow this structure:
{
"error": {
"code": "ERROR_CODE",
"message": "Description with next steps"
}
} | Code | Status | Meaning |
|---|---|---|
UNAUTHORIZED | 401 | Invalid or missing API key |
FORBIDDEN | 403 | API key does not own this site |
NOT_FOUND | 404 | Site not found |
ENDPOINT_NOT_FOUND | 404 | Unknown URL path |
RATE_LIMITED | 429 | Too many requests (includes Retry-After header) |
ANON_DEPLOY_LIMITED | 429 | Anonymous deploy limit hit — use your API key or wait |
TOO_LARGE | 413 | Archive exceeds 50 MB compressed size limit |
SITE_LIMIT_REACHED | 400 | Max sites for your tier — confirm email to increase |
INVALID_ARCHIVE | 400 | Bad or corrupted archive — upload a .zip or .tar.gz |
NO_INDEX | 400 | Archive missing index.html at root — if using a build tool, zip the output directory (dist/ or build/) |
TOO_MANY_FILES | 400 | Archive has more than 1,000 files |
PATH_TRAVERSAL | 400 | File paths must be relative and within the archive root |
FORBIDDEN_EXTENSION | 400 | Only static web files allowed (HTML, CSS, JS, images, fonts, media) |
INVALID_EMAIL | 400 | A valid email address is required |
INVALID_EMAIL_FORMAT | 400 | Email format is invalid |
EMAIL_TAKEN | 409 | Email linked to another account — use that key or recover via POST /account/recover |
EMAIL_ALREADY_CONFIRMED | 409 | Email already confirmed on another account |
INVALID_TOKEN | 400 | Confirmation token invalid or expired — request a new one via POST /account/email |
INTERNAL_ERROR | 500 | Server error — try again later |