API медиафайлов
API загрузки медиафайлов
Загрузите изображение, документ, аудио- или видеофайл в Медиакаталог вашего рабочего пространства и получите ссылку для скачивания. Передайте эту ссылку в API отправки сообщений или в API создания напоминаний как img_url, если у вас нет собственного хостинга файлов.
https://wbiztool.com/api/v1/media/upload/Тело запроса: multipart/form-data
Файл сохраняется сразу, а ответ содержит его file_url. Загруженные файлы также появляются на странице Медиакаталог в вашей панели управления.
Быстрый пример#
curl -X POST https://wbiztool.com/api/v1/media/upload/ \
-F client_id=12345 \
-F api_key=YOUR_API_KEY \
-F media_file=@./invoice-4821.pdfimport requests
with open("invoice-4821.pdf", "rb") as f:
response = requests.post(
"https://wbiztool.com/api/v1/media/upload/",
data={"client_id": 12345, "api_key": "YOUR_API_KEY"},
files={"media_file": f},
timeout=120,
)
try:
result = response.json()
except ValueError:
# A proxy can reject a very large upload with an HTML page before it reaches WbizTool.
raise SystemExit(f"HTTP {response.status_code}: not JSON. Check the file size.")
if result["status"] == 1:
print("Uploaded:", result["data"]["file_url"])
else:
print("Failed:", result["message"])// Node.js 20+ (built-in fetch, FormData and fs.openAsBlob). Save as .mjs to use top-level await.
import { openAsBlob } from "node:fs";
const form = new FormData();
form.append("client_id", "12345");
form.append("api_key", "YOUR_API_KEY");
form.append("media_file", await openAsBlob("./invoice-4821.pdf"), "invoice-4821.pdf");
// Don't set Content-Type yourself; fetch adds the multipart boundary.
const response = await fetch("https://wbiztool.com/api/v1/media/upload/", { method: "POST", body: form });
const result = await response.json();
if (result.status === 1) {
console.log("Uploaded:", result.data.file_url);
} else {
console.error("Failed:", result.message);
}<?php
$ch = curl_init('https://wbiztool.com/api/v1/media/upload/');
curl_setopt_array($ch, [
CURLOPT_POST => true,
// An array body (not json_encode) makes cURL send multipart/form-data.
CURLOPT_POSTFIELDS => [
'client_id' => 12345,
'api_key' => 'YOUR_API_KEY',
'media_file' => new CURLFile('/path/to/invoice-4821.pdf', 'application/pdf', 'invoice-4821.pdf'),
],
CURLOPT_RETURNTRANSFER => true,
CURLOPT_TIMEOUT => 120,
]);
$result = json_decode(curl_exec($ch), true);
curl_close($ch);
if (($result['status'] ?? 0) === 1) {
echo 'Uploaded: ' . $result['data']['file_url'];
} else {
echo 'Failed: ' . ($result['message'] ?? 'no response');
}Замените 12345 и YOUR_API_KEY своими значениями. Где их найти, описано в разделе Аутентификация.
Параметры запроса#
Отправляйте запрос как multipart/form-data. Тело JSON и параметры в строке запроса этот endpoint не читает.
client_idintegerобязательноВаш API Client ID из раздела Настройки → API ключи.
api_keystringобязательноВаш API-ключ с той же страницы.
media_filefileобязательноЗагружаемый файл размером до 64 МБ; он должен помещаться в хранилище медиафайлов рабочего пространства. Его тип определяется по расширению в имени файла, поэтому имя должно заканчиваться одним из поддерживаемых расширений.
Поддерживаемые типы файлов#
| Категория | Расширения |
|---|---|
| Изображения | .jpg, .jpeg, .png, .gif, .webp, .bmp |
| Документы | .pdf, .doc, .docx, .xls, .xlsx, .ppt, .pptx, .txt, .csv |
| Аудио | .mp3, .m4a, .wav, .ogg, .aac |
| Видео | .mp4, .mov, .avi |
| Архивы | .zip, .rar |
Изображения сохраняются с file_type, равным image; всё остальное — file.
Хранилище рабочего пространства#
Все файлы в Медиакаталоге рабочего пространства делят один лимит хранилища, который задаётся тарифом рабочего пространства. Учитываются и файлы, загруженные через этот API, и загруженные на странице Медиакаталога, а удаление файла освобождает его место.
| Тариф | Хранилище медиафайлов |
|---|---|
| Пробный период | 250 МБ |
| Lite | 1 ГБ |
| Standard | 2 ГБ |
| Advanced | 5 ГБ |
| Enterprise | 10 ГБ |
| AppSumo Plan 1 и Plan 2 | 1 ГБ |
| AppSumo Plan 3 | 2 ГБ |
| AppSumo Plan 4 | 3 ГБ |
| AppSumo Plan 5 | 5 ГБ |
У старых тарифов и у рабочего пространства без активного тарифа — 1 ГБ. Загрузка, которая не помещается, отклоняется с ошибкой Storage full: … (см. Ошибки). Рабочее пространство, которое уже превысило лимит, сохраняет свои файлы, но не может добавлять новые, пока для них не появится место.
Ответ#
Успешный запрос возвращает HTTP 200:
{
"status": 1,
"message": "File uploaded successfully",
"data": {
"id": 5122,
"file_name": "media_12345_17895804001234_3f9a1c7e.pdf",
"original_file_name": "invoice-4821.pdf",
"file_url": "https://wbiztool-static.s3.ap-southeast-1.amazonaws.com/media/org_12345/media_12345_17895804001234_3f9a1c7e.pdf",
"file_type": "file",
"file_size": 248312,
"file_size_display": "242.5 KB",
"mime_type": "application/pdf",
"is_image": false,
"file_extension": "pdf",
"created_at": "2026-09-16T10:20:31.512934+00:00"
}
}
| Поле | Тип | Описание |
|---|---|---|
status | integer | 1, если файл загружен, 0, если запрос не выполнен. |
message | string | File uploaded successfully, иначе текст ошибки. |
data.id | integer | ID медиафайла. Используйте его в API получения медиафайла. |
data.file_name | string | Имя, под которым хранится файл; генерируется WbizTool: media_, ID вашего рабочего пространства, время загрузки и случайная часть, с расширением файла. |
data.original_file_name | string | Имя загруженного вами файла. |
data.file_url | string | Прямая ссылка для скачивания. Используйте её как img_url или file_url при отправке. Она публичная и не истекает, но перестаёт работать после удаления файла. Она может быть на media.wbiztool.com (наш CDN) или на wbiztool-static.s3.ap-southeast-1.amazonaws.com; оба адреса отдают один и тот же файл, поэтому сохраняйте ссылку как есть и не составляйте такие URL сами. |
data.file_type | string | image или file. |
data.file_size | integer | Размер в байтах. |
data.file_size_display | string | Размер в удобном для чтения виде с одним знаком после запятой, например 242.5 KB. |
data.mime_type | string | MIME-тип, определённый по расширению, например application/pdf. |
data.is_image | boolean | true, если file_type равен image. |
data.file_extension | string | Расширение original_file_name в нижнем регистре, без точки. |
data.created_at | string | Время загрузки в формате ISO 8601 в UTC со смещением +00:00. |
Ошибки#
Ошибки тоже возвращаются с HTTP 200 и status, равным 0:
{ "status": 0, "message": "File is too large. Maximum size is 64MB. Your file: 71.3MB" }
| Сообщение | Как исправить |
|---|---|
Only POST method is supported | Отправьте запрос POST. |
client_id is required | Добавьте client_id как поле формы. Проверьте, что тело запроса — multipart/form-data, а не JSON. |
api_key is required | Добавьте api_key как поле формы. |
media_file is required | Передайте файл в поле с именем media_file. |
client_id must be a valid integer | Передайте client_id числом. |
Invalid API key | Проверьте, что ключ существует, не удалён и не отключён. |
Invalid client_id for this API key | Ключ принадлежит другому client_id. |
File is too large. Maximum size is 64MB. Your file: …MB | Загрузите файл размером не более 64 МБ. |
File type not supported. Type detected: … | Используйте одно из поддерживаемых расширений. |
Storage full: this workspace uses … of its … of media storage, and this file is …. Delete files you no longer need in the Media directory, or contact us if you need more space. | Файл не помещается в хранилище медиафайлов рабочего пространства. Удалите ненужные файлы на странице Медиакаталог или свяжитесь с нами, чтобы получить больше места. |
Error uploading file: … | Не удалось завершить загрузку. Повторите попытку. Эта ошибка также возвращается, если API-ключ не привязан к рабочему пространству; создайте новый ключ в нужном рабочем пространстве. |
Загрузка и отправка#
Загрузите файл, затем передайте file_url в API отправки сообщений: для изображений — как img_url с msg_type 1, для остальных файлов — как file_url с msg_type 2.
import requests
BASE = "https://wbiztool.com/api/v1"
AUTH = {"client_id": 12345, "api_key": "YOUR_API_KEY"}
with open("invoice-4821.pdf", "rb") as f:
upload = requests.post(f"{BASE}/media/upload/", data=AUTH, files={"media_file": f}, timeout=120).json()
if upload["status"] != 1:
raise SystemExit("Upload failed: " + upload["message"])
media = upload["data"]
message = {
**AUTH,
"whatsapp_client": 678,
"country_code": "91",
"phone": "9876543210",
"msg": "Your invoice for order #4821 is attached.",
}
if media["is_image"]:
message.update(msg_type=1, img_url=media["file_url"])
else:
message.update(msg_type=2, file_url=media["file_url"], file_name=media["original_file_name"])
sent = requests.post(f"{BASE}/send_msg/", json=message, timeout=60).json()
print(sent)// Node.js 20+ (built-in fetch, FormData and fs.openAsBlob). Save as .mjs to use top-level await.
import { openAsBlob } from "node:fs";
const BASE = "https://wbiztool.com/api/v1";
const form = new FormData();
form.append("client_id", "12345");
form.append("api_key", "YOUR_API_KEY");
form.append("media_file", await openAsBlob("./invoice-4821.pdf"), "invoice-4821.pdf");
const upload = await (await fetch(`${BASE}/media/upload/`, { method: "POST", body: form })).json();
if (upload.status !== 1) throw new Error(`Upload failed: ${upload.message}`);
const media = upload.data;
const message = {
client_id: 12345,
api_key: "YOUR_API_KEY",
whatsapp_client: 678,
country_code: "91",
phone: "9876543210",
msg: "Your invoice for order #4821 is attached.",
...(media.is_image
? { msg_type: 1, img_url: media.file_url }
: { msg_type: 2, file_url: media.file_url, file_name: media.original_file_name }),
};
const sent = await fetch(`${BASE}/send_msg/`, {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify(message),
});
console.log(await sent.json());Каждый тип файлов, который принимает этот API, сохраняет своё расширение при отправке с msg_type 2, например brochure.doc или catalogue.zip. Аудио WAV и OGG приходит как документ, а не как воспроизводимое аудио, а при отправке как изображение (msg_type 1) завершается ошибкой File type not supported. MP3, M4A и AAC приходят как аудио, которое воспроизводится в чате, а текст идёт отдельным сообщением. См. раздел Отправка изображений и файлов. Имя отправляется в нижнем регистре (Invoice-4821.PDF приходит как invoice-4821.pdf).
Изображения, отправляемые с msg_type 1, должны быть не больше 16 МБ. Более крупные изображения здесь загружаются без проблем, но не отправляются с ошибкой File exceeds WhatsApp size limit (16MB max). Сначала сожмите их или отправьте как файл с msg_type 2.
Советы#
- Используйте загрузки повторно. Сохраните
idилиfile_urlи отправляйте один и тот же файл многократно, не загружая его заново. - Давайте файлам понятные исходные имена.
original_file_nameотображается в панели управления и хорошо подходит в качествеfile_nameпри отправке. - Ранее загруженные файлы можно найти через API списка медиафайлов.
