PageDrop API Documentation
PageDrop lets you deploy HTML pages instantly via a simple REST API. Send your HTML in a POST request and receive a live URL in the response. Sites are hosted forever by default, or you can set a custom TTL. No signup, no API keys, no authentication required.
https://pagedrop.dev/api/v1
Authentication
No authentication is required. The API is completely free and open. Simply make HTTP requests to the endpoints below. Delete operations require the X-Delete-Token header, which is provided when a site is created.
POST /sites
Create a new hosted site. Accepts JSON with raw HTML or a multipart form upload with a file (HTML or ZIP).
Option 1: JSON Body
| Field | Type | Required | Description |
|---|---|---|---|
html |
string | required | Raw HTML content to host. Max 5 MB. |
ttl |
string | optional | Time-to-live. Format: number + unit (h=hours, d=days, m=months). Examples: 1d, 12h, 30d. Default: never expires. Max: 365d. |
Option 2: Multipart Upload
| Field | Type | Required | Description |
|---|---|---|---|
file |
file | required | HTML file (.html) or ZIP archive (.zip) containing a project with an index.html at the root. Max 10MB for ZIP. |
Example Request (JSON)
curl -X POST "https://pagedrop.dev/api/v1/sites" \
-H "Content-Type: application/json" \
-d '{"html": "<h1>Hello World</h1><p>Deployed with PageDrop!</p>"}'Example Request (ZIP Upload)
curl -X POST "https://pagedrop.dev/api/v1/sites" \ -F "file=@my-project.zip"
Success Response
{
"status": "success",
"data": {
"siteId": "a1b2c3d4",
"url": "https://pagedrop.dev/s/a1b2c3d4",
"deleteToken": "dlt_e5f6a7b8c9d0e1f2a3b4c5d6e7f8a9b0c1d2e3f4a5b6c7d8",
"expiresAt": null,
"ttlDays": null,
"files": ["index.html"],
"totalSizeBytes": 1234,
"createdAt": "2026-02-17T12:00:00.000Z"
}
}deleteToken if you want to delete the site later. It is only returned once at creation time.
GET /sites/:siteId
Retrieve metadata about a hosted site.
Path Parameters
| Param | Type | Description |
|---|---|---|
siteId |
string | The unique site identifier returned at creation |
Example Response
{
"status": "success",
"data": {
"siteId": "a1b2c3d4",
"url": "https://pagedrop.dev/s/a1b2c3d4",
"createdAt": "2026-02-17T12:00:00.000Z",
"expiresAt": null,
"fileCount": 1,
"totalSizeBytes": 1234,
"files": ["index.html"]
}
}DELETE /sites/:siteId
Delete a hosted site. Requires the X-Delete-Token header.
Headers
| Header | Required | Description |
|---|---|---|
X-Delete-Token |
required | The delete token returned when the site was created |
Example Request
curl -X DELETE "https://pagedrop.dev/api/v1/sites/a1b2c3d4" \ -H "X-Delete-Token: dlt_e5f6a7b8c9d0e1f2a3b4c5d6e7f8a9b0c1d2e3f4a5b6c7d8"
Success Response
{
"status": "success",
"message": "Site a1b2c3d4 has been deleted"
}GET /sites/:siteId/files
List all files in a hosted site. Useful for ZIP-deployed sites with multiple assets.
Example Response
{
"status": "success",
"data": {
"siteId": "a1b2c3d4",
"files": [
{ "path": "index.html", "contentType": "text/html; charset=utf-8" },
{ "path": "style.css", "contentType": "text/css" },
{ "path": "app.js", "contentType": "application/javascript" }
],
"totalSizeBytes": 8192
}
}GET /s/:siteId
View the hosted site in a browser. This is the public URL users visit to see the deployed page. Returns the raw HTML content with appropriate Content-Type headers.
/api/v1 namespace. It serves the hosted content directly, not JSON metadata.
Response Format
All API endpoints return JSON. Successful responses are wrapped in a standard envelope with status: "success" and a data object. Error responses include error and message fields.
Error Response
{
"error": "Validation failed",
"message": "Request body must include 'html' field or upload a file"
}Error Codes
| Status | Meaning |
|---|---|
400 | Bad Request — Missing or invalid input (no HTML, invalid ZIP, exceeds size limit) |
401 | Unauthorized — Invalid or missing X-Delete-Token for DELETE operations |
404 | Not Found — Site does not exist or has expired |
413 | Payload Too Large — HTML exceeds 5 MB or ZIP exceeds 10 MB |
429 | Too Many Requests — Rate limit exceeded |
500 | Internal Server Error — Something went wrong on our end |
Rate Limits
The API applies rate limiting to protect service quality:
| Limit | Value |
|---|---|
| Site creations per minute | 10 per IP address |
| Read requests per minute | 60 per IP address |
| Window | 60 seconds sliding window |
When rate limited, the API returns a 429 status with a Retry-After header.
RateLimit-Limit, RateLimit-Remaining, RateLimit-Reset.
Size Limits
| Resource | Limit |
|---|---|
| HTML body (JSON) | 5 MB |
| ZIP upload | 10 MB |
| Hosting duration | Forever (default), or set custom TTL up to 365 days via ttl parameter |
| Files per ZIP | 50 files max |
cURL Examples
# Deploy raw HTML
curl -X POST "https://pagedrop.dev/api/v1/sites" \
-H "Content-Type: application/json" \
-d '{"html": "<h1>Hello!</h1>"}'
# Upload a ZIP project
curl -X POST "https://pagedrop.dev/api/v1/sites" \
-F "file=@my-project.zip"
# Get site metadata
curl "https://pagedrop.dev/api/v1/sites/a1b2c3d4"
# List files in a site
curl "https://pagedrop.dev/api/v1/sites/a1b2c3d4/files"
# Delete a site
curl -X DELETE "https://pagedrop.dev/api/v1/sites/a1b2c3d4" \
-H "X-Delete-Token: dlt_YOUR_TOKEN_HERE"JavaScript Example
// Deploy HTML
const response = await fetch("https://pagedrop.dev/api/v1/sites", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({
html: "<h1>Hello World</h1><p>Deployed with PageDrop</p>"
})
});
const { data } = await response.json();
console.log(`Live at: ${data.url}`);
console.log(`Expires: ${data.expiresAt ?? "Never"}`);
console.log(`Delete token: ${data.deleteToken}`); // Save this!
// Get site metadata
const meta = await fetch(`https://pagedrop.dev/api/v1/sites/${data.siteId}`);
console.log(await meta.json());
// Upload a ZIP file
const formData = new FormData();
formData.append("file", zipFileBlob, "project.zip");
const upload = await fetch("https://pagedrop.dev/api/v1/sites", {
method: "POST",
body: formData
});
console.log(await upload.json());
// Delete a site
await fetch(`https://pagedrop.dev/api/v1/sites/${data.siteId}`, {
method: "DELETE",
headers: { "X-Delete-Token": data.deleteToken }
});Python Example
import requests
# Deploy HTML
response = requests.post(
"https://pagedrop.dev/api/v1/sites",
json={"html": "<h1>Hello World</h1><p>Deployed with PageDrop</p>"}
)
result = response.json()
site = result["data"]
print(f"Live at: {site['url']}")
print(f"Expires: {site['expiresAt'] or 'Never'}")
print(f"Delete token: {site['deleteToken']}") # Save this!
# Get site metadata
meta = requests.get(f"https://pagedrop.dev/api/v1/sites/{site['siteId']}")
print(meta.json())
# Upload a ZIP file
with open("my-project.zip", "rb") as f:
upload = requests.post(
"https://pagedrop.dev/api/v1/sites",
files={"file": ("project.zip", f, "application/zip")}
)
print(upload.json())
# Delete a site
requests.delete(
f"https://pagedrop.dev/api/v1/sites/{site['siteId']}",
headers={"X-Delete-Token": site["deleteToken"]}
)MCP Integration
PageDrop supports the Model Context Protocol (MCP), allowing AI assistants like Claude, VS Code Copilot, Cursor, and other MCP-compatible clients to deploy and manage HTML sites directly.
Installation
Add the following to your claude_desktop_config.json (or equivalent MCP client configuration):
{
"mcpServers": {
"pagedrop": {
"command": "npx",
"args": ["-y", "pagedrop-mcp"]
}
}
}Available Tools
| Tool | Description | Parameters |
|---|---|---|
deploy_html |
Deploy HTML content and get a live URL instantly | html (required), ttl (optional) |
get_site_info |
Retrieve metadata about a hosted site | siteId (required) |
delete_site |
Delete a hosted site using its delete token | siteId (required), deleteToken (required) |
Environment Variables
| Variable | Default | Description |
|---|---|---|
PAGEDROP_BASE_URL |
https://pagedrop.dev |
Override the base URL for API requests (useful for self-hosted instances) |