---
seo_title: Integraciones: MCP, n8n, CLI, SDKs y Widgets | EnConvert
meta_desc: Accede a la API de EnConvert desde las herramientas que ya usas: un servidor MCP para agentes de código, un nodo n8n, una CLI de terminal, diez SDKs y widgets web.
keywords: integraciones de enconvert, servidor mcp para conversión de archivos, nodo n8n de conversión de archivos, cli para convertir archivos, sdk de conversión de archivos, integrar widget conversor de archivos en mi web, widget de conversión de archivos para sitio web, widget de conversión de archivos sin código, shortcode conversor de archivos para wordpress, embeber widget url a pdf
---

# Integraciones

La misma API, accesible desde las herramientas que ya usas. Un servidor MCP mete EnConvert en un agente de código, un nodo n8n en un flujo de trabajo, una CLI en tu terminal, diez SDKs en el código de tu aplicación y un widget web en tu propio sitio.

---

## Elige tu superficie

Todas las superficies de abajo llaman a los mismos endpoints REST públicos con la misma API key, contra el mismo proyecto y la misma asignación mensual de operaciones.

| Superficie | Paquete | Úsala cuando |
|---------|---------|-------------|
| [Configuración de MCP](/es/docs/guides/integrations/mcp-setup.md) | `@enconvert/mcp` | Quieres que un agente de código como Claude Code, Cursor, Windsurf o Claude Desktop llame a la API por sí mismo, en el chat, sin que tú escribas HTTP. |
| [n8n](/es/docs/guides/integrations/n8n.md) | `@enconvert/n8n-nodes-enconvert` | Estás construyendo un flujo de trabajo de n8n y quieres conversiones, scraping y rastreo como un nodo que emite datos binarios reales. |
| [CLI](/es/docs/guides/integrations/cli.md) | `@enconvert/cli` | Quieres convertir archivos o extraer datos web desde una terminal o un script de shell, con salida `--json` y códigos de salida estables. |
| [SDKs](/es/docs/guides/integrations/sdks.md) | diez clientes de lenguaje | Estás escribiendo código de aplicación y quieres métodos tipados con autocompletado en el editor en lugar de HTTP hecho a mano. |

