# Publicar en LinkedIn

> Publica el contenido aprobado en la única cuenta o página de LinkedIn de esta conexión.



{/* AUTO-GENERATED by @emisso/codegen. DO NOT EDIT. */}

|                     |                                                                   |
| ------------------- | ----------------------------------------------------------------- |
| **Tool ID**         | `linkedin.publicacion.publicar`                                   |
| **Nombre MCP**      | `linkedin__publicacion__publicar`                                 |
| **Conector**        | `linkedin`                                                        |
| **Plano**           | `action`                                                          |
| **Scope (permiso)** | `linkedin:publish`                                                |
| **Auth**            | `connection_credentials`                                          |
| **Versión**         | `1`                                                               |
| **Sensible**        | sí                                                                |
| **Deprecado**       | no                                                                |
| **Comportamiento**  | readOnly=false, destructive=true, idempotent=true, openWorld=true |

> **Requiere conexión.** Indica cuál en cada llamada: header `X-Connect-Connection` en REST y campo `connectionId` en el `execute_write` de MCP. No hay resolución implícita, ni siquiera con una sola conexión activa: la conexión es la empresa. El id sale de [`conexiones.estado.consultar`](/docs/referencia/conexiones/estado-consultar).

## Qué hace [#qué-hace]

Beta privada: requiere permiso explícito y una Idempotency-Key UUID v4 estable. La persona debe aprobar contenido y destino antes de ejecutar. Un resultado pendiente o desconocido exige revisión, nunca otra clave ni otro envío. No programa, borra ni modifica publicaciones. Formatos: texto (3000 caracteres), 1 a 20 imágenes JPG/PNG/GIF de hasta 8 MB con texto alternativo, o un único video MP4 entre 75 KB y 100 MiB (3 s a 30 min) que debe quedar disponible antes de publicar. Si el canal no termina de procesar un video dentro del tiempo de la corrida, no se publica nada y se informa no\_publicado.

## Entrada [#entrada]

| Campo                  | Tipo                   | Requerido         | Descripción                                                                                                                                            |
| ---------------------- | ---------------------- | ----------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `texto`                | string                 | no · default `""` | Texto aprobado por la persona para este destino; puede estar vacío si hay imágenes aprobadas. El proveedor valida su límite y formato antes del envío. |
| `medios`               | lista de objeto        | no · default `[]` | Archivos aprobados: hasta 20 imágenes, o exactamente un video. Las capacidades de cada canal se comprueban antes de producir un efecto externo.        |
| `medios[].url`         | string                 | sí                | URL HTTPS pública del archivo que el proveedor puede descargar. Sin credenciales ni parámetros secretos.                                               |
| `medios[].tipo`        | `"imagen"` · `"video"` | sí                | Tipo del archivo. Un video va solo (sin otras imágenes ni videos). Un formato no admitido por el canal se rechaza antes de publicar.                   |
| `medios[].descripcion` | string                 | no · default `""` | Texto alternativo de la imagen (X, LinkedIn e Instagram imagen/carrusel). En videos no se envía: ningún canal de la beta lo admite por esta vía.       |

<details>
  <summary>
    JSON Schema de entrada
  </summary>

  ```json
  {
    "$schema": "https://json-schema.org/draft/2020-12/schema",
    "type": "object",
    "properties": {
      "texto": {
        "default": "",
        "description": "Texto aprobado por la persona para este destino; puede estar vacío si hay imágenes aprobadas. El proveedor valida su límite y formato antes del envío.",
        "type": "string",
        "maxLength": 10000
      },
      "medios": {
        "default": [],
        "description": "Archivos aprobados: hasta 20 imágenes, o exactamente un video. Las capacidades de cada canal se comprueban antes de producir un efecto externo.",
        "maxItems": 20,
        "type": "array",
        "items": {
          "type": "object",
          "properties": {
            "url": {
              "type": "string",
              "maxLength": 2048,
              "format": "uri",
              "description": "URL HTTPS pública del archivo que el proveedor puede descargar. Sin credenciales ni parámetros secretos."
            },
            "tipo": {
              "type": "string",
              "enum": [
                "imagen",
                "video"
              ],
              "description": "Tipo del archivo. Un video va solo (sin otras imágenes ni videos). Un formato no admitido por el canal se rechaza antes de publicar."
            },
            "descripcion": {
              "default": "",
              "description": "Texto alternativo de la imagen (X, LinkedIn e Instagram imagen/carrusel). En videos no se envía: ningún canal de la beta lo admite por esta vía.",
              "type": "string",
              "maxLength": 1000
            }
          },
          "required": [
            "url",
            "tipo"
          ],
          "additionalProperties": false
        }
      }
    },
    "additionalProperties": false
  }
  ```
