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 — ..."
}
Save your key! It is shown only once. You need it to redeploy, manage sites, or attach an email. To make your account recoverable, attach your email via 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 — ..."
}
FieldDescription
siteIdUnique site identifier, used in the URL and for management
urlLive URL where the site is accessible
screenshotScreenshot URL — visual preview of the deployed site
expiresAtWhen the site will be automatically deleted
filesNumber of files extracted from archive
sizeBytesTotal size of extracted files in bytes
keyAPI key — only returned on anonymous deploy, shown once
accountCurrent account state: tier, email, site count, limits, expiry
hintSuggested next action (useful for AI agents)
Email during deploy: Passing 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"
}
FieldDescription
tieranonymous or free
emailConfirmed email, or null
sitesNumber of active sites
sitesLimitMax sites for your tier
expiryDaysHow long new sites last before auto-deletion
createdAtWhen 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."
}
Note: This does not upgrade the account immediately. The user must click the confirmation link in the email. The token expires after 24 hours.

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."
}
Note: Always returns the same response regardless of whether the email exists, to prevent enumeration.

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 /deployAnonymous deploy (creates account + returns key)
POST /account/emailAttach email (key passed in body)
GET /account/confirmEmail confirmation link
POST /account/recoverKey recovery

Authenticated Endpoints

POST /deployDeploy with existing key
POST /deploy/:siteIdRedeploy
GET /accountAccount status
GET /sitesList sites
GET /sites/:siteIdSite details
DELETE /sites/:siteIdDelete site

Tiers

Accounts start as anonymous and upgrade to free after confirming an email.

AnonymousFree (confirmed email)
Sites35
Expiry7 days30 days (renewable on redeploy)
Key recoveryNot possibleVia email
Deploy rate5/hr per IP10/hr per account

Upgrading extends all existing site expiry dates to 30 days.

Rate Limits & Quotas

ActionLimit
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 archive1,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"
  }
}
CodeStatusMeaning
UNAUTHORIZED401Invalid or missing API key
FORBIDDEN403API key does not own this site
NOT_FOUND404Site not found
ENDPOINT_NOT_FOUND404Unknown URL path
RATE_LIMITED429Too many requests (includes Retry-After header)
ANON_DEPLOY_LIMITED429Anonymous deploy limit hit — use your API key or wait
TOO_LARGE413Archive exceeds 50 MB compressed size limit
SITE_LIMIT_REACHED400Max sites for your tier — confirm email to increase
INVALID_ARCHIVE400Bad or corrupted archive — upload a .zip or .tar.gz
NO_INDEX400Archive missing index.html at root — if using a build tool, zip the output directory (dist/ or build/)
TOO_MANY_FILES400Archive has more than 1,000 files
PATH_TRAVERSAL400File paths must be relative and within the archive root
FORBIDDEN_EXTENSION400Only static web files allowed (HTML, CSS, JS, images, fonts, media)
INVALID_EMAIL400A valid email address is required
INVALID_EMAIL_FORMAT400Email format is invalid
EMAIL_TAKEN409Email linked to another account — use that key or recover via POST /account/recover
EMAIL_ALREADY_CONFIRMED409Email already confirmed on another account
INVALID_TOKEN400Confirmation token invalid or expired — request a new one via POST /account/email
INTERNAL_ERROR500Server error — try again later