Deploy to Dropage
Upload an HTML file or a zip / tar / tar.gz / tgz archive to dropage.online and return a public URL. Default expiry is 1 hour; the user may also choose 6 hours, 24 hours, 7 days, or 14 days, and optionally have the page disabled after 1 or 10 visits. Uploaded files are retained until 30 days after upload, independently of public link expiry.
Platform Detection
Before running the upload command, detect the user's platform and use the appropriate curl command:
- Windows:
curl.exe - macOS/Linux:
curl
Optional upload fields
Both are optional; omit to use defaults.
expiry— one of1h(default),6h,24h,7d,14dmax_visits—0(default, unlimited),1, or10. Page is disabled after the limit is reached.
Daily quotas and user reminders
| Expiry | Site-wide successful uploads/day | Successful uploads/IP/day |
|---|---|---|
7d |
50 | 5 |
14d |
10 | 1 |
The tiers have separate quotas. Each resets at 00:00 UTC+8 on the next calendar day. Only successful uploads count, including records later expired or cleaned; deletion does not refund quota. The 1h, 6h, and 24h tiers have no extra daily quota. All tiers still follow per-IP rate limits and the site-wide 1,000 uploads/hour limit.
Before a 7-day or 14-day upload, tell the user the selected tier's site-wide and per-IP daily limits and reset time. Use the requested expiry; if it is unspecified, use 1 hour. Never silently shorten a requested expiry to bypass an exhausted quota. Existing uploaded pages keep their expiration times; use the five current values for new uploads. The API still accepts legacy 10m, 3h, and 12h for old clients. A successful legacy response adds warning: {code: "LEGACY_EXPIRY", message: "...", skill_url: "https://dropage.online/dropage-deploy.md"}. Report that the upload succeeded, ask the user to update their installed skill from skill_url, and do not retry the successful upload.
Steps
-
Identify the file to deploy. Accept a single
.htmlfile or an archive (.zip,.tar,.tar.gz,.tgz) whose root containsindex.html.Archive packaging requirements:
- Supported formats:
.zip,.tar,.tar.gz,.tgz(NOT.7z,.rar,.tar.bz2,.tar.xz) index.htmlmust be at the root level of the archive, not inside a subfolder- Correct:
site.zip→index.html,style.css,js/ - Wrong:
site.zip→my-site/index.html,my-site/style.css - If all entries share a single top-level directory (e.g.
my-site/), it is auto-stripped during extraction - Max 50 files per archive
- Avoid Chinese or special characters in filenames to prevent encoding issues
- Supported formats:
-
Detect platform and run the upload command:
Windows (PowerShell / CMD)
curl.exe -s -F "file=@<filepath>" -F "expiry=1h" -F "max_visits=0" https://dropage.online/api/upload
macOS / Linux (Bash / Zsh)
curl -s -F "file=@<filepath>" -F "expiry=1h" -F "max_visits=0" https://dropage.online/api/upload
- Parse the JSON response and report the result to the user.
Response format
Success (HTTP 201):
{"success": true, "url": "https://dropage.online/a1b2c3d4e5f6/", "expires_at": "2026-06-29T14:00:00+08:00", "max_visits": 0, "id": "a1b2c3d4e5f6"}
Failure (HTTP 4xx):
{"success": false, "error": "reason"}
14-day upload: concrete quota failure examples
Use -i to include the HTTP status and Retry-After header:
# Windows
curl.exe -sS -i -F "file=@page.html" -F "expiry=14d" https://dropage.online/api/upload
# macOS/Linux
curl -sS -i -F "file=@page.html" -F "expiry=14d" https://dropage.online/api/upload
The following examples assume a request at 2026-09-05 23:00 UTC+8. The actual reset is 2026-09-06 00:00 UTC+8, returned as 2026-09-05T16:00:00.000Z (UTC). Retry-After: 3600 is illustrative; use the actual server response. The API's error text is currently Chinese regardless of the page language; interpret the structured fields and explain them in the user's language.
Per-IP daily allowance exhausted: this IP has already successfully uploaded one 14d page today. Another 14d upload is rejected:
HTTP/1.1 429 Too Many Requests
Content-Type: application/json; charset=utf-8
Retry-After: 3600
{
"success": false,
"error": "14 天档当前 IP今日配额已用完(每天 1 个)。请在 UTC+8 次日 00:00 后重试,或选择其他有效期;仍受通用上传频率限制。",
"code": "DAILY_QUOTA_EXCEEDED",
"expiry": "14d",
"scope": "ip",
"limit": 1,
"reset_at": "2026-09-05T16:00:00.000Z"
}
Tell the user: “The upload failed because this IP has used today's one-upload allowance for the 14-day tier. It resets at 2026-09-06 00:00 UTC+8. No new page was created.”
Site-wide daily allowance exhausted: ten 14d uploads have already succeeded today. An additional request from an IP that has not used its own allowance is rejected:
HTTP/1.1 429 Too Many Requests
Content-Type: application/json; charset=utf-8
Retry-After: 3600
{
"success": false,
"error": "14 天档全站今日配额已用完(每天 10 个)。请在 UTC+8 次日 00:00 后重试,或选择其他有效期;仍受通用上传频率限制。",
"code": "DAILY_QUOTA_EXCEEDED",
"expiry": "14d",
"scope": "global",
"limit": 10,
"reset_at": "2026-09-05T16:00:00.000Z"
}
Tell the user: “The upload failed because today's site-wide allowance of ten 14-day pages is exhausted. It resets at 2026-09-06 00:00 UTC+8. No new page was created.”
When both daily limits are exhausted, the API reports scope: "ip" first. The general upload rate limiter runs before daily quota checks and can instead return a generic HTTP 429 without DAILY_QUOTA_EXCEEDED; do not assume every 429 is a daily quota error. A rejected upload returns no public URL, creates no upload record, and consumes no additional daily quota. Do not loop retries or silently change expiry. Wait until the reported reset, or let the user choose another tier.
Report to the user
On success, show:
- The public URL
- Expiration time (per the chosen expiry; default 1 hour from upload)
- Visit limit, if any (disabled after 1 or 10 visits)
On failure, show the error reason. For HTTP 429, inspect code and Retry-After. When code is DAILY_QUOTA_EXCEEDED, report the affected expiry, scope (ip or global), limit, and reset_at to the user. Wait until reset, or let the user choose another suitable tier; do not immediately retry.
Limits
- File types:
.html,.zip,.tar,.tar.gz,.tgzonly - Max size: 30 MB
- Archive must contain
index.htmlat the root level - Max 50 files per archive
- Expiry:
1h(default) /6h/24h/7d/14d - Max visits:
0(unlimited, default) /1/10 - Storage retention: uploaded files are physically deleted 30 days after upload; database metadata is retained. Expiry and visit limits still disable public access earlier.
- Access log retention: 30 days
- Rate limit: 3 per minute, 30 per half hour, 45 per hour per IP
Examples
Deploy a single HTML file (defaults)
# Windows
curl.exe -s -F "file=@index.html" https://dropage.online/api/upload
# macOS/Linux
curl -s -F "file=@index.html" https://dropage.online/api/upload
Deploy a zip archive
# Windows
curl.exe -s -F "file=@site.zip" https://dropage.online/api/upload
# macOS/Linux
curl -s -F "file=@site.zip" https://dropage.online/api/upload
Deploy a tar.gz archive (Linux/macOS common)
# Windows
curl.exe -s -F "file=@site.tar.gz" https://dropage.online/api/upload
# macOS/Linux
curl -s -F "file=@site.tar.gz" https://dropage.online/api/upload
Deploy with 1-hour expiry, disabled after 1 visit
# Windows
curl.exe -s -F "file=@index.html" -F "expiry=1h" -F "max_visits=1" https://dropage.online/api/upload
# macOS/Linux
curl -s -F "file=@index.html" -F "expiry=1h" -F "max_visits=1" https://dropage.online/api/upload
Deploy with long expiry (daily quotas apply)
7d: 50 successful uploads/day site-wide, 5/IP/day. 14d: 10 site-wide, 1/IP/day. Reset: 00:00 UTC+8.
# Windows: 7 days
curl.exe -s -F "file=@index.html" -F "expiry=7d" https://dropage.online/api/upload
# macOS/Linux: 14 days
curl -s -F "file=@index.html" -F "expiry=14d" https://dropage.online/api/upload
For 6-hour or 24-hour expiry, use -F "expiry=6h" or -F "expiry=24h" respectively.
Deploy from specific path
# Windows
curl.exe -s -F "file=@C:\Users\me\project\index.html" https://dropage.online/api/upload
# macOS/Linux
curl -s -F "file=@/home/user/project/index.html" https://dropage.online/api/upload
Troubleshooting
"file not found" error
- Verify the file path is correct and the file exists
- On Windows PowerShell, use backward slashes or absolute paths:
@C:\path\to\file.html - On macOS/Linux, use forward slashes:
@/home/user/file.html - If the path contains spaces, quote it:
@"C:\path with spaces\file.html"(Windows) or@"/path/with spaces/file.html"(macOS/Linux)
Empty file or wrong file type
- File must be non-empty and have one of these extensions:
.html,.zip,.tar,.tar.gz,.tgz(case-insensitive) - Hidden files (e.g.
.htmlfiles starting with a dot) are not supported
HTTP 400 (Bad Request) — "不支持的文件格式"
- File extension must be one of:
.html,.zip,.tar,.tar.gz,.tgz - Do not use
.htm,.xhtml,.rar,.7z,.tar.bz2,.tar.xz, or other formats
HTTP 400 (Bad Request) — Archive errors
- Archive does not contain
index.htmlat the root level (after top-level directory stripping) - Archive has more than 50 files
- Archive is corrupted, truncated, or uses unsupported compression
- For tar.gz: ensure the file is a valid gzip-compressed tar (not raw gzip of a single file)
HTTP 413 (Payload Too Large)
- File exceeds the 30 MB limit
- Compress images or assets before deploying
- For large projects, consider splitting into multiple deployments
HTTP 429 (Too Many Requests)
- Rate limit exceeded: 3 per minute, 30 per 30 minutes, 45 per hour per IP
- Wait for the cooldown period before retrying
- Daily quota errors have
code: DAILY_QUOTA_EXCEEDEDplusexpiry,scope,limit, andreset_at. Tell the user whether the site-wide or per-IP allowance is exhausted and show the reset time (00:00 UTC+8). HonorRetry-After; do not loop retries or silently choose a shorter expiry. - An expired or cleaned page still counts toward the day on which it was successfully uploaded. Failed uploads do not consume daily quota.
