API de mídia
API de upload de mídia
Envie uma imagem, um documento, um áudio ou um vídeo para o Diretório de mídia do seu espaço de trabalho e receba de volta uma URL de download. Passe essa URL para Enviar mensagem ou para Criar lembrete como img_url, quando você não tiver sua própria hospedagem de arquivos.
https://wbiztool.com/api/v1/media/upload/Corpo: multipart/form-data
O arquivo é armazenado imediatamente e a resposta inclui o file_url dele. Os arquivos enviados também aparecem na página Diretório de mídia do seu painel.
Exemplo rápido#
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');
}Substitua 12345 e YOUR_API_KEY pelos seus próprios valores. Veja em Autenticação onde encontrá-los.
Parâmetros da requisição#
Envie a requisição como multipart/form-data. Este endpoint não lê corpos JSON nem parâmetros na query string.
client_idintegerobrigatórioSeu ID do Cliente da API, em Configurações → Chaves API.
api_keystringobrigatórioSua chave de API, na mesma página.
media_filefileobrigatórioO arquivo a enviar, com até 64 MB, e ele precisa caber no armazenamento de mídia do espaço de trabalho. O tipo é definido pela extensão do nome do arquivo, então o nome precisa terminar com uma das extensões aceitas.
Tipos de arquivo aceitos#
| Categoria | Extensões |
|---|---|
| Imagens | .jpg, .jpeg, .png, .gif, .webp, .bmp |
| Documentos | .pdf, .doc, .docx, .xls, .xlsx, .ppt, .pptx, .txt, .csv |
| Áudio | .mp3, .m4a, .wav, .ogg, .aac |
| Vídeo | .mp4, .mov, .avi |
| Arquivos compactados | .zip, .rar |
Imagens são armazenadas com file_type igual a image; todo o resto é file.
Armazenamento por espaço de trabalho#
Todos os arquivos do Diretório de mídia de um espaço de trabalho compartilham um único limite de armazenamento, definido pelo plano do espaço de trabalho. Os arquivos enviados por esta API e pela página Diretório de mídia contam igualmente, e excluir um arquivo libera o espaço dele.
| Plano | Armazenamento de mídia |
|---|---|
| Teste grátis | 250 MB |
| Lite | 1 GB |
| Standard | 2 GB |
| Advanced | 5 GB |
| Enterprise | 10 GB |
| AppSumo Plan 1 e Plan 2 | 1 GB |
| AppSumo Plan 3 | 2 GB |
| AppSumo Plan 4 | 3 GB |
| AppSumo Plan 5 | 5 GB |
Planos antigos, e um espaço de trabalho sem plano ativo, têm 1 GB. Um upload que não cabe é recusado com Storage full: … (veja Erros). Um espaço de trabalho que já passou do limite mantém os arquivos, mas não pode adicionar novos até ter espaço para eles.
Resposta#
Uma requisição bem-sucedida retorna 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"
}
}
| Campo | Tipo | Descrição |
|---|---|---|
status | integer | 1 se o arquivo foi enviado, 0 se a requisição falhou. |
message | string | File uploaded successfully; caso contrário, o erro. |
data.id | integer | ID do arquivo de mídia. Use-o com Obter arquivo de mídia. |
data.file_name | string | Nome com o qual o arquivo é armazenado, gerado pelo WbizTool: media_, o ID do seu espaço de trabalho, o horário do upload e uma parte aleatória, com a extensão do arquivo. |
data.original_file_name | string | O nome do arquivo que você enviou. |
data.file_url | string | URL de download direto. Use-a como img_url ou file_url ao enviar. Ela é pública e não expira, mas para de funcionar quando o arquivo é excluído. Ela pode estar em media.wbiztool.com (a nossa CDN) ou em wbiztool-static.s3.ap-southeast-1.amazonaws.com; as duas entregam o mesmo arquivo, então guarde-a como está e não monte essas URLs você mesmo. |
data.file_type | string | image ou file. |
data.file_size | integer | Tamanho em bytes. |
data.file_size_display | string | Tamanho legível com uma casa decimal, por exemplo 242.5 KB. |
data.mime_type | string | Tipo MIME deduzido da extensão, por exemplo application/pdf. |
data.is_image | boolean | true quando file_type é image. |
data.file_extension | string | Extensão de original_file_name em minúsculas, sem o ponto. |
data.created_at | string | Horário do upload, em ISO 8601, em UTC, com deslocamento +00:00. |
Erros#
Os erros também retornam HTTP 200, com status igual a 0:
{ "status": 0, "message": "File is too large. Maximum size is 64MB. Your file: 71.3MB" }
| Mensagem | Como corrigir |
|---|---|
Only POST method is supported | Envie uma requisição POST. |
client_id is required | Adicione client_id como campo de formulário. Verifique se o corpo é multipart/form-data, e não JSON. |
api_key is required | Adicione api_key como campo de formulário. |
media_file is required | Envie o arquivo em um campo chamado media_file. |
client_id must be a valid integer | Envie client_id como número. |
Invalid API key | Verifique se a chave existe e não foi excluída nem desativada. |
Invalid client_id for this API key | A chave pertence a outro client_id. |
File is too large. Maximum size is 64MB. Your file: …MB | Envie um arquivo de 64 MB ou menos. |
File type not supported. Type detected: … | Use uma das extensões aceitas. |
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. | O arquivo não cabe no armazenamento de mídia do espaço de trabalho. Exclua os arquivos de que você não precisa mais na página Diretório de mídia ou fale conosco para ter mais espaço. |
Error uploading file: … | Não foi possível concluir o upload. Tente novamente. Você também recebe esta mensagem se a chave de API não estiver vinculada a um espaço de trabalho; crie uma nova chave no espaço de trabalho que você quer usar. |
Enviar o arquivo e mandar a mensagem#
Faça o upload do arquivo e depois passe file_url para Enviar mensagem: como img_url com msg_type 1 para imagens, ou como file_url com msg_type 2 para outros arquivos.
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());Todos os tipos de arquivo que esta API aceita mantêm a extensão quando são enviados com msg_type 2, por exemplo brochure.doc ou catalogue.zip. Áudios WAV e OGG chegam como documentos, e não como áudio reproduzível, e falham com File type not supported quando enviados como imagem (msg_type 1). MP3, M4A e AAC chegam como áudio que toca na conversa, com o texto como mensagem separada. Veja Enviar imagens e arquivos. O nome é enviado em letras minúsculas (Invoice-4821.PDF chega como invoice-4821.pdf).
Imagens enviadas com msg_type 1 precisam ter 16 MB ou menos. Imagens maiores são aceitas no upload aqui, mas falham no envio com File exceeds WhatsApp size limit (16MB max). Comprima-as antes ou envie-as como arquivo com msg_type 2.
Dicas#
- Reutilize os uploads. Guarde o
idou ofile_urle envie o mesmo arquivo várias vezes em vez de fazer o upload de novo. - Mantenha um nome original significativo.
original_file_nameé o que você vê no painel e um bom valor parafile_nameao enviar. - Encontre uploads anteriores com Listar mídia.
