Loading...
面向 JDownloader 等客戶端的 HTTP JSON API。呼叫介面需在帳戶中建立 API 金鑰。
This HTTP API lets third-party download managers (e.g. JDownloader) use your account without your website password. Authenticate with a personal API key you create in Profile → API access (after signing in).
This documentation page is public; only API calls require the key.
https://<your-portal-host>/api/external/v1Send the API key on every request, using one of:
| Method | Header |
|---|---|
| Bearer | Authorization: Bearer <api_key> |
| Custom | X-Api-Key: <api_key> |
Keys are opaque strings starting with obb_. Store the key only on the client side; we keep a hash server-side. If you rotate the key in Profile, old keys stop working immediately.
GET /api/external/v1/account
Success (200):
{
"success": true,
"data": {
"accountType": "premium",
"trafficleft": 466894644646,
"trafficmax": 1099511627776,
"trafficmax_daily": 64424509440,
"timeleft": null,
"login_check_interval": 1800000
}
}
| Field | Type | Description |
|---|---|---|
accountType | string | premium if trafficmax > 0, else free |
trafficleft | number | Remaining account traffic (bytes) |
trafficmax | number | Total purchased traffic quota (bytes) |
trafficmax_daily | number | Per-host 24h usage cap enforced by the portal (bytes); same semantics as the web UI |
timeleft | number | null |
login_check_interval | number | Suggested polling interval (ms); default 30 minutes |
GET /api/external/v1/hosts
The hostname list is served by Storage Master and proxied by the portal so it always matches the adapters deployed on Master.
Success (200):
{
"success": true,
"data": {
"supportedhosts": [
{
"host": "rapidgator.net",
"maxChunks": 16,
"maxDownloads": 3,
"resumable": true,
"currently_working": true
}
],
"updated_at": 1710000000000
}
}
| Field | Description |
|---|---|
maxChunks | Max parallel connections per file the client may use |
maxDownloads | Suggested max simultaneous downloads per host |
resumable | Whether ranged/resume downloads are expected to work via our proxy |
currently_working | If false, GUI clients should hide the host |
Same authentication as other external endpoints. GET /api/external/v1/hosts returns one row per URL hostname (e.g. separate rows for rapidgator.net and rg.to). Prefer GET /api/external/v1/hosts/grouped if you want one row per file-hosting service with alternate domains listed together.
GET /api/external/v1/hosts/grouped
Same source as /hosts, but entries sharing the same backend adapter are merged. Each item includes a canonical host (first hostname in Master’s list for that service), a sorted domains array of all URL hostnames for that service, and merged limits (maxChunks / maxDownloads are maxima across domains; resumable and currently_working require all underlying rows to match).
Success (200):
{
"success": true,
"data": {
"supportedhosts": [
{
"host": "rapidgator.net",
"domains": ["rapidgator.net", "rg.to"],
"maxChunks": 16,
"maxDownloads": 3,
"resumable": true,
"currently_working": true
}
],
"updated_at": 1710000000000
}
}
| Field | Description |
|---|---|
host | Canonical hostname for the service (stable id) |
domains | All hostnames users may see in links for that service |
| (others) | Same meaning as in /hosts |
POST /api/external/v1/unrestrict
Body:
{
"url": "https://rapidgator.net/file/xxxxx/example.avi",
"password": "optional-host-password-reserved"
}
password is accepted for forward compatibility; host-specific password handling may be extended later.
Important: Our server may still be fetching the file from the host after this call. The proxy URL is not guaranteed to be usable until the file is fully downloaded to our storage. Use **download_ready** and poll **GET /api/external/v1/link/{linkId}** until download_ready is true.
Success (200) — file still downloading on our side:
{
"success": true,
"data": {
"linkId": "abc123",
"download_ready": false,
"remote_status": "downloading",
"link": null,
"filename": "example.avi",
"filesize": "30833612",
"hostDomain": "rapidgator.net",
"maxchunks": 16,
"resumable": true,
"poll_after_seconds": 2,
"reusedExisting": false
}
}
Success (200) — file ready on our storage:
{
"success": true,
"data": {
"linkId": "abc123",
"download_ready": true,
"remote_status": "done",
"link": "https://your-proxy/download/abc123/example.avi",
"filename": "example.avi",
"filesize": "30833612",
"hostDomain": "rapidgator.net",
"maxchunks": 16,
"resumable": true,
"poll_after_seconds": 2,
"reusedExisting": false
}
}
| Field | Description |
|---|---|
linkId | Stable id for polling (see Section 4) |
download_ready | true only when the file is fully on our servers (remote_status === done) |
remote_status | Master file state: pending, downloading, done, error, … |
link | Direct HTTPS URL only when download_ready; otherwise null |
poll_after_seconds | Suggested delay before the next poll (seconds), if remote_status is 'error', poll_after_seconds may be a bigger value, like number 60. |
filesize | String (digits), size in bytes |
reusedExisting | true if an existing valid link was returned without charging traffic again (same file / same user) |
Traffic: New files consume traffic from your account when the link is created, consistent with the web dashboard. Reusing an existing valid link does not deduct traffic again.
GET /api/external/v1/link/{linkId}
Same authentication as other endpoints. Call this after POST /unrestrict (Section 3 above) until download_ready is true.
Success (200):
{
"success": true,
"data": {
"linkId": "abc123",
"download_ready": false,
"remote_status": "downloading",
"link": null,
"filename": "example.avi",
"filesize": "30833612",
"maxchunks": 16,
"resumable": true,
"poll_after_seconds": 2
}
}
When download_ready is true, link matches the direct download URL described for POST /unrestrict in Section 3 (same field semantics).
Errors: 404 if the link does not exist or does not belong to this API key’s account.
Errors use a stable numeric status so clients never need to parse localized text.
{
"success": false,
"status": 52,
"msg": "Human-readable message (may be localized)",
"retry_in_seconds": 60
}
retry_in_seconds is present only when a retry makes sense.
| Status | HTTP | Meaning |
|---|---|---|
| 1 | 401 | Missing or invalid API key |
| 2 | 403 | Account not usable (reserved) |
| 52 | 402 | Insufficient traffic for this file |
| 54 | 429 | Per-host 24h usage limit exceeded |
| 55 | 429 | Too many concurrent downloads on this platform |
| 56 | 429 | Solo / low-speed slot limit reached (same as 55) |
| 101 | 400 | Unsupported URL or host |
| 102 | 403 | Source / file banned |
| 103 | 400 | Private file / payment to uploader required |
| 104 | 404 | File offline or not found |
| 105 | 503 | Service maintenance / upstream unavailable (retry) |
| 106 | * | Upstream / generic external error |
| 900 | 400 | Validation / bad request |
| 999 | 500 | Internal error |
**/account** at login_check_interval (default 30 min).**/hosts** on the same schedule; the list tracks Master configuration.**POST /unrestrict**, if download_ready is false, poll **GET /link/{linkId}** every poll_after_seconds until download_ready is true, then start the HTTP download using link.**remote_status** becomes **error**, stop polling; the transfer failed on our side.**link** when the user pauses and resumes, when possible—we return reusedExisting: true when no extra traffic is charged.usenet host entry.**GET /hosts/grouped** (one service per row, domains array for alternate hostnames). **GET /hosts** unchanged.POST /unrestrict returns linkId, download_ready, remote_status; link is null until ready. Added **GET /link/{linkId}** for polling.