Media API
List media files API
Get the files in your workspace's media library with their download URLs, newest first. Filter by type or search by name to find a file you uploaded earlier and reuse its URL in a message.
https://wbiztool.com/api/v1/media/list/Body: Query string, or a JSON body with POST
The list includes files uploaded with the Upload media API and on the Media directory page. Deleted files are not included.
Quick example#
curl -G https://wbiztool.com/api/v1/media/list/ \
--data-urlencode client_id=12345 \
--data-urlencode api_key=YOUR_API_KEY \
--data-urlencode file_type=image \
--data-urlencode page=1 \
--data-urlencode limit=20import requests
response = requests.get(
"https://wbiztool.com/api/v1/media/list/",
params={
"client_id": 12345,
"api_key": "YOUR_API_KEY",
"file_type": "image",
"page": 1,
"limit": 20,
},
timeout=60,
)
result = response.json()
if result["status"] == 1:
data = result["data"]
print(f"Page {data['page']} of {data['total_pages']} ({data['total_count']} files)")
for media in data["media_files"]:
print(media["id"], media["original_file_name"], media["file_url"])
else:
print("Failed:", result["message"])// Node.js 18+ (built-in fetch). Save as .mjs to use top-level await.
const url = new URL("https://wbiztool.com/api/v1/media/list/");
url.search = new URLSearchParams({
client_id: "12345",
api_key: "YOUR_API_KEY",
file_type: "image",
page: "1",
limit: "20",
});
const response = await fetch(url);
const result = await response.json();
if (result.status === 1) {
const { data } = result;
console.log(`Page ${data.page} of ${data.total_pages} (${data.total_count} files)`);
for (const media of data.media_files) {
console.log(media.id, media.original_file_name, media.file_url);
}
} else {
console.error("Failed:", result.message);
}<?php
$query = http_build_query([
'client_id' => 12345,
'api_key' => 'YOUR_API_KEY',
'file_type' => 'image',
'page' => 1,
'limit' => 20,
]);
$ch = curl_init('https://wbiztool.com/api/v1/media/list/?' . $query);
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_TIMEOUT => 60,
]);
$result = json_decode(curl_exec($ch), true);
curl_close($ch);
if (($result['status'] ?? 0) === 1) {
foreach ($result['data']['media_files'] as $media) {
echo $media['id'] . ' ' . $media['original_file_name'] . ' ' . $media['file_url'] . "\n";
}
} else {
echo 'Failed: ' . ($result['message'] ?? 'no response');
}Replace 12345 and YOUR_API_KEY with your own values. See Authentication for where to find them.
Request parameters#
Send the parameters in the query string of a GET request, or as a JSON body in a POST request with Content-Type: application/json. Don't mix the two: if client_id is in the query string, the JSON body is ignored. A form-encoded POST also works for client_id, api_key, file_type and search, but page and limit are ignored in form fields; send those in the query string or JSON.
Authentication
client_idintegerrequiredYour API Client ID from Settings → API keys.
api_keystringrequiredYour API key from the same page.
Filters and pagination
pageintegeroptionalPage number, starting at
1(default). Values below 1 are treated as1.limitintegeroptionalFiles per page, from 1 to 100. Default
20. Values above 100 are treated as100, and values below 1 as20.file_typestringoptionalimagefor images only, orfilefor everything else. Any other value is ignored.searchstringoptionalOnly return files whose original name or stored name contains this text. Not case-sensitive.
curl -X POST https://wbiztool.com/api/v1/media/list/ \
-H "Content-Type: application/json" \
-d '{
"client_id": 12345,
"api_key": "YOUR_API_KEY",
"search": "invoice",
"page": 1,
"limit": 50
}'Response#
{
"status": 1,
"message": "Media files retrieved successfully",
"data": {
"total_count": 1,
"page": 1,
"limit": 20,
"total_pages": 1,
"has_next": false,
"has_previous": false,
"media_files": [
{
"id": 5123,
"file_name": "media_12345_17895806123456.jpg",
"original_file_name": "diwali-sale.jpg",
"file_url": "https://wbiztool-static.s3.ap-southeast-1.amazonaws.com/media/org_12345/media_12345_17895806123456.jpg",
"file_type": "image",
"file_size": 524288,
"file_size_display": "512.0 KB",
"mime_type": "image/jpeg",
"is_image": true,
"file_extension": "jpg",
"created_at": "2026-09-16T10:23:52.106447+00:00",
"uploaded_by": "[email protected]"
}
]
}
}
| Field | Type | Description |
|---|---|---|
status | integer | 1 on success, 0 if the request failed. |
message | string | Media files retrieved successfully, otherwise the error. |
data.total_count | integer | Files matching your filters, across all pages. |
data.page | integer | The page returned. |
data.limit | integer | The page size used, after the 1 to 100 adjustment. |
data.total_pages | integer | Number of pages. 0 when there are no files. |
data.has_next | boolean | true if there's a page after this one. |
data.has_previous | boolean | true if page is greater than 1. |
data.media_files | array | The files on this page, newest first. Empty if the page is past the end. |
Media file fields#
| Field | Type | Description |
|---|---|---|
id | integer | ID of the media file. Use it with Get media file. |
file_name | string | Name the file is stored under. |
original_file_name | string | The name the file had when it was uploaded. |
file_url | string | Direct download URL. Use it as img_url or file_url when sending. |
file_type | string | image or file. |
file_size | integer | Size in bytes. |
file_size_display | string | Readable size with one decimal, for example 512.0 KB. |
mime_type | string | MIME type, for example image/jpeg. |
is_image | boolean | true when file_type is image. |
file_extension | string | Lower-case extension of original_file_name, without the dot. |
created_at | string | Upload time, ISO 8601 in UTC with a +00:00 offset. |
uploaded_by | string or null | Login username (usually the email address) of the team member who uploaded the file. |
Errors#
Errors also return HTTP 200, with status set to 0:
{ "status": 0, "message": "Invalid API key" }
| Message | How to fix it |
|---|---|
client_id is required | Add client_id. If you send JSON, check the body is valid JSON (a parse error is reported as this message). |
api_key is required | Add api_key. |
client_id must be a valid integer | Send client_id as a number. |
Invalid API key | Check the key exists and hasn't been deleted or disabled. |
Invalid client_id for this API key | The key belongs to a different client_id. |
Error retrieving media files: … | Usually page or limit in the query string or form fields isn't a whole number. In a JSON body there's no error: if page isn't a whole number, page, limit, file_type and search are all ignored, so you get page 1 with 20 files and no filters. If only limit isn't, limit, file_type and search are ignored. |
Reading every page#
Keep requesting the next page while data.has_next is true.
import requests
files, page = [], 1
while True:
result = requests.get(
"https://wbiztool.com/api/v1/media/list/",
params={"client_id": 12345, "api_key": "YOUR_API_KEY", "page": page, "limit": 100},
timeout=60,
).json()
if result["status"] != 1:
raise RuntimeError(result["message"])
files += result["data"]["media_files"]
if not result["data"]["has_next"]:
break
page += 1
print(len(files), "files")// Node.js 18+ (built-in fetch). Save as .mjs to use top-level await.
const files = [];
let page = 1;
while (true) {
const url = new URL("https://wbiztool.com/api/v1/media/list/");
url.search = new URLSearchParams({ client_id: "12345", api_key: "YOUR_API_KEY", page: String(page), limit: "100" });
const result = await (await fetch(url)).json();
if (result.status !== 1) throw new Error(result.message);
files.push(...result.data.media_files);
if (!result.data.has_next) break;
page += 1;
}
console.log(files.length, "files");Tips#
- Use the right send parameter: when
is_imageistrue, send the URL asimg_urlwithmsg_type1; otherwise asfile_urlwithmsg_type2. See Send message. - Keep your API key out of logs: query strings are often logged by proxies and servers. If that matters to you, use
POSTwith a JSON body instead.
