Saltar al contenido

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

  1. Pedí el token con POST /login y mandalo en el header Authorization de todas las llamadas.
  2. 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, en messages[].audio.id.
  3. Descargá el archivo con GET /{version}/{id}/{did}/media y guardalo con la extensión que corresponde al Content-Type de 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.ogg

Si 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

  1. Pedí el token con POST /login.
  2. Subí el archivo con POST /{version}/{did}/uploads, multipart con el part file.
  3. La respuesta es {"h": "4::..."}. Ese valor es el header_handle del 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ámetroTipoRequeridoDescripción
versionStringSíVersión de Graph API de Meta. Se reenvía tal cual.
idStringSíID de la media.
didStringSíIdentificador del canal.
El orden de los argumentos es {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

ValorOrigen en el payload inbound
identry[].changes[].value.messages[].audio.id (igual para image.id, document.id, video.id y sticker.id).
didentry[].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.ogg

El --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.ogg

Response

É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ódigoCaso
401Token inválido o con permisos insuficientes.
MetaLos 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....
Un 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ámetroTipoRequeridoDescripción
versionStringSíVersión de Graph API de Meta. Se reenvía tal cual.
didStringSíIdentificador del canal.

Body (multipart/form-data)

CampoTipoRequeridoDescripción
fileFileSí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ódigoCaso
400Falta el part file en el formulario multipart: {"message":"file require"}.
401Token inválido o con permisos insuficientes.
MetaLos 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ámetroTipoRequeridoDescripción
versionStringSíVersión de Graph API de Meta. Se reenvía tal cual.
didStringSíIdentificador del canal.
media_idStringSí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ódigoCaso
401Token inválido o con permisos insuficientes.
MetaLos errores de Meta se reenvían tal cual, con su código de estado y su cuerpo.