Saltar al contenido principal
Actualizado el Oct 25, 2026

Subir archivos (API y MCP)

Lo que aprenderás
  • Cómo subir una imagen o archivo de forma programática y obtener una referencia reutilizable
  • El flujo de subida REST en dos pasos (y la herramienta MCP de un paso)
  • Dónde usar la referencia {bucket, fullPath} resultante

Muchas funciones de AutoTalk usan medios — una imagen de producto para un catálogo de WhatsApp, un mensaje multimedia, una foto de perfil. En lugar de alojar esos archivos por tu cuenta, súbelos a AutoTalk una vez y obtén una referencia de almacenamiento propia que puedes reutilizar en todas partes:

{ "bucket": "autotalk-prod", "fullPath": "companies/<id>/api/images/storage_manual_upload/<id>.png" }

Esa referencia {bucket, fullPath} es aceptada por send_message, campos de documentos Dynadata y funciones como createWhatsappWebEvoProduct (en su array images) — consulta Dónde usar la referencia.

REST: la subida en dos pasos​

La subida por la API REST es un PUT firmado, de modo que los bytes van directo al almacenamiento. Autentica cada llamada con tu x-api-key.

1. Reserva una URL de subida firmada​

curl -X POST https://api.autotalk.io/v1/storage/upload-url \
-H "x-api-key: sk-YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"mimeType": "image/png",
"fileSize": 41161,
"fileName": "product.png",
"purpose": "whatsapp_catalog_product_image"
}'

La respuesta te da una uploadUrl de corta duración, los requiredHeaders exactos y un uploadIntentId:

{
"success": true,
"uploadIntentId": "...",
"uploadUrl": "https://storage.autotalk.io/...&X-Amz-Signature=...",
"uploadMode": "signed_put",
"bucket": "autotalk-prod",
"fullPath": "companies/<id>/api/images/whatsapp_catalog_product_image/<id>.png",
"category": "images",
"requiredHeaders": { "Content-Type": "image/png", "Content-Length": "41161", "x-amz-meta-...": "..." }
}

2. Haz el PUT de los bytes​

Sube el archivo directamente a uploadUrl, enviando todas las entradas de requiredHeaders exactamente como se indican. El tamaño del cuerpo debe coincidir con fileSize.

curl -X PUT "<uploadUrl>" \
-H "Content-Type: image/png" \
-H "Content-Length: 41161" \
--data-binary @product.png

3. Finaliza​

curl -X POST https://api.autotalk.io/v1/storage/upload-complete \
-H "x-api-key: sk-YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{ "uploadIntentId": "<uploadIntentId>" }'

La respuesta es tu referencia reutilizable:

{ "success": true, "bucket": "autotalk-prod", "fullPath": "companies/<id>/api/images/whatsapp_catalog_product_image/<id>.png", "size": 41161, "contentType": "image/png", "category": "images", "fileName": "product.png" }

Archivos grandes: subida por partes​

Un solo PUT admite como máximo 90 MB. Para un archivo de entre 90 MB y 1 GB, añade "multipart": true a la petición del paso 1. Sin eso, un archivo de más de 90 MB se rechaza con 400 y un mensaje que te pide añadir la flag. La respuesta trae entonces "uploadMode": "multipart_put", "uploadUrl": null y una lista parts en lugar de una sola URL:

{
"success": true,
"uploadIntentId": "...",
"uploadMode": "multipart_put",
"uploadUrl": null,
"partSize": 67108864,
"parts": [
{ "partNumber": 1, "offset": 0, "size": 67108864, "uploadUrl": "https://storage.autotalk.io/...&partNumber=1&...", "requiredHeaders": { "Content-Length": "67108864" } },
{ "partNumber": 2, "offset": 67108864, "size": 32891136, "uploadUrl": "https://storage.autotalk.io/...&partNumber=2&...", "requiredHeaders": { "Content-Length": "32891136" } }
],
"expiresAtMs": 1760000000000,
"bucket": "autotalk-prod",
"fullPath": "companies/<id>/api/documents/storage_manual_upload/<id>.pdf",
"category": "documents"
}

