CMS y webs
Sube imágenes a Webflow y usa SocialCutter
Sube el maestro a los Assets de Webflow con la API v2, llamalo con SocialCutter y usa las salidas correctas en el CMS Collection o en la pagina.
- Webflow
- API v2
- Assets
- CMS Collection
- SocialCutter
- feature image
- imagenes
El problema: un maestro, muchas medidas
Webflow te deja subir una imagen y colocarla en un CMS Collection o en el campo de imagen de una página. Lo que no hace por ti es generar la misma imagen en las medidas que pide cada red: 1200x630 para la tarjeta de Facebook, 1080x1920 para TikTok, 1200x675 para X. Si subes un solo JPG y lo reutilizas, acabas con recortes forzados o con el objeto cortado.
El flujo de esta guía sube un solo maestro a los Assets de Webflow, lo procesa con SocialCutter y usa cada salida en su sitio. Un origen, todas las medidas correctas.
Requisitos y token de sitio
Necesitas la Webflow Data API v2 (base https://api.webflow.com/v2) y un token de sitio. Créalo en Site settings → Apps & integrations → API access y activa los scopes que usaremos:
| Scope | Para qué |
|---|---|
assets:read / assets:write | Crear y leer Assets |
cms:read / cms:write | Leer y escribir items de la colección |
sites:read / sites:write | Resolver el site_id y publicar el sitio |
Los nombres exactos de los scopes se ven en la pantalla de creación del token y pueden variar entre versiones. La referencia oficial está en https://developers.webflow.com/data/reference. La API v2 sustituye a la v1 antigua: si encuentras ejemplos con /sites/{site_id}/assets sin el prefijo /v2, son de la versión retirada.
Guarda el token y el site_id en variables:
export WEBFLOW_TOKEN="tu_token_de_sitio"
export SITE_ID="tu_site_id"
export API_URL="https://api.socialcutter.theboomer.dev"
export API_KEY="sc_tu_clave"
1. Subir el maestro a los Assets
La subida en la API v2 es en dos pasos, tal como describe la referencia oficial (Upload Asset): primero se crea el registro del asset y la API devuelve una URL de subida con los detalles del formulario; después se envía el fichero en multipart a esa URL.
POST https://api.webflow.com/v2/sites/{site_id}/assets · scope assets:write
| Campo | Obligatorio | Qué es |
|---|---|---|
fileName | Sí | Nombre con extensión; menos de 100 caracteres |
fileHash | Sí | MD5 del contenido del fichero |
parentFolder | No | ID de la carpeta de Assets donde queda el fichero |
Crear el asset
curl -s -X POST "https://api.webflow.com/v2/sites/$SITE_ID/assets" \
-H "Authorization: Bearer $WEBFLOW_TOKEN" \
-H "accept-version: 2.0.0" \
-H "Content-Type: application/json" \
-d '{
"fileName": "maestro.jpg",
"fileHash": "hash_md5_del_fichero",
"parentFolder": "id_de_la_carpeta"
}' > asset.json
jq '{id, contentType, uploadUrl, assetUrl, hostedUrl, parentFolder}' asset.json
La respuesta 200 trae, entre otros, estos campos:
| Campo | Qué es |
|---|---|
id | Identificador del asset; el que usarás después para leerlo o cambiar su texto alternativo |
uploadUrl | URL temporal prefirmada de Amazon S3 a la que se envía el binario |
uploadDetails | Metadatos para subir el binario: los campos del formulario que hay que mandar junto al fichero |
assetUrl | Enlace del asset en S3 |
hostedUrl | Enlace del asset, el que se usa para referenciarlo |
parentFolder | Carpeta destino del asset |
contentType, originalFileName, createdOn, lastUpdated | Tipo, nombre original y fechas |
La documentación lo dice explícito: hay que usar uploadUrl y uploadDetails en la petición POST a S3 para completar la subida. Esa URL la emite Webflow; SocialCutter no aloja tu fichero.
El fileHash es el MD5 del contenido del fichero: se calcula con md5sum maestro.jpg (en macOS, md5 -q maestro.jpg). Webflow lo usa para evitar duplicados: si el hash coincide con el de un fichero que ya existe, no lo guarda otra vez. Si no coincide, la subida falla con 400. parentFolder es el ID de la carpeta de Assets y es opcional.
Crear la carpeta destino (opcional)
Si quieres que los assets no caigan en la raíz del panel, crea antes la carpeta:
curl -s -X POST "https://api.webflow.com/v2/sites/$SITE_ID/asset_folders" \
-H "Authorization: Bearer $WEBFLOW_TOKEN" \
-H "accept-version: 2.0.0" \
-H "Content-Type: application/json" \
-d '{ "displayName": "SocialCutter" }' > folder.json
jq '{id, displayName, parentFolder}' folder.json
El endpoint es POST /v2/sites/{site_id}/asset_folders (scope assets:write) y acepta displayName (obligatorio) y parentFolder (opcional, para anidar carpetas). Guarda el id que devuelve y pásalo como parentFolder al crear el asset.
Subir el fichero
Los campos de uploadDetails hay que enviarlos tal cual, junto al fichero, a la uploadUrl:
UPLOAD_URL=$(jq -r '.uploadUrl' asset.json)
jq -r '.uploadDetails | to_entries[] | "\(.key)=\(.value)"' asset.json > fields.txt
curl -s -X POST "$UPLOAD_URL" \
$(while IFS= read -r line; do printf -- "-F %s " "$line"; done < fields.txt) \
-F "file=@./maestro.jpg" > upload.json
No inventes los nombres de los campos: vienen en uploadDetails y cambian según el tipo de asset. Envía exactamente los que devuelva la API.
Límite de tamaño: las imágenes de Webflow no pueden superar 4 MB (los documentos, 10 MB), según la guía Working with Assets. El maestro que acepta SocialCutter llega a 5 MB, así que un maestro grande puede no entrar directamente en los Assets: genéralo antes con SocialCutter, que devuelve salidas mucho más ligeras, o redúcelo.
Comprobar que el asset ha quedado bien
GET https://api.webflow.com/v2/assets/{asset_id} (scope assets:read) devuelve el detalle del asset ya subido:
curl -s "https://api.webflow.com/v2/assets/$ASSET_ID" \
-H "Authorization: Bearer $WEBFLOW_TOKEN" \
-H "accept-version: 2.0.0" \
| jq '{id, hostedUrl, contentType, size, originalFileName, altText}'
Los campos que sirven para verificar: hostedUrl (el enlace real, el que pasarás a SocialCutter), contentType (tipo de fichero), size (tamaño en bytes), originalFileName, altText y variants (las variantes responsive que genera Webflow para servir la imagen). Si hostedUrl no carga al abrirlo, la subida a uploadUrl no se completó: repite el POST con los campos de uploadDetails y el fichero.
El mismo detalle se puede listar por carpeta. Ojo: el campo folderId solo aparece en las respuestas de listado, no al consultar un asset suelto. El listado acepta folderId (ObjectId hexadecimal de 24 caracteres) y paginación con limit (máximo 100) y offset:
curl -s "https://api.webflow.com/v2/sites/$SITE_ID/assets?folderId=$FOLDER_ID&limit=100" \
-H "Authorization: Bearer $WEBFLOW_TOKEN" \
-H "accept-version: 2.0.0" \
| jq '.assets[] | {id, hostedUrl, size, folderId, altText}'
El texto alternativo y el nombre visible se cambian con PATCH https://api.webflow.com/v2/assets/{asset_id} (scope assets:write), enviando altText y/o displayName.
2. Llamar a SocialCutter con la URL del asset
Cuando el maestro está en los Assets, su hostedUrl es el origen para SocialCutter:
curl -s -X POST "$API_URL/api/v1/images/process" \
-H "X-API-Key: *** \
-H "Content-Type: application/json" \
-d "{
\"source\": { \"type\": \"url\", \"value\": \"$(jq -r '.hostedUrl' asset.json)\" },
\"destinations\": [
{ \"platform\": \"facebook\", \"format\": \"link\" },
{ \"platform\": \"instagram\", \"format\": \"post\" },
{ \"platform\": \"twitter\", \"format\": \"summary_large_image\" }
]
}" > sc.json
jq '.image_id, (.outputs[] | {url, platform, format, width, height})' sc.json
Cada elemento de outputs trae la URL de la salida, su plataforma, su formato y sus medidas. El recorte de cover (por defecto) es centrado.
3. Publicar el sitio
Los Assets nuevos y los items creados no se ven en el sitio publicado hasta que lo publiques:
curl -s -X POST "https://api.webflow.com/v2/sites/$SITE_ID/publish" \
-H "Authorization: Bearer $WEBFLOW_TOKEN" \
-H "accept-version: 2.0.0" \
-H "Content-Type: application/json" \
-d '{ "publishToWebflowSubdomain": true, "customDomains": ["tu-dominio.com"] }'
Ajusta customDomains a los dominios reales del proyecto.
4. Usar las salidas en el CMS Collection
Si el CMS Collection tiene un campo de imagen, hay dos caminos: subir cada salida como Asset (repitiendo el paso 1) y referenciar su id, o pasar la URL directamente si tu campo lo admite. Consulta el esquema de la colección antes de construir el item:
# Lista de colecciones
curl -s "https://api.webflow.com/v2/sites/$SITE_ID/collections" \
-H "Authorization: Bearer $WEBFLOW_TOKEN" \
-H "accept-version: 2.0.0" | jq '.collections[] | {id, slug}'
# Esquema de una coleccion (campos y tipos)
curl -s "https://api.webflow.com/v2/collections/$COLLECTION_ID" \
-H "Authorization: Bearer $WEBFLOW_TOKEN" \
-H "accept-version: 2.0.0" | jq '.fields[] | {slug, type}'
Crea el item en vivo con el valor del campo de imagen tomado de outputs[0].url:
curl -s -X POST "https://api.webflow.com/v2/collections/$COLLECTION_ID/items/live" \
-H "Authorization: Bearer $WEBFLOW_TOKEN" \
-H "accept-version: 2.0.0" \
-H "Content-Type: application/json" \
-d "{
\"fieldData\": {
\"name\": \"Entrada de ejemplo\",
\"slug\": \"entrada-de-ejemplo\",
\"imagen\": \"$(jq -r '.outputs[0].url' sc.json)\"
}
}"
El nombre real del campo de imagen es el slug que devuelve el esquema, no tiene por qué llamarse imagen.
5. Usar las salidas como imágenes de página
Para una imagen suelta en una página, sube la salida a los Assets y usa su URL en el HTML. En la práctica, el patrón más limpio es: subir el maestro, procesar con SocialCutter y subir cada salida una vez, guardando su hostedUrl para referenciarla desde el CMS o desde las páginas.
Ahí está la ventaja del orden: el fichero que subes a los Assets ya viene generado por SocialCutter en la proporción del destino (1080x1080 para instagram post, 1200x627 para linkedin post), con recorte centrado. Webflow solo lo aloja y genera sus variantes responsive, así que el CDN sirve ficheros que ya están en la medida correcta y no versiones recortadas del maestro original.
Coste
- 1 uso por destino (combinación de plataforma y formato) por petición.
- Destinos repetidos en la misma petición no se cobran dos veces.
- Los procesamientos fallidos se devuelven.
Errores típicos
| Situación | Causa probable |
|---|---|
| 401 en Webflow | Token ausente, mal formado o sin el scope necesario (assets:write para crear el asset) |
| 400 al crear el asset | fileHash no coincide con el MD5 del fichero, o fileName supera los 100 caracteres |
El asset queda vacío o hostedUrl no carga | No se completó el POST a uploadUrl con los campos de uploadDetails |
| La imagen no aparece | Falta publicar el sitio o el item está en borrador |
| 401 en SocialCutter | Clave sc_ mal formada o revocada |
| 413 en SocialCutter | El maestro supera 5 MB |
| El maestro no sube a Webflow | Supera el límite de 4 MB por imagen de Webflow |
| 429 en SocialCutter | Cuota del monedero agotada |
| Campo de imagen vacío | El slug del campo no es el que creías: revisa el esquema |
| Un asset aparece duplicado o no aparece | Webflow usa el fileHash para no repetir ficheros con el mismo MD5 |
Siguientes pasos
- Guía de WordPress: Publica las medidas correctas en WordPress
- Guía de Shopify: Imágenes de producto y blog en Shopify
- Automatización: Orquesta el flujo con n8n
- API desde la terminal: Procesa imágenes con curl
- Referencia oficial de Webflow: https://developers.webflow.com/data/reference
Preguntas frecuentes
¿Qué permisos necesita el token de sitio de Webflow?
Un token de sitio creado en Site settings → Apps & integrations → API access. Para este flujo activa los scopes de assets (lectura y escritura), cms (lectura y escritura) y sites (lectura y escritura para poder publicar). Revisa los nombres exactos en la pantalla de creación, que cambian entre versiones.
¿Qué devuelve el endpoint que crea el asset?
La respuesta 200 trae id, uploadUrl (URL prefirmada de Amazon S3 para el binario), uploadDetails (los campos del formulario de subida), assetUrl (enlace del asset en S3), hostedUrl (enlace del asset), parentFolder y datos como contentType, originalFileName y createdOn.
¿Para qué sirve parentFolder al crear el asset?
Es opcional y es el ID de la carpeta de Assets en la que queda el fichero. Las carpetas se crean con POST /v2/sites/{site_id}/asset_folders, que acepta displayName y un parentFolder opcional, y devuelve su id.
¿Cómo compruebo que el asset se ha subido bien?
Con GET /v2/assets/{asset_id}, que devuelve hostedUrl, contentType, size en bytes, originalFileName y altText. Si hostedUrl no responde, el POST a uploadUrl no se completó con los campos de uploadDetails.
¿Hay un límite de tamaño al subir la imagen a Webflow?
Sí: las imágenes de Webflow no pueden superar 4 MB y los documentos 10 MB. La API de SocialCutter acepta maestros de hasta 5 MB, así que un maestro grande puede no entrar directamente en Assets: pásalo antes por SocialCutter, cuyas salidas pesan mucho menos, o redúcelo.
¿Puedo usar la URL del asset de Webflow como origen en SocialCutter?
Sí. Tras subir el maestro, la API devuelve su hostedUrl; pasa esa URL como source en POST /api/v1/images/process y SocialCutter descargará el fichero desde ahí.
¿Hace falta publicar el sitio para que el CMS Collection muestre las imagenes?
Los items creados en la colección con el endpoint en vivo y el sitio publicado con POST /sites/{site_id}/publish quedan visibles. Si solo creas items en borrador, no aparecen hasta publicarlos.
¿Cuánto cuesta procesar la imagen?
1 uso por destino, es decir por cada combinación de plataforma y formato que pidas. Los destinos repetidos en la misma petición no se cobran dos veces y los fallos se devuelven.