> ## Documentation Index
> Fetch the complete documentation index at: https://web2md.org/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# API REST

> Convierte cualquier URL o HTML a Markdown de forma programática

## Descripción general

La API REST de Web2MD te permite convertir cualquier página web o HTML sin procesar a Markdown limpio de forma programática. Úsala para crear pipelines, automatizar la ingesta de contenido o integrar Web2MD en tus propias herramientas.

<Note>
  La API REST requiere un **plan PRO**. Genera tu clave de API desde el [panel de Web2MD](https://web2md.org/dashboard/api-keys).
</Note>

### Especificaciones legibles por máquina

| Recurso                    | URL                                                                            | Descripción                                                         |
| -------------------------- | ------------------------------------------------------------------------------ | ------------------------------------------------------------------- |
| Especificación OpenAPI 3.1 | [`/api/v1/openapi.json`](https://web2md.org/api/v1/openapi.json)               | Esquema completo de la API para generación de código y herramientas |
| Manifiesto de plugin de IA | [`/.well-known/ai-plugin.json`](https://web2md.org/.well-known/ai-plugin.json) | Descubrimiento por agentes (ChatGPT Plugins / asistentes de IA)     |

Usa la especificación OpenAPI para generar automáticamente SDKs de cliente o importarla en herramientas como Postman, Swagger UI o frameworks de agentes de IA.

## Autenticación

Todas las solicitudes deben incluir tu clave de API en el encabezado `Authorization`:

```
Authorization: Bearer w2m_your_key_here
```

Las claves de API tienen el prefijo `w2m_` y están vinculadas a tu cuenta.

## Endpoint

<Card>
  <strong>POST</strong> `https://web2md.org/api/v1/convert`
</Card>

### Cuerpo de la solicitud

| Campo     | Tipo     | Requerido             | Descripción                             |
| --------- | -------- | --------------------- | --------------------------------------- |
| `url`     | `string` | Uno de `url` o `html` | La URL de la página a convertir         |
| `html`    | `string` | Uno de `url` o `html` | Cadena de HTML sin procesar a convertir |
| `options` | `object` | No                    | Opciones de conversión (ver abajo)      |

<Warning>
  Proporciona `url` o `html`, no ambos. La solicitud fallará con un error `400` si ambos están presentes o si no se proporciona ninguno.
</Warning>

### Opciones

| Campo           | Tipo      | Valor predeterminado | Descripción                                                    |
| --------------- | --------- | -------------------- | -------------------------------------------------------------- |
| `includeImages` | `boolean` | `true`               | Incluir referencias de imágenes en el resultado                |
| `includeLinks`  | `boolean` | `true`               | Conservar los hipervínculos en el resultado                    |
| `includeMeta`   | `boolean` | `true`               | Anteponer los metadatos de la página como front matter en YAML |

### Respuesta

Una respuesta exitosa devuelve:

```json theme={null}
{
  "success": true,
  "data": {
    "markdown": "# Page Title\n\nConverted content...",
    "metadata": {
      "title": "Page Title",
      "url": "https://example.com/article",
      "extractedAt": "2026-03-22T10:30:00.000Z",
      "wordCount": 1250,
      "tokenCount": 1680,
      "readingTime": 5,
      "author": "Jane Doe",
      "publishedDate": "2026-03-20",
      "description": "A brief summary extracted from the page meta tags."
    }
  }
}
```

| Campo           | Tipo      | Descripción                                                      |
| --------------- | --------- | ---------------------------------------------------------------- |
| `title`         | `string`  | Título de la página extraído de `<title>`                        |
| `url`           | `string`  | URL de origen (si se proporcionó)                                |
| `extractedAt`   | `string`  | Marca de tiempo ISO 8601 de la conversión                        |
| `wordCount`     | `integer` | Recuento total de palabras (palabras en inglés + caracteres CJK) |
| `tokenCount`    | `integer` | Recuento estimado de tokens para LLM                             |
| `readingTime`   | `integer` | Tiempo de lectura estimado en minutos                            |
| `author`        | `string?` | Nombre del autor obtenido de las etiquetas meta o JSON-LD        |
| `publishedDate` | `string?` | Fecha de publicación (AAAA-MM-DD)                                |
| `description`   | `string?` | Descripción de la página obtenida de Open Graph o etiquetas meta |

## Límites de tasa

Las solicitudes a la API están limitadas a **60 solicitudes por minuto** por clave de API. Si superas el límite, la API devuelve un código de estado `429`. Espera a que se restablezca la ventana antes de volver a intentarlo.

## Respuestas de error

| Estado | Significado                                            | Ejemplo                                                            |
| ------ | ------------------------------------------------------ | ------------------------------------------------------------------ |
| `400`  | Solicitud incorrecta — entrada faltante o en conflicto | Se proporcionaron tanto `url` como `html`, o ninguno               |
| `401`  | No autorizado — clave de API inválida o faltante       | Falta el encabezado `Authorization`                                |
| `422`  | No procesable — no se pudo obtener la URL              | El sitio de destino devolvió un error o expiró el tiempo de espera |
| `429`  | Límite de tasa excedido                                | Más de 60 solicitudes en un minuto                                 |
| `500`  | Error interno del servidor                             | Fallo inesperado de nuestro lado                                   |

Todas las respuestas de error siguen esta estructura:

```json theme={null}
{
  "success": false,
  "error": {
    "code": "RATE_LIMIT_EXCEEDED",
    "message": "Rate limit exceeded. Try again in 45 seconds."
  }
}
```

## Ejemplos

### Convertir una URL con curl

```bash theme={null}
curl -X POST https://web2md.org/api/v1/convert \
  -H "Authorization: Bearer w2m_your_key_here" \
  -H "Content-Type: application/json" \
  -d '{
    "url": "https://example.com/blog/post",
    "options": {
      "includeImages": true,
      "includeLinks": true,
      "includeMeta": false
    }
  }'
```

### Convertir HTML sin procesar con curl

```bash theme={null}
curl -X POST https://web2md.org/api/v1/convert \
  -H "Authorization: Bearer w2m_your_key_here" \
  -H "Content-Type: application/json" \
  -d '{
    "html": "<h1>Hello World</h1><p>This is a <strong>test</strong> paragraph.</p>"
  }'
```

### JavaScript (fetch)

```javascript theme={null}
const response = await fetch("https://web2md.org/api/v1/convert", {
  method: "POST",
  headers: {
    "Authorization": "Bearer w2m_your_key_here",
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    url: "https://example.com/blog/post",
    options: {
      includeImages: true,
      includeLinks: true,
    },
  }),
});

const result = await response.json();

if (result.success) {
  console.log(result.data.markdown);
  console.log(`Word count: ${result.data.metadata.wordCount}`);
} else {
  console.error(result.error.message);
}
```

<Tip>
  Guarda tu clave de API en una variable de entorno en lugar de escribirla directamente en el código. Por ejemplo, usa `process.env.WEB2MD_API_KEY` en Node.js.
</Tip>
