# API Documentation

If you have any questions about the API or need dev support, please open a ticket with our [customer service](https://www.premiumize.me/help).

## Table of contents

- [Authentication](https://www.premiumize.me/api#auth)  - [API key](https://www.premiumize.me/api#auth-apikey)
  - [OAuth 2.0](https://www.premiumize.me/api#auth-oauth)    - [Authorization Code with PKCE](https://www.premiumize.me/api#auth-oauth-pkce)
    - [Device Code](https://www.premiumize.me/api#auth-oauth-device)
    - [Authorization Code](https://www.premiumize.me/api#auth-oauth-authcode)
    - [Resource Owner Password Credentials](https://www.premiumize.me/api#auth-oauth-password) _(legacy)_
    - [Implicit](https://www.premiumize.me/api#auth-oauth-implicit) _(legacy)_
- [Response format](https://www.premiumize.me/api#response)
- [API methods](https://www.premiumize.me/api#methods)  - [Account](https://www.premiumize.me/api#account)
  - [Folders](https://www.premiumize.me/api#folders) _(includes search and upload)_
  - [Files (items)](https://www.premiumize.me/api#items)
  - [Transfers](https://www.premiumize.me/api#transfers)
  - [Cache](https://www.premiumize.me/api#cache)
  - [Services](https://www.premiumize.me/api#services)
  - [ZIP downloads](https://www.premiumize.me/api#zip)
- [Error codes](https://www.premiumize.me/api#errors)

## Authentication

Endpoints accept **either** an API key or an OAuth 2.0 access token. Pick whichever fits your client.

#### API key

Find your API key under [Account](https://www.premiumize.me/account).

**Recommended — pass it as a Bearer token in the `Authorization` header:**

```
curl 'https://www.premiumize.me/api/account/info' \
  -H 'Authorization: Bearer YOUR_API_KEY'
```

The Bearer header keeps your key out of server logs, browser history, Referer headers, and CDN caches. The same header is used for OAuth 2.0 access tokens (see below); the server accepts whichever credential type you pass.

**Legacy alternatives** — still accepted for backwards compatibility, but new clients should use the Bearer header above:

- `?apikey=YOUR_API_KEY` as a query-string parameter, or `apikey=YOUR_API_KEY` in a POST body. Most widely used historically.
- `?pin=YOUR_API_KEY` / `pin=YOUR_API_KEY` — legacy alias for `apikey`; the server treats `pin` as identical to `apikey`. Predates the rename to `apikey`.
- Session cookie — used by the website's own JavaScript for browser sessions. Not available for external clients.

#### OAuth 2.0

For applications acting on behalf of a user, register an OAuth client [here](https://www.premiumize.me/registerclient) to obtain a `client_id` and `client_secret`. Pick the flow that fits your client:

- **Authorization Code with PKCE** — recommended default. Works for mobile, SPA, CLI, native, and any client that can handle a browser redirect.
- **Device Code** — TVs, set-top boxes, and other input-constrained devices.
- **Authorization Code** — server-side apps that can keep a `client_secret`.
- **Resource Owner Password Credentials** — first-party clients that can collect the user's username + password directly. Discouraged by OAuth 2.1; documented for parity with the legacy spec.
- **Implicit** — legacy; superseded by Authorization Code with PKCE.

**Endpoints:** authorization at `https://www.premiumize.me/authorize`, token exchange at `https://www.premiumize.me/token`. The only scope is `full` (access to all API methods). Once you have an access token, pass it in the `Authorization: Bearer` header on every API call (same header used for plain API keys above).

##### Authorization Code with PKCE (recommended default)

Use this for any client that can handle a browser redirect — mobile apps, single-page web apps, native desktop apps, CLI tools. PKCE (Proof Key for Code Exchange) replaces the static `client_secret` with a fresh one-shot proof per authorization, so the client doesn't need to ship a secret.

**Step 1 — Generate a verifier and challenge:**

- `code_verifier` — a random URL-safe string, 43–128 characters. Keep it in memory; never send it on the first redirect.
- `code_challenge` — the SHA-256 of the verifier, then base64url-encoded (no padding).

```
code_verifier  = base64url(random_bytes(32))            // ~43 chars
code_challenge = base64url(sha256(code_verifier))
```

**Step 2 — Redirect with the challenge:**

```
https://www.premiumize.me/authorize
    ?response_type=code
    &client_id=YOUR_CLIENT_ID
    &redirect_uri=https://your.app/callback
    &state=RANDOM_STRING
    &code_challenge=THE_CHALLENGE
    &code_challenge_method=S256
```

The user signs in (if not already) and is shown a consent screen for your app. After they approve, the browser is redirected to your `redirect_uri` with the auth code attached as a query parameter:

```
https://your.app/callback?code=THE_CODE&state=RANDOM_STRING
```

Verify `state` matches what you sent in Step 2. If the user denies, the redirect carries `?error=access_denied&state=...` instead.

**Step 3 — Exchange the code, including the verifier:**

```
curl -X POST 'https://www.premiumize.me/token' \
  -d 'grant_type=authorization_code' \
  -d 'code=THE_CODE' \
  -d 'client_id=YOUR_CLIENT_ID' \
  -d 'redirect_uri=https://your.app/callback' \
  -d 'code_verifier=THE_VERIFIER'
```

The server hashes the supplied `code_verifier` and rejects the exchange if it doesn't match the `code_challenge` from Step 2.

##### Device Code (for TVs, set-top boxes, CLI tools)

For devices that can't easily handle a browser redirect. The user authorizes the device from a phone or laptop by entering a short code.

**Step 1 — Request a code pair:**

```
curl -X POST 'https://www.premiumize.me/token' \
  -d 'response_type=device_code' \
  -d 'client_id=YOUR_CLIENT_ID'
```

Response:

```
{
    "verification_uri": "https://www.premiumize.me/device",
    "user_code":        "kpwx-3m7r",
    "device_code":      "...",
    "expires_in":       600,
    "interval":         5
}
```

- `verification_uri` — the page the user opens.
- `user_code` — short human-typeable code, format `xxxx-xxxx`. Case-insensitive; the dash is optional when the user types it.
- `device_code` — opaque token the device uses to poll. Treat as a secret.
- `expires_in` — lifetime in seconds (currently 600 = 10 minutes). After this, request a fresh pair.
- `interval` — minimum seconds between poll calls. Polling faster will trigger `slow_down`.

**Step 2 — Show the user where to go.** Display `verification_uri` and `user_code` on the device. The user opens the URL on a phone or laptop, signs in if not already, and enters the code.

**Step 3 — Poll the token endpoint:**

```
curl -X POST 'https://www.premiumize.me/token' \
  -d 'grant_type=device_code' \
  -d 'code=THE_DEVICE_CODE' \
  -d 'client_id=YOUR_CLIENT_ID'
```

While pending, every poll returns HTTP `400` with an `error` string. On success the same call returns the token envelope:

```
{
    "access_token": "...",
    "token_type":   "Bearer",
    "expires_in":   ...,
    "scope":        "full"
}
```

**Polling errors** (HTTP `400` with `{"error":"...","error_description":"..."}`):

| error | What it means | Action |
| --- | --- | --- |
| `authorization_pending` | User hasn't entered the code yet. | Keep polling at `interval`. |
| `slow_down` | You polled too soon. | Wait at least `interval` seconds before the next poll. Some clients double their interval after this. |
| `access_denied` | User rejected the request. | Stop polling; surface to the user. |
| `invalid_grant` | Device code is unknown, doesn't match the `client_id`, or has expired. | Stop polling. If `expires_in` elapsed, start over from Step 1. |

**Polling pseudocode:**

```
{ verification_uri, user_code, device_code, interval } = POST /token (response_type=device_code)
display user_code and verification_uri to user
loop:
    sleep(interval)
    response = POST /token (grant_type=device_code, code=device_code)
    if response.access_token: break  # done
    if response.error == "authorization_pending": continue
    if response.error == "slow_down":              interval += 5; continue
    if response.error == "access_denied":          abort
    if response.error == "invalid_grant":          abort  # expired or unknown
```

##### Authorization Code (server-side apps with a `client_secret`)

Standard three-leg OAuth Authorization Code flow. Use this only if your client can keep the `client_secret` safe (i.e. on a server you control). For everything else, use PKCE above.

1\. Redirect the user to the authorization endpoint:

```
https://www.premiumize.me/authorize
    ?response_type=code
    &client_id=YOUR_CLIENT_ID
    &redirect_uri=https://your.app/callback
    &state=RANDOM_STRING
```

2\. After the user approves, the browser is redirected to your `redirect_uri` with `?code=...&state=...`. Verify `state` matches what you sent.

3\. Exchange the code for an access token:

```
curl -X POST 'https://www.premiumize.me/token' \
  -d 'grant_type=authorization_code' \
  -d 'code=THE_CODE' \
  -d 'client_id=YOUR_CLIENT_ID' \
  -d 'client_secret=YOUR_CLIENT_SECRET' \
  -d 'redirect_uri=https://your.app/callback'
```

Response: `{"access_token":"...","token_type":"Bearer","expires_in":...,"scope":"full"}`.

##### Resource Owner Password Credentials (legacy first-party flow)

_Discouraged by OAuth 2.1._ Only use for first-party clients that the user already trusts with their account password (e.g. an official native app you ship). Third-party integrations must use Authorization Code with PKCE so credentials never leave the user's browser.

Exchange the user's credentials for a token directly:

```
curl -X POST 'https://www.premiumize.me/token' \
  -d 'grant_type=password' \
  -d 'client_id=YOUR_CLIENT_ID' \
  -d 'client_secret=YOUR_CLIENT_SECRET' \
  -d 'username=USER_EMAIL' \
  -d 'password=USER_PASSWORD'
```

Response: `{"access_token":"...","token_type":"Bearer","expires_in":...,"scope":"full"}`. The user's credentials are validated against the same login backend as the website.

##### Implicit (legacy)

_Deprecated by OAuth 2.1._ Prefer Authorization Code with PKCE for new browser-only apps — same security model, no token in the URL fragment, and refresh tokens are supported. Documented here for existing integrations only.

Redirect the user once and read the access token from the URL fragment on the redirect back:

```
https://www.premiumize.me/authorize
    ?response_type=token
    &client_id=YOUR_CLIENT_ID
    &redirect_uri=https://your.app/callback
    &state=RANDOM_STRING
```

After approval the user is redirected to `https://your.app/callback#access_token=...&token_type=Bearer&expires_in=...&state=...`. The token lives in the URL fragment (`#`), not the query string.

## Response format

Every endpoint returns JSON with a `status` field:

#### Success

```
{
    "status": "success",
    ...endpoint-specific fields...
}
```

#### Error

```
{
    "status":  "error",
    "message": "Human-readable description.",
    "code":    "error_code_string"
}
```

The HTTP status is `200` for normal responses including business-logic errors. `500` is used for catastrophic server failures (still returned as a JSON envelope on `/api/*` paths).

_Any field present in a response but not documented falls into one of two categories: **legacy** — kept for backward compatibility and will eventually be removed; or **experimental** — may change shape or disappear. Do not rely on either. This applies to every endpoint below._

## API methods

### Account

#### GET`/api/account/info`

Returns information about the authenticated user.

**Parameters:** _None._

**Response:**

```
{
    "status":         "success",
    "customer_id":    "1234567",
    "premium_until":  1799999999,
    "limit_used":     0.42,
    "booster_points": 0
}
```

- `customer_id` — Public-facing account identifier.
- `premium_until` — Unix timestamp; `null` for free accounts.
- `limit_used` — Fair-use fraction in `[0, 1]`.
- `booster_points` — Booster points remaining.

##### Deprecated values

- `space_used` — Bytes used on cloud storage. Computing this can be slow, so it will eventually move to a separate API call and may be cached or approximated. Treat as informational only; do not rely on it for quota enforcement or other programmatic decisions.

### Folders

#### GET`/api/folder/list`

Lists the contents of a folder. If neither `id` nor `path` is passed, the root folder is returned.

**Parameters:**

- `id` — Folder ID. Optional.
- `path` — Path string (alternative to `id`). Optional.
- `includebreadcrumbs=true` — Include parent folder chain. Optional.

**Response:**

```
{
    "status":    "success",
    "name":      "MyFolder",
    "parent_id": "...",
    "folder_id": "...",
    "breadcrumbs": [\
        {"id": "...", "name": "My Files"},\
        {"id": "...",  "name": "Parent"},\
        {"id": "...",  "name": "MyFolder"}\
    ],
    "content": [\
        {\
            "id":         "...",\
            "name":       "Subfolder",\
            "type":       "folder",\
            "created_at": 1700000000\
        },\
        {\
            "id":         "...",\
            "name":       "video.mkv",\
            "type":       "file",\
            "created_at": 1700000000,\
            "size":       123456789,\
            "mime_type":  "video/x-matroska",\
            "link":       "https://..."\
        }\
    ]
}
```

- Folder entries always carry `id`, `name`, `type`, `created_at`.
- File entries additionally carry `size` (bytes), `mime_type`, and `link` (download URL).
- `created_at` is a Unix timestamp.
- `breadcrumbs` is only present when `includebreadcrumbs=true` is passed; ordered from root to current folder.

##### Deprecated values

- `stream_link` — a streaming URL for files that were already in a directly streamable format or had been transcoded (`null` for everything else). Transcode infrastructure has been retired; this field remains for compatibility but will always equal `link` or `null`. Use `link` directly.
- `directlink` — appeared in production responses but was never documented. A direct-download URL bypassing the CDN; will soon return the same value as `link` (CDN link). Use `link`.
- `crc32` — appeared in production responses but was never documented. Kept for legacy compatibility; do not rely on it.
- `unpackable` — appeared in production responses but was never documented. Kept for legacy compatibility; do not rely on it.
- `transcode_status` — appeared in older API versions but was never actually included in this endpoint's response. Not returned.

#### POST`/api/folder/create`

Creates a folder.

**Parameters:**

- `name` — Folder name. Required.
- `parent_id` — Parent folder ID. Optional; defaults to root.

**Response:**

```
{
    "status": "success",
    "id":     "..."
}
```

#### POST`/api/folder/rename`

Renames a folder.

**Parameters:**

- `id` — Folder ID.
- `name` — New name.

**Response:**

```
{
    "status": "success"
}
```

#### POST`/api/folder/delete`

Deletes a folder and its contents.

**Parameters:**

- `id` — Folder ID.

**Response:**

```
{
    "status": "success"
}
```

#### POST`/api/folder/paste`

Moves files and/or folders into a target folder.

**Parameters:**

- `id` — Target folder ID.
- `files[]` — File IDs to move. Optional.
- `folders[]` — Folder IDs to move. Optional.

At least one of `files[]` or `folders[]` is required.

**Response:**

```
{
    "status": "success"
}
```

#### GET`/api/folder/uploadinfo`

Returns an upload token and URL for direct file upload to a folder. Two-step flow: call this endpoint to get a one-shot upload `url` and `token`, then POST your file to that `url`.

**Parameters:**

- `id` — Target folder ID. Optional; defaults to root.

**Response:**

```
{
    "status": "success",
    "token":  "...",
    "url":    "https://..."
}
```

**How to upload** — POST to the returned `url` as `multipart/form-data` with:

- `token` — the token from the response above.
- `file` — the file binary (form field name must be `file`).

```
curl -X POST "$URL" \
  -F "token=$TOKEN" \
  -F "file=@/path/to/your.file"
```

The token is single-use — request a fresh one for each upload.

#### GET`/api/folder/search`

Searches for matching files and folders across the user's storage.

**Parameters:**

- `q` — Search query string.

**Response:**

```
{
    "status":  "success",
    "name":    "Search Results",
    "content": [\
        {\
            "id":         "...",\
            "name":       "MyFolder",\
            "type":       "folder",\
            "created_at": 1700000000\
        },\
        {\
            "id":         "...",\
            "name":       "video.mkv",\
            "type":       "file",\
            "created_at": 1700000000,\
            "size":       123456789,\
            "mime_type":  "video/x-matroska",\
            "link":       "https://..."\
        }\
    ]
}
```

- Folder entries always carry `id`, `name`, `type`, `created_at`.
- File entries additionally carry `size` (bytes), `mime_type`, and `link` (download URL).
- `created_at` is a Unix timestamp.

##### Deprecated values

The following fields are still returned for backwards compatibility but **should not be used by new clients**.

- `directlink` — kept as a copy of `link` (will become identical) for backwards compatibility only. Use `link`.
- `stream_link` — for videos this mirrors `link`; for non-videos it's `null`. No longer a transcode-aware streaming URL. Use `link`.
- `unpackable` — best-effort filename-extension heuristic; not authoritative. Do not use.

### Files (items)

#### GET`/api/item/details`

Returns full metadata for a single file. Folder IDs are not accepted; pass a file ID only.

**Parameters:**

- `id` — File ID.

**Response:**

```
{
    "status":     "success",
    "id":         "...",
    "name":       "video.mkv",
    "size":       123456789,
    "created_at": 1700000000,
    "folder_id":  "...",
    "mime_type":  "video/x-matroska",
    "link":       "https://..."
}
```

- `created_at` — Unix timestamp.

##### Deprecated values

The following fields are still returned for backwards compatibility but **should not be used by new clients** — don't read, store, compare, or pass them through. Each note indicates whether the field was previously returned by production and whether it appeared in the old SwaggerHub spec.

- `type` — returned by production and previously documented. Always `"file"` since this endpoint only returns files. Do not use.
- `user_id` / `customer_id` — returned by production, never documented. Serve no useful purpose: the request is already scoped to your authenticated user. Do not use.
- `directlink` — returned by production, never documented. Used to be a separate direct-download URL distinct from the CDN link; users can now choose their preferred location in account settings, so `link` already respects that. Use `link` instead.
- `stream_link` — returned by production and previously documented. No longer a transcode-aware streaming URL: for videos it mirrors `link`, for non-videos it's `null`. Use `link` instead.
- `transcode_status` — returned by production and previously documented. Kept with a dummy value (`"good_as_is"` for video files, `"not_applicable"` otherwise); no longer reflects real transcode state. Do not use.
- `crc32` — returned by production, never documented. Backend-stored checksum that may stop being emitted. Do not use.
- `md5` — returned by production, never documented. Backend-stored checksum that may stop being emitted. Do not use.
- `server_name` — returned by production, never documented. Internal storage-server identifier (parsed from the CDN URL). Do not use.
- `unpackable` — returned by production, never documented. Best-effort heuristic based on filename extension (rar, zip, 7z, tar, etc.); not authoritative. Do not use.
- `virus_scan` — returned by production and previously documented. The virus-scan integration is being retired. Do not use.
- `vcodec` / `acodec` — returned by production and previously documented. Codec metadata; populated for videos as empty strings for everything else. Do not use.
- `resx` / `resy` — returned by production and previously documented. Video resolution; empty strings for non-videos. Do not use.
- `duration` — returned by production and previously documented. Video duration in seconds (as a numeric string); empty for non-videos. Do not use.
- `audio_track_names` — returned by production and previously documented. Array of audio-track labels for videos. Do not use.
- `opensubtitles_hash` — returned by production and previously documented. OpenSubtitles file hash. Do not use.
- `bitrate` — appeared in the old SwaggerHub spec but was never actually returned by production. Not returned.

#### POST`/api/item/rename`

Renames a file.

**Parameters:**

- `id` — File ID.
- `name` — New name.

**Response:**

```
{
    "status": "success"
}
```

#### POST`/api/item/delete`

Deletes a file.

**Parameters:**

- `id` — File ID.

**Response:**

```
{
    "status": "success"
}
```

#### GET`/api/item/listall`

Returns a flat list of every file the user owns, with full path.

**Parameters:** _None._

**Response:**

```
{
    "status": "success",
    "files": [\
        {\
            "id":         "...",\
            "name":       "video.mkv",\
            "path":       "folder/sub/video.mkv",\
            "size":       123456789,\
            "created_at": 1700000000,\
            "mime_type":  "video/x-matroska"\
        }\
    ]
}
```

Each `files` entry has `id`, `name`, `path` (the slash-joined path from root), `size` (bytes), `created_at` (Unix timestamp), and `mime_type`.

##### Deprecated values

- `virus_scan` — returned by production, never documented. Hardcoded to `"ok"` because the upstream JSON-RPC layer doesn't expose the real scan status here. Do not use.

### Transfers

#### POST`/api/transfer/create`

Submits a transfer to be downloaded into the cloud.

**Parameters:**

- `src` — A URI for the transfer (as a string) or a source file for the transfer (multipart upload).
- `folder_id` — Target folder. Optional.
- `password` — Password for the transfer. Optional.

**Response:**

```
{
    "status": "success",
    "id":     "...",
    "name":   "video.mkv"
}
```

If `src` is a container (`.dlc` / `.ccf` / `.rsdf`) the response is instead `{"status":"success","type":"container","content":[...links...]}` — submit the extracted links one by one. (The container case is the only situation in which `type` carries a stable value; see Deprecated values.)

##### Deprecated values

- `type` — returned by production and previously documented. On the normal (non-container) response this carries an internal classification (e.g. the source kind) that is not stable across versions. Do not use. The exception is the container response above, where `type` is the literal string `"container"` and serves as a discriminator — that specific value is stable.

#### POST`/api/transfer/directdl`

Generates direct download links from a transfer source without storing it in your cloud. The `content` array can hold one or many file entries — a single hoster URL typically resolves to one file, while a magnet or torrent source resolves to every file inside the archive.

**Parameters:**

- `src` — Transfer source URL.

**Response:**

```
{
    "status":  "success",
    "content": [\
        {\
            "path": "Folder/video1.mkv",\
            "size": 123456789,\
            "link": "https://..."\
        },\
        {\
            "path": "Folder/video2.mkv",\
            "size": 234567890,\
            "link": "https://..."\
        }\
    ]
}
```

- Each `content` entry has `path` (slash-joined path inside the source), `size` (bytes), and `link` (download URL).

##### Deprecated values

The following fields are still returned for backwards compatibility but **should not be used by new clients**.

- `content[].stream_link` — for videos this mirrors `link`; for non-videos it's `null`. No longer a transcode-aware streaming URL. Use `link`.
- `content[].transcode_status` — kept with a dummy value (`"good_as_is"` for video files, `"not_applicable"` otherwise); no longer reflects real transcode state. Do not use.
- `location` / `filename` / `filesize` — top-level convenience fields that mirror the first `content` entry's `link`, `path`, and `size` respectively. Provided for legacy single-file callers; new clients should iterate `content`. Do not use.

#### GET`/api/transfer/list`

Returns every transfer the user has created — active, queued, finished, and errored — newest first. Use this to drive a UI that shows download progress, retry failed jobs, etc. Responses are not cached; expect to poll while a transfer is running.

**Parameters:** _None._

**Response:**

```
{
    "status":    "success",
    "transfers": [\
        {\
            "id":        "...",\
            "name":      "video.mkv",\
            "status":    "running",\
            "progress":  0.42,\
            "message":   "Downloading from server",\
            "folder_id": "...",\
            "file_id":   null\
        },\
        {\
            "id":        "...",\
            "name":      "movie.mkv",\
            "status":    "finished",\
            "progress":  1.0,\
            "message":   "",\
            "folder_id": "...",\
            "file_id":   "..."\
        }\
    ]
}
```

- `id` — Transfer ID. Use this with [`/api/transfer/retry`](https://www.premiumize.me/api#transfers) and [`/api/transfer/delete`](https://www.premiumize.me/api#transfers).
- `name` — Display name for the transfer.
- `status` — One of `queued`, `running`, `finished`, `seeding`, `error`. `seeding` means a torrent has finished downloading and is now seeding; the file is already available in the cloud.
- `progress` — Float between `0.0` and `1.0`. Always `1.0` for `finished`; 0.0 for `queued` and `error`.
- `message` — Free-form human-readable status text. Empty string when there's nothing to say.
- `folder_id` — Folder the transfer was placed into once finished. `null` while the transfer is still `queued`, `running`, or `error` (no files placed yet), and also `null` if the transfer was routed to an external cloud instead of your own. Populated for `finished` and `seeding` transfers in your own cloud.
- `file_id` — File ID in the cloud once the transfer finishes. `null` while in progress, also `null` if the transfer produced a folder (multi-file source) or was routed to an external cloud.

##### Deprecated values

- `src` — old-school URL pointing at an authenticated proxy (`/api/job/src?id=…`) that 302-redirects to the original source URL or streams a fetched `.torrent`/`.nzb` file. Will eventually be replaced with a dedicated endpoint that returns the source as structured data; do not build new clients around this URL.
- `other_cloud_id` — returned by production, never documented. Internal identifier for transfers routed to a connected external cloud (FTP, OAuth provider, etc.); external-cloud configuration isn't exposed via the API. Do not use.

#### POST`/api/transfer/retry`

Re-queues a failed transfer.

**Parameters:**

- `id` — Transfer ID.

**Response:**

```
{
    "status": "success"
}
```

#### POST`/api/transfer/delete`

Deletes a transfer record.

**Parameters:**

- `id` — Transfer ID.

**Response:**

```
{
    "status": "success"
}
```

#### POST`/api/transfer/clearfinished`

Removes all finished transfers from the list.

**Parameters:** _None._

**Response:**

```
{
    "status": "success"
}
```

### Cache

#### POST`/api/cache/check`

Tests whether links are already in the cache.

**Parameters:**

- `items[]` — Links to check.

**Response:** parallel arrays indexed by request order:

```
{
    "status":   "success",
    "response": [true, false, ...],
    "filename": ["My.Transfer.Name", null, ...],
    "filesize": ["12345678901", 0, ...]
}
```

##### Deprecated values

- `transcoded` — returned by production and previously documented. Originally indicated whether the cached content had been transcoded for streaming. Transcoding infrastructure has been retired and clients are expected to play source files directly, so the field is now a vestigial filename-extension heuristic: `null` on a miss, `true` if any file in the cached content has a video extension, otherwise `false`. Do not use.

### Services

#### GET`/api/services/list`

Returns metadata for every supported service.

**Parameters:** _None._

**Response:**

```
{
    "status": "success",
    "cache": [\
        "exampleservice1",\
        "exampleservice2"\
    ],
    "directdl": [\
        "exampleservice1",\
        "exampleservice2"\
    ],
    "queue": [\
        "exampleservice1",\
        "exampleservice2"\
    ],
    "fairusefactor": {
        "exampleservice1": 1,
        "exampleservice2": 2
    },
    "aliases": {
        "exampleservice1": ["example1.alt"],
        "exampleservice2": ["example2.alt", "example2.also"]
    },
    "regexpatterns": {
        "exampleservice1": [\
            "^https?://(?:www\\.)?exampleservice1\\.com/.*$",\
            "^https?://(?:www\\.)?example1\\.alt/.*$"\
        ],
        "exampleservice2": ["^https?://(?:www\\.)?exampleservice2\\.com/.*$"]
    }
}
```

- `cache` — Service names whose links can be looked up via [`/api/cache/check`](https://www.premiumize.me/api#cache). A hit is not guaranteed; the cache is best-effort.
- `directdl` — Service names whose links can be submitted to [`/api/transfer/directdl`](https://www.premiumize.me/api#transfers) to obtain an instantly-downloadable URL.
- `queue` — Service names whose links can be submitted to [`/api/transfer/create`](https://www.premiumize.me/api#transfers); the system fetches them into the cloud asynchronously.
- `fairusefactor` — Per-service multiplier for fair-use point consumption when fetching data. See [/fairuse](https://www.premiumize.me/fairuse) for details.
- `aliases` — Additional TLDs / domain aliases recognised for each service. Best-effort, no completeness guarantee.
- `regexpatterns` — Regex patterns we use to detect URLs belonging to each service. Best-effort, no completeness guarantee.

### ZIP downloads

#### POST`/api/zip/generate`

Bundles selected files and folders into a single .zip download. The call is synchronous — once the response returns, the `location` URL can be downloaded instantly. Resuming and multi-part downloads will work if a user pastes the link into a custom download manager, but your software should fetch the URL with a single connection.

**Parameters:**

- `files[]` — File IDs to include. Optional.
- `folders[]` — Folder IDs to include. Optional.

At least one of `files[]` or `folders[]` is required.

**Response:**

```
{
    "status":   "success",
    "location": "https://..."
}
```

**Filename:** the download filename is encoded in the `location` URL itself — the server does _not_ set a `Content-Disposition` header, so clients should derive the filename from the URL path.

- Single file source → the file's name with a `.zip` suffix (e.g. `video.mkv.zip`).
- Single folder source → the folder's name with a `.zip` suffix (e.g. `MyFolder.zip`).
- Multiple sources → a generated filename based on the current date and time.

## Error codes

The `code` field is a stable string identifier. Codes are grouped by retry semantics.

#### Transient — retry now may succeed

| Code | HTTP | Meaning |
| --- | --- | --- |
| `link_generation_failed` | `200` | There was an error generating the link right now. |
| `transient_error` | `200` | Other errors which have no specific error code are grouped here. |

#### Semi-permanent — wait, raise quota, or upgrade, then retry

| Code | HTTP | Meaning |
| --- | --- | --- |
| `service_down` | `200` | The target service is unreachable right now. Retry after a delay. |
| `service_limit_reached` | `200` | This account's usage limit for this service has been reached. |
| `account_limit_reached` | `200` | Your fair-use points, booster points, or active-job count is exhausted. |
| `rate_limit_reached` | `200` | You've made too many API requests too quickly. |
| `semi_permanent_error` | `200` | Other errors which have no specific error code are grouped here. |

#### Permanent — same request will keep failing

| Code | HTTP | Meaning |
| --- | --- | --- |
| `service_unsupported` | `200` | The link points to a service we can't process. |
| `not_found` | `200` | The requested resource (file, transfer, source, feed) doesn't exist. |
| `authentication_failed` | `200` | API key missing, invalid, or expired. |
| `permission_denied` | `200` | Authenticated but not allowed: account restricted, unconfirmed, or accessing someone else's resource. |
| `invalid_request` | `200` | Required parameters are missing or malformed. |
| `permanent_error` | `200` | Other errors which have no specific error code are grouped here. |

#### Unknown — catastrophic failure outside the normal envelope

| Code | HTTP | Meaning |
| --- | --- | --- |
| `unknown_error` | `500` | The request didn't complete normally — network blip, parse error, or uncaught server exception. Worth a retry, but back off. |

[back to top](https://www.premiumize.me/api#top)

This website uses only essential cookies for login, authentication, and session management. See our [Privacy Policy](https://www.premiumize.me/privacy) for details.

Got it