API v2 (beta)
Medios
El Directorio de medios guarda los archivos de tu espacio de trabajo: listas de precios, menús, folletos, fotos de productos. Sube un archivo una vez y luego envíalo tantas veces como quieras con "media": {"media_id": …} en un mensaje o un recordatorio. Es el mismo directorio que la página Directorio de medios del panel, así que los archivos subidos allí también aparecen aquí.
| Operación | Endpoint | Permiso |
|---|---|---|
| Subir un archivo | POST /api/v2/media | media |
| Listar archivos | GET /api/v2/media | media |
| Obtener un archivo | GET /api/v2/media/{id} | media |
| Eliminar un archivo | DELETE /api/v2/media/{id} | media |
Subir un archivo#
https://wbiztool.com/api/v2/mediaCuerpo: multipart/form-data
Envía un archivo por solicitud como multipart/form-data, en el campo file. Es el único endpoint de v2 que no acepta JSON. La respuesta es 201 con el objeto Media.
- Hasta 64 MB por archivo.
- Tipos: el tipo se deduce de la extensión al final del nombre del archivo, así que no la quites.
| Clase | Extensiones |
|---|---|
| Imágenes | .jpg, .jpeg, .jpe, .png, .gif, .webp, .bmp |
| Documentos | .pdf, .doc, .docx, .xls, .xlsx, .ppt, .pptx, .csv, .txt |
| Audio | .mp3, .m4a, .wav, .ogg, .oga, .aac |
| Vídeo | .mp4, .mov, .avi |
| Archivos comprimidos | .zip, .rar |
- Almacenamiento: todos los archivos del espacio de trabajo juntos pueden ocupar lo que permite su plan, de 250 MB a 10 GB (consulta Almacenamiento por plan). Un archivo que no cabe se rechaza con
storage_full. - Un archivo de imagen (
typeimage) se envía como imagen por defecto; cualquier otro, como archivo. - Envía una
Idempotency-Keypara que un reintento después de un tiempo de espera agotado no guarde el archivo dos veces.
curl -X POST https://wbiztool.com/api/v2/media \
-H "Authorization: Bearer $WBIZTOOL_API_KEY" \
-H "Idempotency-Key: price-list-2026-10" \
-F "file=@./price list.pdf"import os
import requests
with open("price list.pdf", "rb") as f:
response = requests.post(
"https://wbiztool.com/api/v2/media",
headers={"Authorization": f"Bearer {os.environ['WBIZTOOL_API_KEY']}"},
files={"file": ("price list.pdf", f, "application/pdf")},
timeout=120,
)
media = response.json()
print(response.status_code, media.get("id"), media.get("url"))// 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("file", await openAsBlob("./price list.pdf"), "price list.pdf");
// Don't set Content-Type yourself; fetch adds the multipart boundary.
const response = await fetch("https://wbiztool.com/api/v2/media", {
method: "POST",
headers: { Authorization: `Bearer ${process.env.WBIZTOOL_API_KEY}` },
body: form,
});
const media = await response.json();
console.log(response.status, media.id, media.url);<?php
$ch = curl_init('https://wbiztool.com/api/v2/media');
curl_setopt_array($ch, [
CURLOPT_POST => true,
CURLOPT_HTTPHEADER => ['Authorization: Bearer ' . getenv('WBIZTOOL_API_KEY')],
// An array body makes cURL send multipart/form-data.
CURLOPT_POSTFIELDS => ['file' => new CURLFile('/path/to/price list.pdf', 'application/pdf', 'price list.pdf')],
CURLOPT_RETURNTRANSFER => true,
CURLOPT_TIMEOUT => 120,
]);
$media = json_decode(curl_exec($ch), true);
curl_close($ch);
echo $media['id'] . ' ' . $media['url'];Respuesta (201):
{
"id": 3301,
"name": "price list.pdf",
"type": "file",
"mime_type": "application/pdf",
"size": 182344,
"url": "https://media.wbiztool.com/media/org_5012/media_5012_17608123450000_0.pdf",
"created_at": "2026-10-18T10:31:40.120Z"
}
Después, envíalo:
{
"to": { "phone": "+919876543210" },
"text": "Here is our new price list.",
"media": { "media_id": 3301 }
}
El destinatario ve el nombre con el que se subió (price list.pdf); indica media.file_name en el mensaje para mostrar otro.
Errores al subir#
| HTTP | Código | Cuándo |
|---|---|---|
400 | validation_failed | No hay ningún archivo en el campo file, o hay más de uno |
413 | file_too_large | El archivo supera los 64 MB |
415 | unsupported_file_type | La extensión no es uno de los tipos anteriores |
415 | unsupported_content_type | La solicitud no es multipart/form-data (por ejemplo, es JSON) |
422 | storage_full | El archivo no cabe en el almacenamiento del plan; used y limit indican cuánto, en bytes |
502 | upload_failed | No se pudo guardar el archivo. Inténtalo de nuevo (con la misma Idempotency-Key) |
Listar archivos#
https://wbiztool.com/api/v2/mediaLos archivos del espacio de trabajo, primero los más recientes, en páginas (limit de 1 a 100, 25 por defecto, y cursor).
curl "https://wbiztool.com/api/v2/media?limit=100" \
-H "Authorization: Bearer $WBIZTOOL_API_KEY"
La respuesta es {"data": [Media, …], "next_cursor": "…" or null}.
Obtener un archivo#
https://wbiztool.com/api/v2/media/{id}curl https://wbiztool.com/api/v2/media/3301 \
-H "Authorization: Bearer $WBIZTOOL_API_KEY"
Un archivo que no existe o que se eliminó responde 404 media_not_found.
Eliminar un archivo#
https://wbiztool.com/api/v2/media/{id}Elimina el archivo del Directorio de medios y del almacenamiento, así que su url deja de funcionar. Los mensajes ya enviados conservan su copia en el teléfono del destinatario.
Se rechaza mientras algo vaya a enviar todavía el archivo: un mensaje que espera para salir (también los de una campaña), un recordatorio activo o un disparador activo de Google Sheets. En ese caso la respuesta es 409 media_in_use, y count indica cuántos hay. Cancélalos o cámbialos antes, o espera a que los mensajes hayan salido.
curl -X DELETE https://wbiztool.com/api/v2/media/3301 \
-H "Authorization: Bearer $WBIZTOOL_API_KEY"
{ "id": 3301, "deleted": true }
| HTTP | Código | Cuándo |
|---|---|---|
404 | media_not_found | No existe ese archivo |
409 | media_in_use | Todavía lo usa un mensaje en espera, un recordatorio activo o un disparador de Google Sheets |
El objeto Media#
| Campo | Tipo | Descripción |
|---|---|---|
id | integer | El ID del archivo: el media_id con el que se envía. |
name | string | El nombre con el que se subió. |
type | string | image para los archivos de imagen, file para todo lo demás. |
mime_type | string | Como application/pdf o image/jpeg. |
size | integer | Tamaño en bytes. |
url | string | Un enlace público al archivo. Cualquiera que tenga el enlace puede abrirlo, así que no subas archivos que deban seguir siendo privados. |
created_at | string | Cuándo se subió. |
Relacionado#
- Directorio de medios en el panel
- Mensajes → Medios: enviar con
media_ido con un enlace - Errores