</details>

## Ejemplo [#ejemplo]

```bash title="curl"
curl -X POST https://connect.emisso.ai/api/v1/tools/linkedin.publicacion.publicar/execute \
  -H "Authorization: Bearer connect_sk_…" \
  -H "X-Connect-Connection: conn_9tKfR2mQx4Vb" \
  -H "Idempotency-Key: 9d1f4c2a-7b30-4e58-9c11-2f6a8de5b743" \
  -H "Content-Type: application/json" \
  -d '{"input":{"texto":"Compartimos una mejora aprobada por nuestro equipo.","medios":[]}}'
```

```json title="MCP · meta-tool execute_write"
{
  "tool": "linkedin.publicacion.publicar",
  "params": {
    "texto": "Compartimos una mejora aprobada por nuestro equipo.",
    "medios": []
  },
  "connectionId": "conn_9tKfR2mQx4Vb",
  "idempotencyKey": "9d1f4c2a-7b30-4e58-9c11-2f6a8de5b743"
}
```

> **Clave de idempotencia obligatoria.** Sin ella la llamada responde `idempotency_key_missing`. Genera un UUID v4 nuevo por operación y envíalo en `Idempotency-Key` (REST) o en `idempotencyKey` (MCP). Repite la misma clave solo al reintentar esa operación.

**Salida esperada (200):**

```json
{
  "data": {
    "estado": "pendiente",
    "publicacionId": "123456789",
    "url": null,
    "operacionId": "req_ejemplo",
    "puedeReintentar": false
  },
  "meta": {
    "request_id": "req_…",
    "tool_id": "linkedin.publicacion.publicar",
    "plane": "action",
    "latency_ms": 7410,
    "audit_status": "recorded"
  }
}
```

## Salida [#salida]

| Campo             | Tipo                                                                         | Requerido | Descripción                                                                                                                                                                                    |                                                                                                                   |
| ----------------- | ---------------------------------------------------------------------------- | --------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------- |
| `estado`          | `"publicado"` · `"pendiente"` · `"resultado_desconocido"` · `"no_publicado"` | sí        | publicado exige una lectura independiente de la misma cuenta; pendiente conserva un identificador aceptado; resultado\_desconocido requiere revisión; no\_publicado indica rechazo confirmado. |                                                                                                                   |
| `publicacionId`   | string                                                                       | null      | sí                                                                                                                                                                                             | Identificador confirmado por el proveedor; null cuando no se conoce. Tener un ID no acredita publicación visible. |
| `url`             | string                                                                       | null      | sí                                                                                                                                                                                             | Enlace público de la publicación confirmada, o null.                                                              |
| `operacionId`     | string                                                                       | sí        | Identificador inmutable de la primera solicitud con esta Idempotency-Key.                                                                                                                      |                                                                                                                   |
| `puedeReintentar` | booleano                                                                     | sí        | No crees otra clave para repetir el efecto. Una repetición de transporte conserva la misma clave.                                                                                              |                                                                                                                   |

