# Integra SocialCutter con WordPress y WooCommerce
> Sube el maestro a la biblioteca de medios por REST API, procesalo con SocialCutter y asigna la salida correcta como imagen destacada y en el contenido.
- URL: https://socialcutter.theboomer.dev/guias/wordpress/
- Idioma: es
- Familia: cms
- Actualizado: 2026-09-24
- Palabras clave: WordPress, WooCommerce, REST API, Application Passwords, imagen destacada, biblioteca de medios, PHP
## Por qué una sola imagen maestra

Un blog con ficha de producto necesita la misma foto en varios sitios: imagen destacada, imagen dentro del texto, tarjeta social y galería. Cada hueco pide una proporción distinta.

El flujo es: **subes un solo maestro, SocialCutter devuelve cada medida y WordPress recibe la que toca en cada hueco**. El recorte de `cover` (el modo por defecto) es **centrado**: escala la imagen y recorta el exceso por igual a los dos lados.

| Uso en WordPress | Destino SocialCutter | Medida |
|---|---|---|
| Imagen destacada de un post | `linkedin` `post` | 1200x627 (1.91:1) |
| Imagen dentro del contenido | `facebook` `post` | 1200x630 (1.91:1) |
| Tarjeta social del post | `twitter` `post` | 1200x675 (16:9) |
| Banner de cabecera del tema | `twitter` `header` | 1500x500 (3:1) |
| Producto WooCommerce (principal) | `instagram` `post` | 1080x1080 (1:1) |
| Segunda imagen de producto | `instagram` `story` | 1080x1920 (9:16) |

Los formatos y medidas salen de `GET /api/v1/platforms`, que es público.

## Antes de empezar

- WordPress 5.6 o superior (Application Passwords) con HTTPS activo.
- La clave `sc_` de SocialCutter, creada en **Perfil → API keys**.
- Para WooCommerce, claves `ck_`/`cs_` de **WooCommerce → Settings → Advanced → REST API**.

```bash
export WP_URL="https://tu-blog.com"
export WP_USER="usuario"
export WP_APP_PASSWORD="abcd efgh ijkl mnop qrst uvwx"
export SC_KEY="sc_tu_clave"
```

## 1. Crear la Application Password

En wp-admin: **Users → Profile → Application Passwords**. Escribe un nombre (`SocialCutter media bot`) y copia la contraseña: se muestra una sola vez.

Se envía por **HTTP Basic Auth** (RFC 7617) sobre HTTPS. Con `curl`, `--user` se encarga del base64:

```bash
# Comprueba la autenticación: devuelve el usuario actual
curl -s --user "$WP_USER:$WP_APP_PASSWORD" "$WP_URL/wp-json/wp/v2/users/me" | jq '{id, name}'
```

Documentación oficial: https://developer.wordpress.org/advanced-administration/security/application-passwords/

## 2. Procesar el maestro con SocialCutter

```bash
curl -s -X POST "https://api.socialcutter.theboomer.dev/api/v1/images/process" \
  -H "X-API-Key: $SC_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: post-42-portada" \
  -d '{
    "source": { "type": "url", "value": "https://tu-cdn.com/maestro.jpg" },
    "destinations": [
      { "platform": "linkedin", "format": "post" },
      { "platform": "instagram", "format": "post" }
    ]
  }' > sc.json

jq '.image_id, (.outputs[] | {url, platform, format})' sc.json
```

La cabecera `Idempotency-Key` hace seguros los reintentos. Con un fichero local, usa `POST /api/v1/images/process/upload` (multipart, máximo 5 MB).

## 3. Subir la salida a la biblioteca de medios

El endpoint de medios acepta el fichero **en el cuerpo de la petición**, como datos binarios, más la cabecera `Content-Disposition` con el nombre del archivo.

```bash
curl -s -o portada.jpg "$(jq -r '.outputs[0].url' sc.json)"

curl -s -X POST "$WP_URL/wp-json/wp/v2/media" \
  --user "$WP_USER:$WP_APP_PASSWORD" \
  -H "Content-Disposition: attachment; filename=portada-1200x627.jpg" \
  -H "Content-Type: image/jpeg" \
  --data-binary "@portada.jpg" > media.json

jq '{id, source_url, media_type, mime_type}' media.json
```

