API Documentation
If you have any questions about the API or need dev support, please open a ticket with our customer service.
Table of contents
- Authentication
- Response format
-
API methods
- Account
- Folders (includes search and upload)
- Files (items)
- Transfers
- Cache
- Services
- ZIP downloads
- Error codes
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.
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_KEYas a query-string parameter, orapikey=YOUR_API_KEYin a POST body. Most widely used historically.?pin=YOUR_API_KEY/pin=YOUR_API_KEY— legacy alias forapikey; the server treatspinas identical toapikey. Predates the rename toapikey.- 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 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, formatxxxx-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 triggerslow_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,
"space_used": 12345678901,
"booster_points": 0
}
customer_id— Public-facing account identifier.premium_until— Unix timestamp;nullfor free accounts.limit_used— Fair-use fraction in[0, 1].space_used— Bytes used on cloud storage.booster_points— Booster points remaining.
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 toid). 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, andlink(download URL). created_atis a Unix timestamp.breadcrumbsis only present whenincludebreadcrumbs=trueis 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 (nullfor everything else). Transcode infrastructure has been retired; this field remains for compatibility but will always equallinkornull. Uselinkdirectly.directlink— appeared in production responses but was never documented. Originally a separate direct-download URL distinct from the CDN link; that distinction no longer exists and this field now returns the same value aslink.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 befile).
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, andlink(download URL). created_atis 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 oflink(will become identical) for backwards compatibility only. Uselink.stream_link— for videos this mirrorslink; for non-videos it'snull. No longer a transcode-aware streaming URL. Uselink.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, solinkalready respects that. Uselinkinstead.stream_link— returned by production and previously documented. No longer a transcode-aware streaming URL: for videos it mirrorslink, for non-videos it'snull. Uselinkinstead.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, wheretypeis 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
contententry haspath(slash-joined path inside the source),size(bytes), andlink(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 mirrorslink; for non-videos it'snull. No longer a transcode-aware streaming URL. Uselink.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 firstcontententry'slink,path, andsizerespectively. Provided for legacy single-file callers; new clients should iteratecontent. 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/retryand/api/transfer/delete.name— Display name for the transfer.status— One ofqueued,running,finished,seeding,error.seedingmeans a torrent has finished downloading and is now seeding; the file is already available in the cloud.progress— Float between0.0and1.0. Always1.0forfinished; 0.0 forqueuedanderror.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.nullwhile the transfer is stillqueued,running, orerror(no files placed yet), and alsonullif the transfer was routed to an external cloud instead of your own. Populated forfinishedandseedingtransfers in your own cloud.file_id— File ID in the cloud once the transfer finishes.nullwhile in progress, alsonullif 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/.nzbfile. 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:nullon a miss,trueif any file in the cached content has a video extension, otherwisefalse. 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. A hit is not guaranteed; the cache is best-effort.directdl— Service names whose links can be submitted to/api/transfer/directdlto obtain an instantly-downloadable URL.queue— Service names whose links can be submitted to/api/transfer/create; the system fetches them into the cloud asynchronously.fairusefactor— Per-service multiplier for fair-use point consumption when fetching data. See /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
.zipsuffix (e.g.video.mkv.zip). - Single folder source → the folder's name with a
.zipsuffix (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. |