Hay una quinta superficie que no tiene página propia: los [widgets web](#web-widgets), cubiertos más abajo, que son los únicos que tus usuarios finales tocan directamente.

Si aún estás decidiendo, [REST, MCP y CLI](/es/docs/concepts/rest-mcp-and-cli.md) compara las superficies de acceso una al lado de otra, y [Autenticación](/es/docs/authentication.md) explica qué tipo de clave necesita cada una.

---

## Widgets web {: #web-widgets }

Los widgets web integran la conversión de URL y archivos en cualquier sitio web con una sola etiqueta script, de modo que tus visitantes convierten una URL a PDF, hacen una captura de pantalla o convierten un archivo subido sin salir de tu página. El código de integración solo lleva un ID de widget. La autenticación ocurre dentro del iframe mediante un desafío de Cloudflare Turnstile y un JWT de corta duración emitido por `POST /v1/widget/{widget_id}/token`, de modo que ninguna API key queda expuesta en el código de tu frontend.

Cada widget está vinculado a un endpoint de conversión y a una lista de dominios permitidos, ambos definidos en el panel. Detrás de un widget puede ir cualquier endpoint de conversión:

- Basados en URL: [url-to-pdf](/es/docs/endpoints/convert/web-pages/url-to-pdf.md), [url-to-screenshot](/es/docs/endpoints/convert/web-pages/url-to-screenshot.md)
- Basados en archivos: todos los endpoints de [formato de datos](/es/docs/endpoints/convert/data-formats.md), [documento a PDF](/es/docs/endpoints/convert/documents.md) y [conversión de imágenes](/es/docs/endpoints/convert/images.md)

### Cómo funcionan los widgets

#### Configuración

1. Ve a tu **Panel > Widgets** de EnConvert y haz clic en **Crear widget**.
2. Selecciona el endpoint de conversión (p. ej., `/v1/convert/url-to-pdf`) y especifica los dominios donde se integrará el widget. Se admiten subdominios comodín (p. ej., `*.example.com`).
3. Se crea automáticamente una API key pública interna para el widget, restringida al endpoint seleccionado y a los dominios permitidos. Esta clave nunca se expone.

Hay dos precondiciones que suelen pillar a la gente: el correo de tu cuenta debe estar verificado y la lista de dominios permitidos no puede estar vacía. La creación del widget se rechaza si falta cualquiera de las dos.

#### Integración

Añade el script de integración a tu sitio web:

```html
<script src="https://enconvert.com/embed.js" data-widget-id="your-widget-id"></script>
```

El script crea un iframe aislado (sandboxed) que carga el widget de EnConvert. No aparece ninguna API key en el código de integración.

#### Flujo en tiempo de ejecución

1. **El widget se carga** en el iframe y obtiene su configuración desde `GET /v1/widget/{widget_id}/config`.
2. **Validación de dominio**: el widget verifica que el origen de la página padre coincida con la lista de dominios permitidos. Admite dominios exactos y patrones de subdominio comodín (`*.example.com`).
3. **El usuario envía una URL o un archivo**: el widget solicita un token de desafío Turnstile invisible.
4. **Intercambio de token**: el widget envía el token de Turnstile a `POST /v1/widget/{widget_id}/token` y recibe un JWT (expiración de 1 hora) más una cookie de refresh token (expiración de 7 días).
5. **Conversión**: el widget llama al endpoint de conversión con el JWT.
6. **Resultado**: la API devuelve una respuesta JSON con una `presigned_url`. El widget muestra un enlace de descarga.
7. **Recuperación por timeout**: si la conversión supera los límites de timeout del proxy inverso, el widget consulta `GET /v1/convert/status/{job_id}` usando el ID de trabajo pregenerado.

#### Renovación automática de tokens

El widget nunca deja de funcionar por una autenticación expirada:

- En la conversión inicial, la API emite tanto un **JWT** (expiración de 1 hora) como un **refresh token** (expiración de 7 días, cookie httpOnly).
- En las conversiones posteriores, el widget primero intenta **renovar el JWT** mediante `POST /v1/widget/{widget_id}/refresh` usando la cookie de refresh token, sin necesidad de ningún desafío Turnstile.
- Si el propio refresh token ha expirado (tras 7 días de inactividad), el widget recurre a un nuevo desafío Turnstile.
- El refresh token se **rota** en cada renovación: cada renovación emite una nueva cookie de 7 días.

Esto significa que un visitante del widget que convierte cada pocos días nunca verá un desafío Turnstile después del primero.

### Endpoints del widget

#### Configuración

Recupera la configuración de un widget específico. No requiere autenticación.

```
GET /v1/widget/{widget_id}/config
```

**Respuesta:**

```json
{
    "endpoint": "/v1/convert/url-to-pdf",
    "input_type": "url",
    "allowed_domains": ["https://example.com", "*.example.com"],
    "turnstile_site_key": "1x00000000000000000000AA",
    "widget_branding": true
}
```

| Campo | Descripción |
|-------|-------------|
| `endpoint` | El endpoint de conversión que este widget está configurado para usar. |
| `input_type` | `"url"` para endpoints basados en URL, `"file"` para endpoints de subida de archivos. |
| `allowed_domains` | Dominios autorizados para integrar este widget. Admite comodines. |
| `turnstile_site_key` | Clave de sitio de Cloudflare Turnstile para la verificación de bots. |
| `widget_branding` | Si se muestra la insignia "Powered by EnConvert". Determinado por el plan de suscripción. |

#### Intercambio de token

Intercambia un token de desafío Turnstile por un JWT. Establece una cookie de refresh token.

```
POST /v1/widget/{widget_id}/token
X-Parent-Origin: https://your-website.com
Content-Type: application/json

{
    "turnstile_token": "cloudflare-challenge-response-token"
}
```

**Respuesta:**

```json
{
    "token": "eyJhbGciOiJIUzI1NiIs...",
    "token_type": "Bearer",
    "expires_in": 3600
}
```

También establece una cookie httpOnly `refresh_token` (expiración de 7 días, `Secure`, `SameSite=none`).

#### Renovación de token

Renueva un JWT expirado usando la cookie httpOnly de refresh token. No se requiere ningún desafío Turnstile.

```
POST /v1/widget/{widget_id}/refresh
X-Parent-Origin: https://your-website.com
```

No se necesita cuerpo de solicitud. El refresh token se lee de la cookie automáticamente.

**Respuesta:**

```json
{
    "token": "eyJhbGciOiJIUzI1NiIs...",
    "token_type": "Bearer",
    "expires_in": 3600
}
```

La cookie de refresh token se rota en cada renovación (se emite una nueva cookie de 7 días).

**Respuestas de error:**
- `401`: no hay cookie de refresh token o el refresh token ha expirado
- `403`: el refresh token no coincide con el proyecto del widget, o el dominio no está autorizado
- `404`: widget no encontrado o desactivado

### Respuesta de conversión

Tanto las conversiones de widget basadas en URL como las basadas en archivos devuelven una respuesta JSON consistente con una URL de descarga prefirmada:

```json
{
    "presigned_url": "https://spaces.example.com/...",
    "object_key": "env/files/{project_id}/url-to-pdf/example_20260405_123456789.pdf",
    "filename": "example_20260405_123456789.pdf",
    "file_size": 123456,
    "conversion_time_seconds": 8.5,
    "job_id": "client-generated-uuid"
}
```

El widget usa la `presigned_url` para mostrar un enlace de descarga. Las URL prefirmadas expiran después de 15 minutos. Consulta [URLs de descarga firmadas](/es/docs/concepts/signed-urls.md) para saber qué significa esa ventana para tus visitantes.

**Restricciones de conversión del widget:**
- Solo una única URL / un único archivo
- Solo modo síncrono (sin async ni por lotes)
- Sin callbacks de webhook ni correos de notificación
- Endpoint restringido al configurado para el widget

### Marca del widget

Los planes que incluyen marca del widget muestran una pequeña insignia **"Powered by EnConvert"** en la parte inferior del widget. Esto se controla mediante el campo `widget_branding` del plan de suscripción:

| Plan | Marca |
|------|----------|
| Founding (gratis) | Se muestra |
| Indie, Studio, Production, Enterprise | Oculta |

La insignia de marca enlaza a `https://www.enconvert.com` y tiene un estilo discreto: texto pequeño debajo del formulario del widget con opacidad reducida.

Para eliminar la marca, sal del plan gratuito Founding. Cualquier plan de pago la oculta.

### Gestión de widgets

Los widgets se gestionan a través del panel de EnConvert o de la API del backend:

| Operación | Endpoint | Descripción |
|-----------|----------|-------------|
| Crear | `POST /widgets` | Crea un widget y autogenera una API key pública interna. |
| Listar | `GET /widgets?project_id={id}` | Lista todos los widgets activos de un proyecto. |
| Obtener | `GET /widgets/{id}` | Recupera los detalles de un único widget. |
| Actualizar | `PATCH /widgets/{id}` | Actualiza el nombre, el endpoint o la API key del widget. |
| Eliminar | `DELETE /widgets/{id}` | Elimina el widget de forma lógica (establece `active=false`). |

<div class="alert alert-info">
<strong>Host diferente:</strong> estas rutas de gestión viven en el backend de EnConvert que sirve el panel, no en <code>api.enconvert.com</code>. Las rutas de conversión y de autenticación de widgets bajo <code>/v1/</code> están en el gateway.
</div>

### Referencia del código de integración

#### HTML estándar

```html
<script src="https://enconvert.com/embed.js" data-widget-id="your-widget-id"></script>
```

El script:
- Crea un iframe aislado (`allow-scripts allow-same-origin allow-forms allow-popups`)
- Establece `width: 100%`, altura inicial de 400px, sin borde
- Habilita el permiso `clipboard-write`
- Usa carga diferida (lazy loading)
- Escucha los mensajes `Enconvert:resize` para autoajustar la altura

#### Shortcode de WordPress

Si usas el plugin de WordPress de EnConvert, integra los widgets usando el shortcode:

```
[enconvert_widget id="your-widget-id"]
```

#### Personalización de estilo

Personaliza la apariencia del widget mediante parámetros de consulta en la URL del script de integración o en la fuente del iframe:

| Parámetro | Variable CSS | Descripción |
|-----------|-------------|-------------|
| `bg` | `--w-bg` | Color de fondo del widget |
| `text` | `--w-text` | Color del texto |
| `btn-bg` | `--w-btn-bg` | Color de fondo del botón |
| `btn-text` | `--w-btn-text` | Color del texto del botón |
| `border` | `--w-border` | Color del borde |
| `radius` | `--w-radius` | Radio del borde |
| `input-bg` | `--w-input-bg` | Fondo del campo de entrada |
| `result-bg` | `--w-result-bg` | Fondo del área de resultado |
| `error` | `--w-error` | Color del texto de error |
| `font` | `--w-font` | Familia tipográfica |
| `padding` | `--w-padding` | Relleno del widget |
| `max-width` | `--w-max-width` | Ancho máximo del widget |

### Comunicación con el iframe

El widget se comunica con la página padre mediante `postMessage`. Escucha estos eventos en la página padre:

| Tipo de evento | Datos | Descripción |
|-----------|------|-------------|
| `Enconvert:ready` | ninguno | El widget se ha cargado y está listo. |
| `Enconvert:resize` | `{ height: number }` | La altura del contenido del widget cambió. Úsalo para redimensionar el iframe. |
| `Enconvert:conversion:complete` | `{ url: string, filename?: string }` | La conversión se completó. `url` es la URL de descarga prefirmada. |
| `Enconvert:conversion:error` | `{ error: string }` | La conversión falló. |

Estos cuatro nombres de eventos son un contrato fijo del protocolo. Respeta las mayúsculas y minúsculas exactamente.

#### Ejemplo: escuchar eventos

```javascript
window.addEventListener("message", function(e) {
    if (!e.data || !e.data.type) return;

    if (e.data.type === "Enconvert:conversion:complete") {
        console.log("Conversion done:", e.data.data.url);
    }

    if (e.data.type === "Enconvert:conversion:error") {
        console.error("Conversion failed:", e.data.data.error);
    }
});
```

### Seguridad

| Capa | Protección |
|-------|-----------|
| **Lista blanca de dominios** | El widget solo funciona en los dominios listados. Admite coincidencias exactas y subdominios comodín. Validación del lado del servidor al emitir el token. |
| **Verificación Turnstile** | Cada solicitud de token inicial requiere una respuesta de desafío Cloudflare Turnstile válida. |
| **Restricción de endpoint** | Cada widget está bloqueado a un único endpoint de conversión mediante `allowed_endpoints` en el JWT. |
| **Expiración de token** | El JWT expira después de 1 hora. El refresh token expira después de 7 días. Ambos se rotan en la renovación. |
| **Seguridad del refresh token** | Cookie httpOnly con `Secure` y `SameSite=none`, inaccesible para JavaScript, solo se envía sobre HTTPS. |
| **Protección CORS** | El API gateway valida el origen del iframe del widget en cada solicitud. |
| **CSP frame-ancestors** | Los endpoints de configuración y token del widget establecen cabeceras `frame-ancestors` que restringen qué dominios pueden integrar el iframe. |
| **Sin claves expuestas** | El código de integración contiene únicamente el ID del widget. La API key interna nunca es visible. |

<div class="alert alert-warning">
<strong>Nunca pongas una clave privada en una página.</strong> Los widgets existen para que el tráfico del navegador funcione con una clave pública de alcance limitado y un JWT de corta duración. Una clave privada <code>sk_</code> enviada desde un navegador se rechaza con HTTP 403 al instante. Consulta <a href="/es/docs/authentication#public-keys-and-jwt">Claves públicas y JWT</a>.
</div>

---

## Preguntas frecuentes

### ¿Cómo integro un widget conversor de archivos en mi sitio web?

Crea un widget en el panel de EnConvert (**Panel > Widgets > Crear widget**) y añade una etiqueta script a tu página: `<script src="https://enconvert.com/embed.js" data-widget-id="your-widget-id"></script>`. Si tu sitio usa WordPress, puedes usar en su lugar el shortcode `[enconvert_widget id="your-widget-id"]` del plugin de WordPress de EnConvert.

### ¿Necesito exponer una API key para integrar un widget de conversión?

No. El código de integración contiene únicamente el ID del widget. Se autogenera una API key pública interna para cada widget, restringida a su endpoint configurado y a los dominios permitidos, y nunca es visible en el código de tu frontend.

### ¿Cómo autentica el widget a los usuarios sin una API key?

El widget solicita un desafío invisible de Cloudflare Turnstile y lo intercambia en `POST /v1/widget/{widget_id}/token` por un JWT con expiración de 1 hora más una cookie de refresh token httpOnly con expiración de 7 días. Las conversiones posteriores renuevan el JWT mediante `POST /v1/widget/{widget_id}/refresh` sin ningún desafío nuevo, y el refresh token se rota en cada renovación.

### ¿Puedo restringir qué dominios pueden usar mi widget integrado?

Sí. Cada widget tiene una lista de dominios permitidos que admite dominios exactos y subdominios comodín como `*.example.com`, validada del lado del servidor al emitir el token, con cabeceras CSP `frame-ancestors` que restringen qué páginas pueden integrar el iframe.

### ¿Cómo elimino la insignia "Powered by EnConvert" del widget?

La insignia se controla mediante el campo `widget_branding` de tu plan de suscripción. Solo el plan gratuito Founding la muestra. Indie, Studio, Production y Enterprise la ocultan, así que cualquier plan de pago elimina la insignia.

### ¿Con qué integración debería empezar?

Si estás escribiendo código, empieza con un [SDK](/es/docs/guides/integrations/sdks.md) para tu lenguaje. Si automatizas sin código, usa [n8n](/es/docs/guides/integrations/n8n.md). Si quieres que un asistente de IA haga el trabajo, instala el [servidor MCP](/es/docs/guides/integrations/mcp-setup.md). Si solo quieres que tus propios visitantes conviertan archivos, usa un [widget web](#web-widgets).

### ¿Las integraciones comparten una sola API key y una sola cuota?

Sí. Todas se autentican como el mismo proyecto, así que las operaciones cuentan contra una única asignación mensual sin importar desde qué superficie se hizo la llamada. Consulta [Límites de frecuencia y cuotas](/es/docs/reference/rate-limits.md).