<details>
  <summary>
    JSON Schema de salida
  </summary>

  ```json
  {
    "$schema": "https://json-schema.org/draft/2020-12/schema",
    "type": "object",
    "properties": {
      "estado": {
        "type": "string",
        "enum": [
          "publicado",
          "pendiente",
          "resultado_desconocido",
          "no_publicado"
        ],
        "description": "publicado exige una lectura independiente de la misma cuenta; pendiente conserva un identificador aceptado; resultado_desconocido requiere revisión; no_publicado indica rechazo confirmado."
      },
      "publicacionId": {
        "anyOf": [
          {
            "type": "string",
            "maxLength": 240
          },
          {
            "type": "null"
          }
        ],
        "description": "Identificador confirmado por el proveedor; null cuando no se conoce. Tener un ID no acredita publicación visible."
      },
      "url": {
        "anyOf": [
          {
            "type": "string",
            "maxLength": 2048,
            "format": "uri"
          },
          {
            "type": "null"
          }
        ],
        "description": "Enlace público de la publicación confirmada, o null."
      },
      "operacionId": {
        "type": "string",
        "description": "Identificador inmutable de la primera solicitud con esta Idempotency-Key."
      },
      "puedeReintentar": {
        "type": "boolean",
        "const": false,
        "description": "No crees otra clave para repetir el efecto. Una repetición de transporte conserva la misma clave."
      }
    },
    "required": [
      "estado",
      "publicacionId",
      "url",
      "operacionId",
      "puedeReintentar"
    ],
    "additionalProperties": false
  }
  ```
</details>

## Errores de esta tool [#errores-de-esta-tool]

| Código                           | HTTP | Reintentable | Qué hacer                                                                                                                                                                                |
| -------------------------------- | ---- | ------------ | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `connection_disabled`            | 403  | no           | Reactívala en /connections o usa otra conexión del mismo sistema.                                                                                                                        |
| `connection_not_found`           | 404  | no           | Usa uno de los connectionId que lista el error, o revisa la conexión en /connections. No hace falta reactivar nada.                                                                      |
| `connection_credential_required` | 428  | no           | Crea un enlace con conexiones.enlace.crear (modo reconectar si la conexión ya existe) y pide a la persona que entregue la credencial de nuevo. No reintentes con la credencial anterior. |
| `connection_busy`                | 409  | sí           | Espera unos segundos y reintenta. Es una espera transitoria: no necesitas volver a conectar ni ingresar la credencial otra vez.                                                          |
| `upstream_error`                 | 502  | sí           | Reintenta más tarde. Si persiste, el problema está en el sistema externo, no en tu integración.                                                                                          |
| `timeout`                        | 504  | sí           | Reintenta. Para sincronizaciones largas usa la vía asíncrona y consulta el estado del trabajo.                                                                                           |
| `connector_onboarding_required`  | 428  | no           | Lee el mensaje: dice qué falta. Se completa en el portal de ese sistema, no en Connect, y después la llamada funciona sin cambios.                                                       |
| `connection_scope_not_enabled`   | 403  | no           | Pide a un owner/admin que habilite el scope en /connections para esa conexión, o usa otra que ya lo tenga activo. Cambiar la credencial del actor no resuelve este error.                |
| `rate_limited`                   | 429  | sí           | Espera y reintenta con backoff exponencial.                                                                                                                                              |
| `upstream_unexpected_response`   | 502  | no           | No reintentes: la respuesta es determinista. Repórtalo con el request\_id para que actualicemos el conector.                                                                             |
| `idempotency_key_missing`        | 400  | no           | Genera un UUID v4, envíalo como Idempotency-Key y reutilízalo solo para reintentos de esta misma operación.                                                                              |
| `idempotency_in_progress`        | 409  | sí           | Espera unos segundos y reintenta con la MISMA clave. Generar una nueva para la misma operación es lo que duplica el efecto.                                                              |
| `idempotency_conflict`           | 409  | no           | Genera una clave nueva para una operación nueva; reutiliza la clave solo para reintentar la misma.                                                                                       |

Toda llamada puede devolver además los códigos transversales (`validation_error`, `unauthorized`, `scope_not_granted`, `rate_limited`, entre otros): el detalle vive en el [catálogo de errores](/docs/referencia/errores).
