Resumen

Última actualización: Aug 31, 2026Sección: Integraciones

Imágenes y almacenamiento de objetos

Referencia completa de la API: https://api.mailoo.app/docs/v1

Mailoo almacena imágenes propiedad del usuario en almacenamiento de objetos compatible con S3 (AWS S3, MinIO, etc.). Todo el acceso pasa por la API de Mailoo; los integradores y navegadores nunca reciben credenciales S3 ni claves de objeto internas.

Esta página es para equipos que integran funcionalidades de Mailoo (blog, formularios, chat, etc.) y necesitan entender cómo se almacenan las imágenes de artículos y otros activos del usuario y cómo leerlos de forma segura.

Resumen

  • Espacio de nombres: Cada usuario del panel obtiene un prefijo de clave dedicado users/{userId}/ en un bucket compartido (userId es el id interno del usuario de Mailoo en la base de datos, un CUID).
  • Identificador público: Los clientes usan el id de media (CUID) devuelto por la API. Las claves S3 son solo internas.
  • Inicialización: La API crea un objeto marcador interno bajo ese prefijo en la primera actividad API autenticada (idempotente). La creación se registra del lado del servidor.
  • Eliminación: Cuando se elimina una cuenta de usuario mediante la API, los objetos bajo users/{userId}/ se eliminan del almacenamiento como parte de ese flujo. Las eliminaciones de proyecto / integración / artículo encolan limpieza S3 en segundo plano para las claves de media asociadas.
  • Subida / eliminación / derivar: Flujos del panel autenticados con Bearer (mediante tu sesión / BFF). No expongas claves S3 ni credenciales del bucket a navegadores o sitios de terceros.
  • Originales vs activos de artículo: La subida permite originales más grandes (hasta 25 MiB antes del procesamiento); POST /images/derive produce copias redimensionadas / recodificadas vinculadas al mismo alcance que la fuente.
  • Validación: El tipo de archivo se verifica con bytes mágicos; la orientación EXIF se aplica y los metadatos se eliminan del lado del servidor. Los GIFs animados se rechazan.
  • URLs de embed canónicas: El markdown / HTML guardado usa URLs HTTP de Mailoo con ``?id={mediaId}`` en /api/v1/images/public/content. Los navegadores no pueden llamar a esa URL con una clave API; los integradores deben usar un proxy (ver abajo).
  • Lectura externa (clave API): GET /api/v1/images/public/content?id=… con X-API-Key y alcance image.external-read (o una clave FULL) devuelve bytes solo para media READY propiedad del usuario de la clave API.
  • ``S3_PUBLIC_BASE_URL``: Detalle interno opcional de la API solamente; no se expone en respuestas JSON y no debe usarse como el contrato público de imágenes.

Resumen de autenticación

Las rutas de imágenes del panel usan una sesión Bearer con sesión iniciada. Las lecturas de integradores usan X-API-Key con image.external-read (o FULL). Esquemas completos: https://api.mailoo.app/docs/v1.


Operación Autenticación


Listar imágenes (cursor) Bearer; projectUid / integrationId / articleId opcionales para contexto de visibilidad

Subir imagen (multipart) Bearer; campos del formulario file, scope, ids de contexto opcionales

Derivar imagen (redimensionar / formato / comprimir) Bearer; JSON sourceId y al menos uno de maxWidth, maxHeight, format

Obtener bytes de imagen (propietario) Bearer; GET /images/{id}/content

Actualizar / eliminar por id Bearer

Obtener bytes de imagen (integrador / servidor) X-API-Key con image.external-read (o FULL); id debe referirse a media READY propiedad del usuario de la clave

Modelo de seguridad (normativo)

  1. Propietario es el id de usuario de Mailoo autenticado desde JWT o clave API --- nunca un id de usuario proporcionado por el cliente.
  2. ``projectUid`` / ``integrationId`` / ``articleId`` son contexto dentro de los datos de ese propietario; la API resuelve y verifica la cadena.
  3. Las claves S3 nunca se devuelven a los clientes.
  4. Las claves API RESTRICTED deben incluir image.external-read para llamar al endpoint de lectura pública.

Alcances (visibilidad)

Los medios se almacenan con uno de los alcances USER, PROJECT, INTEGRATION o ARTICLE. La lista con contexto devuelve elementos READY visibles para ese contexto de editor.

Fotos de stock (panel de Blog)

Cada integración Blog puede almacenar sus propias claves API de Unsplash y Pexels bajo Conexión y ajustes (cifradas en integration.config.stockPhotos; nunca devueltas en texto plano). No hay claves de stock API a nivel de plataforma.

En el panel de imágenes del editor de artículos, la pestaña Stock busca con las claves de esa integración. Al elegir una foto se importan los bytes a UserMedia (mismos alcances y URLs de embed públicas que una subida normal). El seguimiento de descarga de Unsplash usa la clave de Unsplash de la integración al importar.