La respuesta trae el `id` del adjunto y su `source_url`. El `alt_text` se envía en la misma petición o después con un `POST` a `/wp-json/wp/v2/media/{id}`. Referencia: https://developer.wordpress.org/rest-api/reference/media/

Al subir el adjunto también puedes dejarlo vinculado a la entrada con el campo `post` del propio medio, que la referencia define como *The ID for the associated post of the attachment*. Sirve para que la biblioteca muestre la entrada asociada sin tocar el post.

## 4. Asignar la imagen destacada y la del contenido

La imagen destacada se asigna por **identificador**, con el campo `featured_media`, que la referencia de la REST API define como *The ID of the featured media for the post*. Ese campo se acepta tanto al **crear** la entrada (`POST /wp-json/wp/v2/posts`) como al **actualizarla** (`POST /wp-json/wp/v2/posts/{id}`).

Al crear la entrada, el adjunto va en la misma petición:

```bash
MEDIA_ID=$(jq -r '.id' media.json)

curl -s -X POST "$WP_URL/wp-json/wp/v2/posts" \
  --user "$WP_USER:$WP_APP_PASSWORD" \
  -H "Content-Type: application/json" \
  -d "{
    \"title\": \"Entrada de ejemplo\",
    \"status\": \"draft\",
    \"featured_media\": $MEDIA_ID
  }" | jq '{id, status, featured_media}'
```

Si la entrada ya existe, actualízala con el mismo campo:

```bash
curl -s -X POST "$WP_URL/wp-json/wp/v2/posts/42" \
  --user "$WP_USER:$WP_APP_PASSWORD" \
  -H "Content-Type: application/json" \
  -d "{\"featured_media\": $MEDIA_ID}" | jq '{id, featured_media, link}'
```

Lo que viaja en `featured_media` es el **ID del adjunto**, nunca una URL. Para comprobar el resultado sin descargar toda la entrada, pide solo ese campo con el parámetro global `_fields`:

```bash
curl -s --user "$WP_USER:$WP_APP_PASSWORD" \
  "$WP_URL/wp-json/wp/v2/posts/42?_fields=id,featured_media" | jq
```

Dentro del contenido, usa la `source_url` del adjunto con una etiqueta `img` normal. Así el tema aplica sus clases y su `srcset`:

```html
<figure>
  <img src="https://tu-blog.com/wp-content/uploads/2026/09/portada-1200x627.jpg"
       alt="Descripción real de la imagen" width="1200" height="627">
</figure>
```

Referencia de posts: https://developer.wordpress.org/rest-api/reference/posts/

## 5. Regenerar los tamaños intermedios de WordPress

WordPress no guarda una sola copia de cada imagen: al subir un adjunto genera varios **tamaños intermedios** (`thumbnail`, `medium`, `medium_large`, `large` y los que registra el tema con `add_image_size`). Dos detalles de `add_image_size( $name, $width, $height, $crop )` importan en este flujo:

- Los nombres `thumb`, `thumbnail`, `medium`, `medium_large`, `large` y `post-thumbnail` están reservados.
- Con `$crop = true` el recorte es **duro y centrado**: la posición por defecto es `center` (o `array( 'left', 'top' )` para moverla).

El problema: los tamaños se calculan **al subir el fichero**. Si el tema cambia sus medidas después, las imágenes ya subidas se quedan con los recortes antiguos y el tema empieza a pedir ficheros que no existen. Los tres casos típicos son: se añadió un tamaño nuevo, cambiaste las dimensiones de uno de **Settings → Media**, o cambiaste a un tema que usa imágenes destacadas de otra medida.

Para saber qué falta, pide el adjunto en contexto de edición. El esquema de medios expone el campo `missing_image_sizes` (*List of the missing image sizes of the attachment*) y el árbol de tamaños en `media_details`:

```bash
curl -s --user "$WP_USER:$WP_APP_PASSWORD" \
  "$WP_URL/wp-json/wp/v2/media/$MEDIA_ID?context=edit" \
  | jq '{id, missing_image_sizes, sizes: (.media_details.sizes | keys)}'
```

### Con WP-CLI

`wp media regenerate` regenera las miniaturas de uno o varios adjuntos:

```bash
# Un adjunto concreto
wp media regenerate 123

# Un rango de IDs
seq 1000 2000 | xargs wp media regenerate

# Solo los adjuntos a los que les faltan tamaños
wp media regenerate --only-missing

# Un solo tamaño, sin confirmación
wp media regenerate --image_size=large --yes

# Toda la biblioteca
wp media regenerate --yes
```

Otras opciones del comando: `--skip-delete` (no borra los ficheros antiguos) y `--delete-unknown` (borra los de tamaños que ya no están registrados). Referencia: https://developer.wordpress.org/cli/commands/media/regenerate/

### Con el plugin Regenerate Thumbnails

Si no tienes acceso a la terminal del servidor, el plugin **Regenerate Thumbnails** hace lo mismo desde el panel, en **Tools → Regenerate Thumbnails**, y también desde la lista de medios y desde la pantalla de edición de cada adjunto. Además puede borrar los ficheros de tamaños antiguos que ya no se usan para liberar espacio. La ficha del plugin avisa de que no se ha probado con las tres últimas versiones mayores de WordPress, y su propio autor recomienda WP-CLI por ser más rápido al no pasar por HTTP. Referencia: https://wordpress.org/plugins/regenerate-thumbnails/

### Dónde encaja SocialCutter

Los dos métodos anteriores recortan a partir del fichero que ya está en la biblioteca. SocialCutter lo hace **antes**: genera el fichero ya en la proporción del destino (`instagram` `post` a 1080x1080, `linkedin` `post` a 1200x627) y ese fichero entra en la biblioteca con la proporción correcta. El recorte de `cover`, el modo por defecto, es **centrado**, igual que el recorte duro de `add_image_size`.

Eso significa que el tamaño intermedio que pide el tema se calcula sobre un original que ya tiene la proporción buena, así que el recorte que hace WordPress parte de un punto de partida correcto y no de una foto en otra proporción. Y si el tema cambia de medidas más adelante, sigues necesitando `wp media regenerate`: la ventaja es que tus recortes de red se vuelven a generar con SocialCutter y se vuelven a subir, sin depender del recorte que haya hecho el tema.

## 6. Variante WooCommerce: galería del producto

WooCommerce tiene su propia REST API en `/wp-json/wc/v3/`. El campo `images` del producto es una lista: **la primera imagen es la principal y el resto forma la galería**. Cada elemento acepta `id` (adjunto de la biblioteca) o `src` (URL que WooCommerce descarga).

Sube primero el adjunto al endpoint de medios de WordPress y referéncialo por `id`; así no se duplica el fichero:

```bash
GALERIA_ID=$(jq -r '.id' media.json)   # adjunto 1:1 subido antes

curl -s -X PUT "$WP_URL/wp-json/wc/v3/products/99" \
  --user "$WC_CK:$WC_CS" \
  -H "Content-Type: application/json" \
  -d "{
    \"images\": [
      { \"id\": $GALERIA_ID, \"alt\": \"Camiseta vista frontal\" },
      { \"src\": \"https://api.socialcutter.theboomer.dev/.../story.jpg\" }
    ]
  }" | jq '.id, .images'
```

La autenticación usa las claves `ck_` y `cs_` generadas en **WooCommerce → Settings → Advanced → REST API**, por Basic Auth sobre HTTPS. Documentación: https://developer.woocommerce.com/docs/apis/rest-api/v3/products/

> Nota: el catálogo de SocialCutter no incluye un formato 4:5. Lo vertical es 9:16 (1080x1920) y lo cuadrado es 1:1 (1080x1080). Si necesitas 4:5 exacto, recorta fuera de SocialCutter.