Para cada parte, haz el PUT de los bytes desde offset hasta offset + size (sin incluirlo) a la uploadUrl de esa parte. Envía sus requiredHeaders y ningún Content-Type: el tipo ya quedó fijado al reservar la subida. Las partes pueden ir en cualquier orden, y una parte que falló puede reenviarse a la misma URL. Todas las partes deben enviarse antes de expiresAtMs, 60 minutos después de la reserva.

Luego llama a upload-complete como en el paso 3. AutoTalk comprueba que cada parte llegó con su tamaño exacto y las une en un solo archivo.

  • Si todavía faltan partes, upload-complete devuelve 409 y la subida sigue abierta. Envía las partes que faltan y vuelve a llamarlo.
  • Si abandonas la subida, caduca a los 60 minutos. Sus partes se descartan y la reserva de cuota se libera.

Para leer un objeto almacenado más tarde, llama a GET /v1/storage/url?path=<fullPath>. Devuelve una URL de descarga firmada válida hasta 7 días — la expiración se fija al inicio del día UTC, así que el enlace dura al menos 6 días desde el momento en que lo generas — y servida con public, max-age=3600, lo que la hace cacheable en el borde de una CDN. Trata la propia cadena de la URL como una credencial portadora durante toda esa ventana: cualquiera que la tenga puede descargar el objeto sin autenticarse, así que no la registres en logs, no la pegues en tickets ni la reenvíes.

MCP: begin/complete o inline en un paso​

Si te conectas mediante el servidor MCP, usa las herramientas de archivo:

  • begin_file_upload({fileName, mimeType, fileSize}) → haz el PUT HTTP a la uploadUrl devuelta → complete_file_upload({uploadIntentId}). Devuelve {bucket, fullPath}. Acepta archivos de hasta 1 GB. Por encima de 90 MB la herramienta responde con uploadMode: "multipart_put" y una lista parts: haz el PUT de cada parte como se describe en Archivos grandes: subida por partes y luego llama a complete_file_upload. Esta herramienta no necesita ninguna flag.
  • upload_file_inline({fileName, mimeType, data}) — pasa los bytes codificados en base64 directamente y obtén {bucket, fullPath} en una sola llamada. Práctico para archivos pequeños (≤ ~1 MB); los archivos más grandes deben usar el flujo en dos pasos.

Dónde usar la referencia​

Pasa {bucket, fullPath} (o, para images, una URL pública o la referencia) donde se acepten medios:

  • Enviar un mensaje multimedia — send_message body.file = {bucket, fullPath}.
  • Catálogo de WhatsApp — createWhatsappWebEvoProduct / updateWhatsappWebEvoProduct images: [{bucket, fullPath}, ...].
  • Foto de perfil / grupo — updateWhatsappWebEvoProfilePicture picture, updateWhatsappWebEvoGroupPicture image.
  • Campos de documento Dynadata — cualquier campo de objeto de almacenamiento (por ejemplo, la imagen de un documento).

Propósitos y límites​

  • purpose (opcional, por defecto storage_manual_upload) indica para qué es el archivo. Valores permitidos: storage_manual_upload, whatsapp_catalog_product_image, template_message_media, chat_media_upload, scheduled_message_media, contact_avatar, company_logo.
  • fileSize puede llegar a 1 GB. Un PUT lleva como máximo 90 MB, porque cada petición tiene que atravesar entera la CDN que hay delante del almacenamiento de AutoTalk. Por eso los archivos de más de 90 MB se suben por partes, cada una por debajo de ese límite. POST /v1/storage/upload-url necesita "multipart": true para esos archivos; begin_file_upload pasa a partes por su cuenta. Una petición de más de 1 GB se rechaza de inmediato con un error claro. Envía el número exacto de bytes; el tamaño almacenado debe coincidir con él.
  • Los bytes subidos cuentan para la cuota de almacenamiento de tu empresa; una subida que la superaría devuelve 409.
  • Los archivos viven bajo el prefijo de tu empresa; solo puedes referenciar objetos de tu propio inquilino (tenant).

Próximos pasos​