API del panel de control (Bearer, editor del proyecto):

  • GET /api/v1/projects/{uid}/integrations/{id}/stock/search?provider=unsplash|pexels&q=…
  • POST /api/v1/projects/{uid}/integrations/{id}/stock/import --- el cuerpo incluye provider, externalId, scope e ids de jerarquía opcionales

Referencia de la API (imágenes)

Ruta base: {apiBase}/api/v1/images.

Listar (Bearer, cursor)

GET /api/v1/images --- consulta: limit (1--100, predeterminado 24), cursor, filtros opcionales projectUid, integrationId, articleId, scope, includeNonReady=true. Respuesta: items, nextCursor, imagePublicEmbedBaseUrl.

Subir (Bearer)

POST /api/v1/images --- multipart: file, scope (USER | PROJECT | INTEGRATION | ARTICLE), más campos de contexto por alcance (projectUid, integrationId, articleId según se requiera). La respuesta incluye id, embedUrl, imagePublicEmbedBaseUrl, metadatos --- sin clave S3.

Derivar imagen (Bearer)

POST /api/v1/images/derive --- JSON: sourceId, maxWidth opcional, maxHeight, format, quality. Al menos uno de maxWidth, maxHeight o format es obligatorio.

Obtener contenido (Bearer)

GET /api/v1/images/{id}/content --- bytes sin procesar para media READY.

Redimensionamiento / transcodificación al vuelo opcional (misma pipeline sharp que derive): parámetros de consulta ``w``, ``h``, ``fit`` (inside | cover | fill, predeterminado inside), ``format`` (jpeg | jpg | png | webp), ``q`` (1--100, predeterminado 85). Al menos uno de ``w``, ``h`` o ``format`` debe estar presente para habilitar el procesamiento; de lo contrario el objeto se transmite tal como está almacenado.

Actualizar / eliminar (Bearer)

  • PATCH /api/v1/images/{id} --- JSON name, altText.
  • DELETE /api/v1/images/{id} --- eliminación de un solo media con bandeja de reintentos S3 en caso de fallo.

Obtener contenido (clave API)

GET /api/v1/images/public/content?id={mediaId} --- X-API-Key; solo para proxies del lado del servidor. Los mismos parámetros de consulta opcionales de transformación que la ruta de contenido Bearer (``w``, ``h``, ``fit``, ``format``, ``q``) aplican cuando al menos uno de ``w``, ``h`` o ``format`` está establecido.

Las variantes pregeneradas mediante ``POST /api/v1/images/derive`` siguen siendo compatibles para URLs estables (un nuevo id de media por variante).

Proxy del integrador y HTML del blog

Los payloads de artículos de la API de Blog incluyen ``imagePublicEmbedBaseUrl`` (prefijo que termina con ?id=). La respuesta de lista de artículos también repite el mismo prefijo en el nivel superior (junto a data / pagination). Las respuestas de descripción de categoría incluyen ``imagePublicEmbedBaseUrl`` en data cuando el HTML de descripción puede referenciar imágenes de Mailoo. El ``htmlContent`` almacenado usa URLs canónicas públicas absolutas bajo ``API_PUBLIC_URL``; reemplaza esas URLs en el HTML con la URL proxy de tu sitio usando el mismo id de media.

Usa ``rewriteMailooPublicImageUrls`` de ``@mailoo/images`` (también re-exportado para hosts que ya dependen de ese paquete). Consulta nextjs-packages{.interpreted-text role="doc"}.

Configuración del operador (solo API)

Establece en el host de la API (no en el navegador):


Variable Propósito


API_PUBLIC_URL Base pública de la API (sin barra final); usada para URLs de embed canónicas

S3_BUCKET Nombre del bucket (obligatorio)

S3_REGION Región (predeterminado us-east-1 si no se establece)

S3_ACCESS_KEY_ID / S3_SECRET_ACCESS_KEY Credenciales (obligatorias)

S3_ENDPOINT Endpoint personalizado para MinIO / compatible con S3 (opcional)

S3_FORCE_PATH_STYLE true para muchas configuraciones MinIO (opcional; predeterminado a path-style cuando S3_ENDPOINT está establecido)

S3_PUBLIC_BASE_URL Opcional; interno de la API solamente --- no forma parte del contrato público de integración

Estas variables pertenecen solo al despliegue de la API (nunca en el navegador).

Lecturas adicionales

  • nextjs-packages{.interpreted-text role="doc"} --- fábrica proxy @mailoo/images
  • blog-headless-cms{.interpreted-text role="doc"}
  • website-forms{.interpreted-text role="doc"}
  • OpenAPI: https://api.mailoo.app/docs/v1