## 7. Snippet PHP: plugin mínimo o functions.php

`wp_remote_post` es la función estándar de WordPress para llamar a APIs externas. Este bloque se puede pegar en el `functions.php` del tema hijo o guardar como plugin propio (basta con el comentario de cabecera).

```php
<?php
/**
 * Plugin Name: SocialCutter Media
 * Description: Procesa un maestro con SocialCutter y lo adjunta como imagen destacada.
 * Version: 1.0.0
 */

function sc_procesar_maestro( int $post_id, string $master_url ): int|WP_Error {
    $key = defined( 'SOCIALCUTTER_API_KEY' ) ? SOCIALCUTTER_API_KEY : '';
    $respuesta = wp_remote_post( 'https://api.socialcutter.theboomer.dev/api/v1/images/process', array(
        'timeout' => 30,
        'headers' => array( 'X-API-Key' => $key, 'Content-Type' => 'application/json' ),
        'body'    => wp_json_encode( array(
            'source'       => array( 'type' => 'url', 'value' => $master_url ),
            'destinations' => array( array( 'platform' => 'linkedin', 'format' => 'post' ) ),
        ) ),
    ) );

    $datos = json_decode( wp_remote_retrieve_body( $respuesta ), true );
    $url   = $datos['outputs'][0]['url'] ?? '';
    if ( '' === $url ) {
        return new WP_Error( 'sc_sin_salida', 'La API no devolvio salidas' );
    }

    require_once ABSPATH . 'wp-admin/includes/media.php';
    require_once ABSPATH . 'wp-admin/includes/file.php';
    require_once ABSPATH . 'wp-admin/includes/image.php';

    $adjunto_id = media_sideload_image( $url, $post_id, null, 'id' );
    if ( is_wp_error( $adjunto_id ) ) {
        return $adjunto_id;
    }

    set_post_thumbnail( $post_id, $adjunto_id );

    return (int) $adjunto_id;
}
```

`media_sideload_image` descarga la URL a la biblioteca y devuelve el ID del adjunto cuando el cuarto parámetro es `'id'`; `set_post_thumbnail` la deja como destacada. Guarda la clave en `wp-config.php`, nunca dentro del tema.

## 8. Sin código: Zapier, Make y n8n

Un automatizador hace lo mismo con nodos: un disparador, un nodo HTTP que llama a `/api/v1/images/process` y un nodo de WordPress o WooCommerce que sube el medio y lo asigna. El flujo completo está en la [guía de automatización con n8n](/guias/n8n/); Zapier y Make siguen el mismo patrón.

## Coste

- **1 uso por destino** (plataforma y formato) por petición; los destinos repetidos no se cobran dos veces.
- Los procesamientos fallidos se devuelven.
- Todos los planes incluyen API y MCP: Free 3 usos/día, Basic 10, Pro 30, Agency 100.

## Errores típicos

| Síntoma | Causa | Solución |
|---|---|---|
| `401` en WordPress | Contraseña de aplicación mal copiada o sitio sin HTTPS | Vuelve a generar la Application Password y comprueba el TLS |
| `413` en SocialCutter | El maestro supera 5 MB | Reduce la imagen antes de subirla |
| La destacada no cambia | Se envió una URL en `featured_media` | Envía el **ID** del adjunto, no la URL |
| `400` al crear la entrada | El ID de `featured_media` no existe o apunta a un adjunto borrado | Comprueba el `id` con `GET /wp-json/wp/v2/media/{id}` |
| El tema pide una miniatura que no existe | El tema registró esa medida después de subir la imagen | Regenera con `wp media regenerate --only-missing` o con el plugin Regenerate Thumbnails |

## Siguientes pasos

- Shopify: [Integra SocialCutter con la Admin API de Shopify](/guias/shopify/)
- Automatización: [Automatiza el recorte de imágenes con n8n](/guias/n8n/)
- Referencia de la API: [Procesa imágenes con la API desde la terminal](/guias/curl/)
- Documentación: https://docs.socialcutter.theboomer.dev