API Cloud (MEDIA)
La API de media permite descargar, subir y eliminar archivos multimedia de WhatsApp. Todas las rutas comparten la base https://channels.chattigo.com/bsp-cloud-chattigo-isv y el header de autenticación Authorization: <JWT> (el JWT en crudo, sin prefijo Bearer ni Basic), obtenido en POST /login.
{version} lo elige el cliente y se reenvía a Meta tal cual: la versión de Graph API la gestiona Meta, por lo que no debe fijarse.
Esta página documenta las rutas actuales de media, GET /{version}/{id}/{did}/media para la descarga y POST /{version}/{did}/uploads para la subida. La forma corregida tiene su propia página: Media v2.
Cómo se conecta con el resto de la API
Descargar la media de un mensaje entrante
- Pedí el token con
POST /loginy mandalo en el headerAuthorizationde todas las llamadas. - Tu webhook recibe el payload del mensaje entrante. De ahí salen los dos datos que necesita la ruta: el canal, en
metadata.display_phone_number, y el identificador de la media, enmessages[].audio.id. - Descargá el archivo con
GET /{version}/{id}/{did}/mediay guardalo con la extensión que corresponde alContent-Typede la respuesta.
curl --request POST \
--url 'https://channels.chattigo.com/bsp-cloud-chattigo-isv/login' \
--header 'Content-Type: application/json' \
--data '{"username": "<user>", "password": "<password>"}'curl --fail --request GET \
--url 'https://channels.chattigo.com/bsp-cloud-chattigo-isv/{version}/980301304349102/5492646715777/media' \
--header 'Authorization: <JWT>' \
--output audio.oggSi querés liberar esa media en Meta, la eliminás con DELETE /{version}/{did}/media/{media_id}.
Subir un archivo y usarlo en una plantilla
- Pedí el token con
POST /login. - Subí el archivo con
POST /{version}/{did}/uploads, multipart con el partfile. - La respuesta es
{"h": "4::..."}. Ese valor es elheader_handledel header de media cuando creás o editás una plantilla, como se explica en Templates.
curl --request POST \
--url 'https://channels.chattigo.com/bsp-cloud-chattigo-isv/{version}/{did}/uploads' \
--header 'Authorization: <JWT>' \
-F 'file=@/ruta/archivo.jpg'Para enviar una media dentro de un mensaje se usa una URL pública en link, no el handle: consultá Messages.
Descargar media
GET /{version}/{id}/{did}/media
Descarga el cuerpo binario de una media de WhatsApp. Reenvía los headers de Meta tal cual, así que el Content-Type, el Content-Length y, cuando Meta lo envía, el Content-Disposition, son los que Meta devuelva.
Parámetros
Path
| Parámetro | Tipo | Requerido | Descripción |
|---|---|---|---|
version | String | Sí | Versión de Graph API de Meta. Se reenvía tal cual. |
id | String | Sí | ID de la media. |
did | String | Sí | Identificador del canal. |
{id} primero y {did} segundo. Invertirlos es el error de integración más común: la descarga falla aunque ambos identificadores existan.Identificadores en el webhook
| Valor | Origen en el payload inbound |
|---|---|
id | entry[].changes[].value.messages[].audio.id (igual para image.id, document.id, video.id y sticker.id). |
did | entry[].changes[].value.metadata.display_phone_number, el mismo valor que la documentación llama waId en PATCH /webhooks/inbound. |
El identificador de canal que usa esta API es el número de teléfono, no el phone_number_id de Meta.
Request
GET /{version}/{id}/{did}/media
curl --fail --request GET \
--url 'https://channels.chattigo.com/bsp-cloud-chattigo-isv/{version}/{id}/{did}/media' \
--header 'Authorization: <JWT>' \
--output audio.oggEl --output audio.ogg del ejemplo es el nombre con el que guardás vos, no un dato que debas conocer de antemano; la extensión puede derivarse del Content-Type de la respuesta. --fail evita que un cuerpo de error se guarde como si fuera la media. Si preferís que curl use el nombre que sugiere la respuesta, reemplazá --output audio.ogg por --remote-header-name --remote-name.
Por ejemplo, este webhook inbound muestra los campos que usa esta ruta para el mensaje de audio:
{
"object": "whatsapp_business_account",
"entry": [
{
"id": "102290129340398",
"changes": [
{
"field": "messages",
"value": {
"messaging_product": "whatsapp",
"metadata": {
"display_phone_number": "5492646715777",
"phone_number_id": "106540352242922"
},
"messages": [
{
"from": "5491122334455",
"id": "wamid.HBgNNTQ5MjY0NjcxNTc3NxUCABIYFj",
"timestamp": "1758552655",
"type": "audio",
"audio": {
"id": "980301304349102",
"mime_type": "audio/ogg; codecs=opus"
}
}
]
}
}
]
}
]
}la descarga se realiza con id = 980301304349102 y did = 5492646715777:
curl --fail --request GET \
--url 'https://channels.chattigo.com/bsp-cloud-chattigo-isv/{version}/980301304349102/5492646715777/media' \
--header 'Authorization: <JWT>' \
--output audio.oggResponse
Éxito (200)
Devuelve el cuerpo binario de la media con los headers que envía Meta, reenviados tal cual: Content-Type, Content-Length y, cuando Meta lo envía, Content-Disposition.
Errores
| Código | Caso |
|---|---|
401 | Token inválido o con permisos insuficientes. |
| Meta | Los errores de Meta se reenvían tal cual, con su código de estado y su cuerpo. Para una media que no existe, expiró o no es accesible, Meta responde 404 con Unsupported get request. Object with ID '<id>' does not exist, cannot be loaded due to missing permissions, or does not support this operation.... |
404 con el cuerpo en texto plano 404 page not found no proviene de Meta: significa que la URL no coincide con ninguna ruta registrada y ningún handler procesó la petición. Verifica que la ruta sea /{version}/{id}/{did}/media, con {id} primero y {did} segundo.Subir media
POST /{version}/{did}/uploads
Sube un archivo a Meta con el flujo de upload resumible. El resultado es el file handle que se usa como header_handle en el header de media de una plantilla, como se explica en Templates.
Parámetros
Path
| Parámetro | Tipo | Requerido | Descripción |
|---|---|---|---|
version | String | Sí | Versión de Graph API de Meta. Se reenvía tal cual. |
did | String | Sí | Identificador del canal. |
Body (multipart/form-data)
| Campo | Tipo | Requerido | Descripción |
|---|---|---|---|
file | File | Sí | Archivo a subir. |
Request
POST /{version}/{did}/uploads
curl --request POST \
--url 'https://channels.chattigo.com/bsp-cloud-chattigo-isv/{version}/{did}/uploads' \
--header 'Authorization: <JWT>' \
-F 'file=@/ruta/archivo.jpg'Response
Éxito (200)
{
"h": "4::aW1hZ2............."
}Errores
| Código | Caso |
|---|---|
400 | Falta el part file en el formulario multipart: {"message":"file require"}. |
401 | Token inválido o con permisos insuficientes. |
| Meta | Los errores de Meta se reenvían tal cual, con su código de estado y su cuerpo. |
Eliminar media
DELETE /{version}/{did}/media/{media_id}
Elimina un asset de media en Meta.
Parámetros
Path
| Parámetro | Tipo | Requerido | Descripción |
|---|---|---|---|
version | String | Sí | Versión de Graph API de Meta. Se reenvía tal cual. |
did | String | Sí | Identificador del canal. |
media_id | String | Sí | ID de la media a eliminar. |
Request
DELETE /{version}/{did}/media/{media_id}
curl --request DELETE \
--url 'https://channels.chattigo.com/bsp-cloud-chattigo-isv/{version}/{did}/media/{media_id}' \
--header 'Authorization: <JWT>'Response
Éxito (200)
{
"success": true
}Errores
| Código | Caso |
|---|---|
401 | Token inválido o con permisos insuficientes. |
| Meta | Los errores de Meta se reenvían tal cual, con su código de estado y su cuerpo. |