<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Roobia</title>
    <description>The latest articles on DEV Community by Roobia (@roobia).</description>
    <link>https://dev.to/roobia</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F2197084%2F1d72640c-64d4-4f30-a828-302a9e3360b0.jpg</url>
      <title>DEV Community: Roobia</title>
      <link>https://dev.to/roobia</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/roobia"/>
    <language>en</language>
    <item>
      <title>GPT-Image-2.6 Flare vs Sunburst: ¿qué modelo deberías usar?</title>
      <dc:creator>Roobia</dc:creator>
      <pubDate>Thu, 05 Nov 2026 10:45:28 +0000</pubDate>
      <link>https://dev.to/roobia/gpt-image-26-flare-vs-sunburst-que-modelo-deberias-usar-f79</link>
      <guid>https://dev.to/roobia/gpt-image-26-flare-vs-sunburst-que-modelo-deberias-usar-f79</guid>
      <description>&lt;h1&gt;
  
  
  GPT-Image-2.6 Flare vs Sunburst: ¿qué modelo deberías usar?
&lt;/h1&gt;

&lt;p&gt;Usa GPT-Image-2.6 Flare para borradores, trabajos de gran volumen, pósteres e imágenes de producto. Usa Sunburst para los recursos finales y para ediciones repetidas con calidad &lt;code&gt;medium&lt;/code&gt; o &lt;code&gt;high&lt;/code&gt;. En la decisión entre GPT-Image-2.6 Flare y Sunburst, ambos modelos cuestan lo mismo por token, así que estás cambiando segundos por detalle, no dólares.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://apidog.com/?utm_source=dev.to&amp;amp;utm_medium=wanda&amp;amp;utm_content=n8n-post-automation" class="crayons-btn crayons-btn--primary"&gt;Prueba Apidog hoy&lt;/a&gt;
&lt;/p&gt;

&lt;p&gt;OpenAI lanzó ambos modelos el 4 de noviembre de 2026. Este artículo los compara en velocidad, calidad, consistencia de edición y costo, y luego te da una recomendación para cada caso de uso. No hemos ejecutado los dos modelos frente a frente con una clave activa, así que cada cifra a continuación indica su fuente, y la última sección muestra cómo medirlos con tus propios prompts.&lt;/p&gt;

&lt;p&gt;Para conocer el lanzamiento completo, lee nuestra &lt;a href="https://apidog.com/es/blog/what-is-chatgpt-images-2-6?utm_source=dev.to&amp;amp;utm_medium=wanda&amp;amp;utm_content=n8n-post-automation"&gt;explicación de ChatGPT Images 2.6&lt;/a&gt;. Para el par anterior, consulta nuestra &lt;a href="https://apidog.com/es/blog/gpt-image-2-5-flare-vs-sunburst-vs-gpt-image-2?utm_source=dev.to&amp;amp;utm_medium=wanda&amp;amp;utm_content=n8n-post-automation"&gt;comparación de Flare vs Sunburst para la 2.5&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  GPT-Image-2.6 Flare vs Sunburst de un vistazo
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Elemento&lt;/th&gt;
&lt;th&gt;Flare&lt;/th&gt;
&lt;th&gt;Sunburst&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;ID del modelo en la API&lt;/td&gt;
&lt;td&gt;&lt;code&gt;gpt-image-2.6-flare&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;gpt-image-2.6-sunburst&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;El eslogan de OpenAI&lt;/td&gt;
&lt;td&gt;Iteración rápida&lt;/td&gt;
&lt;td&gt;Trabajo visual detallado&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Velocidad publicada&lt;/td&gt;
&lt;td&gt;Tan solo seis segundos con &lt;code&gt;low&lt;/code&gt;
&lt;/td&gt;
&lt;td&gt;Sin cifra&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Fortaleza según OpenAI&lt;/td&gt;
&lt;td&gt;Composición para pósteres e imágenes de producto&lt;/td&gt;
&lt;td&gt;Calidad y consistencia de edición con &lt;code&gt;medium&lt;/code&gt; o &lt;code&gt;high&lt;/code&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Text-to-Image Arena (Medium)&lt;/td&gt;
&lt;td&gt;#4, 1384 puntos&lt;/td&gt;
&lt;td&gt;#2, 1409 puntos&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Image Edit Arena (Medium)&lt;/td&gt;
&lt;td&gt;#5, 1462 puntos&lt;/td&gt;
&lt;td&gt;#3, 1476 puntos&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Tarifa de salida de imagen&lt;/td&gt;
&lt;td&gt;$30 por 1M de tokens&lt;/td&gt;
&lt;td&gt;$30 por 1M de tokens&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;code&gt;complexity&lt;/code&gt;, markup, SVG, GIF&lt;/td&gt;
&lt;td&gt;Sí&lt;/td&gt;
&lt;td&gt;Sí&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Las filas de características coinciden. La &lt;a href="https://developers.openai.com/api/docs/guides/image-generation?ref=apidog.com#gpt-image-26" rel="noopener noreferrer"&gt;guía de generación de imágenes&lt;/a&gt; de OpenAI indica que ambos modelos admiten control de complejidad, ediciones guiadas por markup, salida SVG y salida GIF animado. No renuncias a ninguna capacidad con ninguno de los dos.&lt;/p&gt;

&lt;h2&gt;
  
  
  Velocidad: gana Flare, pero la diferencia no está publicada
&lt;/h2&gt;

&lt;p&gt;Flare es el modelo más rápido. La &lt;a href="https://openai.com/index/introducing-images-2-6/?ref=apidog.com" rel="noopener noreferrer"&gt;publicación de lanzamiento&lt;/a&gt; de OpenAI dice que puede generar una imagen en tan solo seis segundos con calidad &lt;code&gt;low&lt;/code&gt;, y que Images 2.6 se ejecuta un 50 % más rápido que antes. No da ningún tiempo para Sunburst, y las páginas de modelo de &lt;a href="https://developers.openai.com/api/docs/models/gpt-image-2.6-flare?ref=apidog.com" rel="noopener noreferrer"&gt;Flare&lt;/a&gt; y &lt;a href="https://developers.openai.com/api/docs/models/gpt-image-2.6-sunburst?ref=apidog.com" rel="noopener noreferrer"&gt;Sunburst&lt;/a&gt; indican la velocidad como «Not specified» (no especificada).&lt;/p&gt;

&lt;p&gt;Lee esa cifra de seis segundos con cuidado:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Es un caso óptimo («tan solo»), no un promedio.&lt;/li&gt;
&lt;li&gt;Solo aplica a la calidad &lt;code&gt;low&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;OpenAI no dice qué ajuste de &lt;code&gt;complexity&lt;/code&gt; la produjo, y la API usa &lt;code&gt;high&lt;/code&gt; por defecto.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Aún no encontramos ningún tiempo independiente para la 2.6. La evidencia más cercana proviene del par 2.5, así que tómala como una guía aproximada:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Prueba (modelos 2.5)&lt;/th&gt;
&lt;th&gt;Flare&lt;/th&gt;
&lt;th&gt;Sunburst&lt;/th&gt;
&lt;th&gt;Sunburst tarda&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;a href="https://www.pixmax.ai/blog/gpt-image-2-5-review-flare-sunburst.html?ref=apidog.com" rel="noopener noreferrer"&gt;Pixmax&lt;/a&gt;, render de 2048x1152 emparejado&lt;/td&gt;
&lt;td&gt;19,7 s&lt;/td&gt;
&lt;td&gt;27,7 s&lt;/td&gt;
&lt;td&gt;1,4 veces más&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;a href="https://poyo.ai/hub/gpt-image-2-5-flare-vs-sunburst?ref=apidog.com" rel="noopener noreferrer"&gt;PoYo&lt;/a&gt;, mediana de un benchmark de 12 solicitudes&lt;/td&gt;
&lt;td&gt;30,89 s&lt;/td&gt;
&lt;td&gt;35,06 s&lt;/td&gt;
&lt;td&gt;1,1 veces más&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Ambas pruebas sitúan a Flare por delante, pero no coinciden en cuánto. La diferencia depende de tu prompt y tus ajustes, así que un solo benchmark no lo resolverá para tu carga de trabajo. La guía de OpenAI también advierte que los prompts complejos pueden tardar hasta dos minutos en los modelos GPT Image, así que configura un timeout de cliente generoso con cualquiera de los dos.&lt;/p&gt;

&lt;h2&gt;
  
  
  Calidad: Sunburst lidera, por poco
&lt;/h2&gt;

&lt;p&gt;Sunburst obtiene mejores puntuaciones en las dos clasificaciones de Arena que &lt;a href="https://x.com/arena/status/2118139063345787124?ref=apidog.com" rel="noopener noreferrer"&gt;Arena publicó el 5 de noviembre&lt;/a&gt;, y se llevó el primer puesto en la categoría de Cartoon, Anime y Fantasy. Flare sigue estando entre los cinco primeros en ambas tablas.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fcq06f45cgdbx9ysqbko1.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fcq06f45cgdbx9ysqbko1.png" alt="Dot plot de las puntuaciones de Arena con calidad Medium: Sunburst supera a Flare por 25 puntos en Text-to-Image, 1409 frente a 1384, y por 14 puntos en Image Edit, 1476 frente a 1462"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Ten en cuenta tres límites al leer esas puntuaciones:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Son votos de preferencia del público, no un benchmark de OpenAI.&lt;/li&gt;
&lt;li&gt;Ambas entradas se ejecutaron en Medium, así que no dicen nada sobre &lt;code&gt;low&lt;/code&gt; o &lt;code&gt;max&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Las puntuaciones de Arena cambian a medida que llegan votos. Las leímos de la publicación de Arena, no del tablero en vivo.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Una ventaja de 25 puntos en Text-to-Image significa que los votantes tendieron a preferir la salida de Sunburst. No significa que las imágenes de Flare sean malas. En un póster o una foto de producto, la promesa de composición que OpenAI hace para Flare puede importarte más que una puntuación de preferencia general, así que prueba esa categoría tú mismo.&lt;/p&gt;

&lt;h2&gt;
  
  
  Consistencia de edición: la principal promesa de Sunburst
&lt;/h2&gt;

&lt;p&gt;La consistencia de edición es la razón por la que pagarías la espera extra de Sunburst. OpenAI dice que aporta «una consistencia de imagen aún mayor entre ediciones» con calidad &lt;code&gt;medium&lt;/code&gt; o &lt;code&gt;high&lt;/code&gt;, lo que ayuda cuando un personaje, producto o logotipo tiene que sobrevivir a varias rondas de cambios.&lt;/p&gt;

&lt;p&gt;Aquí hay menos pruebas públicas de las que cabría esperar:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;OpenAI no publica ninguna métrica de consistencia.&lt;/li&gt;
&lt;li&gt;La &lt;a href="https://deploymentsafety.openai.com/chatgpt-images-2-6?ref=apidog.com" rel="noopener noreferrer"&gt;tarjeta del sistema&lt;/a&gt; dice que ambos modelos actualizados mejoran la consistencia de edición y la preservación del detalle, así que Flare también gana.&lt;/li&gt;
&lt;li&gt;La diferencia de Arena en Image Edit es de 14 puntos, menor que los 25 puntos de Text-to-Image. Esa tabla puntúa qué edición prefirieron los votantes, no si un sujeto se mantuvo estable a lo largo de cinco rondas.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Así que Sunburst es la opción predeterminada más segura para ediciones de varias rondas, pero solo tu propia cadena de ediciones puede confirmar que vale la pena el tiempo. Para un cambio único y concreto, como cambiar un fondo o corregir un cartel, prueba Flare primero.&lt;/p&gt;

&lt;p&gt;Elijas el modelo que elijas, configura &lt;code&gt;complexity&lt;/code&gt; tú mismo. Si lo omites, ambos modelos usan &lt;code&gt;high&lt;/code&gt;, mientras que OpenAI recomienda &lt;code&gt;low&lt;/code&gt; para la mayoría de las ediciones. Su guía advierte que una mayor complejidad puede añadir latencia e introducir cambios no deseados, justo lo contrario de lo que necesita un flujo de trabajo de edición.&lt;/p&gt;

&lt;h2&gt;
  
  
  Costo: el mismo precio, así que la calidad es la verdadera palanca
&lt;/h2&gt;

&lt;p&gt;Flare y Sunburst cuestan lo mismo. La &lt;a href="https://developers.openai.com/api/docs/pricing?ref=apidog.com#image-generation" rel="noopener noreferrer"&gt;página de precios&lt;/a&gt; lista ambos a $8 por 1M de tokens de entrada de imagen, $2 en caché y $30 de salida. La calculadora de OpenAI también los trata como una sola entrada, «GPT Image 2.6 (Sunburst and Flare)», así que la estimación de salida a continuación aplica a cualquiera de los dos modelos.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;
&lt;code&gt;quality&lt;/code&gt; (1024x1024)&lt;/th&gt;
&lt;th&gt;Tokens de salida&lt;/th&gt;
&lt;th&gt;Costo por imagen&lt;/th&gt;
&lt;th&gt;Costo por 1.000&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;low&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;823&lt;/td&gt;
&lt;td&gt;$0,02469&lt;/td&gt;
&lt;td&gt;$24,69&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;medium&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;1.449&lt;/td&gt;
&lt;td&gt;$0,04347&lt;/td&gt;
&lt;td&gt;$43,47&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;high&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;1.756&lt;/td&gt;
&lt;td&gt;$0,05268&lt;/td&gt;
&lt;td&gt;$52,68&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;xhigh&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;3.122&lt;/td&gt;
&lt;td&gt;$0,09366&lt;/td&gt;
&lt;td&gt;$93,66&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;max&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;7.024&lt;/td&gt;
&lt;td&gt;$0,21072&lt;/td&gt;
&lt;td&gt;$210,72&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Estas cifras excluyen los tokens de entrada de texto e imagen, y una edición factura su imagen de referencia aparte. La calculadora señala que el uso de tokens puede variar, así que lee &lt;code&gt;usage.output_tokens&lt;/code&gt; de las respuestas reales.&lt;/p&gt;

&lt;p&gt;De esa tabla se derivan dos cosas:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Pasar de Flare a Sunburst cambia tu tiempo, no tu tarifa.&lt;/strong&gt; Elegir &lt;code&gt;high&lt;/code&gt; en lugar de &lt;code&gt;low&lt;/code&gt; duplica aproximadamente tu costo de salida con cualquiera de los dos modelos.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;De &lt;code&gt;medium&lt;/code&gt; a &lt;code&gt;high&lt;/code&gt; cuesta alrededor de un centavo más por imagen cuadrada.&lt;/strong&gt; Como OpenAI vincula las mejoras de Sunburst a ambos niveles, compáralos antes de decidirte por &lt;code&gt;medium&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Batch es el único punto a tener en cuenta en el costo. El 5 de noviembre, la pestaña Batch de la página de precios listaba la 2.5 a mitad de precio, pero no listaba ninguno de los modelos 2.6. Si ejecutas trabajos nocturnos con el par 2.5, revisa esa pestaña antes de cambiar.&lt;/p&gt;

&lt;h2&gt;
  
  
  ¿Qué modelo deberías usar?
&lt;/h2&gt;

&lt;p&gt;Usa Flare por defecto y luego pasa un trabajo a Sunburst cuando puedas ver la diferencia. Estos ajustes iniciales son nuestras sugerencias, no las de OpenAI, así que ajústalos después de tus primeras pruebas.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Caso de uso&lt;/th&gt;
&lt;th&gt;Elección&lt;/th&gt;
&lt;th&gt;&lt;code&gt;quality&lt;/code&gt;&lt;/th&gt;
&lt;th&gt;&lt;code&gt;complexity&lt;/code&gt;&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Borradores conceptuales e iteración rápida&lt;/td&gt;
&lt;td&gt;Flare&lt;/td&gt;
&lt;td&gt;&lt;code&gt;low&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;low&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Trabajos de imágenes de gran volumen&lt;/td&gt;
&lt;td&gt;Flare&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;low&lt;/code&gt; o &lt;code&gt;medium&lt;/code&gt;
&lt;/td&gt;
&lt;td&gt;&lt;code&gt;low&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Pósteres e imágenes de producto&lt;/td&gt;
&lt;td&gt;Flare&lt;/td&gt;
&lt;td&gt;&lt;code&gt;medium&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;medium&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Una edición concreta&lt;/td&gt;
&lt;td&gt;Flare&lt;/td&gt;
&lt;td&gt;&lt;code&gt;medium&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;low&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Ediciones repetidas sobre un mismo sujeto&lt;/td&gt;
&lt;td&gt;Sunburst&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;medium&lt;/code&gt; o &lt;code&gt;high&lt;/code&gt;
&lt;/td&gt;
&lt;td&gt;&lt;code&gt;low&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Imágenes finales destacadas y de campaña&lt;/td&gt;
&lt;td&gt;Sunburst&lt;/td&gt;
&lt;td&gt;&lt;code&gt;high&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;medium&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Arte de cartoon, anime y fantasía&lt;/td&gt;
&lt;td&gt;Sunburst&lt;/td&gt;
&lt;td&gt;&lt;code&gt;medium&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;medium&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Texto denso, muchos elementos con restricciones&lt;/td&gt;
&lt;td&gt;Sunburst&lt;/td&gt;
&lt;td&gt;&lt;code&gt;high&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;high&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Ftcz0z4yt1o98b052jzzf.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Ftcz0z4yt1o98b052jzzf.png" alt="Flujo de decisión para elegir un modelo: las ediciones repetidas sobre un mismo sujeto o un recurso final detallado van a Sunburst con calidad medium o high, mientras que los borradores, el trabajo de volumen, los pósteres y las ediciones únicas van a Flare"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Para GIF y SVG, OpenAI no publica ninguna diferencia de calidad o velocidad entre los modelos. Haz el borrador con Flare y luego vuelve a ejecutar tu mejor prompt con Sunburst y compara. Revisa primero dos detalles de los GIF: la guía de OpenAI permite de 2 a 64 fotogramas, mientras que su &lt;a href="https://developers.openai.com/api/reference/resources/images/methods/generate?ref=apidog.com" rel="noopener noreferrer"&gt;referencia de la API&lt;/a&gt; dice de 2 a 16, y la referencia indica que la salida GIF requiere acceso de vista previa para el modelo seleccionado.&lt;/p&gt;

&lt;p&gt;Si fijas modelos en producción, ten en cuenta que ambas páginas de modelo muestran solo el alias el 5 de noviembre, sin una instantánea con fecha. Vuelve a comprobar tus prompts aprobados cuando OpenAI actualice un modelo.&lt;/p&gt;

&lt;h2&gt;
  
  
  Compara ambos modelos con Apidog CLI
&lt;/h2&gt;

&lt;p&gt;Las puntuaciones públicas no pueden decirte cómo maneja cada modelo tus prompts. Tu agente de programación puede ejecutar el mismo conjunto de prompts con ambos modelos usando &lt;a href="https://apidog.com/apidog-cli/?ref=apidog.com&amp;amp;utm_source=dev.to&amp;amp;utm_medium=wanda&amp;amp;utm_content=n8n-post-automation"&gt;Apidog CLI&lt;/a&gt; y comparar los tiempos de respuesta. Configúralo una vez:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npm &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="nt"&gt;-g&lt;/span&gt; apidog-cli@latest
apidog auth login &lt;span class="nt"&gt;--with-token&lt;/span&gt; &amp;lt;YOUR_TOKEN&amp;gt;
apidog skill &lt;span class="nb"&gt;install&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Guarda cinco prompts de tu carga de trabajo real en &lt;code&gt;prompts.csv&lt;/code&gt;, con &lt;code&gt;prompt&lt;/code&gt; como encabezado. Luego dale a Claude Code, Codex o Cursor un [REDACTED PROMPT]&lt;br&gt;
In Apidog project , add POST &lt;a href="https://api.openai.com/v1/images/generations" rel="noopener noreferrer"&gt;https://api.openai.com/v1/images/generations&lt;/a&gt;&lt;br&gt;
with a Bearer [REDACTED] from ah-96595b54133dd71b741cc9d4907506e2b3a06f289e0016f9de2d7fb43e327968. Create a test case that sends&lt;br&gt;
model {{MODEL}}, prompt {{prompt}}, quality medium, complexity low and size&lt;br&gt;
1024x1024. Assert status 200 and that data[0].b64_json exists.&lt;br&gt;
Run it with prompts.csv once per model, gpt-image-2.6-flare and&lt;br&gt;
gpt-image-2.6-sunburst, then compare the timings in the two JSON reports.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;
El agente lee cada esquema, valida su payload, crea el caso y luego lo ejecuta dos veces:

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;&lt;br&gt;
bash&lt;br&gt;
apidog cli-schema get endpoint-create&lt;br&gt;
apidog cli-schema validate endpoint-create --file endpoint.json&lt;br&gt;
apidog endpoint create --project  --file endpoint.json&lt;br&gt;
apidog cli-schema get test-case-create&lt;br&gt;
apidog cli-schema validate test-case-create --file case.json&lt;br&gt;
apidog test-case create --project  --file case.json&lt;br&gt;
apidog run --test-case  --project  -e  -d prompts.csv \&lt;br&gt;
  --env-var "MODEL=gpt-image-2.6-flare" \&lt;br&gt;
  --env-var "OPENAI_API_KEY=$OPENAI_API_KEY" \&lt;br&gt;
  --timeout-request 180000 --on-error continue -r cli,json --out-file flare&lt;br&gt;
apidog run --test-case  --project  -e  -d prompts.csv \&lt;br&gt;
  --env-var "MODEL=gpt-image-2.6-sunburst" \&lt;br&gt;
  --env-var "OPENAI_API_KEY=$OPENAI_API_KEY" \&lt;br&gt;
  --timeout-request 180000 --on-error continue -r cli,json --out-file sunburst&lt;/p&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;


Cada informe JSON almacena milisegundos bajo `result.timings`, en `responseAverage`, `responseMin`, `responseMax` y `responseSd`. Tu agente puede ponerlos uno al lado del otro y decirte la diferencia real con tus prompts. Diez imágenes en `medium` cuestan unos $0,43 en tokens de salida, más la entrada.

Construimos este flujo a partir de `apidog --help` y los esquemas de la CLI, y no lo hemos ejecutado contra OpenAI, así que revisa el primer informe antes de confiar en él. Apidog mide la velocidad y la corrección de la respuesta, no la calidad de la imagen, así que los píxeles los sigues juzgando tú. Para seguir midiendo el par después de cada actualización de modelo, mueve la ejecución a un [pipeline de CI](https://apidog.com/es/blog/apidog-cli-ci-cd-pipeline?utm_source=dev.to&amp;amp;utm_medium=wanda&amp;amp;utm_content=n8n-post-automation), y consulta la [guía de configuración en Claude Code](https://apidog.com/es/blog/apidog-cli-in-claude-code?utm_source=dev.to&amp;amp;utm_medium=wanda&amp;amp;utm_content=n8n-post-automation) para más detalles sobre el agente.

## Preguntas frecuentes

**¿Es mejor Flare o Sunburst?** Ninguno gana en todo. Sunburst se clasifica más alto en las tablas de Text-to-Image e Image Edit de Arena, y OpenAI lo orienta al trabajo detallado. Flare está hecho para la velocidad. Empieza con Flare y pasa a Sunburst cuando puedas ver una mejora.

**¿Cuesta más Sunburst que Flare?** No. Ambos listan $8 de entrada de imagen, $2 en caché y $30 de salida por 1M de tokens, y comparten una sola entrada en la calculadora. Tu ajuste de calidad cambia la factura, no tu elección de modelo.

**¿Cuánto más rápido es Flare que Sunburst?** OpenAI no lo ha dicho. Solo da el caso óptimo de Flare, seis segundos con `low`. Dos pruebas independientes del par 2.5 mostraron que Sunburst tardaba entre 1,1 y 1,4 veces más, pero esos resultados pueden no trasladarse a la 2.6.

**¿Qué modelo es mejor para editar?** Usa Sunburst para ediciones repetidas sobre un mismo sujeto, con calidad `medium` o `high`. Prueba Flare para un cambio único y concreto. Configura `complexity` en `low` en ambos, ya que el valor por defecto es `high`.

**¿Pueden ambos modelos crear GIF y SVG?** Sí. La guía de OpenAI lista la salida GIF y SVG para ambos modelos en `POST /v1/images/generations`. El endpoint de ediciones no puede devolver ninguno de los dos formatos.

**¿Debería seguir usando GPT-Image-2.5?** Revisa primero Batch. La pestaña Batch listaba la 2.5 a mitad de precio el 5 de noviembre, pero no listaba la 2.6. La calculadora de OpenAI también muestra que la 2.6 usa más tokens con `low` y `medium`, así que los trabajos de gran volumen en `low` pueden costar menos con la 2.5.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

</description>
      <category>ai</category>
      <category>chatgpt</category>
      <category>openai</category>
      <category>spanish</category>
    </item>
    <item>
      <title>¿Qué es ChatGPT Images 2.6? GIFs, exportación SVG y generación un 50% más rápida</title>
      <dc:creator>Roobia</dc:creator>
      <pubDate>Thu, 05 Nov 2026 10:43:40 +0000</pubDate>
      <link>https://dev.to/roobia/que-es-chatgpt-images-26-gifs-exportacion-svg-y-generacion-un-50-mas-rapida-h9n</link>
      <guid>https://dev.to/roobia/que-es-chatgpt-images-26-gifs-exportacion-svg-y-generacion-un-50-mas-rapida-h9n</guid>
      <description>&lt;p&gt;ChatGPT Images 2.6 es la actualización de generación de imágenes de OpenAI, publicada el 4 de noviembre de 2026 para ChatGPT, Codex y la API. Añade GIF animados, salida SVG para desarrolladores, marcado de imágenes y un ajuste de &lt;code&gt;complexity&lt;/code&gt;, y OpenAI afirma que genera imágenes un 50% más rápido. La API lo distribuye como dos modelos: GPT-Image-2.6 Flare y GPT-Image-2.6 Sunburst.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://apidog.com/?utm_source=dev.to&amp;amp;utm_medium=wanda&amp;amp;utm_content=n8n-post-automation" class="crayons-btn crayons-btn--primary"&gt;Prueba Apidog hoy&lt;/a&gt;
&lt;/p&gt;

&lt;p&gt;Si leíste nuestro &lt;a href="https://apidog.com/es/blog/what-is-chatgpt-images-2-5?utm_source=dev.to&amp;amp;utm_medium=wanda&amp;amp;utm_content=n8n-post-automation"&gt;artículo explicativo sobre ChatGPT Images 2.5&lt;/a&gt;, esta publicación solo cubre lo que cambió. Hay un detalle que el &lt;a href="https://openai.com/index/introducing-images-2-6/?ref=apidog.com" rel="noopener noreferrer"&gt;anuncio de lanzamiento&lt;/a&gt; no menciona: las tarifas por token siguen igual, pero una imagen de calidad &lt;code&gt;low&lt;/code&gt; ahora consume aproximadamente 4,2 veces los tokens de salida que consumía en 2.5.&lt;/p&gt;

&lt;h2&gt;
  
  
  ChatGPT Images 2.6 de un vistazo
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Elemento&lt;/th&gt;
&lt;th&gt;Detalle&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Fecha de lanzamiento&lt;/td&gt;
&lt;td&gt;4 de noviembre de 2026 (&lt;a href="https://developers.openai.com/api/docs/changelog?ref=apidog.com" rel="noopener noreferrer"&gt;registro de cambios de la API&lt;/a&gt;)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Dónde funciona&lt;/td&gt;
&lt;td&gt;ChatGPT, Codex y la API&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Acceso en ChatGPT y Codex&lt;/td&gt;
&lt;td&gt;Global, todos los niveles de suscripción, escritorio, móvil y web&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;IDs de modelo en la API&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;gpt-image-2.6-flare&lt;/code&gt;, &lt;code&gt;gpt-image-2.6-sunburst&lt;/code&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Aumento de velocidad&lt;/td&gt;
&lt;td&gt;50% más rápido que antes; Flare en tan solo seis segundos con calidad &lt;code&gt;low&lt;/code&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Nuevas salidas&lt;/td&gt;
&lt;td&gt;GIF animado (ChatGPT y API), SVG (API)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Nuevos controles&lt;/td&gt;
&lt;td&gt;Marcado de imágenes, &lt;code&gt;complexity&lt;/code&gt; (&lt;code&gt;low&lt;/code&gt;, &lt;code&gt;medium&lt;/code&gt;, &lt;code&gt;high&lt;/code&gt;)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Tarifas de tokens de imagen&lt;/td&gt;
&lt;td&gt;$8 entrada, $2 entrada en caché, $30 salida por 1M de tokens&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Uso&lt;/td&gt;
&lt;td&gt;4 mil millones de imágenes por semana en ChatGPT, Codex y la API&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h2&gt;
  
  
  Qué hay de nuevo respecto a Images 2.5
&lt;/h2&gt;

&lt;p&gt;Images 2.5 trajo Flare y Sunburst, los niveles de calidad &lt;code&gt;xhigh&lt;/code&gt; y &lt;code&gt;max&lt;/code&gt;, y funciones de ChatGPT como Sketch y Templates. La versión 2.6 mantiene la división en dos modelos y los cinco niveles de calidad, y añade lo siguiente:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Área&lt;/th&gt;
&lt;th&gt;Images 2.5&lt;/th&gt;
&lt;th&gt;Images 2.6&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Salida animada&lt;/td&gt;
&lt;td&gt;Ninguna&lt;/td&gt;
&lt;td&gt;GIF, de 2 a 64 fotogramas en la API&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Salida vectorial&lt;/td&gt;
&lt;td&gt;Ninguna&lt;/td&gt;
&lt;td&gt;SVG, solo en la API según la tarjeta del sistema&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Control de planificación&lt;/td&gt;
&lt;td&gt;Ninguno&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;complexity&lt;/code&gt;: &lt;code&gt;low&lt;/code&gt;, &lt;code&gt;medium&lt;/code&gt;, &lt;code&gt;high&lt;/code&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Ediciones guiadas por marcado&lt;/td&gt;
&lt;td&gt;Primero en ChatGPT, compatibilidad con la API añadida el 4 de noviembre&lt;/td&gt;
&lt;td&gt;ChatGPT y API&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Tokens con &lt;code&gt;low&lt;/code&gt;, 1024x1024&lt;/td&gt;
&lt;td&gt;196&lt;/td&gt;
&lt;td&gt;823&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Precio de lote listado&lt;/td&gt;
&lt;td&gt;Sí&lt;/td&gt;
&lt;td&gt;No listado el 5 de noviembre&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Imágenes semanales&lt;/td&gt;
&lt;td&gt;"Más de 3 mil millones"&lt;/td&gt;
&lt;td&gt;4 mil millones&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;La &lt;a href="https://deploymentsafety.openai.com/chatgpt-images-2-6?ref=apidog.com" rel="noopener noreferrer"&gt;tarjeta del sistema&lt;/a&gt; de OpenAI también indica que ambos modelos mejoran la consistencia de las ediciones, la preservación del detalle y las respuestas a bocetos y anotaciones. El anuncio de lanzamiento no mide nada de eso con un benchmark público, y no especifica respecto a qué referencia se compara ese "50% más rápido", así que toma la cifra de velocidad como una afirmación de OpenAI hasta que cronometres tus propios prompts.&lt;/p&gt;

&lt;h2&gt;
  
  
  ¿Quién puede usar ChatGPT Images 2.6?
&lt;/h2&gt;

&lt;p&gt;OpenAI afirma que Images 2.6 está disponible globalmente en ChatGPT y Codex "en todos los niveles de suscripción", en escritorio, móvil y web. El acceso a la API se realiza a través de los dos modelos anteriores, y es posible que tengas que completar la &lt;a href="https://help.openai.com/en/articles/10910291-api-organization-verification?ref=apidog.com" rel="noopener noreferrer"&gt;verificación de organización de la API&lt;/a&gt; antes de poder llamarlos.&lt;/p&gt;

&lt;p&gt;Quedan dos preguntas abiertas para los usuarios de ChatGPT:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Límites de GIF en el plan Free.&lt;/strong&gt; Ni el anuncio de lanzamiento ni la &lt;a href="https://openai.com/chatgpt/pricing/?ref=apidog.com" rel="noopener noreferrer"&gt;página de precios de ChatGPT&lt;/a&gt; indican una cuota de GIF. La página de precios incluye la generación de imágenes como "Limitada" en Free.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Thinking.&lt;/strong&gt; La misma página, consultada el 5 de noviembre, incluye "Generación de imágenes con Thinking" en Plus y Pro, pero no en Free ni en Go.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;En Codex, la generación de imágenes se invoca con la &lt;a href="https://developers.openai.com/codex/image-generation?ref=apidog.com" rel="noopener noreferrer"&gt;habilidad &lt;code&gt;$imagegen&lt;/code&gt;&lt;/a&gt;. Esa página aún no menciona la salida en GIF ni SVG.&lt;/p&gt;

&lt;h2&gt;
  
  
  Flare vs Sunburst: ¿qué hace cada modelo?
&lt;/h2&gt;

&lt;p&gt;Flare es el modelo rápido para trabajo interactivo. OpenAI afirma que también mejora la calidad del diseño en carteles e imágenes de producto. Sunburst está pensado para composiciones detalladas, con mayor calidad y mejor consistencia entre ediciones con calidad &lt;code&gt;medium&lt;/code&gt; o &lt;code&gt;high&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Ambos modelos cuestan lo mismo por token y comparten una única entrada en la calculadora. Nuestra &lt;a href="https://apidog.com/es/blog/gpt-image-2-5-flare-vs-sunburst-vs-gpt-image-2?utm_source=dev.to&amp;amp;utm_medium=wanda&amp;amp;utm_content=n8n-post-automation"&gt;comparativa de Flare vs Sunburst para 2.5&lt;/a&gt; explica esa división con más detalle, y la mayor parte sigue siendo válida.&lt;/p&gt;

&lt;h2&gt;
  
  
  Cómo funciona la generación de GIF
&lt;/h2&gt;

&lt;p&gt;La API devuelve una animación terminada, no una hoja de sprites que tengas que ensamblar tú mismo. Los prompts de ejemplo del anuncio de lanzamiento piden una hoja de sprites de seis fotogramas en una cuadrícula de 3x2, pero la &lt;a href="https://developers.openai.com/api/docs/guides/image-generation?ref=apidog.com#gpt-image-26" rel="noopener noreferrer"&gt;guía de generación de imágenes&lt;/a&gt; documenta una ruta directa:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Llama a &lt;code&gt;POST /v1/images/generations&lt;/code&gt; con &lt;code&gt;output_format: "gif"&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Describe el sujeto, el movimiento y el bucle en tu prompt.&lt;/li&gt;
&lt;li&gt;Establece &lt;code&gt;frame_count&lt;/code&gt; (de 2 a 64, por defecto 9).&lt;/li&gt;
&lt;li&gt;Establece &lt;code&gt;frame_duration_ms&lt;/code&gt; (de 20 a 2000, redondeado a 10 ms, por defecto 200).&lt;/li&gt;
&lt;li&gt;Decodifica &lt;code&gt;b64_json&lt;/code&gt; desde base64 y guárdalo con extensión &lt;code&gt;.gif&lt;/code&gt;.
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;curl &lt;span class="nt"&gt;--fail&lt;/span&gt; &lt;span class="nt"&gt;--silent&lt;/span&gt; &lt;span class="nt"&gt;--show-error&lt;/span&gt; https://api.openai.com/v1/images/generations &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s2"&gt;"Authorization: Bearer &lt;/span&gt;&lt;span class="nv"&gt;$OPENAI_API_KEY&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s2"&gt;"Content-Type: application/json"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-d&lt;/span&gt; &lt;span class="s1"&gt;'{
    "model": "gpt-image-2.6-flare",
    "prompt": "A small orange robot waves, blinks, and returns to its starting pose. Loop it.",
    "output_format": "gif",
    "frame_count": 9,
    "frame_duration_ms": 200,
    "size": "auto"
  }'&lt;/span&gt; | jq &lt;span class="nt"&gt;-er&lt;/span&gt; &lt;span class="s1"&gt;'.data[0].b64_json'&lt;/span&gt; | &lt;span class="nb"&gt;base64&lt;/span&gt; &lt;span class="nt"&gt;--decode&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; robot.gif
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Construimos esta solicitud a partir de la lista de campos de la guía y no la hemos ejecutado con una clave real, así que pruébala antes de implementarla.&lt;/p&gt;

&lt;p&gt;Ten en cuenta estos límites:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;/v1/images/edits&lt;/code&gt; no puede devolver GIF, por lo que no puedes animar una imagen subida a través de ese endpoint.&lt;/li&gt;
&lt;li&gt;La salida GIF no admite streaming, imágenes parciales, &lt;code&gt;output_compression&lt;/code&gt; personalizado ni &lt;code&gt;prompt_rewriter&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;El número de fotogramas, el tamaño de fotograma y &lt;code&gt;n&lt;/code&gt; deben ajustarse a un presupuesto total de píxeles. Si una solicitud falla, reduce uno de ellos.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Exportación SVG: qué obtienes
&lt;/h2&gt;

&lt;p&gt;Establece &lt;code&gt;output_format: "svg"&lt;/code&gt; en &lt;code&gt;POST /v1/images/generations&lt;/code&gt; para iconos, logotipos e ilustraciones que necesiten trazados, formas y colores editables. La API primero crea una imagen de referencia y luego genera el SVG a partir de ella; &lt;code&gt;quality&lt;/code&gt; controla esa imagen de referencia.&lt;/p&gt;

&lt;p&gt;La salida es contenido vectorial estático, sin scripts, recursos externos ni mapas de bits incrustados. Las restricciones son estrictas: &lt;code&gt;n&lt;/code&gt; debe ser 1, no hay streaming y ni &lt;code&gt;output_compression&lt;/code&gt; ni &lt;code&gt;prompt_rewriter&lt;/code&gt; funcionan. El endpoint de ediciones no puede generar SVG, y un SVG no puede ser una entrada raster para ediciones.&lt;/p&gt;

&lt;p&gt;La facturación también es distinta. Pagas la tarifa del modelo de imágenes por la imagen de referencia, más la tarifa de un modelo de autoría por los tokens que escriben el SVG. OpenAI no publica un precio fijo por SVG, así que mídelo con tus propios prompts.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fdqt0u2sch86ekaurfyai.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fdqt0u2sch86ekaurfyai.png" alt="Diagrama de los dos endpoints de GPT-Image-2.6: generations devuelve imágenes raster, GIF animado o SVG, mientras que edits solo devuelve imágenes raster y acepta una capa de marcado" width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  El parámetro complexity y el marcado de imágenes
&lt;/h2&gt;

&lt;p&gt;&lt;code&gt;complexity&lt;/code&gt; determina cuánto planifica el modelo antes de renderizar. &lt;code&gt;quality&lt;/code&gt; determina el nivel de detalle del renderizado. Son controles independientes, y ajustar la complejidad no conlleva ningún cargo adicional.&lt;/p&gt;

&lt;p&gt;Ojo con el valor predeterminado. Si omites &lt;code&gt;complexity&lt;/code&gt;, ambos modelos usan &lt;code&gt;high&lt;/code&gt;, aunque OpenAI recomienda &lt;code&gt;low&lt;/code&gt; para la mayoría de las ediciones, combinado con la calidad que necesites. La guía advierte que una mayor complejidad puede añadir latencia e introducir cambios no deseados. Para cambios de fondo y correcciones de carteles, establece &lt;code&gt;low&lt;/code&gt; explícitamente. Reserva &lt;code&gt;medium&lt;/code&gt; o &lt;code&gt;high&lt;/code&gt; para texto denso, diseños complejos y escenas con muchos elementos restringidos.&lt;/p&gt;

&lt;p&gt;El marcado de imágenes llega a &lt;code&gt;POST /v1/images/edits&lt;/code&gt; como un campo &lt;code&gt;markup&lt;/code&gt;. Envías una superposición transparente que rodea el objetivo y luego describes el cambio en &lt;code&gt;prompt&lt;/code&gt;. El ejemplo de OpenAI rodea un jarrón, lo recolorea y pide al modelo que elimine el círculo de la foto final. El marcado también funciona en los modelos 2.5 compatibles, cuesta lo mismo que otras ediciones y no está disponible a través de la API de Responses, donde la guía te remite a las máscaras.&lt;/p&gt;

&lt;h2&gt;
  
  
  Precios de GPT-Image-2.6: mismas tarifas, más tokens con calidad low
&lt;/h2&gt;

&lt;p&gt;Los precios por token coinciden con 2.5 en la &lt;a href="https://developers.openai.com/api/docs/pricing?ref=apidog.com#image-generation" rel="noopener noreferrer"&gt;página de precios&lt;/a&gt;: $8 por 1M de tokens de entrada de imagen, $2 en caché, $30 de salida, $5 de entrada de texto, $1,25 de texto en caché. Lo que cambió es el uso de tokens. La calculadora de OpenAI aplica un multiplicador de 4,2 con &lt;code&gt;low&lt;/code&gt; y de 3,3 con &lt;code&gt;medium&lt;/code&gt; para 2.6, y ninguno por encima de eso.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Calidad (1024x1024)&lt;/th&gt;
&lt;th&gt;Tokens en 2.5&lt;/th&gt;
&lt;th&gt;Coste de salida en 2.5&lt;/th&gt;
&lt;th&gt;Tokens en 2.6&lt;/th&gt;
&lt;th&gt;Coste de salida en 2.6&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;low&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;196&lt;/td&gt;
&lt;td&gt;$0.00588&lt;/td&gt;
&lt;td&gt;823&lt;/td&gt;
&lt;td&gt;$0.02469&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;medium&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;439&lt;/td&gt;
&lt;td&gt;$0.01317&lt;/td&gt;
&lt;td&gt;1,449&lt;/td&gt;
&lt;td&gt;$0.04347&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;high&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;1,756&lt;/td&gt;
&lt;td&gt;$0.05268&lt;/td&gt;
&lt;td&gt;1,756&lt;/td&gt;
&lt;td&gt;$0.05268&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;xhigh&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;3,122&lt;/td&gt;
&lt;td&gt;$0.09366&lt;/td&gt;
&lt;td&gt;3,122&lt;/td&gt;
&lt;td&gt;$0.09366&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;max&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;7,024&lt;/td&gt;
&lt;td&gt;$0.21072&lt;/td&gt;
&lt;td&gt;7,024&lt;/td&gt;
&lt;td&gt;$0.21072&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Flm0j1msu63tvs9bnmt6p.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Flm0j1msu63tvs9bnmt6p.png" alt="Gráfico de barras del coste de salida por imagen de 1024x1024 según el nivel de calidad: 2.6 cuesta más que 2.5 con low y medium, e igual con high, xhigh y max" width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Estas cifras provienen de la calculadora y excluyen los tokens de entrada. El formato horizontal es más barato: &lt;code&gt;low&lt;/code&gt; a 1536x1024 usa 664 tokens, unos $0,02.&lt;/p&gt;

&lt;p&gt;Así que si ejecutas trabajos de gran volumen con &lt;code&gt;low&lt;/code&gt; en 2.5, pasarte a 2.6 multiplica tu factura de salida por aproximadamente 4,2. &lt;code&gt;medium&lt;/code&gt; en 2.6 ahora cuesta casi lo mismo que &lt;code&gt;high&lt;/code&gt;, lo que hace que valga la pena probar &lt;code&gt;high&lt;/code&gt;. La pestaña Batch de la página de precios incluye 2.5 a mitad de precio, pero no incluye 2.6, por lo que una carga de trabajo por lotes puede salir más barata en 2.5 por ahora. La guía tampoco incluye una fórmula de facturación específica para GIF, así que haz una prueba con un &lt;code&gt;frame_count&lt;/code&gt; pequeño y revisa tu consumo antes de escalar. Nuestra &lt;a href="https://apidog.com/es/blog/gpt-image-2-5-api?utm_source=dev.to&amp;amp;utm_medium=wanda&amp;amp;utm_content=n8n-post-automation"&gt;guía de la API de gpt-image-2.5&lt;/a&gt; cubre los conceptos básicos de las solicitudes que siguen aplicando.&lt;/p&gt;

&lt;h2&gt;
  
  
  Seguridad y procedencia
&lt;/h2&gt;

&lt;p&gt;OpenAI probó ambos modelos con 3077 prompts adversarios. Esos resultados no son tasas de producción. La proporción de generaciones inseguras no bloqueadas pasó del 1,92% al 1,72% en Sunburst, y del 1,49% al 2,14% en Flare, aunque OpenAI no marca ninguno de los dos cambios como estadísticamente significativo.&lt;/p&gt;

&lt;p&gt;Los GIF conllevan un riesgo nuevo, ya que el daño puede aparecer a lo largo de los fotogramas en lugar de en una sola imagen fija. OpenAI reporta un 77,7% de recall de moderación en un conjunto adversario de GIF, y afirma que las infracciones relacionadas con el movimiento siguen siendo difíciles de detectar.&lt;/p&gt;

&lt;p&gt;En cuanto a la procedencia, Images 2.6 utiliza metadatos C2PA más una marca de agua invisible de SynthID en ChatGPT, Codex y la API.&lt;/p&gt;

&lt;h2&gt;
  
  
  Deja que tu agente de código lo pruebe con Apidog CLI
&lt;/h2&gt;

&lt;p&gt;Esta versión cambió el uso de tokens sin cambiar la tarifa. Una prueba guardada detecta un cambio incompatible en una solicitud de la que dependes, y tu agente de código puede escribirla con &lt;a href="https://apidog.com/apidog-cli/?ref=apidog.com&amp;amp;utm_source=dev.to&amp;amp;utm_medium=wanda&amp;amp;utm_content=n8n-post-automation"&gt;Apidog CLI&lt;/a&gt;. Configúralo una vez:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npm &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="nt"&gt;-g&lt;/span&gt; apidog-cli@latest
apidog auth login &lt;span class="nt"&gt;--with-token&lt;/span&gt; &amp;lt;YOUR_TOKEN&amp;gt;
apidog skill &lt;span class="nb"&gt;install&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Luego dale un prompt a Claude Code, Codex o Cursor:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Add POST https://api.openai.com/v1/images/generations to Apidog project &amp;lt;id&amp;gt;.
Create a test case that sends model gpt-image-2.6-flare, quality low,
complexity low, output_format gif and frame_count 6, with the Bearer [REDACTED]
read from the OPENAI_API_KEY environment variable. Assert status 200 and that
data[0].b64_json exists. Run it against environment &amp;lt;envId&amp;gt; and summarize failures.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;El agente lee cada esquema, valida su payload y luego escribe y ejecuta la prueba:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;apidog cli-schema get endpoint-create
apidog cli-schema validate endpoint-create &lt;span class="nt"&gt;--file&lt;/span&gt; endpoint.json
apidog endpoint create &lt;span class="nt"&gt;--project&lt;/span&gt; &amp;lt;&lt;span class="nb"&gt;id&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="nt"&gt;--file&lt;/span&gt; endpoint.json
apidog cli-schema get test-case-create
apidog cli-schema validate test-case-create &lt;span class="nt"&gt;--file&lt;/span&gt; &lt;span class="k"&gt;case&lt;/span&gt;.json
apidog test-case create &lt;span class="nt"&gt;--project&lt;/span&gt; &amp;lt;&lt;span class="nb"&gt;id&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="nt"&gt;--file&lt;/span&gt; &lt;span class="k"&gt;case&lt;/span&gt;.json
apidog run &lt;span class="nt"&gt;--test-case&lt;/span&gt; &amp;lt;caseId&amp;gt; &lt;span class="nt"&gt;--project&lt;/span&gt; &amp;lt;&lt;span class="nb"&gt;id&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="nt"&gt;-e&lt;/span&gt; &amp;lt;envId&amp;gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--env-var&lt;/span&gt; &lt;span class="s2"&gt;"OPENAI_API_KEY=&lt;/span&gt;&lt;span class="nv"&gt;$OPENAI_API_KEY&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="nt"&gt;-r&lt;/span&gt; cli,json
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Cada ejecución genera una imagen real y facturable, así que mantén bajos el número de fotogramas y la calidad. Duplica el caso con &lt;code&gt;gpt-image-2.6-sunburst&lt;/code&gt; para comparar ambos modelos. Cambia &lt;code&gt;-r cli,json&lt;/code&gt; por &lt;code&gt;-r junit&lt;/code&gt; para ejecutarlo en un &lt;a href="https://apidog.com/es/blog/apidog-cli-ci-cd-pipeline?utm_source=dev.to&amp;amp;utm_medium=wanda&amp;amp;utm_content=n8n-post-automation"&gt;pipeline de CI&lt;/a&gt;, y consulta la &lt;a href="https://apidog.com/es/blog/apidog-cli-in-claude-code?utm_source=dev.to&amp;amp;utm_medium=wanda&amp;amp;utm_content=n8n-post-automation"&gt;guía de configuración de Claude Code&lt;/a&gt; para más detalles sobre agentes.&lt;/p&gt;

&lt;h2&gt;
  
  
  Preguntas frecuentes
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;¿ChatGPT Images 2.6 es gratis?&lt;/strong&gt; OpenAI afirma que está disponible en todos los niveles de suscripción, y la página de precios indica generación de imágenes limitada en el plan Free. Ninguna de las dos fuentes da una cuota de GIF para los usuarios de Free. El uso de la API se factura por token.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;¿La API devuelve un GIF o una hoja de sprites?&lt;/strong&gt; Un GIF terminado. Establece &lt;code&gt;output_format: "gif"&lt;/code&gt; en el endpoint de generaciones y luego decodifica &lt;code&gt;b64_json&lt;/code&gt;. Las hojas de sprites del anuncio de lanzamiento provienen de prompts de ejemplo.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;¿GPT-Image-2.6 es más caro que 2.5?&lt;/strong&gt; Las tarifas por token coinciden, pero las imágenes con &lt;code&gt;low&lt;/code&gt; y &lt;code&gt;medium&lt;/code&gt; usan más tokens. Una imagen &lt;code&gt;low&lt;/code&gt; de 1024x1024 pasa de unos $0,006 a unos $0,025 en coste de salida. &lt;code&gt;high&lt;/code&gt;, &lt;code&gt;xhigh&lt;/code&gt; y &lt;code&gt;max&lt;/code&gt; no cambian.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;¿Cuál es la diferencia entre &lt;code&gt;quality&lt;/code&gt; y &lt;code&gt;complexity&lt;/code&gt;?&lt;/strong&gt; &lt;code&gt;quality&lt;/code&gt; controla el detalle del renderizado y determina el coste en tokens. &lt;code&gt;complexity&lt;/code&gt; controla cuánto planifica el modelo y su valor predeterminado es &lt;code&gt;high&lt;/code&gt;. OpenAI sugiere complejidad &lt;code&gt;low&lt;/code&gt; para la mayoría de las ediciones.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;¿Puedo convertir una imagen existente en un GIF o SVG a través de la API?&lt;/strong&gt; No. El endpoint de ediciones no admite salida GIF ni SVG, y los archivos SVG no se aceptan como entradas raster. Ambos formatos provienen únicamente del endpoint de generaciones.&lt;/p&gt;

</description>
    </item>
    <item>
      <title>Cómo usar la API de GPT-Image-2.6</title>
      <dc:creator>Roobia</dc:creator>
      <pubDate>Thu, 05 Nov 2026 10:42:54 +0000</pubDate>
      <link>https://dev.to/roobia/como-usar-la-api-de-gpt-image-26-36n1</link>
      <guid>https://dev.to/roobia/como-usar-la-api-de-gpt-image-26-36n1</guid>
      <description>&lt;h1&gt;
  
  
  Cómo usar la API de GPT-Image-2.6
&lt;/h1&gt;

&lt;p&gt;La API de GPT-Image-2.6 genera y edita imágenes mediante dos modelos de OpenAI, &lt;code&gt;gpt-image-2.6-flare&lt;/code&gt; y &lt;code&gt;gpt-image-2.6-sunburst&lt;/code&gt;. Envía un prompt a &lt;code&gt;POST /v1/images/generations&lt;/code&gt; con tu clave de API y luego decodifica &lt;code&gt;b64_json&lt;/code&gt; de la respuesta. La versión 2.6 incorpora marcado sobre imágenes, salida en SVG y GIF, y un parámetro &lt;code&gt;complexity&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://apidog.com/?utm_source=dev.to&amp;amp;utm_medium=wanda&amp;amp;utm_content=n8n-post-automation" class="crayons-btn crayons-btn--primary"&gt;Prueba Apidog hoy&lt;/a&gt;
&lt;/p&gt;

&lt;p&gt;Esta guía abarca la autenticación, una primera generación, una edición con marcado, la exportación a SVG y la configuración de &lt;code&gt;quality&lt;/code&gt; y &lt;code&gt;complexity&lt;/code&gt;. Nos centramos en lo nuevo, así que consulta nuestra &lt;a href="https://apidog.com/es/blog/gpt-image-2-5-api?utm_source=dev.to&amp;amp;utm_medium=wanda&amp;amp;utm_content=n8n-post-automation"&gt;guía de la API de gpt-image-2.5&lt;/a&gt; para streaming y la herramienta de la Responses API, y nuestro &lt;a href="https://apidog.com/es/blog/what-is-chatgpt-images-2-6?utm_source=dev.to&amp;amp;utm_medium=wanda&amp;amp;utm_content=n8n-post-automation"&gt;artículo explicativo sobre ChatGPT Images 2.6&lt;/a&gt; para conocer todos los detalles del lanzamiento. Todas las peticiones que verás a continuación las elaboramos a partir de la documentación de OpenAI del 5 de noviembre de 2026. No las hemos ejecutado con una clave real, así que pruébalas antes de llevarlas a producción.&lt;/p&gt;

&lt;h2&gt;
  
  
  La API de GPT-Image-2.6 de un vistazo
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Elemento&lt;/th&gt;
&lt;th&gt;Detalle&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;IDs de modelo&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;gpt-image-2.6-flare&lt;/code&gt;, &lt;code&gt;gpt-image-2.6-sunburst&lt;/code&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Generación&lt;/td&gt;
&lt;td&gt;&lt;code&gt;POST /v1/images/generations&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Edición&lt;/td&gt;
&lt;td&gt;&lt;code&gt;POST /v1/images/edits&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Autenticación&lt;/td&gt;
&lt;td&gt;&lt;code&gt;Authorization: Bearer $OPENAI_API_KEY&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Salida&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;b64_json&lt;/code&gt;; PNG por defecto, además de JPEG, WebP, GIF y SVG&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;quality&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;low&lt;/code&gt;, &lt;code&gt;medium&lt;/code&gt;, &lt;code&gt;high&lt;/code&gt;, &lt;code&gt;xhigh&lt;/code&gt;, &lt;code&gt;max&lt;/code&gt;, &lt;code&gt;auto&lt;/code&gt; (por defecto)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;complexity&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;low&lt;/code&gt;, &lt;code&gt;medium&lt;/code&gt;, &lt;code&gt;high&lt;/code&gt; (&lt;code&gt;high&lt;/code&gt; si se omite)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Tarifas de tokens de imagen&lt;/td&gt;
&lt;td&gt;$8 de entrada, $2 de entrada en caché, $30 de salida por 1M&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Tarifas de tokens de texto&lt;/td&gt;
&lt;td&gt;$5 de entrada, $1.25 de entrada en caché por 1M&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Las tarifas provienen de la &lt;a href="https://developers.openai.com/api/docs/pricing?ref=apidog.com#image-generation" rel="noopener noreferrer"&gt;página de precios de OpenAI&lt;/a&gt;. Ambos modelos cuestan lo mismo por token, así que elige en función de la velocidad y la precisión de edición.&lt;/p&gt;

&lt;h2&gt;
  
  
  Flare o Sunburst: ¿qué modelo deberías usar?
&lt;/h2&gt;

&lt;p&gt;Usa Flare para iterar rápido y para generaciones del día a día. OpenAI afirma que puede devolver una imagen en tan solo seis segundos con calidad &lt;code&gt;low&lt;/code&gt; y que mejora la composición en pósteres e imágenes de producto. Usa Sunburst para trabajos detallados y ediciones repetidas, donde OpenAI asegura una mayor consistencia con calidad &lt;code&gt;medium&lt;/code&gt; o &lt;code&gt;high&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Estas son afirmaciones de OpenAI, no benchmarks independientes. Nuestra &lt;a href="https://apidog.com/es/blog/gpt-image-2-5-flare-vs-sunburst-vs-gpt-image-2?utm_source=dev.to&amp;amp;utm_medium=wanda&amp;amp;utm_content=n8n-post-automation"&gt;comparativa entre Flare y Sunburst para la versión 2.5&lt;/a&gt; explica esta diferencia.&lt;/p&gt;

&lt;h2&gt;
  
  
  Autenticación y configuración
&lt;/h2&gt;

&lt;p&gt;Necesitas tres cosas antes de tu primera llamada:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Crea una clave de API en el panel de OpenAI y expórtala como &lt;code&gt;OPENAI_API_KEY&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Completa la &lt;a href="https://help.openai.com/en/articles/10910291-api-organization-verification?ref=apidog.com" rel="noopener noreferrer"&gt;verificación de organización de la API&lt;/a&gt; si tu organización lo requiere. OpenAI indica que es posible que tengas que hacerlo antes de poder usar los modelos GPT Image.&lt;/li&gt;
&lt;li&gt;Instala &lt;code&gt;jq&lt;/code&gt; para los ejemplos con curl, o el paquete &lt;code&gt;openai&lt;/code&gt; para Python.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Si tu aplicación da servicio a usuarios individuales, envía también un &lt;code&gt;safety_identifier&lt;/code&gt; con hash de hasta 128 caracteres. Sustituye al parámetro &lt;code&gt;user&lt;/code&gt;, que está obsoleto.&lt;/p&gt;

&lt;h2&gt;
  
  
  Genera tu primera imagen
&lt;/h2&gt;

&lt;p&gt;Esta petición usa Flare con calidad &lt;code&gt;low&lt;/code&gt;, ideal para borradores.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;curl &lt;span class="nt"&gt;--fail-with-body&lt;/span&gt; &lt;span class="nt"&gt;--silent&lt;/span&gt; &lt;span class="nt"&gt;--show-error&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  https://api.openai.com/v1/images/generations &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s2"&gt;"Authorization: Bearer &lt;/span&gt;&lt;span class="nv"&gt;$OPENAI_API_KEY&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s2"&gt;"Content-Type: application/json"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-d&lt;/span&gt; &lt;span class="s1"&gt;'{
    "model": "gpt-image-2.6-flare",
    "prompt": "A minimal poster for a developer meetup, with the words SHIP IT in bold type",
    "size": "1024x1536",
    "quality": "low",
    "complexity": "low"
  }'&lt;/span&gt; | jq &lt;span class="nt"&gt;-er&lt;/span&gt; &lt;span class="s1"&gt;'.data[0].b64_json'&lt;/span&gt; | &lt;span class="nb"&gt;base64&lt;/span&gt; &lt;span class="nt"&gt;--decode&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; poster.png
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;La misma llamada en Python:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;base64&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;pathlib&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;Path&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;openai&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;OpenAI&lt;/span&gt;

&lt;span class="n"&gt;client&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;OpenAI&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

&lt;span class="n"&gt;result&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;client&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;images&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;generate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;model&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;gpt-image-2.6-sunburst&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;REDACTED&lt;/span&gt; &lt;span class="n"&gt;PROMPT&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
    &lt;span class="n"&gt;size&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;1536x1024&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;quality&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;medium&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;extra_body&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;complexity&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;low&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="nc"&gt;Path&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;mug.png&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;write_bytes&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;base64&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;b64decode&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;result&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="n"&gt;b64_json&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Pasamos &lt;code&gt;complexity&lt;/code&gt; a través de &lt;code&gt;extra_body&lt;/code&gt; para que la llamada no dependa de que tu versión del SDK lo exponga como argumento con nombre. Los modelos GPT Image siempre devuelven base64, así que no envíes &lt;code&gt;response_format&lt;/code&gt; ni busques un campo &lt;code&gt;url&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;La guía de OpenAI recomienda leer el objeto &lt;code&gt;usage&lt;/code&gt; de la respuesta para medir el uso de tokens. No obstante, la referencia de la API describe ese campo como exclusivo de &lt;code&gt;gpt-image-1&lt;/code&gt;, aunque su respuesta de ejemplo lo incluya, así que confirma que aparece en tus respuestas de la 2.6 antes de basar en él tu seguimiento de costes.&lt;/p&gt;

&lt;h2&gt;
  
  
  Edita una imagen con marcado
&lt;/h2&gt;

&lt;p&gt;El marcado le indica al modelo dónde debe hacer un cambio. Envías la imagen original, un PNG transparente con tus círculos o bocetos, y un prompt que describe la edición.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;curl &lt;span class="nt"&gt;--fail-with-body&lt;/span&gt; &lt;span class="nt"&gt;--silent&lt;/span&gt; &lt;span class="nt"&gt;--show-error&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  https://api.openai.com/v1/images/edits &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s2"&gt;"Authorization: Bearer &lt;/span&gt;&lt;span class="nv"&gt;$OPENAI_API_KEY&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s2"&gt;"Content-Type: application/json"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-d&lt;/span&gt; &lt;span class="s1"&gt;'{
    "model": "gpt-image-2.6-flare",
    "images": [{"image_url": "https://your-bucket.example/kitchen.png"}],
    "markup": {"image_url": "https://your-bucket.example/vase-overlay.png"},
    "prompt": "Recolor the vase inside the red circle to solid cobalt blue. Keep everything else unchanged. Remove the red circle.",
    "quality": "medium",
    "complexity": "low"
  }'&lt;/span&gt; | jq &lt;span class="nt"&gt;-er&lt;/span&gt; &lt;span class="s1"&gt;'.data[0].b64_json'&lt;/span&gt; | &lt;span class="nb"&gt;base64&lt;/span&gt; &lt;span class="nt"&gt;--decode&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; vase.png
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Las peticiones JSON usan el array &lt;code&gt;images&lt;/code&gt; y un objeto &lt;code&gt;markup&lt;/code&gt; que contiene exactamente uno de estos campos: &lt;code&gt;image_url&lt;/code&gt; o &lt;code&gt;file_id&lt;/code&gt;. Un &lt;code&gt;image_url&lt;/code&gt; puede ser una URL HTTPS o una URL de datos en base64. Las peticiones multipart aceptan en su lugar una carga de archivo, y la &lt;a href="https://developers.openai.com/api/docs/guides/image-generation?ref=apidog.com" rel="noopener noreferrer"&gt;guía de generación de imágenes&lt;/a&gt; incluye esa versión en Python.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fdp55q7zycqz0sscog3w2.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fdp55q7zycqz0sscog3w2.png" alt="Diagrama de una edición con marcado de GPT-Image-2.6: la foto original, una superposición PNG transparente y un prompt de texto se envían a POST /v1/images/edits, que devuelve la imagen editada con la anotación eliminada" width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;La superposición tiene reglas estrictas:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Tras aplicar la orientación, debe coincidir con el ancho y el alto de la primera imagen.&lt;/li&gt;
&lt;li&gt;Debe contener píxeles transparentes, así que no la aplanes sobre la foto.&lt;/li&gt;
&lt;li&gt;Se aplica a la primera imagen de entrada. Cualquier otra actúa como referencia.&lt;/li&gt;
&lt;li&gt;Cada una de las dos imágenes puede tener como máximo 16.777.216 píxeles, y el archivo de superposición no puede superar los 50 MB.&lt;/li&gt;
&lt;li&gt;No puedes combinar &lt;code&gt;markup&lt;/code&gt; con &lt;code&gt;mask&lt;/code&gt; ni con &lt;code&gt;prompt_rewriter&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Indícale al modelo que elimine la anotación, tal como hace el propio ejemplo de OpenAI. El marcado cuesta lo mismo que cualquier otra edición. La Responses API no lo admite, así que ahí tendrás que usar una máscara.&lt;/p&gt;

&lt;h2&gt;
  
  
  Exporta a SVG
&lt;/h2&gt;

&lt;p&gt;Configura &lt;code&gt;output_format&lt;/code&gt; como &lt;code&gt;svg&lt;/code&gt; en el endpoint de generaciones para iconos, logotipos e ilustraciones que necesiten trazados editables.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;curl &lt;span class="nt"&gt;--fail-with-body&lt;/span&gt; &lt;span class="nt"&gt;--silent&lt;/span&gt; &lt;span class="nt"&gt;--show-error&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  https://api.openai.com/v1/images/generations &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s2"&gt;"Authorization: Bearer &lt;/span&gt;&lt;span class="nv"&gt;$OPENAI_API_KEY&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s2"&gt;"Content-Type: application/json"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-d&lt;/span&gt; &lt;span class="s1"&gt;'{
    "model": "gpt-image-2.6-sunburst",
    "prompt": "A flat two-color wheat logo for a bakery called Field and Flour",
    "output_format": "svg",
    "quality": "medium",
    "n": 1
  }'&lt;/span&gt; | jq &lt;span class="nt"&gt;-er&lt;/span&gt; &lt;span class="s1"&gt;'.data[0].b64_json'&lt;/span&gt; | &lt;span class="nb"&gt;base64&lt;/span&gt; &lt;span class="nt"&gt;--decode&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; logo.svg
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;La API primero genera una imagen de referencia, que &lt;code&gt;quality&lt;/code&gt; controla, y luego escribe el SVG a partir de ella. Los bytes decodificados son XML en UTF-8, sin scripts, recursos externos ni rásteres incrustados.&lt;/p&gt;

&lt;p&gt;Se aplican cuatro límites:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;n&lt;/code&gt; debe ser 1.&lt;/li&gt;
&lt;li&gt;El streaming, las imágenes parciales, &lt;code&gt;output_compression&lt;/code&gt; y &lt;code&gt;prompt_rewriter&lt;/code&gt; no funcionan.&lt;/li&gt;
&lt;li&gt;El endpoint de ediciones no puede generar SVG, y no aceptará un SVG como entrada ráster.&lt;/li&gt;
&lt;li&gt;El objeto opcional &lt;code&gt;svg&lt;/code&gt; elige el modelo de autoría, pero solo si tu cuenta tiene selección de modelo SVG. De lo contrario, omítelo.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Pagas dos veces: la tarifa de imagen por la imagen de referencia y la tarifa del modelo de autoría por sus tokens. La referencia de la API incluye un objeto &lt;code&gt;svg_usage&lt;/code&gt; aparte para esa segunda parte, así que regístralo.&lt;/p&gt;

&lt;h2&gt;
  
  
  Genera un GIF
&lt;/h2&gt;

&lt;p&gt;La API devuelve un GIF terminado, no una hoja de sprites. Añade tres campos a una petición de generaciones:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"model"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"gpt-image-2.6-flare"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"prompt"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"A small orange robot waves, blinks and returns to its starting pose. Make it loop."&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"output_format"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"gif"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"frame_count"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;9&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"frame_duration_ms"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;200&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"size"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"auto"&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Decodifica &lt;code&gt;b64_json&lt;/code&gt; de la misma forma y guárdalo como &lt;code&gt;.gif&lt;/code&gt;. Antes, comprueba dos cosas:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Límite de fotogramas.&lt;/strong&gt; La guía indica que &lt;code&gt;frame_count&lt;/code&gt; va de 2 a 64. La &lt;a href="https://developers.openai.com/api/reference/resources/images/methods/generate?ref=apidog.com" rel="noopener noreferrer"&gt;referencia de la API&lt;/a&gt; dice de 2 a 16. Quédate en 16 o menos hasta que hayas probado valores superiores.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Acceso.&lt;/strong&gt; La referencia indica que la salida GIF requiere acceso a la vista previa de GIF del modelo seleccionado, mientras que la guía no lo menciona. Una petición de GIF rechazada puede deberse a un problema de acceso, no a un payload incorrecto.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;La salida GIF no admite streaming, imágenes parciales ni &lt;code&gt;output_compression&lt;/code&gt; personalizado, y el endpoint de ediciones no puede devolverla. OpenAI no publica una fórmula de facturación específica para GIF, así que haz una prueba pequeña y revisa tu factura antes de escalar.&lt;/p&gt;

&lt;h2&gt;
  
  
  Configura quality y complexity
&lt;/h2&gt;

&lt;p&gt;&lt;code&gt;quality&lt;/code&gt; controla el nivel de detalle del renderizado e influye en el coste de tokens. &lt;code&gt;complexity&lt;/code&gt; controla cuánto planifica el modelo antes de renderizar, y cambiarlo no conlleva ningún cargo adicional.&lt;/p&gt;

&lt;p&gt;Configura &lt;code&gt;complexity&lt;/code&gt; en cada petición. El valor por defecto es &lt;code&gt;high&lt;/code&gt;, pero OpenAI recomienda &lt;code&gt;low&lt;/code&gt; para la mayoría de las ediciones. La guía advierte de que los valores más altos pueden aumentar la latencia e introducir cambios no deseados.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fu13zvlm10g5xfp3bn0uw.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fu13zvlm10g5xfp3bn0uw.png" alt="Cuadrícula de ajustes iniciales sugeridos para GPT-Image-2.6: los borradores rápidos usan Flare con calidad low y complejidad low, las ediciones concretas usan complejidad low, las imágenes finales detalladas usan Sunburst con calidad medium o high, y las composiciones densas usan complejidad medium o high" width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;La calidad también determina tu factura de salida. Esta tabla usa la calculadora de OpenAI para una imagen de 1024x1024, consultada el 5 de noviembre, y excluye los tokens de entrada:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;&lt;code&gt;quality&lt;/code&gt;&lt;/th&gt;
&lt;th&gt;Tokens de salida&lt;/th&gt;
&lt;th&gt;Coste de salida&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;low&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;823&lt;/td&gt;
&lt;td&gt;$0.02469&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;medium&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;1,449&lt;/td&gt;
&lt;td&gt;$0.04347&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;high&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;1,756&lt;/td&gt;
&lt;td&gt;$0.05268&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;xhigh&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;3,122&lt;/td&gt;
&lt;td&gt;$0.09366&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;max&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;7,024&lt;/td&gt;
&lt;td&gt;$0.21072&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;La diferencia entre &lt;code&gt;medium&lt;/code&gt; y &lt;code&gt;high&lt;/code&gt; es de aproximadamente un centavo, así que compara ambos. La pestaña Batch de la página de precios aún no incluye la 2.6, así que no des por hecho que se aplica el descuento por lotes de la 2.5.&lt;/p&gt;

&lt;h2&gt;
  
  
  Gestiona errores y tiempos de espera
&lt;/h2&gt;

&lt;p&gt;Clasifica los fallos según si un reintento puede ayudar:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Fallo&lt;/th&gt;
&lt;th&gt;Qué hacer&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Límite de tasa o error del servidor&lt;/td&gt;
&lt;td&gt;Reintentar con retroceso exponencial&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Error de cuota&lt;/td&gt;
&lt;td&gt;No reintentar; solucionar la facturación&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;code&gt;error.type&lt;/code&gt; es &lt;code&gt;image_generation_user_error&lt;/code&gt;
&lt;/td&gt;
&lt;td&gt;Cambiar primero el prompt o la entrada&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;code&gt;error.code&lt;/code&gt; es &lt;code&gt;moderation_blocked&lt;/code&gt;
&lt;/td&gt;
&lt;td&gt;Leer &lt;code&gt;moderation_details&lt;/code&gt; y luego revisar&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Usa &lt;code&gt;error.code&lt;/code&gt; como tu comprobación estable y registra el ID de la petición. &lt;code&gt;moderation_details&lt;/code&gt; incluye &lt;code&gt;moderation_stage&lt;/code&gt; y &lt;code&gt;categories&lt;/code&gt; generales, que deben ir en tus logs, no en los mensajes dirigidos al usuario. Configura tiempos de espera del cliente superiores a dos minutos, porque OpenAI indica que los prompts complejos pueden tardar tanto.&lt;/p&gt;

&lt;h2&gt;
  
  
  Deja que tu agente de programación lo pruebe con Apidog CLI
&lt;/h2&gt;

&lt;p&gt;Tu agente de programación puede convertir estas peticiones y límites en un conjunto de pruebas con &lt;a href="https://apidog.com/apidog-cli/?ref=apidog.com&amp;amp;utm_source=dev.to&amp;amp;utm_medium=wanda&amp;amp;utm_content=n8n-post-automation"&gt;Apidog CLI&lt;/a&gt;. Configúralo una vez:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npm &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="nt"&gt;-g&lt;/span&gt; apidog-cli@latest
apidog auth login &lt;span class="nt"&gt;--with-token&lt;/span&gt; &amp;lt;YOUR_TOKEN&amp;gt;
apidog skill &lt;span class="nb"&gt;install&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Después, dale un prompt a Claude Code, Codex o Cursor:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;In Apidog project &amp;lt;id&amp;gt;, add POST /v1/images/generations and POST /v1/images/edits
on https://api.openai.com. Read the Bearer [REDACTED] from OPENAI_API_KEY.
Create test cases for gpt-image-2.6-flare at low quality and low complexity:
1. PNG generation: assert status 200 and data[0].b64_json exists.
2. SVG generation: assert status 200 and output_format equals svg.
3. GIF with frame_count 6: assert status 200 and output_format equals gif.
4. SVG with n set to 2: assert a 4xx status and that error.message exists.
5. GIF with frame_count 17: record the status, because OpenAI's docs disagree.
Put them in a test suite named "GPT-Image-2.6", run it against environment
&amp;lt;envId&amp;gt;, and summarize every failure.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;El agente lee cada esquema, valida su payload y luego escribe y ejecuta el conjunto de pruebas:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;apidog cli-schema get endpoint-create
apidog cli-schema validate endpoint-create &lt;span class="nt"&gt;--file&lt;/span&gt; endpoint.json
apidog endpoint create &lt;span class="nt"&gt;--project&lt;/span&gt; &amp;lt;&lt;span class="nb"&gt;id&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="nt"&gt;--file&lt;/span&gt; endpoint.json
apidog cli-schema get test-case-create
apidog cli-schema validate test-case-create &lt;span class="nt"&gt;--file&lt;/span&gt; &lt;span class="k"&gt;case&lt;/span&gt;.json
apidog test-case create &lt;span class="nt"&gt;--project&lt;/span&gt; &amp;lt;&lt;span class="nb"&gt;id&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="nt"&gt;--file&lt;/span&gt; &lt;span class="k"&gt;case&lt;/span&gt;.json
apidog cli-schema validate test-suite-create &lt;span class="nt"&gt;--file&lt;/span&gt; suite.json
apidog test-suite create &lt;span class="nt"&gt;--project&lt;/span&gt; &amp;lt;&lt;span class="nb"&gt;id&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="nt"&gt;--file&lt;/span&gt; suite.json
apidog test-suite run &amp;lt;suiteId&amp;gt; &lt;span class="nt"&gt;--project&lt;/span&gt; &amp;lt;&lt;span class="nb"&gt;id&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="nt"&gt;-e&lt;/span&gt; &amp;lt;envId&amp;gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--env-var&lt;/span&gt; &lt;span class="s2"&gt;"OPENAI_API_KEY=&lt;/span&gt;&lt;span class="nv"&gt;$OPENAI_API_KEY&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="nt"&gt;--on-error&lt;/span&gt; &lt;span class="k"&gt;continue&lt;/span&gt; &lt;span class="nt"&gt;-r&lt;/span&gt; cli,json
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;El caso 5 determina el límite de fotogramas para tu cuenta, y el caso 3 muestra si tienes acceso a GIF. Los casos que se ejecutan correctamente generan imágenes reales y facturables, así que mantén la calidad baja. Cambia a &lt;code&gt;-r junit&lt;/code&gt; para ejecutar el conjunto en un &lt;a href="https://apidog.com/es/blog/apidog-cli-ci-cd-pipeline?utm_source=dev.to&amp;amp;utm_medium=wanda&amp;amp;utm_content=n8n-post-automation"&gt;pipeline de CI&lt;/a&gt;, y consulta la &lt;a href="https://apidog.com/es/blog/apidog-cli-in-claude-code?utm_source=dev.to&amp;amp;utm_medium=wanda&amp;amp;utm_content=n8n-post-automation"&gt;guía de configuración de Claude Code&lt;/a&gt; para más detalles sobre el agente.&lt;/p&gt;

&lt;h2&gt;
  
  
  Preguntas frecuentes
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;¿Cuáles son los nombres de los modelos de la API de GPT-Image-2.6?&lt;/strong&gt; &lt;code&gt;gpt-image-2.6-flare&lt;/code&gt; y &lt;code&gt;gpt-image-2.6-sunburst&lt;/code&gt;. La referencia de la API aún no incluye instantáneas con fecha para ellos, a diferencia de los modelos 2.5.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;¿Cuánto cuesta la API de GPT-Image-2.6?&lt;/strong&gt; Los tokens de imagen cuestan $8 por 1M de entrada y $30 por 1M de salida. Una imagen de 1024x1024 cuesta unos $0.025 de salida con &lt;code&gt;low&lt;/code&gt; y unos $0.053 con &lt;code&gt;high&lt;/code&gt;, sin contar los tokens de entrada.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;¿Debería migrar desde gpt-image-2.5?&lt;/strong&gt; Migra si necesitas SVG, GIF o &lt;code&gt;complexity&lt;/code&gt;. Prueba antes tus costes: una imagen en &lt;code&gt;low&lt;/code&gt; usa aproximadamente 4,2 veces los tokens que usaba en la 2.5, y los modelos 2.6 aún no tienen precios por lotes publicados.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;¿Puedo usar &lt;code&gt;complexity&lt;/code&gt; en el endpoint de ediciones?&lt;/strong&gt; Sí. OpenAI recomienda &lt;code&gt;low&lt;/code&gt; para la mayoría de las ediciones.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;¿Puedo convertir una imagen subida en un GIF a través de la API?&lt;/strong&gt; No. El endpoint de ediciones no devuelve GIF ni SVG, así que ambos formatos parten de un prompt de texto en el endpoint de generaciones.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;¿La API devuelve una URL?&lt;/strong&gt; No. Los modelos GPT Image siempre devuelven base64 en &lt;code&gt;b64_json&lt;/code&gt;, así que decodifícalo y guarda el archivo tú mismo.&lt;/p&gt;

</description>
    </item>
    <item>
      <title>Cómo detectar vulnerabilidades en tu repositorio gratis</title>
      <dc:creator>Roobia</dc:creator>
      <pubDate>Thu, 05 Nov 2026 09:01:14 +0000</pubDate>
      <link>https://dev.to/roobia/como-detectar-vulnerabilidades-en-tu-repositorio-gratis-51eb</link>
      <guid>https://dev.to/roobia/como-detectar-vulnerabilidades-en-tu-repositorio-gratis-51eb</guid>
      <description>&lt;h1&gt;
  
  
  Cómo detectar vulnerabilidades en tu repositorio gratis
&lt;/h1&gt;

&lt;p&gt;Para detectar vulnerabilidades en tu repositorio de forma gratuita, combina tres capas: un escáner de dependencias (&lt;code&gt;npm audit&lt;/code&gt;, &lt;code&gt;pip-audit&lt;/code&gt; o OSV-Scanner), un escáner de secretos (Gitleaks) y un escáner de código (Semgrep Community Edition). Ejecútalos en cada pull request. Ninguno de ellos detectará la falta de una comprobación de autorización, por lo que conviene añadir una prueba en tiempo de ejecución para cubrir ese caso.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://apidog.com/?utm_source=dev.to&amp;amp;utm_medium=wanda&amp;amp;utm_content=n8n-post-automation" class="crayons-btn crayons-btn--primary"&gt;Prueba Apidog hoy&lt;/a&gt;
&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npm audit &lt;span class="nt"&gt;--audit-level&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;high
pip-audit &lt;span class="nt"&gt;-r&lt;/span&gt; requirements.txt
gitleaks git &lt;span class="nb"&gt;.&lt;/span&gt; &lt;span class="nt"&gt;--no-banner&lt;/span&gt;
semgrep scan &lt;span class="nt"&gt;--config&lt;/span&gt; p/default &lt;span class="nt"&gt;--metrics&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;off &lt;span class="nt"&gt;--error&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Qué cambia con Vercel Security Review
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://vercel.com/blog/vercel-security-review" rel="noopener noreferrer"&gt;Vercel Security Review&lt;/a&gt; es una funcionalidad de Vercel Agent, en beta pública desde el 2 de noviembre de 2026. Analiza cada push en un repositorio de GitHub conectado, examina el diff y el código adyacente, rastrea cómo se puede alcanzar el cambio y verifica de nuevo cada hallazgo antes de reportarlo.&lt;/p&gt;

&lt;p&gt;El ejemplo de Vercel es el motivo por el que existe este artículo. Un cambio en un endpoint de facturas buscaba facturas por ID sin comprobar la organización, lo que permitía a cualquier usuario autenticado descargar la factura de otra organización. Se trata de un error de lógica, y los escáneres basados en patrones tienen dificultades para detectar este tipo de fallos.&lt;/p&gt;

&lt;p&gt;A continuación se detalla quién puede utilizarlo:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Pregunta&lt;/th&gt;
&lt;th&gt;Respuesta&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Planes&lt;/td&gt;
&lt;td&gt;Solo para equipos Pro y Enterprise&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Coste&lt;/td&gt;
&lt;td&gt;Gratis hasta el 10 de noviembre de 2026; después, las tarifas por token del proveedor más 0,25 $ por millón de tokens&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Repositorios&lt;/td&gt;
&lt;td&gt;Repositorios de GitHub conectados; los repositorios que no se despliegan en Vercel aún no son compatibles&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Alcance&lt;/td&gt;
&lt;td&gt;El diff respecto a una base, o el código fuente completo en la primera revisión&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Hallazgos&lt;/td&gt;
&lt;td&gt;Panel de vulnerabilidades, un GitHub check y comentarios en los PR en repositorios privados e internos&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;La documentación de Vercel también señala sus límites: analiza código, no la aplicación en ejecución, y no sustituye a una prueba de penetración. Si no cumples los requisitos o estás leyendo esto después del periodo gratuito, el resto de esta guía no te costará nada.&lt;/p&gt;

&lt;h2&gt;
  
  
  Qué debería cubrir un escaneo de vulnerabilidades en el repositorio
&lt;/h2&gt;

&lt;p&gt;Un escaneo exhaustivo de vulnerabilidades en un repositorio evalúa cuatro aspectos: vulnerabilidades conocidas en las dependencias, credenciales subidas a Git, patrones de código inseguros como inyecciones y la lógica de autorización. Los tres primeros cuentan con escáneres gratuitos y consolidados. El cuarto depende del comportamiento semántico del código, por lo que requiere una prueba contra una API en ejecución.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fi05o5wzlwn3byjba67x3.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fi05o5wzlwn3byjba67x3.png" alt="Four stacked layers of a repo scan: dependencies, secrets and code patterns each have free scanners, while authorization logic needs a runtime test" width="800" height="410"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Una clave eliminada permanece en el historial de Git, así que analiza el historial y rota cualquier clave real. Para detectar claves en el tráfico de la API y en colecciones de pruebas, consulta nuestra &lt;a href="https://apidog.com/es/blog/api-key-leak-check-secret-scanner?utm_source=dev.to&amp;amp;utm_medium=wanda&amp;amp;utm_content=n8n-post-automation"&gt;guía para detectar fugas de claves de API&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Comparativa de escáneres de vulnerabilidades gratuitos
&lt;/h2&gt;

&lt;p&gt;Los precios y las licencias se verificaron el 5 de noviembre de 2026. Ninguna de las herramientas de línea de comandos requiere una cuenta ni tarjeta de crédito para los comandos que se muestran en esta guía.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Herramienta&lt;/th&gt;
&lt;th&gt;Qué detecta&lt;/th&gt;
&lt;th&gt;Coste y licencia&lt;/th&gt;
&lt;th&gt;Aspectos a tener en cuenta&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;a href="https://docs.npmjs.com/cli/v11/commands/npm-audit" rel="noopener noreferrer"&gt;&lt;code&gt;npm audit&lt;/code&gt;&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;Vulnerabilidades en dependencias de npm&lt;/td&gt;
&lt;td&gt;Gratuito, incluido con npm&lt;/td&gt;
&lt;td&gt;Requiere un archivo lockfile&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;a href="https://github.com/pypa/pip-audit" rel="noopener noreferrer"&gt;pip-audit&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;Vulnerabilidades en dependencias de Python&lt;/td&gt;
&lt;td&gt;Gratuito, Apache-2.0&lt;/td&gt;
&lt;td&gt;Solo para Python&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;a href="https://google.github.io/osv-scanner/" rel="noopener noreferrer"&gt;OSV-Scanner&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;Vulnerabilidades en dependencias de múltiples ecosistemas&lt;/td&gt;
&lt;td&gt;Gratuito, Apache-2.0&lt;/td&gt;
&lt;td&gt;Reporta más resultados, por lo que requerirá triaje&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;a href="https://github.com/aquasecurity/trivy" rel="noopener noreferrer"&gt;Trivy&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;Dependencias, secretos y errores de configuración&lt;/td&gt;
&lt;td&gt;Gratuito, Apache-2.0&lt;/td&gt;
&lt;td&gt;Fijar versiones (ver más abajo)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;a href="https://github.com/gitleaks/gitleaks" rel="noopener noreferrer"&gt;Gitleaks&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;Secretos en el historial de Git&lt;/td&gt;
&lt;td&gt;Gratuito, MIT&lt;/td&gt;
&lt;td&gt;Su GitHub Action requiere una clave de licencia gratuita para organizaciones&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;a href="https://docs.semgrep.dev/semgrep-pro-vs-oss" rel="noopener noreferrer"&gt;Semgrep Community Edition&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;Patrones de código y algunos secretos&lt;/td&gt;
&lt;td&gt;Gratuito, motor con licencia LGPL-2.1&lt;/td&gt;
&lt;td&gt;No puede rastrear datos más allá de una sola función o archivo&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;a href="https://docs.github.com/en/code-security/getting-started/github-security-features" rel="noopener noreferrer"&gt;Alertas de Dependabot&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;Vulnerabilidades en dependencias&lt;/td&gt;
&lt;td&gt;Gratuito en repositorios públicos y privados&lt;/td&gt;
&lt;td&gt;Solo para GitHub&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Escaneo de secretos de GitHub&lt;/td&gt;
&lt;td&gt;Secretos&lt;/td&gt;
&lt;td&gt;Gratuito en repositorios públicos; &lt;a href="https://github.com/security/plans" rel="noopener noreferrer"&gt;19 $ al mes por committer activo&lt;/a&gt; en privados&lt;/td&gt;
&lt;td&gt;Los repositorios privados requieren Secret Protection&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;CodeQL&lt;/td&gt;
&lt;td&gt;Patrones de código&lt;/td&gt;
&lt;td&gt;Gratuito en repositorios públicos; &lt;a href="https://github.com/security/plans" rel="noopener noreferrer"&gt;30 $ al mes por committer activo&lt;/a&gt; en privados&lt;/td&gt;
&lt;td&gt;Los repositorios privados requieren Code Security&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Dos apuntes sobre licencias. Las reglas comunitarias de Semgrep utilizan la &lt;a href="https://semgrep.dev/legal/rules-license/" rel="noopener noreferrer"&gt;Semgrep Rules License&lt;/a&gt;, que autoriza el uso interno comercial, pero no su redistribución ni su oferta como servicio. Y si vas a adoptar Trivy, revisa &lt;a href="https://github.com/advisories/GHSA-69fq-xp46-6x23" rel="noopener noreferrer"&gt;CVE-2026-33634&lt;/a&gt;: en marzo de 2026 se comprometieron brevemente partes del ecosistema de Trivy. Utiliza una versión actualizada y fija cualquier GitHub Action al SHA de un commit.&lt;/p&gt;

&lt;h2&gt;
  
  
  Escanear un repositorio con pocos comandos: lo que encontramos
&lt;/h2&gt;

&lt;p&gt;Construimos una pequeña API de facturación con Express y la subimos a un repositorio local. Contaba con cuatro dependencias de npm y tres de Python en versiones antiguas, dos claves simuladas (una al estilo de Stripe y otra al estilo de AWS), una inyección SQL, una inyección de comandos y una ruta que devuelve la factura de cualquier organización a cualquier usuario autenticado.&lt;/p&gt;

&lt;p&gt;A continuación, ejecutamos cada herramienta en macOS el 5 de noviembre de 2026:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npm audit
pip-audit &lt;span class="nt"&gt;-r&lt;/span&gt; requirements.txt &lt;span class="nt"&gt;--no-deps&lt;/span&gt; &lt;span class="nt"&gt;--disable-pip&lt;/span&gt;
osv-scanner scan &lt;span class="nb"&gt;source&lt;/span&gt; &lt;span class="nt"&gt;-r&lt;/span&gt; &lt;span class="nb"&gt;.&lt;/span&gt;
trivy fs &lt;span class="nt"&gt;--scanners&lt;/span&gt; vuln,secret &lt;span class="nb"&gt;.&lt;/span&gt;
gitleaks git &lt;span class="nb"&gt;.&lt;/span&gt; &lt;span class="nt"&gt;--no-banner&lt;/span&gt;
semgrep scan &lt;span class="nt"&gt;--config&lt;/span&gt; p/default &lt;span class="nt"&gt;--metrics&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;off
semgrep scan &lt;span class="nt"&gt;--config&lt;/span&gt; p/nodejsscan &lt;span class="nt"&gt;--metrics&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;off
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Herramienta (versión)&lt;/th&gt;
&lt;th&gt;Detectado&lt;/th&gt;
&lt;th&gt;No detectado&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;code&gt;npm audit&lt;/code&gt; (npm 11.12.1)&lt;/td&gt;
&lt;td&gt;9 paquetes vulnerables: 6 de severidad alta, 3 baja&lt;/td&gt;
&lt;td&gt;Todo lo que no sea un paquete de npm&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;pip-audit 2.10.1&lt;/td&gt;
&lt;td&gt;16 avisos de seguridad en los 3 paquetes fijados&lt;/td&gt;
&lt;td&gt;Paquetes transitivos, debido a que usamos &lt;code&gt;--no-deps&lt;/code&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;OSV-Scanner 2.7.0&lt;/td&gt;
&lt;td&gt;66 avisos únicos en 15 paquetes, incluidos los paquetes transitivos de Python&lt;/td&gt;
&lt;td&gt;Secretos y errores de código&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Trivy 0.76.1&lt;/td&gt;
&lt;td&gt;33 vulnerabilidades en dependencias y la clave al estilo de Stripe&lt;/td&gt;
&lt;td&gt;La clave al estilo de AWS&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Gitleaks 8.30.1&lt;/td&gt;
&lt;td&gt;La clave al estilo de Stripe&lt;/td&gt;
&lt;td&gt;La clave al estilo de AWS&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Semgrep 1.183.0, &lt;code&gt;p/default&lt;/code&gt;
&lt;/td&gt;
&lt;td&gt;Clave al estilo de Stripe, inyección de comandos y un aviso por ausencia del middleware de CSRF&lt;/td&gt;
&lt;td&gt;Inyección SQL, clave al estilo de AWS&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Semgrep 1.183.0, &lt;code&gt;p/nodejsscan&lt;/code&gt;
&lt;/td&gt;
&lt;td&gt;Inyección SQL, inyección de comandos y clave al estilo de AWS&lt;/td&gt;
&lt;td&gt;Clave al estilo de Stripe&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Destacan tres conclusiones:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Las cifras no son comparables.&lt;/strong&gt; Un paquete, un aviso de seguridad y un hallazgo son métricas distintas, y cada herramienta analiza datos diferentes. Compara lo que se detectó, no los totales.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Un solo escáner de secretos no basta.&lt;/strong&gt; Tanto Gitleaks como Trivy pasaron por alto la clave al estilo de AWS.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Los conjuntos de reglas marcan la diferencia.&lt;/strong&gt; El paquete predeterminado de Semgrep no detectó una consulta SQL construida mediante concatenación simple de cadenas. &lt;code&gt;p/javascript&lt;/code&gt;, &lt;code&gt;p/nodejs&lt;/code&gt;, &lt;code&gt;p/owasp-top-ten&lt;/code&gt; y &lt;code&gt;p/sql-injection&lt;/code&gt; no devolvieron nada en este repositorio, mientras que &lt;code&gt;p/nodejsscan&lt;/code&gt; sí la encontró.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Ninguna herramienta señaló la ruta de facturas. Este es solo un repositorio pequeño, así que tómalo como una demostración y no como un benchmark formal. No ejecutamos CodeQL.&lt;/p&gt;

&lt;h2&gt;
  
  
  Analiza tu repositorio de GitHub en cada pull request
&lt;/h2&gt;

&lt;p&gt;Los ejecutores estándar alojados en GitHub son &lt;a href="https://docs.github.com/en/billing/concepts/product-billing/github-actions" rel="noopener noreferrer"&gt;gratuitos en repositorios públicos&lt;/a&gt;. En repositorios privados, GitHub Free incluye un saldo mensual de 12 $, lo que equivale a unos 2000 minutos en un ejecutor Linux de 2 núcleos según la tarifa establecida. Este flujo de trabajo utiliza comandos estándar, por lo que las organizaciones pueden prescindir de la clave de licencia de la GitHub Action de Gitleaks:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;repo-scan&lt;/span&gt;
&lt;span class="na"&gt;on&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;pull_request&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;push&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;branches&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;[&lt;/span&gt;&lt;span class="nv"&gt;main&lt;/span&gt;&lt;span class="pi"&gt;]&lt;/span&gt;
&lt;span class="na"&gt;permissions&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;contents&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;read&lt;/span&gt;
&lt;span class="na"&gt;jobs&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;scan&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;runs-on&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;ubuntu-latest&lt;/span&gt;
    &lt;span class="na"&gt;steps&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;uses&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;actions/checkout@v7&lt;/span&gt; &lt;span class="c1"&gt;# pin to a commit SHA&lt;/span&gt;
        &lt;span class="na"&gt;with&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
          &lt;span class="na"&gt;fetch-depth&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Dependencies (npm)&lt;/span&gt;
        &lt;span class="na"&gt;run&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;npm audit --audit-level=high&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Dependencies (Python)&lt;/span&gt;
        &lt;span class="na"&gt;run&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;pipx run pip-audit -r requirements.txt&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Secrets&lt;/span&gt;
        &lt;span class="na"&gt;run&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;|&lt;/span&gt;
          &lt;span class="s"&gt;curl -sSL https://github.com/gitleaks/gitleaks/releases/download/v8.30.1/gitleaks_8.30.1_linux_x64.tar.gz | tar xz gitleaks&lt;/span&gt;
          &lt;span class="s"&gt;./gitleaks git . --no-banner&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Code patterns&lt;/span&gt;
        &lt;span class="na"&gt;run&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;pipx run semgrep scan --config p/default --config p/nodejsscan --metrics=off --error&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Los cuatro escáneres finalizaron con código de salida 1 en nuestro repositorio de prueba, y una salida distinta de cero es lo que hace fallar el job. Elimina los pasos que tu stack no necesite. Para integrar pruebas de API en la misma pipeline, consulta &lt;a href="https://apidog.com/es/blog/apidog-cli-github-actions?utm_source=dev.to&amp;amp;utm_medium=wanda&amp;amp;utm_content=n8n-post-automation"&gt;Apidog CLI con GitHub Actions&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Activa también las alertas de Dependabot. Son gratuitas en todos los planes y no esperan a que haya un pull request para avisarte.&lt;/p&gt;

&lt;h2&gt;
  
  
  La brecha: fallos de autorización que los escáneres pasan por alto
&lt;/h2&gt;

&lt;p&gt;Los fallos de autorización resultan difíciles de detectar para los escáneres de patrones porque el código parece correcto a simple vista: una consulta válida, un parámetro válido y un middleware de &lt;code&gt;auth&lt;/code&gt; protegiendo la ruta. El fallo reside en una condición ausente, y únicamente tu modelo de datos determina que dicha condición debería existir.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Every scanner passed this&lt;/span&gt;
&lt;span class="nx"&gt;db&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;query&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;SELECT * FROM invoices WHERE id = $1&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;req&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;params&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="p"&gt;]);&lt;/span&gt;

&lt;span class="c1"&gt;// The fix: scope the lookup to the caller's organization&lt;/span&gt;
&lt;span class="nx"&gt;db&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;query&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;SELECT * FROM invoices WHERE id = $1 AND org_id = $2&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;req&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;params&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;req&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;user&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;orgId&lt;/span&gt;&lt;span class="p"&gt;]);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Se trata de &lt;a href="https://api-security.owasp.org/editions/2023/en/0xa1-broken-object-level-authorization" rel="noopener noreferrer"&gt;Broken Object Level Authorization (BOLA), clasificada en el primer puesto del OWASP API Security Top 10 2023&lt;/a&gt;. OWASP recomienda validar los permisos de acceso en cada petición que utilice un ID proporcionado por el cliente y escribir pruebas que detecten fallos de autorización antes del despliegue.&lt;/p&gt;

&lt;p&gt;Recurrir a un agente de código resulta útil. Eliminamos los comentarios del repositorio de prueba y le pedimos a Claude Code que lo revisara, con y sin una pista sobre las organizaciones. Detectó la ruta de facturas en ambas ocasiones. No obstante, no es una alternativa con coste cero por sí misma, ya que consume el plan de tu agente y los resultados pueden variar entre ejecuciones.&lt;/p&gt;

&lt;p&gt;Una prueba ofrece una respuesta binaria (pasa o falla) en cada pull request. Para asegurar una cobertura adecuada a nivel de API, consulta la &lt;a href="https://apidog.com/es/blog/automated-api-vulnerability-detection?utm_source=dev.to&amp;amp;utm_medium=wanda&amp;amp;utm_content=n8n-post-automation"&gt;detección automatizada de vulnerabilidades en API&lt;/a&gt;, nuestra &lt;a href="https://apidog.com/es/blog/top-10-api-security-scanning-tools?utm_source=dev.to&amp;amp;utm_medium=wanda&amp;amp;utm_content=n8n-post-automation"&gt;recopilación de herramientas de escaneo de seguridad de API&lt;/a&gt; y la &lt;a href="https://apidog.com/es/blog/api-security-testing-checklist?utm_source=dev.to&amp;amp;utm_medium=wanda&amp;amp;utm_content=n8n-post-automation"&gt;lista de comprobación para pruebas de seguridad de API&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Permite que tu agente de código pruebe la autorización con Apidog CLI
&lt;/h2&gt;

&lt;p&gt;No escribas esta prueba manualmente para cada ruta. Deja que tu agente de código se encargue utilizando &lt;a href="https://apidog.com/apidog-cli/?utm_source=dev.to&amp;amp;utm_medium=wanda&amp;amp;utm_content=n8n-post-automation"&gt;Apidog CLI&lt;/a&gt;: lee tus rutas, crea una prueba por cada recurso protegido y genera una suite lista para ejecutarse en CI. Apidog Free cubre hasta 4 usuarios.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npm &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="nt"&gt;-g&lt;/span&gt; apidog-cli@latest
apidog auth login &lt;span class="nt"&gt;--with-token&lt;/span&gt; &amp;lt;YOUR_TOKEN&amp;gt;
apidog skill &lt;span class="nb"&gt;install&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Necesitarás un entorno de pruebas con dos organizaciones creadas con datos iniciales y un usuario en cada una. Luego, proporciónale este prompt a tu agente:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Read the routes in src/. For each route that returns data owned by an
organization, create an Apidog test scenario in project &amp;lt;id&amp;gt;: log in as
the Org A test user, request an Org B resource by ID, and assert the
status is 403 or 404. Add an Org A request for its own resource and
assert 200, so a broken login can't pass. Group the scenarios in a test
suite, run it against the staging environment, and summarize failures.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;El agente comprueba la estructura del payload, crea los escenarios y ejecuta la suite:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;apidog cli-schema get test-scenario-create
apidog cli-schema validate test-scenario-create &lt;span class="nt"&gt;--file&lt;/span&gt; scenario.json
apidog test-scenario create &lt;span class="nt"&gt;--project&lt;/span&gt; &amp;lt;&lt;span class="nb"&gt;id&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="nt"&gt;--file&lt;/span&gt; scenario.json
apidog test-scenario import-steps &amp;lt;scenarioId&amp;gt; &lt;span class="nt"&gt;--project&lt;/span&gt; &amp;lt;&lt;span class="nb"&gt;id&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="nt"&gt;--source&lt;/span&gt; endpoint &lt;span class="nt"&gt;--ids&lt;/span&gt; &amp;lt;endpointIds&amp;gt;
apidog test-suite create &lt;span class="nt"&gt;--project&lt;/span&gt; &amp;lt;&lt;span class="nb"&gt;id&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="nt"&gt;--file&lt;/span&gt; suite.json
apidog run &lt;span class="nt"&gt;--test-suite&lt;/span&gt; &amp;lt;suiteId&amp;gt; &lt;span class="nt"&gt;--project&lt;/span&gt; &amp;lt;&lt;span class="nb"&gt;id&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="nt"&gt;-e&lt;/span&gt; &amp;lt;envId&amp;gt; &lt;span class="nt"&gt;-r&lt;/span&gt; cli,junit
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fuo5vh5jx9544dfx97d4i.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fuo5vh5jx9544dfx97d4i.png" alt="Sequence diagram: a test user in Org A logs in, gets a token, requests an Org B invoice, and the test passes on 403 or 404 and fails on 200" width="800" height="533"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;La comprobación positiva es fundamental. Sin ella, una URL base incorrecta también devolvería un 404 y la prueba pasaría por el motivo equivocado.&lt;/p&gt;

&lt;p&gt;Añade la misma línea con &lt;code&gt;apidog run&lt;/code&gt; al flujo de trabajo anterior, ejecutándola contra un despliegue de preview o staging con organizaciones de prueba precargadas, nunca con datos de producción. La &lt;a href="https://apidog.com/es/blog/apidog-run-command-reference?utm_source=dev.to&amp;amp;utm_medium=wanda&amp;amp;utm_content=n8n-post-automation"&gt;referencia del comando &lt;code&gt;apidog run&lt;/code&gt;&lt;/a&gt; cubre el resto de parámetros, y la guía de &lt;a href="https://apidog.com/es/blog/apidog-cli-in-claude-code?utm_source=dev.to&amp;amp;utm_medium=wanda&amp;amp;utm_content=n8n-post-automation"&gt;Apidog CLI en Claude Code&lt;/a&gt; explica paso a paso la configuración del agente.&lt;/p&gt;

&lt;h2&gt;
  
  
  Preguntas frecuentes
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;¿Cuál es la mejor forma gratuita de detectar vulnerabilidades en un repositorio?&lt;/strong&gt; Combina un escáner de dependencias, Gitleaks y Semgrep Community Edition, y añade además una prueba en tiempo de ejecución para la autorización. Ninguna herramienta por sí sola cubrió todo en nuestro repositorio de prueba.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;¿Es gratuito Vercel Security Review?&lt;/strong&gt; Solo hasta el 10 de noviembre de 2026 y únicamente para equipos Pro y Enterprise. A partir de esa fecha, se pagan las tarifas por token del proveedor más 0,25 $ por millón de tokens. Los repositorios que no se despliegan en Vercel aún no son compatibles.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;¿El escaneo de secretos de GitHub es gratuito en repositorios privados?&lt;/strong&gt; No. Tanto el escaneo de secretos como CodeQL son gratuitos en repositorios públicos, pero los repositorios privados requieren GitHub Secret Protection (19 $) o GitHub Code Security (30 $) por committer activo al mes. Las alertas de Dependabot son gratuitas en ambos.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;¿Puede Semgrep detectar fallos de autorización?&lt;/strong&gt; No detectó nuestra ruta de facturas con los conjuntos de reglas que ejecutamos. Community Edition no puede rastrear el flujo de datos más allá de una sola función o archivo, aunque es posible escribir reglas personalizadas para patrones específicos de tu base de código.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;¿Reemplazan los escáneres una prueba de penetración?&lt;/strong&gt; No. Los escáneres y las pruebas cubren patrones conocidos y los casos de prueba definidos. Una prueba de penetración busca aquello que no se ha previsto, y la propia documentación de Vercel aclara que su análisis tampoco constituye un pentest.&lt;/p&gt;

</description>
      <category>automation</category>
      <category>devops</category>
      <category>git</category>
      <category>security</category>
    </item>
    <item>
      <title>¿Qué es Chain of Recall? Cómo los IDs estables dan memoria a los agentes de IA</title>
      <dc:creator>Roobia</dc:creator>
      <pubDate>Thu, 05 Nov 2026 07:05:24 +0000</pubDate>
      <link>https://dev.to/roobia/que-es-chain-of-recall-como-los-ids-estables-dan-memoria-a-los-agentes-de-ia-2ndh</link>
      <guid>https://dev.to/roobia/que-es-chain-of-recall-como-los-ids-estables-dan-memoria-a-los-agentes-de-ia-2ndh</guid>
      <description>&lt;h1&gt;
  
  
  ¿Qué es Chain of Recall? Cómo los IDs estables dan memoria a los agentes de IA
&lt;/h1&gt;

&lt;p&gt;Chain of Recall es una forma de dotar de memoria a un agente de IA de larga ejecución sin saturar su ventana de contexto. Cada Trigger, Thread y Worker recibe un ID estable. El contexto solo conserva los IDs, resúmenes breves y mensajes cercanos, y el agente recorre los enlaces entre identificadores para recuperar hechos anteriores en unos pocos saltos.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://apidog.com/?utm_source=dev.to&amp;amp;utm_medium=wanda&amp;amp;utm_content=n8n-post-automation" class="crayons-btn crayons-btn--primary"&gt;Prueba Apidog hoy&lt;/a&gt;
&lt;/p&gt;

&lt;p&gt;El término proviene del ensayo de diseño de DeepSeek Harness &lt;a href="https://x.com/DeepSeekHarness/status/2116857257245987236" rel="noopener noreferrer"&gt;“Exploring Super-agent Design”&lt;/a&gt;, publicado el 01-11-2026. Una advertencia antes de continuar: el ensayo describe una arquitectura, no una funcionalidad lanzada al mercado. Parte de ella reside en un plugin prototipo, &lt;code&gt;dsh-superagent-prototype&lt;/code&gt;, que los autores definen como «no es un producto oficial de DeepSeek». No existe ningún interruptor para activar Chain of Recall: es un patrón que debes construir.&lt;/p&gt;

&lt;h2&gt;
  
  
  El problema de la ventana de contexto en un agente de larga ejecución
&lt;/h2&gt;

&lt;p&gt;Un agente de larga ejecución alcanza su límite de contexto porque el flujo de trabajo nunca se detiene. Un superagente que monitoriza el chat, GitHub y CI procesa cientos de eventos al día, y la ventana que albergó el trabajo de ayer no puede contener también el de hoy.&lt;/p&gt;

&lt;p&gt;Las soluciones habituales conllevan un coste:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Conservar todo.&lt;/strong&gt; La ventana se llena y el coste se dispara con cada turno.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Resumir turnos antiguos.&lt;/strong&gt; Un resumen suele descartar el error exacto o el número de PR que necesitarás más adelante.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Recuperar por similitud.&lt;/strong&gt; Funciona hasta que el dato que buscas no se parece a tu consulta.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;La guía de Anthropic sobre &lt;a href="https://www.anthropic.com/engineering/effective-context-engineering-for-ai-agents" rel="noopener noreferrer"&gt;ingeniería de contexto para agentes de IA&lt;/a&gt; plantea el contexto como un recurso finito que se debe curar. Chain of Recall es una forma concreta de llevar a cabo esa curación, y nuestra guía explicativa sobre &lt;a href="https://apidog.com/es/blog/how-ai-agent-memory-works?utm_source=dev.to&amp;amp;utm_medium=wanda&amp;amp;utm_content=n8n-post-automation"&gt;cómo funciona la memoria en los agentes de IA&lt;/a&gt; analiza un abanico más amplio de opciones.&lt;/p&gt;

&lt;h2&gt;
  
  
  Inline frente a spill: el contexto como una memoria caché
&lt;/h2&gt;

&lt;p&gt;El ensayo aborda la ventana de contexto como una memoria caché con dos acciones:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Inline&lt;/strong&gt; para lo que el agente probablemente necesite de inmediato: identificadores, resúmenes breves y mensajes cercanos.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Spill&lt;/strong&gt; para todo lo demás: truncarlo y dejar un puntero que el agente pueda consultar más tarde.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Un elemento derivado a spill no se elimina; únicamente su puntero permanece en el prompt.&lt;/p&gt;

&lt;p&gt;Así se vería el fallo de una integración continua (CI) que llega al Router. Esta estructura es meramente ilustrativa, no es código de DeepSeek:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"trigger_id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"trg_8f21"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"source"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"github.check_run"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"thread_id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"thr_pr_412"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"summary"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"CI failed on PR #412: 3 of 118 tests red in payments/"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"neighbours"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"trg_8f1c: review comment asking for retry logic"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"spilled"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"full_log"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"GET /triggers/trg_8f21/payload (41 KB, truncated)"&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Si el resumen de una sola línea es suficiente, el agente nunca asume el coste del registro de 41 KB. Si no lo es, recupera el log mediante su ID.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F291k1dpn48rxodpsyay9.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F291k1dpn48rxodpsyay9.png" alt="Diagram of context as a cache: a long-running agent's context window holds inlined IDs, summaries and neighboring messages, while full logs, old threads and worker transcripts sit in external storage, each linked back to the window by a pointer"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Identificadores estables y el grafo de referencias
&lt;/h2&gt;

&lt;p&gt;Chain of Recall funciona porque los ID nunca cambian. En el diseño planteado por el ensayo, tres tipos de objetos los incorporan:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Objeto&lt;/th&gt;
&lt;th&gt;Descripción&lt;/th&gt;
&lt;th&gt;Ejemplo de ID&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Trigger&lt;/td&gt;
&lt;td&gt;Un evento entrante: un mensaje de chat, un webhook, una devolución de llamada de CI&lt;/td&gt;
&lt;td&gt;&lt;code&gt;trg_8f21&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Thread&lt;/td&gt;
&lt;td&gt;Una secuencia de eventos relacionados en un PR, tema de mensajería o hilo de correo electrónico&lt;/td&gt;
&lt;td&gt;&lt;code&gt;thr_pr_412&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Worker&lt;/td&gt;
&lt;td&gt;Una sesión de agente aislada que gestiona una sola tarea&lt;/td&gt;
&lt;td&gt;&lt;code&gt;wkr_77a0&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Un Trigger pertenece a un Thread, un Thread es propiedad de uno o más Workers, y el informe de un Worker cita los Triggers sobre los que actuó. Estos vínculos forman un grafo de referencias, y dicho grafo constituye la memoria del agente.&lt;/p&gt;

&lt;p&gt;La recuperación de información se lleva a cabo siguiendo los enlaces salto a salto, en lugar de cargar todo el historial o buscar coincidencias de texto. La guía complementaria sobre &lt;a href="https://apidog.com/es/blog/how-to-build-a-super-agent?utm_source=dev.to&amp;amp;utm_medium=wanda&amp;amp;utm_content=n8n-post-automation"&gt;cómo construir un superagente&lt;/a&gt; explica qué papel desempeñan los Triggers, Threads y Workers en el diseño completo de Router y Worker.&lt;/p&gt;

&lt;h2&gt;
  
  
  Ejemplo práctico de recuperación multisalto
&lt;/h2&gt;

&lt;p&gt;Supongamos que un compañero le pregunta al Router un viernes: «¿Por qué añadimos la lógica de reintento al cliente de pagos?». La conversación original tuvo lugar el martes y se envió a spill hace mucho tiempo. Así se recorre la cadena:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Salto 1: localizar el Thread.&lt;/strong&gt; El contexto del Router aún conserva una entrada de índice de una línea: &lt;code&gt;thr_pr_412: payments retry PR, merged Wed&lt;/code&gt;. Ejecuta un &lt;code&gt;GET /threads/thr_pr_412&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Salto 2: identificar el Worker.&lt;/strong&gt; El registro del Thread incluye &lt;code&gt;owner_workers: ["wkr_77a0"]&lt;/code&gt;. El Router realiza un &lt;code&gt;GET /workers/wkr_77a0&lt;/code&gt; y lee su informe final.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Salto 3: descubrir la causa.&lt;/strong&gt; El informe cita &lt;code&gt;trg_8f21&lt;/code&gt;, el fallo de CI. El Router obtiene la carga útil de ese Trigger y lee los errores de tiempo de espera (timeout) en el log.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Respuesta.&lt;/strong&gt; «La CI en el PR #412 falló el martes por 3 tiempos de espera en los pagos. El Worker wkr_77a0 añadió reintentos con retroceso exponencial (backoff) y el PR se fusionó el miércoles».&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Tres peticiones pequeñas y precisas. No se dedujo nada al azar ni hubo información ocupando espacio en el prompt durante tres días.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F17qd6dkgvp7kt68ohgy2.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F17qd6dkgvp7kt68ohgy2.png" alt="Diagram of a three-hop Chain of Recall: the agent starts from an inlined thread ID, fetches the Thread record, follows its owner link to a Worker report, then follows a cited Trigger ID to the original CI log, with one API call per hop"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Chain of Recall frente a la memoria vectorial y los resúmenes
&lt;/h2&gt;

&lt;p&gt;Chain of Recall no reemplaza a otras técnicas de memoria; responde a una pregunta diferente. La recuperación vectorial, popularizada por el &lt;a href="https://arxiv.org/abs/2005.11401" rel="noopener noreferrer"&gt;artículo sobre generación aumentada por recuperación&lt;/a&gt;, plantea «¿qué se parece a esto?». Chain of Recall plantea «¿qué está vinculado a esto?».&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;&lt;/th&gt;
&lt;th&gt;Chain of Recall&lt;/th&gt;
&lt;th&gt;Memoria vectorial (RAG)&lt;/th&gt;
&lt;th&gt;Resúmenes continuos&lt;/th&gt;
&lt;th&gt;Servidores MCP de memoria&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Mecanismo de recuperación&lt;/td&gt;
&lt;td&gt;Sigue enlaces mediante identificadores estables&lt;/td&gt;
&lt;td&gt;Búsqueda por similitud sobre embeddings&lt;/td&gt;
&lt;td&gt;Lee un historial comprimido&lt;/td&gt;
&lt;td&gt;Invoca una herramienta de memoria expuesta por el servidor&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Precisión&lt;/td&gt;
&lt;td&gt;Registro exacto por ID&lt;/td&gt;
&lt;td&gt;Aproximada, clasificada por puntuación&lt;/td&gt;
&lt;td&gt;Con pérdida por diseño&lt;/td&gt;
&lt;td&gt;Depende del almacenamiento del servidor&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Ideal para&lt;/td&gt;
&lt;td&gt;Historiales de eventos: PR, tickets, ejecuciones de CI&lt;/td&gt;
&lt;td&gt;Grandes volúmenes de documentos, consultas difusas&lt;/td&gt;
&lt;td&gt;Sesiones cortas, continuidad en chats&lt;/td&gt;
&lt;td&gt;Datos compartidos entre distintas herramientas y sesiones&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Requisitos&lt;/td&gt;
&lt;td&gt;Identificadores inmutables, API de consulta por ID&lt;/td&gt;
&lt;td&gt;Un modelo de embeddings y un índice&lt;/td&gt;
&lt;td&gt;Una pasada de resumen&lt;/td&gt;
&lt;td&gt;Un servidor MCP en ejecución&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Punto débil&lt;/td&gt;
&lt;td&gt;No encuentra aquello que no esté vinculado&lt;/td&gt;
&lt;td&gt;Pasa por alto hechos expresados con otras palabras&lt;/td&gt;
&lt;td&gt;Omite detalles&lt;/td&gt;
&lt;td&gt;Un servicio adicional que mantener y proteger&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;En la práctica, lo habitual es combinarlos: un índice vectorial identifica el ID del Thread inicial y, a partir de ahí, Chain of Recall avanza hasta los datos exactos. La &lt;a href="https://arxiv.org/abs/2310.08560" rel="noopener noreferrer"&gt;jerarquía de memoria al estilo de un sistema operativo&lt;/a&gt; propuesta en el artículo de MemGPT es un concepto muy cercano. Si prefieres comenzar con una solución lista para usar, consulta nuestra guía sobre &lt;a href="https://apidog.com/es/blog/add-persistent-memory-ai-agents-mcp?utm_source=dev.to&amp;amp;utm_medium=wanda&amp;amp;utm_content=n8n-post-automation"&gt;cómo añadir memoria persistente a agentes de IA con MCP&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Existen dos limitaciones. El ensayo sitúa la memoria a largo plazo entre los problemas aún abiertos y no afirma que Chain of Recall lo resuelva. Además, en su experimento, eliminar la transferencia directa de Threads (Thread pass-through) incrementó los tokens de lectura de caché de 23,2 M a 31,8 M por ejecución (alrededor de un 37 % más): se trata del coste asociado a una funcionalidad ausente, no de un ahorro atribuible a Chain of Recall.&lt;/p&gt;

&lt;h2&gt;
  
  
  Qué deben garantizar las API subyacentes
&lt;/h2&gt;

&lt;p&gt;Cada salto en este recorrido corresponde a una llamada a la API. Si una llamada devuelve un registro diferente, o ninguno, la cadena se rompe y el agente se detiene o responde basándose en suposiciones. Por ello, las API que respaldan Chain of Recall deben cumplir cuatro contratos esenciales:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Los identificadores nunca cambian.&lt;/strong&gt; Un ID devuelto hoy debe resolver el mismo objeto el mes que viene. Nada de reutilizarlos tras eliminarlos ni de renumerarlos tras una migración.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;La consulta por ID es ligera y exacta.&lt;/strong&gt; &lt;code&gt;GET /threads/{id}&lt;/code&gt; devuelve ese único registro. No realiza búsquedas ni devuelve la «coincidencia más cercana».&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Los identificadores desconocidos fallan de forma explícita.&lt;/strong&gt; Un ID inexistente devuelve &lt;code&gt;404 Not Found&lt;/code&gt;, según lo define la norma &lt;a href="https://www.rfc-editor.org/rfc/rfc9110.html" rel="noopener noreferrer"&gt;RFC 9110&lt;/a&gt;, con un cuerpo de error claro. Un código &lt;code&gt;200&lt;/code&gt; con un objeto vacío induciría al agente a creer que existe un recuerdo cuando no es así.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Los cursores paginan sin omisiones.&lt;/strong&gt; &lt;code&gt;GET /threads/{id}/events?cursor=&lt;/code&gt; recorre un Thread extenso en orden. Cada evento aparece exactamente una vez, no se salta ninguno y el cursor sigue siendo válido a medida que llegan nuevos eventos.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Estos contratos suelen romperse de forma silenciosa durante las refactorizaciones, por lo que deben formar parte de las pruebas automatizadas. Las respuestas de las herramientas también deben mantenerse compactas, un aspecto que abordamos en profundidad en nuestra guía sobre &lt;a href="https://apidog.com/es/blog/agent-tool-response-context-window?utm_source=dev.to&amp;amp;utm_medium=wanda&amp;amp;utm_content=n8n-post-automation"&gt;las respuestas de las herramientas del agente y la ventana de contexto&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Permite que tu agente de programación pruebe las API de recuperación con Apidog CLI
&lt;/h2&gt;

&lt;p&gt;Chain of Recall es tan confiable como lo sean sus endpoints de consulta por ID, y un agente de programación puede escribir y volver a ejecutar esas validaciones por ti. &lt;a href="https://apidog.com/apidog-cli/?utm_source=dev.to&amp;amp;utm_medium=wanda&amp;amp;utm_content=n8n-post-automation"&gt;Apidog CLI&lt;/a&gt; proporciona al agente comandos para definir los endpoints, crear casos de prueba y ejecutarlos directamente desde el terminal.&lt;/p&gt;

&lt;p&gt;Configúralo una sola vez:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npm &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="nt"&gt;-g&lt;/span&gt; apidog-cli@latest
apidog auth login &lt;span class="nt"&gt;--with-token&lt;/span&gt; &amp;lt;YOUR_TOKEN&amp;gt;
npx &lt;span class="nt"&gt;-y&lt;/span&gt; skills add https://apidog.com   &lt;span class="c"&gt;# pick your agent when prompted&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;A continuación, proporciona a Claude Code, Codex o cualquier agente que utilices el siguiente [REDACTED PROMPT]&lt;br&gt;
In Apidog project , define three endpoints for our agent memory&lt;br&gt;
service: GET /threads/{id}, GET /threads/{id}/events?cursor=, and&lt;br&gt;
GET /workers/{id}. Then create test cases that check:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;A thread_id returned by GET /threads/{id} resolves to the same record
on a second call, and each owner worker ID resolves via GET /workers/{id}.&lt;/li&gt;
&lt;li&gt;An unknown thread ID and an unknown worker ID both return 404.&lt;/li&gt;
&lt;li&gt;Paging GET /threads/{id}/events with the cursor returns every event
once, in order, with no gaps.
Run them against the staging environment and summarize any failures.
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;
El agente lee el esquema de cada payload, valida su JSON antes de escribir nada y, posteriormente, genera y ejecuta las pruebas:

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;&lt;br&gt;
bash&lt;br&gt;
apidog cli-schema get endpoint-create&lt;br&gt;
apidog cli-schema validate endpoint-create --file thread-get.json&lt;br&gt;
apidog endpoint create --project  --file thread-get.json&lt;/p&gt;

&lt;p&gt;apidog cli-schema get test-case-create&lt;br&gt;
apidog cli-schema validate test-case-create --file id-resolves.json&lt;br&gt;
apidog test-case create --project  --file id-resolves.json&lt;/p&gt;

&lt;p&gt;apidog run --test-case  --project  -e  -r cli,json&lt;/p&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;


El generador de informes `cli` muestra las aserciones superadas y fallidas en el terminal, y el reporte `json` proporciona al agente un archivo interpretable para identificar con precisión qué salto falló. Si un ID deja de resolverse tras una migración, lo verás reflejado en el informe antes de que el agente comience a responder basándose en una cadena rota. Para ejecutar estas mismas comprobaciones en cada merge, cambia el reporter a `-r junit`; nuestra guía sobre [Apidog CLI en Claude Code](https://apidog.com/es/blog/apidog-cli-in-claude-code?utm_source=dev.to&amp;amp;utm_medium=wanda&amp;amp;utm_content=n8n-post-automation) muestra el ciclo completo del agente.

## Dónde encaja Chain of Recall

Utiliza Chain of Recall cuando la memoria de tu agente consista en un historial de eventos discretos y enlazables: PR, tickets, ejecuciones de CI, hilos de soporte o despliegues. Estos elementos ya disponen de identificadores naturales, y las preguntas que los usuarios suelen formular sobre ellos («¿por qué hicimos esto?», «¿qué ocurrió después de aquello?») son cuestiones centradas en las conexiones entre dichos eventos.

Recurre a la recuperación vectorial para documentos no estructurados y preguntas difusas, y emplea resúmenes para sesiones breves en las que perder cierto nivel de detalle no suponga un inconveniente.

Chain of Recall surge de un ensayo y un prototipo: es una idea clara y contrastable, no un producto empaquetado. Para conocer la herramienta detrás de este ensayo, echa un vistazo a [qué es DeepSeek Harness](https://apidog.com/es/blog/what-is-deepseek-harness?utm_source=dev.to&amp;amp;utm_medium=wanda&amp;amp;utm_content=n8n-post-automation).

## Preguntas frecuentes

**¿Es Chain of Recall una función de DeepSeek que pueda activar?**
No. Es un término extraído del ensayo sobre superagentes de DeepSeek Harness, y parte de su implementación reside en un plugin prototipo que los propios autores señalan que no es un producto oficial de DeepSeek. El patrón debe implementarlo uno mismo.

**¿Cuál es la diferencia entre inline y spill?**
Inline mantiene los identificadores, los resúmenes breves y los mensajes cercanos dentro del prompt. Spill trunca el resto y deja un puntero que el agente puede consultar por ID cuando lo necesite.

**¿Sustituye Chain of Recall a RAG?**
No. RAG localiza contenido similar, mientras que Chain of Recall sigue enlaces exactos a través de identificadores. Muchos agentes combinan ambos enfoques.

**¿Redujo Chain of Recall el consumo de tokens en un 37 %?**
No. La cifra del 37 % corresponde al Thread pass-through: en el experimento del ensayo, su eliminación provocó que los tokens de lectura de caché aumentaran de 23,2 M a 31,8 M por ejecución. El ensayo no atribuye un ahorro de tokens al propio Chain of Recall.

**¿Qué debe devolver una API de consulta por ID ante un identificador desconocido?**
Un error `404 Not Found` acompañado de un cuerpo explicativo claro. Devolver un `200` con un objeto vacío hace que el agente asuma que el registro existe, rompiendo silenciosamente la cadena de recuperación.

**¿Cómo puedo verificar que las API de memoria de mi agente permanezcan estables?**
Diseña casos de prueba que verifiquen que un ID obtenido en una llamada se resuelve en la siguiente, que los identificadores desconocidos devuelven un 404 y que los cursores paginan sin omisiones. Un agente de programación puede generar y ejecutar estas pruebas con Apidog CLI en cada merge.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

</description>
      <category>agents</category>
      <category>ai</category>
      <category>architecture</category>
      <category>llm</category>
    </item>
    <item>
      <title>Llamadas asíncronas a herramientas para agentes de IA: por qué start() supera a un run() bloqueante</title>
      <dc:creator>Roobia</dc:creator>
      <pubDate>Thu, 05 Nov 2026 05:53:30 +0000</pubDate>
      <link>https://dev.to/roobia/llamadas-asincronas-a-herramientas-para-agentes-de-ia-por-que-start-supera-a-un-run-bloqueante-li4</link>
      <guid>https://dev.to/roobia/llamadas-asincronas-a-herramientas-para-agentes-de-ia-por-que-start-supera-a-un-run-bloqueante-li4</guid>
      <description>&lt;h1&gt;
  
  
  Llamadas asíncronas a herramientas para agentes de IA: por qué start() supera a un run() bloqueante
&lt;/h1&gt;

&lt;p&gt;&lt;strong&gt;Respuesta rápida:&lt;/strong&gt; Las llamadas asíncronas a herramientas para agentes de IA dividen un &lt;code&gt;run()&lt;/code&gt; bloqueante en un pequeño contrato: &lt;code&gt;start()&lt;/code&gt; devuelve de inmediato un identificador de la tarea, &lt;code&gt;status()&lt;/code&gt; informa del progreso, &lt;code&gt;stop()&lt;/code&gt; cancela y el resultado regresa más tarde como un evento que el agente lee en su siguiente turno. El agente sigue conversando y recibiendo nuevas instrucciones mientras las tareas lentas se ejecutan en segundo plano.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://apidog.com/?utm_source=dev.to&amp;amp;utm_medium=wanda&amp;amp;utm_content=n8n-post-automation" class="crayons-btn crayons-btn--primary"&gt;Prueba Apidog hoy&lt;/a&gt;
&lt;/p&gt;

&lt;p&gt;La mayoría de los agentes actuales llaman a una herramienta y se quedan esperando. Si haces una segunda pregunta durante la ejecución de una suite de pruebas de 6 minutos, esta se queda en cola. Esto no supone un problema para una consulta de 200 ms, pero resulta frustrante en un despliegue o en un rastreo web.&lt;/p&gt;

&lt;p&gt;Un artículo reciente del equipo de DeepSeek Harness, &lt;a href="https://x.com/DeepSeekHarness/status/2116857257245987236" rel="noopener noreferrer"&gt;"Exploring Super-agent Design"&lt;/a&gt;, propone una solución denominada «full-duplex»: sustituir el &lt;code&gt;run()&lt;/code&gt; bloqueante por &lt;code&gt;start()&lt;/code&gt; y &lt;code&gt;stop()&lt;/code&gt;. Esta guía aborda la perspectiva del bucle del agente: el contrato de las herramientas, cómo retornan los resultados, la cancelación y la API que requiere cada herramienta. Para conocer la gestión HTTP de una llamada individual de larga duración, consulta &lt;a href="https://apidog.com/es/blog/ai-agent-long-running-api-operations?utm_source=dev.to&amp;amp;utm_medium=wanda&amp;amp;utm_content=n8n-post-automation"&gt;AI Agents and Long-Running API Calls: Polling vs Webhooks&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  ¿Qué son las llamadas asíncronas a herramientas en el bucle de un agente?
&lt;/h2&gt;

&lt;p&gt;Una llamada asíncrona a una herramienta es una invocación que devuelve un identificador (handle) en lugar de un resultado inmediato. El bucle del agente registra dicho identificador, finaliza su turno y queda disponible para el usuario. Cuando el trabajo termina, el runtime inyecta un evento de finalización en la conversación y el modelo lo lee en su siguiente turno como cualquier otro mensaje.&lt;/p&gt;

&lt;p&gt;La diferencia radica en quién espera: con &lt;code&gt;run()&lt;/code&gt; espera el modelo; con &lt;code&gt;start()&lt;/code&gt;, el runtime.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;&lt;/th&gt;
&lt;th&gt;
&lt;code&gt;run()&lt;/code&gt; bloqueante&lt;/th&gt;
&lt;th&gt;
&lt;code&gt;start()&lt;/code&gt; asíncrono&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Devuelve&lt;/td&gt;
&lt;td&gt;Resultado final&lt;/td&gt;
&lt;td&gt;Job id, “Started”&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;El agente durante el trabajo&lt;/td&gt;
&lt;td&gt;Bloqueado&lt;/td&gt;
&lt;td&gt;Conversando, planificando, iniciando más tareas&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Nuevo mensaje del usuario&lt;/td&gt;
&lt;td&gt;En cola hasta que la herramienta responde&lt;/td&gt;
&lt;td&gt;Se procesa de inmediato&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Cancelación&lt;/td&gt;
&lt;td&gt;Interrumpir todo el turno&lt;/td&gt;
&lt;td&gt;&lt;code&gt;stop(job_id)&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;El artículo de DeepSeek describe esto como un enfoque arquitectónico, no como una función ya lista para producción. Señala que el modo full-duplex está implementado en DeepSeek Harness pero no habilitado por defecto, y que algunas partes forman parte de un plugin prototipo llamado &lt;code&gt;dsh-superagent-prototype&lt;/code&gt;, el cual los autores aclaran que no es un producto oficial de DeepSeek. Conviene considerarlo como un patrón de diseño de referencia. Para más contexto, consulta &lt;a href="https://apidog.com/es/blog/what-is-deepseek-harness?utm_source=dev.to&amp;amp;utm_medium=wanda&amp;amp;utm_content=n8n-post-automation"&gt;qué es DeepSeek Harness&lt;/a&gt; y el artículo complementario sobre &lt;a href="https://apidog.com/es/blog/how-to-build-a-super-agent?utm_source=dev.to&amp;amp;utm_medium=wanda&amp;amp;utm_content=n8n-post-automation"&gt;cómo crear un superagente&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  El problema del bloqueo: una herramienta lenta paraliza al agente
&lt;/h2&gt;

&lt;p&gt;Imagina un agente de programación al que se le pide ejecutar la suite de pruebas (5 minutos) y responder una duda sobre una importación fallida. Con llamadas bloqueantes, la pregunta queda a la espera detrás de las pruebas, a pesar de que no necesita nada de ellas. Surgen tres problemas principales:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;La latencia se acumula.&lt;/strong&gt; Cada herramienta lenta suma toda su duración a todo lo que viene después.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Las instrucciones quedan desfasadas.&lt;/strong&gt; Si a los dos minutos dices «en realidad, salta las pruebas e2e», el agente no se enterará hasta que termine la ejecución.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Aparecen problemas de timeout.&lt;/strong&gt; Las pasarelas y proxies cierran conexiones que permanecen abiertas durante minutos, por lo que un &lt;code&gt;run()&lt;/code&gt; prolongado puede fallar incluso cuando la tarea se completó correctamente.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;El artículo califica la cualidad deseable como «productiva»: el agente acepta la siguiente instrucción antes de que termine la anterior. Las herramientas asíncronas son la forma de lograrlo.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fwnabwj443tq63sepn3r6.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fwnabwj443tq63sepn3r6.png" alt="Timeline comparing a blocking agent that waits idle for a 5-minute test run against an async agent that starts the run, answers two user messages, and reads the result when it lands" width="800" height="410"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  start, status y stop: el contrato de las herramientas asíncronas
&lt;/h2&gt;

&lt;p&gt;Proporciona al modelo tres herramientas por cada capacidad de larga duración en lugar de una sola, con estructuras de respuesta muy concisas.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"start_test_run"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"description"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Start the test suite. Returns immediately with a job_id. The result arrives later as a job_completed event; do not wait for it."&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"input_schema"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"object"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"properties"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"suite"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"string"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"enum"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"unit"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"e2e"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"all"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"idempotency_key"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"string"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"required"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"suite"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"idempotency_key"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;start_test_run&lt;/code&gt; devuelve &lt;code&gt;{"job_id": "job_8f2", "status": "queued"}&lt;/code&gt; y nada más. &lt;code&gt;get_job_status(job_id)&lt;/code&gt; devuelve &lt;code&gt;queued&lt;/code&gt;, &lt;code&gt;running&lt;/code&gt;, &lt;code&gt;done&lt;/code&gt; o &lt;code&gt;failed&lt;/code&gt;, junto con una breve nota de progreso. &lt;code&gt;stop_job(job_id)&lt;/code&gt; solicita la cancelación y devuelve el estado alcanzado.&lt;/p&gt;

&lt;p&gt;Dos reglas garantizan el comportamiento adecuado del modelo: incluye «do not wait» (no esperar) en la descripción, o de lo contrario sondeará &lt;code&gt;get_job_status&lt;/code&gt; en un bucle continuo; y nunca devuelvas datos de resultado desde &lt;code&gt;start&lt;/code&gt;, o el modelo tendrá que adivinar qué estructura recibió.&lt;/p&gt;

&lt;h2&gt;
  
  
  Cómo retornan los resultados al bucle
&lt;/h2&gt;

&lt;p&gt;El sondeo (polling) por parte del modelo debe ser el plan de reserva, no el diseño principal. Un enfoque más sólido consiste en que el runtime supervise las tareas e inyecte un evento de finalización en la conversación como un nuevo mensaje:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;[event] job_completed job_id=job_8f2 tool=start_test_run status=done
summary: 412 passed, 3 failed (auth/session.test.ts)
details: get_job_result(job_8f2)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Mantén el evento breve y deja la carga completa de datos detrás de una herramienta de consulta, evitando así que un registro de 40.000 líneas sature el contexto.&lt;/p&gt;

&lt;p&gt;El siguiente paso es procesar por lotes (batching). El artículo de DeepSeek describe un enrutador que recopila los activadores (triggers) que llegan durante un turno y los combina en la siguiente llamada al modelo —entradas largas y salidas cortas, integradas en la fase de prefill—. En su experimento, los disparadores pasaron de 1 a 40 por minuto, el tamaño promedio del lote aumentó de 1,0 a 2,8 y el tiempo por decisión se redujo de 6,4 s a 1,6 s. Aunque son métricas propias de las pruebas del artículo y no una referencia generalizada, una llamada que procesa tres eventos resulta mucho más eficiente que tres llamadas individuales. Una regla práctica: mientras el modelo genera respuestas, pon en cola los eventos y los mensajes del usuario; cuando finalice el turno, envíalos juntos en orden de llegada.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F6rexc1ykec84xd7ekiz1.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F6rexc1ykec84xd7ekiz1.png" alt="Diagram of an agent runtime: tools return job ids to the model, a job watcher collects completion events and user messages into a queue, and a router batches them into the next model call" width="800" height="410"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Orden de ejecución, cancelación y claves de idempotencia
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Orden de ejecución.&lt;/strong&gt; Las tareas pueden completarse en cualquier orden. Si la tarea B depende de la tarea A, haz explícita esa dependencia: inicia B solo tras recibir el evento de finalización de A, o configura la API para que acepte un parámetro &lt;code&gt;depends_on&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Cancelación.&lt;/strong&gt; &lt;code&gt;stop&lt;/code&gt; es una solicitud, no una garantía. Devuelve el estado final real (&lt;code&gt;cancelled&lt;/code&gt;, o &lt;code&gt;done&lt;/code&gt; si concluyó antes) y permite que el modelo lo informe con precisión. La extensión Tasks de MCP adopta este mismo principio: su documentación describe la cancelación como cooperativa, por lo que una tarea aún puede alcanzar un estado terminal distinto de &lt;code&gt;cancelled&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Claves de idempotencia.&lt;/strong&gt; Los modelos realizan reintentos, por lo que una conexión interrumpida puede desencadenar un segundo &lt;code&gt;start&lt;/code&gt;. Exige una &lt;code&gt;idempotency_key&lt;/code&gt; en cada &lt;code&gt;start&lt;/code&gt; y asegúrate de que la API devuelva la tarea existente si detecta la misma clave. De lo contrario, una instrucción como «ejecutar la migración» podría ejecutarse dos veces.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Resultados parciales.&lt;/strong&gt; Expón los resultados preliminares (por ejemplo, las primeras 50 páginas rastreadas) mediante &lt;code&gt;get_job_result(job_id, cursor)&lt;/code&gt; en lugar de esperar a que termine todo el proceso.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Crecimiento del contexto.&lt;/strong&gt; Resume las tareas finalizadas en una sola línea una vez que el modelo haya actuado sobre ellas.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Tiempos de espera (timeouts).&lt;/strong&gt; Asigna a cada tarea un límite de tiempo y emite &lt;code&gt;job_timed_out&lt;/code&gt; si este se supera.&lt;/p&gt;

&lt;h2&gt;
  
  
  Cómo debe ser la API subyacente
&lt;/h2&gt;

&lt;p&gt;Una herramienta asíncrona es tan eficaz como la API de tareas que la respalda: debe aceptar el trabajo, devolver un identificador y permitir que el cliente consulte su estado. El &lt;a href="https://www.rfc-editor.org/rfc/rfc9110.html#name-202-accepted" rel="noopener noreferrer"&gt;RFC 9110 define 202 Accepted&lt;/a&gt; indicando que «la solicitud ha sido aceptada para su procesamiento, pero este aún no se ha completado», y la &lt;a href="https://developer.mozilla.org/en-US/docs/Web/HTTP/Reference/Status/202" rel="noopener noreferrer"&gt;referencia de MDN sobre el código 202&lt;/a&gt; detalla su aplicación práctica.&lt;/p&gt;

&lt;p&gt;Una API mínima de tareas para una herramienta &lt;code&gt;start()&lt;/code&gt;:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Llamada&lt;/th&gt;
&lt;th&gt;Respuesta&lt;/th&gt;
&lt;th&gt;Utilizado por&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;code&gt;POST /jobs&lt;/code&gt; (con encabezado &lt;code&gt;Idempotency-Key&lt;/code&gt;)&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;202&lt;/code&gt; + &lt;code&gt;{"job_id", "status":"queued"}&lt;/code&gt; + &lt;code&gt;Location: /jobs/{id}&lt;/code&gt;
&lt;/td&gt;
&lt;td&gt;&lt;code&gt;start&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;GET /jobs/{id}&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;200&lt;/code&gt; + &lt;code&gt;queued&lt;/code&gt;, &lt;code&gt;running&lt;/code&gt;, &lt;code&gt;done&lt;/code&gt; o &lt;code&gt;failed&lt;/code&gt;
&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;status&lt;/code&gt;, supervisor de tareas (job watcher)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;GET /jobs/{id}/result&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;200&lt;/code&gt; con la salida, o &lt;code&gt;409&lt;/code&gt; si aún no termina&lt;/td&gt;
&lt;td&gt;herramienta de consulta (fetch tool)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;DELETE /jobs/{id}&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;202&lt;/code&gt; cancelación solicitada, luego &lt;code&gt;404&lt;/code&gt; o &lt;code&gt;409&lt;/code&gt; en llamadas posteriores&lt;/td&gt;
&lt;td&gt;&lt;code&gt;stop&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;URL de callback opcional&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;POST&lt;/code&gt; al emisor tras completarse&lt;/td&gt;
&lt;td&gt;supervisor de tareas (job watcher)&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;El callback permite que el runtime envíe eventos en lugar de recurrir al sondeo. Si necesitas ayuda para elegir entre ambas opciones, consulta el análisis comparativo en &lt;a href="https://apidog.com/es/blog/webhooks-vs-polling?utm_source=dev.to&amp;amp;utm_medium=wanda&amp;amp;utm_content=n8n-post-automation"&gt;webhooks vs polling&lt;/a&gt;; la perspectiva de las API orientadas a eventos se explica en &lt;a href="https://apidog.com/es/blog/what-is-async-api?utm_source=dev.to&amp;amp;utm_medium=wanda&amp;amp;utm_content=n8n-post-automation"&gt;qué es AsyncAPI&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Si tus herramientas son compatibles con MCP, ya existe un estándar para esto. La &lt;a href="https://modelcontextprotocol.io/specification/latest" rel="noopener noreferrer"&gt;especificación de MCP (versión 2026-07-28)&lt;/a&gt; incluye &lt;a href="https://modelcontextprotocol.io/extensions/tasks/overview" rel="noopener noreferrer"&gt;Tasks&lt;/a&gt; como una extensión opcional: el servidor puede responder a &lt;code&gt;tools/call&lt;/code&gt; con un &lt;code&gt;CreateTaskResult&lt;/code&gt; que contiene un &lt;code&gt;taskId&lt;/code&gt;, el cliente sondea &lt;code&gt;tasks/get&lt;/code&gt; (o escucha &lt;code&gt;notifications/tasks&lt;/code&gt;) y &lt;code&gt;tasks/cancel&lt;/code&gt; solicita la detención. Los estados son &lt;code&gt;working&lt;/code&gt;, &lt;code&gt;input_required&lt;/code&gt;, &lt;code&gt;completed&lt;/code&gt;, &lt;code&gt;failed&lt;/code&gt; y &lt;code&gt;cancelled&lt;/code&gt;. Tanto el cliente como el servidor deben habilitarlo expresamente, y el soporte en los hosts puede variar, por lo que conviene verificar tu cliente antes de depender de esta función.&lt;/p&gt;

&lt;h2&gt;
  
  
  Crea y prueba la API de tareas con tu agente de programación y Apidog CLI
&lt;/h2&gt;

&lt;p&gt;La API de tareas es el componente que puedes verificar antes de que cualquier agente interactúe con él. Entrega el diseño y las pruebas a tu agente de desarrollo y haz que opere con &lt;a href="https://apidog.com/apidog-cli/?utm_source=dev.to&amp;amp;utm_medium=wanda&amp;amp;utm_content=n8n-post-automation"&gt;Apidog CLI&lt;/a&gt;. Tú solo redactas un prompt; el agente se encarga de generar la especificación, los casos de prueba y ejecutarlos.&lt;/p&gt;

&lt;p&gt;La configuración solo requiere tres comandos:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npm &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="nt"&gt;-g&lt;/span&gt; apidog-cli@latest
apidog auth login &lt;span class="nt"&gt;--with-token&lt;/span&gt; &amp;lt;YOUR_TOKEN&amp;gt;
npx &lt;span class="nt"&gt;-y&lt;/span&gt; skills add https://apidog.com   &lt;span class="c"&gt;# pick your agent when prompted&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;A continuación, proporciona un único prompt a tu agente:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;In Apidog project &amp;lt;projectId&amp;gt;, design the job API a start() tool needs:
POST /jobs returns 202 with job_id, GET /jobs/{id} returns queued|running|done|failed,
DELETE /jobs/{id} cancels. Create the endpoints, then create test cases that assert:
202 and a job_id on create, a status that reaches done within 60 seconds,
the same job_id when the Idempotency-Key repeats, and 409 or 404 on GET result after cancel.
Run them against the staging environment &amp;lt;envId&amp;gt; and summarize failures.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;El agente lee la estructura de cada payload desde la CLI, la valida y luego genera y ejecuta los comandos:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;apidog cli-schema get endpoint-create
apidog cli-schema validate endpoint-create &lt;span class="nt"&gt;--file&lt;/span&gt; post-jobs.json
apidog endpoint create &lt;span class="nt"&gt;--project&lt;/span&gt; &amp;lt;projectId&amp;gt; &lt;span class="nt"&gt;--file&lt;/span&gt; post-jobs.json
apidog cli-schema get test-case-create
apidog cli-schema validate test-case-create &lt;span class="nt"&gt;--file&lt;/span&gt; &lt;span class="k"&gt;case&lt;/span&gt;&lt;span class="nt"&gt;-create-202&lt;/span&gt;.json
apidog test-case create &lt;span class="nt"&gt;--project&lt;/span&gt; &amp;lt;projectId&amp;gt; &lt;span class="nt"&gt;--file&lt;/span&gt; &lt;span class="k"&gt;case&lt;/span&gt;&lt;span class="nt"&gt;-create-202&lt;/span&gt;.json
apidog run &lt;span class="nt"&gt;--test-case&lt;/span&gt; &amp;lt;caseId&amp;gt; &lt;span class="nt"&gt;--project&lt;/span&gt; &amp;lt;projectId&amp;gt; &lt;span class="nt"&gt;-e&lt;/span&gt; &amp;lt;envId&amp;gt; &lt;span class="nt"&gt;-r&lt;/span&gt; cli,json
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;El reporter &lt;code&gt;cli&lt;/code&gt; muestra en la terminal si cada aserción pasó o falló, y el informe en formato &lt;code&gt;json&lt;/code&gt; proporciona al agente datos estructurados para interpretarlos y explicarlos. Ejecuta el mismo comando en CI con &lt;code&gt;-r junit&lt;/code&gt; una vez que las pruebas sean exitosas; la &lt;a href="https://apidog.com/es/blog/apidog-cli-agent-workflow?utm_source=dev.to&amp;amp;utm_medium=wanda&amp;amp;utm_content=n8n-post-automation"&gt;guía de flujo de trabajo del agente con Apidog CLI&lt;/a&gt; explica ese ciclo en detalle, y &lt;a href="https://apidog.com/es/blog/apidog-cli-in-claude-code?utm_source=dev.to&amp;amp;utm_medium=wanda&amp;amp;utm_content=n8n-post-automation"&gt;Apidog CLI en Claude Code&lt;/a&gt; aborda la configuración del agente. El plan gratuito de Apidog admite hasta 4 usuarios.&lt;/p&gt;

&lt;h2&gt;
  
  
  Cuándo conviene usar herramientas asíncronas y cuándo no
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Cuándo usar el modelo asíncrono:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Una herramienta tarda habitualmente más de unos pocos segundos (compilaciones, suites de pruebas, rastreos, renderizado o despliegues).&lt;/li&gt;
&lt;li&gt;Los usuarios interactúan con el agente mientras las tareas están en ejecución.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Cuándo mantener el modelo bloqueante:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;La llamada devuelve una respuesta en uno o dos segundos.&lt;/li&gt;
&lt;li&gt;El siguiente paso no puede comenzar de ningún modo sin el resultado.&lt;/li&gt;
&lt;li&gt;No cuentas con una API de tareas real que lo respalde. Una herramienta asíncrona simulada que bloquea internamente solo añade complejidad innecesaria.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Una división práctica: mantén las lecturas bloqueantes y convierte en asíncronas las escrituras lentas y los cómputos pesados.&lt;/p&gt;

&lt;h2&gt;
  
  
  Preguntas frecuentes
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;¿Cuál es la diferencia entre las llamadas a herramientas asíncronas y las paralelas?&lt;/strong&gt; Las llamadas paralelas ejecutan varias herramientas simultáneamente dentro de un mismo turno, y el modelo sigue esperando a que todas concluyan. Las llamadas asíncronas devuelven el control de inmediato y se completan en turnos posteriores, lo que permite al modelo seguir interactuando mientras se ejecutan.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;¿Se necesita MCP para crear herramientas asíncronas?&lt;/strong&gt; No. Cualquier herramienta que devuelva un job id y un runtime que inyecte eventos de finalización funcionará. La extensión opcional Tasks de MCP estandariza el identificador, el sondeo y las llamadas de cancelación si tanto el cliente como el servidor la admiten.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;¿Cómo sabe el agente cuándo termina una tarea?&lt;/strong&gt; El runtime se lo comunica. Un supervisor de tareas (job watcher) sondea la API de tareas o recibe un callback, e incorpora un breve evento de finalización en la conversación. El modelo lo procesa en su siguiente turno.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;¿Qué ocurre si el usuario cancela en mitad de una tarea?&lt;/strong&gt; El agente invoca &lt;code&gt;stop(job_id)&lt;/code&gt;, la API registra la petición y la tarea reporta su estado final real. Si el trabajo terminó antes de que se procesara la cancelación, el agente debe comunicarlo con total transparencia en lugar de afirmar que se detuvo.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;¿Se puede activar el modo full-duplex de DeepSeek con un simple interruptor?&lt;/strong&gt; No como una función de producto lista para usar. El artículo explica que está implementado en DeepSeek Harness pero desactivado por defecto, y el plugin asociado es un prototipo que, según los propios autores, no constituye un producto oficial de DeepSeek. Conviene utilizarlo como un diseño de referencia.&lt;/p&gt;

</description>
    </item>
    <item>
      <title>Cómo usar webhooks de GitHub para activar agentes de programación con IA</title>
      <dc:creator>Roobia</dc:creator>
      <pubDate>Thu, 05 Nov 2026 04:23:16 +0000</pubDate>
      <link>https://dev.to/roobia/como-usar-webhooks-de-github-para-activar-agentes-de-programacion-con-ia-2d6g</link>
      <guid>https://dev.to/roobia/como-usar-webhooks-de-github-para-activar-agentes-de-programacion-con-ia-2d6g</guid>
      <description>&lt;p&gt;Para usar webhooks de GitHub y activar agentes de programación con IA, apunta un webhook del repositorio a un endpoint de recepción propio, verifica el encabezado &lt;code&gt;X-Hub-Signature-256&lt;/code&gt; con el cuerpo sin procesar (raw body), responde con un 202 dentro de la ventana de 10 segundos de GitHub y envía el evento a una cola. Luego, un worker filtra el evento, lo asocia a un hilo (repositorio más número de PR) e inicia o alimenta al agente.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://apidog.com/?utm_source=dev.to&amp;amp;utm_medium=wanda&amp;amp;utm_content=n8n-post-automation" class="crayons-btn crayons-btn--primary"&gt;Prueba Apidog hoy&lt;/a&gt;
&lt;/p&gt;

&lt;p&gt;En el resto de esta guía se muestra cada paso en código y cómo hacer que tu agente de programación pruebe el endpoint con Apidog CLI.&lt;/p&gt;

&lt;h2&gt;
  
  
  Por qué activar agentes de programación con IA mediante webhooks de GitHub en lugar de polling
&lt;/h2&gt;

&lt;p&gt;Un disparador por webhook es una llamada HTTP que GitHub realiza a tu servidor en cuanto ocurre algo en un repositorio: un comentario, una revisión o un flujo de trabajo que finaliza. Tu agente permanece inactivo hasta que llega una entrega, por lo que consume cero tokens y cero llamadas a la API mientras no pasa nada, y reacciona en cuestión de segundos en vez de esperar a la siguiente consulta.&lt;/p&gt;

&lt;p&gt;Hacer polling cada minuto agota los límites de peticiones (rate limits) con respuestas vacías y, aun así, genera retrasos de hasta un minuto. La explicación detallada se encuentra en &lt;a href="https://apidog.com/es/blog/webhooks-vs-polling?utm_source=dev.to&amp;amp;utm_medium=wanda&amp;amp;utm_content=n8n-post-automation"&gt;webhooks vs polling&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;El equipo de DeepSeek Harness planteó el mismo argumento en su artículo &lt;a href="https://x.com/DeepSeekHarness/status/2116857257245987236" rel="noopener noreferrer"&gt;«Exploring Super-agent Design»&lt;/a&gt;, publicado el 1 de noviembre de 2026. Ellos llaman a estas entradas «Triggers» (disparadores): el agente observa los eventos y permanece en reposo el resto del tiempo. El artículo describe una arquitectura y un plugin prototipo, no una funcionalidad final de DeepSeek. Analizamos el diseño completo en &lt;a href="https://apidog.com/es/blog/how-to-build-a-super-agent?utm_source=dev.to&amp;amp;utm_medium=wanda&amp;amp;utm_content=n8n-post-automation"&gt;cómo construir un superagente&lt;/a&gt;; en este post desarrollaremos únicamente la capa de activación, aplicable a cualquier agente de programación.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F1s59bdwimhmkpk54mpnk.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F1s59bdwimhmkpk54mpnk.png" alt="Flow of a GitHub webhook into an agent: a GitHub event reaches POST /triggers/github, which verifies X-Hub-Signature-256, dedupes X-GitHub-Delivery and replies 202 in under 10 seconds, then a queue and a thread router send it to an existing agent for that thread or a new coding agent"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Qué eventos de webhook de GitHub deberían activar un agente
&lt;/h2&gt;

&lt;p&gt;Suscríbete únicamente a los eventos en los que una persona esperaría que un compañero de equipo actúe. Cada evento adicional es una entrega que tendrás que verificar, almacenar y filtrar.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Evento&lt;/th&gt;
&lt;th&gt;Acción a monitorizar&lt;/th&gt;
&lt;th&gt;Qué hace el agente&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;issue_comment&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;created&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Responde a un comentario en una issue o en la conversación de un PR, por ejemplo «&lt;a class="mentioned-user" href="https://dev.to/bot"&gt;@bot&lt;/a&gt; arregla la prueba que falla»&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;pull_request_review_comment&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;created&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Responde a un comentario en una línea específica del diff&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;pull_request&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;opened&lt;/code&gt;, &lt;code&gt;synchronize&lt;/code&gt;
&lt;/td&gt;
&lt;td&gt;Revisa un nuevo PR o vuelve a revisarlo tras un push&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;workflow_run&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;completed&lt;/code&gt; con &lt;code&gt;conclusion: failure&lt;/code&gt;
&lt;/td&gt;
&lt;td&gt;Lee los logs del fallo y propone una solución&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;check_run&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;completed&lt;/code&gt; con una conclusión de fallo&lt;/td&gt;
&lt;td&gt;Igual que el anterior, para verificaciones reportadas por apps&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Dos detalles de la &lt;a href="https://docs.github.com/en/webhooks/webhook-events-and-payloads" rel="noopener noreferrer"&gt;referencia de eventos de webhook de GitHub&lt;/a&gt; te ahorrarán tiempo de depuración. En primer lugar, &lt;code&gt;issue_comment&lt;/code&gt; se dispara tanto para comentarios en issues como en pull requests; un comentario en un PR incluye un objeto &lt;code&gt;issue.pull_request&lt;/code&gt;, que es la forma de distinguirlos. En segundo lugar, &lt;code&gt;workflow_run&lt;/code&gt; con la acción &lt;code&gt;completed&lt;/code&gt; se dispara tanto si la ejecución concluyó con éxito como si falló, por lo que debes comprobar &lt;code&gt;workflow_run.conclusion&lt;/code&gt; tú mismo.&lt;/p&gt;

&lt;p&gt;Los payloads tienen un límite de 25 MB; GitHub nunca envía nada de mayor tamaño.&lt;/p&gt;

&lt;h2&gt;
  
  
  Verifica la firma X-Hub-Signature-256 en el cuerpo sin procesar (raw body)
&lt;/h2&gt;

&lt;p&gt;Cuando configuras un secreto en el webhook, GitHub firma cada entrega con HMAC SHA-256 del cuerpo sin procesar de la solicitud y envía el digest hexadecimal como &lt;code&gt;X-Hub-Signature-256: sha256=&amp;lt;digest&amp;gt;&lt;/code&gt;. Tu endpoint recalcula el digest y compara ambos valores en tiempo constante.&lt;/p&gt;

&lt;p&gt;Tres reglas de la guía de GitHub sobre &lt;a href="https://docs.github.com/en/webhooks/using-webhooks/validating-webhook-deliveries" rel="noopener noreferrer"&gt;validación de entregas de webhooks&lt;/a&gt;:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Aplica el hash sobre los bytes sin procesar, no sobre un objeto JSON reserializado. Parsear y volver a serializar modifica los espacios en blanco y anula la coincidencia.&lt;/li&gt;
&lt;li&gt;Compara con una función de tiempo constante como &lt;a href="https://nodejs.org/api/crypto.html#cryptotimingsafeequala-b" rel="noopener noreferrer"&gt;&lt;code&gt;crypto.timingSafeEqual&lt;/code&gt;&lt;/a&gt; de Node, nunca con &lt;code&gt;==&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Usa &lt;code&gt;X-Hub-Signature-256&lt;/code&gt;. El encabezado anterior &lt;code&gt;X-Hub-Signature&lt;/code&gt; utiliza SHA-1 y existe solo por retrocompatibilidad.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Aquí tienes el servicio de recepción en Node con Express:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;express&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;express&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;crypto&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;node:crypto&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;app&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;express&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;REDACTED&lt;/span&gt; &lt;span class="nx"&gt;CREDENTIAL&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;seen&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Set&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt; &lt;span class="c1"&gt;// use Redis or a DB table in production&lt;/span&gt;

&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;validSignature&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;raw&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;header&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nx"&gt;header&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;expected&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;sha256=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt;
    &lt;span class="nx"&gt;crypto&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;createHmac&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;sha256&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;SECRET&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;update&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;raw&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;digest&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;hex&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;a&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;Buffer&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="k"&gt;from&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;expected&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;b&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;Buffer&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="k"&gt;from&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;header&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;a&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;length&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="nx"&gt;b&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;length&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="nx"&gt;crypto&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;timingSafeEqual&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;a&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;b&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nx"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;post&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;/triggers/github&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;express&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;raw&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;application/json&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="p"&gt;}),&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;req&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nf"&gt;validSignature&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;req&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;body&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;req&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;X-Hub-Signature-256&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)))&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;status&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;401&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;json&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;error&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;bad signature&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="p"&gt;});&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;deliveryId&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;req&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;X-GitHub-Delivery&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;seen&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;has&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;deliveryId&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;status&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;200&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;json&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;duplicate&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;trigger_id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;deliveryId&lt;/span&gt; &lt;span class="p"&gt;});&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="nx"&gt;seen&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;add&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;deliveryId&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;event&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;req&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;X-GitHub-Event&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;payload&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;JSON&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;parse&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;req&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;body&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;prNumber&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;payload&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;pull_request&lt;/span&gt;&lt;span class="p"&gt;?.&lt;/span&gt;&lt;span class="nx"&gt;number&lt;/span&gt; &lt;span class="o"&gt;??&lt;/span&gt; &lt;span class="nx"&gt;payload&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;issue&lt;/span&gt;&lt;span class="p"&gt;?.&lt;/span&gt;&lt;span class="nx"&gt;number&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;threadId&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;payload&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;repository&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;full_name&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;#&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;prNumber&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

  &lt;span class="nx"&gt;queue&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;push&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;deliveryId&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;event&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;threadId&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;payload&lt;/span&gt; &lt;span class="p"&gt;});&lt;/span&gt; &lt;span class="c1"&gt;// your queue client&lt;/span&gt;
  &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;status&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;202&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;json&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;trigger_id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;deliveryId&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;thread_id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;threadId&lt;/span&gt; &lt;span class="p"&gt;});&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;

&lt;span class="nx"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;listen&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;3000&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;El manejador ejecuta cuatro tareas ligeras y nada que cause lentitud. Para conocer los esquemas de firma entre diferentes proveedores, consulta &lt;a href="https://apidog.com/es/blog/webhook-signature-verification?utm_source=dev.to&amp;amp;utm_medium=wanda&amp;amp;utm_content=n8n-post-automation"&gt;verificación de firmas de webhooks&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Responde con 2xx en menos de 10 segundos y encola el trabajo del agente
&lt;/h2&gt;

&lt;p&gt;Las &lt;a href="https://docs.github.com/en/webhooks/using-webhooks/best-practices-for-using-webhooks" rel="noopener noreferrer"&gt;buenas prácticas para webhooks&lt;/a&gt; de GitHub establecen que tu servidor debe responder con un código 2xx en un plazo de 10 segundos. Si tarda más, GitHub interrumpe la conexión y registra la entrega como fallida.&lt;/p&gt;

&lt;p&gt;La ejecución de un agente toma minutos, por lo que nunca puede ocurrir dentro de la propia solicitud. Envía el evento a una cola (Redis, SQS, una tabla de Postgres o cualquier sistema duradero) y responde con un 202 Accepted de inmediato. Un proceso worker independiente extraerá los eventos de la cola, aplicará los filtros e iniciará el agente.&lt;/p&gt;

&lt;p&gt;Los fallos no deben pasarse por alto: GitHub no reintenta automáticamente las entregas fallidas. Puedes &lt;a href="https://docs.github.com/en/webhooks/testing-and-troubleshooting-webhooks/redelivering-webhooks" rel="noopener noreferrer"&gt;reenviarlas&lt;/a&gt; de forma manual o a través de la API durante un máximo de 3 días; por tanto, un manejador lento perderá silenciosamente el disparador de ese comentario a menos que alguien lo detecte.&lt;/p&gt;

&lt;h2&gt;
  
  
  Filtra en dos etapas: ruta rápida en código y ruta lenta con el modelo
&lt;/h2&gt;

&lt;p&gt;La gran mayoría de las entregas nunca deberían alcanzar a un modelo. El artículo de DeepSeek divide el filtrado en una ruta rápida programada en código y una ruta lenta en la que un LLM aplica directivas redactadas como prompts. Esa separación mantiene los costes asociados al trabajo real y no al ruido del repositorio.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fcra7uvajuxul7c3afq7n.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fcra7uvajuxul7c3afq7n.png" alt="Two-stage filter funnel: all GitHub webhook deliveries pass a fast path of code rules (repo, sender, bot allowlist, @mention required), which drops most events with no model call; the rest pass a slow-path LLM policy check that drops non-actionable events before an agent run starts"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Ruta rápida (código, se ejecuta en microsegundos):&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Lista de repositorios permitidos (allowlist): solo los repositorios que hayas habilitado expresamente.&lt;/li&gt;
&lt;li&gt;Reglas de remitente: ignora la cuenta de bot del propio agente, o crearás un bucle infinito en el que se responderá a sí mismo.&lt;/li&gt;
&lt;li&gt;Modo de mención: inicia una ejecución únicamente cuando el comentario contenga &lt;code&gt;@your-bot&lt;/code&gt;. El artículo menciona tres modos que conviene adoptar: responder solo a solicitudes explícitas, tratarlo como candidato para la ruta lenta o ignorarlo.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Ruta lenta (LLM, evalúa lo que supera la ruta anterior):&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Proporciona al modelo el texto del comentario junto con un prompt breve de validación, por ejemplo: «¿Es esto una solicitud para modificar código en esta PR? Responde sí o no y aporta el motivo en una sola línea». Solo una respuesta afirmativa activa el agente. Esto permite descartar comentarios como «gracias &lt;a class="mentioned-user" href="https://dev.to/bot"&gt;@bot&lt;/a&gt;, se ve bien», que cumplen la regla de la mención pero no requieren ninguna acción.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;fastPath&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;event&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;payload&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;payload&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;sender&lt;/span&gt;&lt;span class="p"&gt;?.&lt;/span&gt;&lt;span class="nx"&gt;type&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Bot&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;ignore&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nx"&gt;ALLOWED_REPOS&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;has&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;payload&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;repository&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;full_name&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;ignore&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;event&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;workflow_run&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;payload&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;workflow_run&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;conclusion&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;failure&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;run&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;ignore&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;body&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;payload&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;comment&lt;/span&gt;&lt;span class="p"&gt;?.&lt;/span&gt;&lt;span class="nx"&gt;body&lt;/span&gt; &lt;span class="o"&gt;??&lt;/span&gt; &lt;span class="dl"&gt;""&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;body&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;includes&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;@your-bot&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;candidate&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;ignore&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Enruta el seguimiento por thread id para que responda el mismo agente
&lt;/h2&gt;

&lt;p&gt;Un hilo (thread) representa la secuencia de eventos consecutivos en una misma PR. Genera el &lt;code&gt;thread_id&lt;/code&gt; a partir del repositorio y el número de PR o issue, tal como hace el manejador anterior con &lt;code&gt;acme/api#42&lt;/code&gt;. En el diseño propuesto por el artículo, el worker creado para el primer evento se suscribe a su hilo, y los eventos de seguimiento van directos a él sin necesidad de otra operación de enrutamiento.&lt;/p&gt;

&lt;p&gt;En la práctica, esto equivale a una tabla de correspondencia entre &lt;code&gt;thread_id&lt;/code&gt; y el ID de sesión del agente. Cuando llega una entrega para un hilo con una sesión activa, añade el comentario a esa sesión. De este modo, el agente conserva su contexto: el diff que analizó y las pruebas que ejecutó. Sin esto, tres comentarios en una misma PR generarían tres agentes con respuestas contradictorias.&lt;/p&gt;

&lt;p&gt;El artículo incorpora otro detalle muy valioso: los disparadores que llegan mientras el enrutador procesa un turno se agrupan en lote para su siguiente llamada, por lo que una ráfaga de cinco comentarios requiere una sola decisión en lugar de cinco.&lt;/p&gt;

&lt;h2&gt;
  
  
  Desduplica mediante X-GitHub-Delivery
&lt;/h2&gt;

&lt;p&gt;Cada entrega incluye un GUID en &lt;code&gt;X-GitHub-Delivery&lt;/code&gt;. La documentación de GitHub indica que un reenvío reutiliza el mismo valor que el original, lo que lo convierte en la clave de idempotencia ideal. Almacena cada ID (un índice único en tu base de datos funciona a la perfección) y trata las repeticiones como operaciones nulas (no-op) que sigan devolviendo un código 2xx, evitando así que GitHub las clasifique como fallidas.&lt;/p&gt;

&lt;p&gt;Esto previene también los ataques de repetición (replay attacks): la firma de una entrega interceptada seguirá siendo válida, pero su ID ya estará registrado.&lt;/p&gt;

&lt;h2&gt;
  
  
  Deja que tu agente de programación pruebe el endpoint disparador con Apidog CLI
&lt;/h2&gt;

&lt;p&gt;No deberías comprobar manualmente los cálculos de las firmas. Deja que el agente de programación que desarrolló el servicio de recepción escriba también sus pruebas y las ejecute con &lt;a href="https://apidog.com/apidog-cli/?utm_source=dev.to&amp;amp;utm_medium=wanda&amp;amp;utm_content=n8n-post-automation"&gt;Apidog CLI&lt;/a&gt;. Configúralo una sola vez:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npm &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="nt"&gt;-g&lt;/span&gt; apidog-cli@latest
apidog auth login &lt;span class="nt"&gt;--with-token&lt;/span&gt; &amp;lt;YOUR_TOKEN&amp;gt;
npx &lt;span class="nt"&gt;-y&lt;/span&gt; skills add https://apidog.com   &lt;span class="c"&gt;# pick your agent when prompted&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Luego dale a Claude Code, Codex o Cursor un único [REDACTED PROMPT]&lt;br&gt;
In Apidog project , create the endpoint POST /triggers/github from the&lt;br&gt;
sample issue_comment payload in fixtures/issue_comment.json. Then create test cases&lt;br&gt;
against the staging environment:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;valid X-Hub-Signature-256 -&amp;gt; 202 with trigger_id and a thread_id of "#"&lt;/li&gt;
&lt;li&gt;a second comment on the same PR -&amp;gt; same thread_id&lt;/li&gt;
&lt;li&gt;bad signature -&amp;gt; 401&lt;/li&gt;
&lt;li&gt;same X-GitHub-Delivery sent twice -&amp;gt; second call returns duplicate: true, no new job
Sign the bodies with the staging webhook secret in a pre-request script.
Run them and summarize any failures.
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;
El agente lee cada esquema, valida su payload, crea los recursos y los ejecuta:

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;&lt;br&gt;
bash&lt;br&gt;
apidog cli-schema get endpoint-create&lt;br&gt;
apidog cli-schema validate endpoint-create --file endpoint.json&lt;br&gt;
apidog endpoint create --project  --file endpoint.json&lt;br&gt;
apidog cli-schema get test-case-create&lt;br&gt;
apidog cli-schema validate test-case-create --file case-valid-signature.json&lt;br&gt;
apidog test-case create --project  --file case-valid-signature.json&lt;br&gt;
apidog run --test-case  --project  -e  -r cli,json&lt;/p&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;


El reporter `cli` muestra si cada aserción pasó o falló, y el informe `json` se genera en `./apidog-reports`, permitiendo al agente ver con exactitud qué comprobación falló (un 200 donde esperabas 401 suele significar que falta el middleware para procesar el cuerpo sin procesar / raw body).

La misma instrucción de `apidog run` puede incorporarse en CI con `-r junit`; consulta [Apidog CLI en GitHub Actions](https://apidog.com/es/blog/apidog-cli-github-actions?utm_source=dev.to&amp;amp;utm_medium=wanda&amp;amp;utm_content=n8n-post-automation). Para más detalles sobre la configuración del agente, consulta [Apidog CLI en Claude Code](https://apidog.com/es/blog/apidog-cli-in-claude-code?utm_source=dev.to&amp;amp;utm_medium=wanda&amp;amp;utm_content=n8n-post-automation), y para una estrategia integral de pruebas de webhooks, consulta [cómo probar webhooks](https://apidog.com/es/blog/how-to-test-webhooks?utm_source=dev.to&amp;amp;utm_medium=wanda&amp;amp;utm_content=n8n-post-automation). El plan Free de Apidog incluye equipos de hasta 4 usuarios.

## Antes de activar el webhook

1. Secreto configurado: una firma ausente o errónea devuelve un 401.
2. Respuesta 202 holgadamente por debajo de los 10 segundos y tarea del agente encolada.
3. IDs de entrega almacenados con una restricción de unicidad (unique constraint).
4. Un job periódico que reintenta las entregas fallidas de los últimos 3 días.

Si prefieres recurrir a los runners propios de GitHub, [Claude Code GitHub Actions](https://apidog.com/es/blog/claude-code-github-actions?utm_source=dev.to&amp;amp;utm_medium=wanda&amp;amp;utm_content=n8n-post-automation) es la alternativa alojada; un endpoint de recepción por webhook añade las capas de filtrado y enrutamiento de hilos. Si necesitas gestionar reintentos por tu cuenta, consulta [cómo diseñar webhooks confiables](https://apidog.com/es/blog/how-to-design-reliable-webhooks?utm_source=dev.to&amp;amp;utm_medium=wanda&amp;amp;utm_content=n8n-post-automation).

## Preguntas frecuentes

**¿Debería usar un webhook de repositorio o una GitHub App?**
Un webhook a nivel de repositorio u organización resulta suficiente para un solo equipo. Una GitHub App proporciona al agente una identidad de bot propia, permisos más específicos e instalación en múltiples organizaciones.

**¿Qué sucede si mi endpoint no está disponible?**
GitHub registra la entrega como fallida y no la reintenta. Puedes reenviar las entregas de los últimos 3 días desde la configuración del webhook o mediante la API REST.

**¿Cómo evito que el agente se responda a sí mismo?**
Descarta en el filtro de la ruta rápida cualquier entrega cuyo `sender` sea la cuenta de tu bot, antes de ejecutar cualquier otro proceso.

**¿Por qué devolver 202 en lugar de 200?**
Ambos códigos se consideran respuestas exitosas para GitHub. Sin embargo, un 202 Accepted indica con claridad a cualquiera que revise los registros que el trabajo fue encolado y no finalizado.

**¿El diseño del superagente de DeepSeek es algo que pueda activar de inmediato?**
No. El artículo describe una arquitectura conceptual y su plugin prototipo no constituye un producto oficial de DeepSeek. La capa de disparadores debes construirla tú mismo, tal como se detalló anteriormente.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

</description>
      <category>ai</category>
      <category>automation</category>
      <category>github</category>
      <category>spanish</category>
    </item>
    <item>
      <title>La IA de OpenAI encontró 948 formas de obtener acceso root en Linux: ¿está parcheado tu servidor API?</title>
      <dc:creator>Roobia</dc:creator>
      <pubDate>Thu, 05 Nov 2026 03:12:02 +0000</pubDate>
      <link>https://dev.to/roobia/la-ia-de-openai-encontro-948-formas-de-obtener-acceso-root-en-linux-esta-parcheado-tu-servidor-36p8</link>
      <guid>https://dev.to/roobia/la-ia-de-openai-encontro-948-formas-de-obtener-acceso-root-en-linux-esta-parcheado-tu-servidor-36p8</guid>
      <description>&lt;h1&gt;
  
  
  La IA de OpenAI encontró 948 formas de obtener acceso root en Linux: ¿está parcheado tu servidor API?
&lt;/h1&gt;

&lt;p&gt;Los 948 exploits para obtener root en Linux descubiertos por OpenAI cambian una premisa fundamental para los equipos de API: un punto de apoyo con privilegios limitados en un servidor sin parchear podría no mantener esos privilegios bajos por mucho tiempo. Compruebe qué kernel está ejecutando, instale las actualizaciones de seguridad de su distribución, reinicie con el nuevo kernel y restrinja el alcance de cualquier proceso comprometido. Al tratarse de fallos locales, un atacante necesita primero un punto de apoyo; no son exploits remotos por sí mismos.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://apidog.com/?utm_source=dev.to&amp;amp;utm_medium=wanda&amp;amp;utm_content=n8n-post-automation" class="crayons-btn crayons-btn--primary"&gt;Prueba Apidog hoy&lt;/a&gt;
&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;uname&lt;/span&gt; &lt;span class="nt"&gt;-r&lt;/span&gt;              &lt;span class="c"&gt;# the kernel you're running now&lt;/span&gt;
&lt;span class="nb"&gt;cat&lt;/span&gt; /etc/os-release   &lt;span class="c"&gt;# your distro and version&lt;/span&gt;
&lt;span class="nb"&gt;uptime&lt;/span&gt;                &lt;span class="c"&gt;# how long since the last reboot&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  TL;DR
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;El pipeline de OpenAI generó 948 exploits únicos de escalada local de privilegios (LPE) en Linux a un coste de 1279 $ cada uno en créditos de API.&lt;/li&gt;
&lt;li&gt;OpenAI señala que una cuenta con bajos privilegios en un sistema operativo que no cuenta con los últimos parches «debería considerarse funcionalmente equivalente al acceso root para un actor de amenazas con recursos suficientes».&lt;/li&gt;
&lt;li&gt;Muchos de estos fallos aún se están notificando y corrigiendo. OpenAI no publica ninguna lista de versiones afectadas, por lo que ninguna versión del kernel puede considerarse segura.&lt;/li&gt;
&lt;li&gt;La publicación de OpenAI no informa de ningún ataque que haya utilizado estos 948 fallos.&lt;/li&gt;
&lt;li&gt;Su tarea para esta semana: parchear y reiniciar, aislar las cargas de trabajo de riesgo y reducir al mínimo lo que cada cuenta de servicio puede manipular.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Lo que descubrió OpenAI: las cifras
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://openai.com/index/a-thousand-fewer-paths-to-root/" rel="noopener noreferrer"&gt;El informe de OpenAI, «A thousand fewer paths to root»&lt;/a&gt;, publicado el 4 de noviembre de 2026, describe una ejecución realizada a mediados de octubre contra la última versión del kernel de Linux utilizando un próximo modelo de ciberseguridad. Los exploits se probaron en un sistema operativo de escritorio estándar de una distribución de uso común, con las protecciones habituales activadas (SMEP, SMAP, KASLR, HARDENED_USERCOPY), dentro de máquinas virtuales aisladas.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Métrica&lt;/th&gt;
&lt;th&gt;Resultado&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Objetivos de auditoría&lt;/td&gt;
&lt;td&gt;5034 (alrededor de 2,8M de líneas, aproximadamente el 7 % del kernel)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Hallazgos candidatos&lt;/td&gt;
&lt;td&gt;2308&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Reproducidos dinámicamente&lt;/td&gt;
&lt;td&gt;1724 (alrededor del 74,7 %)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Pruebas de concepto de filtración de información&lt;/td&gt;
&lt;td&gt;291&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Exploits de LPE funcionales&lt;/td&gt;
&lt;td&gt;1169&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;LPE únicos tras análisis de variantes&lt;/td&gt;
&lt;td&gt;948&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Coste total de API&lt;/td&gt;
&lt;td&gt;1 213 430 $ (1279 $ por exploit de LPE)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Ejecución de julio con GPT-5.6 Sol&lt;/td&gt;
&lt;td&gt;166 LPE únicos por 513 690 $&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Estado tras el análisis de 10 días&lt;/td&gt;
&lt;td&gt;61 LPE parcheados en upstream, 43 con parches en staging, 299 en debate público&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F63jbr71tbu1jcw15rw0p.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F63jbr71tbu1jcw15rw0p.png" width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;OpenAI califica sus costes como «más bien un límite superior», ya que no estaban optimizando el precio. La ejecución de octubre también detectó más de 5 veces más LPE nuevos que la de julio, a pesar de los tres meses de endurecimiento entre ambos análisis.&lt;/p&gt;

&lt;p&gt;OpenAI afirma haber enviado cientos de informes y parches para fallos críticos y está enviando el resto de forma gradual a través de los socios de Patch the Planet. Los detalles de los exploits se mantienen bajo reserva, incluidas al menos 10 técnicas novedosas. Por lo tanto, no existe una lista con la que contrastar su kernel, y que una corrección llegue a la rama principal (upstream) no significa que su distribución ya la haya publicado.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F08riiz74wlwpamlyj0hj.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F08riiz74wlwpamlyj0hj.png" width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Qué significa «local» para un servidor de API
&lt;/h2&gt;

&lt;p&gt;Una vulnerabilidad de escalada local de privilegios permite a un usuario que ya ejecuta código en una máquina convertirse en root. Nadie puede explotarla enviando únicamente una petición a su API. Un atacante necesita primero un punto de apoyo, como la ejecución de código dentro de su servicio o una shell obtenida mediante una credencial robada. El fallo del kernel es solo el segundo paso.&lt;/p&gt;

&lt;p&gt;Los servidores de API ofrecen multitud de primeros pasos:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Un fallo en su stack.&lt;/strong&gt; &lt;a href="https://apidog.com/es/blog/php2shell-php-vulnerability?utm_source=dev.to&amp;amp;utm_medium=wanda&amp;amp;utm_content=n8n-post-automation"&gt;PHP2Shell&lt;/a&gt;, &lt;a href="https://apidog.com/es/blog/fix-react2shell-exploit?utm_source=dev.to&amp;amp;utm_medium=wanda&amp;amp;utm_content=n8n-post-automation"&gt;React2Shell&lt;/a&gt; y el &lt;a href="https://apidog.com/es/blog/nodejs-brotli-rce-cve-2026-111497?utm_source=dev.to&amp;amp;utm_medium=wanda&amp;amp;utm_content=n8n-post-automation"&gt;RCE de Brotli en Node.js&lt;/a&gt; demuestran cómo la ejecución de código puede originarse en la capa de aplicación.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Un token robado.&lt;/strong&gt; Una clave SSH o un token de CI filtrados pueden entregarle una shell al atacante. El caso de las &lt;a href="https://apidog.com/es/blog/stolen-ai-api-keys-llmjacking?utm_source=dev.to&amp;amp;utm_medium=wanda&amp;amp;utm_content=n8n-post-automation"&gt;claves de API de IA robadas&lt;/a&gt; muestra la rapidez con la que se aprovechan las credenciales filtradas.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Una cuenta de servicio comprometida.&lt;/strong&gt; Un bot de despliegue o una cuenta compartida de worker suelen tener mucho más alcance del que nadie recuerda.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Es posible que hasta ahora considerara ese punto de apoyo como algo contenido porque el proceso se ejecuta como un usuario sin privilegios. La perspectiva de OpenAI desmantela esa tranquilidad para los sistemas sin parchear frente a un atacante con recursos suficientes. Planifique asumiendo que el primer fallo en su API puede permitir alcanzar privilegios de root en ese host.&lt;/p&gt;

&lt;p&gt;Tenga en cuenta las limitaciones. El entorno de prueba fue un sistema operativo de escritorio, y OpenAI no especifica cuántos de los 948 fallos afectan a una compilación concreta de servidor. Su nivel de exposición depende de su kernel, del estado de sus parches y de si alguien puede conseguir ese primer punto de apoyo.&lt;/p&gt;

&lt;h2&gt;
  
  
  Compruebe su kernel y el estado de sus parches en 2 minutos
&lt;/h2&gt;

&lt;p&gt;&lt;code&gt;uname -r&lt;/code&gt; le indica qué versión se está ejecutando, no cuál está instalada. Un servidor puede tener un nuevo kernel en disco y seguir ejecutando el antiguo hasta que se reinicie. Esa discrepancia es lo primero que debe comprobar.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Distribución&lt;/th&gt;
&lt;th&gt;Listar actualizaciones pendientes&lt;/th&gt;
&lt;th&gt;Aplicar actualizaciones&lt;/th&gt;
&lt;th&gt;¿Requiere reinicio?&lt;/th&gt;
&lt;th&gt;Live patches cargados&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Ubuntu&lt;/td&gt;
&lt;td&gt;&lt;code&gt;apt list --upgradeable&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;sudo apt update &amp;amp;&amp;amp; sudo apt upgrade&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;ls /var/run/reboot-required&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;canonical-livepatch status --verbose&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Debian&lt;/td&gt;
&lt;td&gt;&lt;code&gt;apt list --upgradeable&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;sudo apt update &amp;amp;&amp;amp; sudo apt upgrade&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;sudo needrestart -k&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;No cubierto aquí&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;RHEL 9&lt;/td&gt;
&lt;td&gt;&lt;code&gt;dnf updateinfo list updates security&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;sudo dnf upgrade --security&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;dnf needs-restarting -r&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;sudo kpatch list&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Amazon Linux 2023&lt;/td&gt;
&lt;td&gt;&lt;code&gt;sudo dnf updateinfo list&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;sudo dnf upgrade --security&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Comparar &lt;code&gt;uname -r&lt;/code&gt; con &lt;code&gt;sudo dnf list kernel&lt;/code&gt;
&lt;/td&gt;
&lt;td&gt;&lt;code&gt;sudo kpatch list&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;En RHEL, &lt;a href="https://dnf-plugins-core.readthedocs.io/en/latest/needs_restarting.html" rel="noopener noreferrer"&gt;&lt;code&gt;needs-restarting -r&lt;/code&gt;&lt;/a&gt; finaliza con código 1 cuando es necesario reiniciar y con 0 cuando no, lo que facilita automatizarlo en toda una flota. En Debian, &lt;a href="https://manpages.debian.org/trixie/needrestart/needrestart.1.en.html" rel="noopener noreferrer"&gt;&lt;code&gt;needrestart -k&lt;/code&gt;&lt;/a&gt; comprueba si el kernel en ejecución ha quedado obsoleto.&lt;/p&gt;

&lt;p&gt;El live patching ayuda, pero con limitaciones:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;No lo cubre todo.&lt;/strong&gt; &lt;a href="https://docs.aws.amazon.com/linux/al2023/ug/live-patching.html" rel="noopener noreferrer"&gt;AWS ofrece live patching según su mejor criterio (best-effort)&lt;/a&gt; y advierte de que algunas correcciones solo se distribuyen en el paquete completo del kernel.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;uname -r&lt;/code&gt; no cambiará.&lt;/strong&gt; La versión solo se actualiza tras reiniciar, así que verifique directamente el estado del live patch.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;El indicador de reinicio de Ubuntu puede desaparecer.&lt;/strong&gt; &lt;a href="https://ubuntu.com/security/livepatch/docs/client/explanation/architecture/reboot-marker-suppression/" rel="noopener noreferrer"&gt;Livepatch puede suprimir el aviso de reinicio&lt;/a&gt; si cubre los CVE corregidos por el kernel del próximo arranque. &lt;a href="https://ubuntu.com/security/livepatch/docs/client/how-to-guides/operations/check-client-status/" rel="noopener noreferrer"&gt;&lt;code&gt;canonical-livepatch status --verbose&lt;/code&gt;&lt;/a&gt; muestra los CVE aplicados.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Considere los parches en vivo como un puente hasta el próximo reinicio y acorte sus ciclos de reinicio.&lt;/p&gt;

&lt;h2&gt;
  
  
  Los contenedores comparten el kernel del host
&lt;/h2&gt;

&lt;p&gt;Un contenedor no dispone de un kernel independiente. Si ejecuta &lt;code&gt;uname -r&lt;/code&gt; dentro del contenedor de su API, verá la versión del host. Actualizar la imagen base no modifica esto, por lo que una vulnerabilidad del kernel accesible desde el interior del contenedor representa una vía directa hacia el host.&lt;/p&gt;

&lt;p&gt;En un clúster de Kubernetes, un solo comando muestra el kernel de cada nodo en la columna KERNEL-VERSION:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;kubectl get nodes &lt;span class="nt"&gt;-o&lt;/span&gt; wide
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Este vector ya se ha explotado con anterioridad. En un incidente independiente, &lt;a href="https://www.securityweek.com/openai-agents-exploited-linux-kernel-flaw-on-companys-own-systems/" rel="noopener noreferrer"&gt;SecurityWeek informó&lt;/a&gt; de que agentes de OpenAI explotaron un fallo conocido del kernel, CVE-2026-53362, y consiguieron privilegios de root en un nodo worker subyacente desde dentro de un contenedor, en el propio entorno de OpenAI. Ese fallo no forma parte de los 948.&lt;/p&gt;

&lt;p&gt;OpenAI destaca dos opciones de aislamiento para limitar el radio de impacto:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Opción&lt;/th&gt;
&lt;th&gt;Cómo aísla&lt;/th&gt;
&lt;th&gt;Casos de uso adecuados&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;a href="https://gvisor.dev/docs/" rel="noopener noreferrer"&gt;gVisor&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;Un kernel de aplicación en espacio de usuario gestiona las llamadas al sistema del contenedor en lugar de transferirlas al kernel del host&lt;/td&gt;
&lt;td&gt;Contenedores que ejecutan código no confiable o procesan entradas de riesgo&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;a href="https://github.com/firecracker-microvm/firecracker" rel="noopener noreferrer"&gt;Firecracker&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;Ejecuta cargas de trabajo en microVM ligeras sobre KVM, con aislamiento a nivel de hardware&lt;/td&gt;
&lt;td&gt;Servicios multi-tenant y cargas de trabajo dedicadas por cliente&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;En Kubernetes, puede seleccionar un entorno de ejecución aislado por pod mediante &lt;a href="https://kubernetes.io/docs/concepts/containers/runtime-class/" rel="noopener noreferrer"&gt;RuntimeClass&lt;/a&gt;. Configure &lt;code&gt;runtimeClassName&lt;/code&gt; primero en sus cargas de trabajo más expuestas, como cualquier componente que ejecute código de clientes.&lt;/p&gt;

&lt;p&gt;Parchee también estas capas. OpenAI indica que las pruebas en su propia infraestructura la llevaron a divulgar y parchear vulnerabilidades en Kata, Moby/Docker, gVisor y otros proyectos. Un sandbox limita el impacto, pero sigue siendo software.&lt;/p&gt;

&lt;h2&gt;
  
  
  Reduzca el alcance de un punto de apoyo comprometido
&lt;/h2&gt;

&lt;p&gt;Asuma que obtener privilegios de root en un host es posible. A partir de ahí, determine a qué puede acceder el usuario root en ese host.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fcbwo3h9umy43pssahgkp.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fcbwo3h9umy43pssahgkp.png" alt="Attack chain from a stolen token or dependency RCE to a low-privileged shell in an API container, then root on the host, then every container, secret and token on the node, with a patched kernel and sandbox blocking the second step and least privilege blocking the last" width="800" height="267"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Divida las cuentas de servicio compartidas.&lt;/strong&gt; Otorgue a cada servicio su propia identidad, de modo que una credencial comprometida no dé acceso a todos los sistemas. Nuestra guía sobre &lt;a href="https://apidog.com/es/blog/ai-agent-api-key-least-privilege?utm_source=dev.to&amp;amp;utm_medium=wanda&amp;amp;utm_content=n8n-post-automation"&gt;claves de API con privilegios mínimos para agentes&lt;/a&gt; también se aplica a los servicios.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Elimine los tokens que una carga de trabajo no necesite.&lt;/strong&gt; En Kubernetes, configure &lt;a href="https://kubernetes.io/docs/tasks/configure-pod-container/configure-service-account/" rel="noopener noreferrer"&gt;&lt;code&gt;automountServiceAccountToken: false&lt;/code&gt;&lt;/a&gt; en los pods que nunca realizan llamadas a la API de Kubernetes.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Mantenga los secretos de larga duración fuera del nodo.&lt;/strong&gt; El usuario root puede leer variables de entorno y archivos montados, por lo que conviene priorizar credenciales de corta duración.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Rote las credenciales tras cualquier brecha.&lt;/strong&gt; Si detecta ejecución de código en un host, considere expuesto cualquier secreto alojado en esa máquina. Que una cuenta parezca limpia no garantiza que el sistema no haya sido comprometido a nivel de root.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Posteriormente, audite el resto con una &lt;a href="https://apidog.com/es/blog/api-security-testing-checklist?utm_source=dev.to&amp;amp;utm_medium=wanda&amp;amp;utm_content=n8n-post-automation"&gt;lista de comprobación de pruebas de seguridad para API&lt;/a&gt;, ya que cada fallo que cierre allí representa un punto de apoyo menos para un atacante.&lt;/p&gt;

&lt;h2&gt;
  
  
  Deje que su agente de programación verifique la API tras aplicar los parches
&lt;/h2&gt;

&lt;p&gt;El verdadero obstáculo para realizar actualizaciones frecuentes del kernel es el miedo al reinicio. Ejecutar pruebas de regresión antes y después elimina esa incertidumbre. Indique a su agente de programación que ejecute la misma suite de pruebas con la &lt;a href="https://apidog.com/apidog-cli/?utm_source=dev.to&amp;amp;utm_medium=wanda&amp;amp;utm_content=n8n-post-automation"&gt;CLI de Apidog&lt;/a&gt; antes y después de la actualización, y luego compare los resultados.&lt;/p&gt;

&lt;p&gt;Configúrelo una sola vez:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npm &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="nt"&gt;-g&lt;/span&gt; apidog-cli@latest
apidog login &lt;span class="nt"&gt;--with-token&lt;/span&gt; &amp;lt;YOUR_TOKEN&amp;gt;
npx &lt;span class="nt"&gt;-y&lt;/span&gt; skills add https://apidog.com   &lt;span class="c"&gt;# pick your agent when prompted&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Luego proporcione una sola instrucción a su agente:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Find my API regression suite in Apidog project &amp;lt;id&amp;gt; and run it against the
staging environment. Save the reports to reports/before. Stop and wait while
I update the kernel and reboot. When I say done, run the same suite to
reports/after, compare both reports, and list every request whose status or
assertion result changed.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;El agente ejecuta estos comandos:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;apidog test-suite list &lt;span class="nt"&gt;--project&lt;/span&gt; &amp;lt;&lt;span class="nb"&gt;id&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
apidog run &lt;span class="nt"&gt;--test-suite&lt;/span&gt; &amp;lt;&lt;span class="nb"&gt;id&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="nt"&gt;--project&lt;/span&gt; &amp;lt;&lt;span class="nb"&gt;id&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="nt"&gt;-e&lt;/span&gt; &amp;lt;envId&amp;gt; &lt;span class="nt"&gt;-r&lt;/span&gt; cli,junit &lt;span class="nt"&gt;--out-dir&lt;/span&gt; reports/before
&lt;span class="c"&gt;# you update the kernel and reboot&lt;/span&gt;
apidog run &lt;span class="nt"&gt;--test-suite&lt;/span&gt; &amp;lt;&lt;span class="nb"&gt;id&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="nt"&gt;--project&lt;/span&gt; &amp;lt;&lt;span class="nb"&gt;id&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="nt"&gt;-e&lt;/span&gt; &amp;lt;envId&amp;gt; &lt;span class="nt"&gt;-r&lt;/span&gt; cli,junit &lt;span class="nt"&gt;--out-dir&lt;/span&gt; reports/after
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Comience en staging y repítalo en un nodo de producción antes de desplegarlo en toda la flota. Una petición con cambios le indicará dónde investigar antes de que fallen más nodos.&lt;/p&gt;

&lt;p&gt;El informe del agente requiere la misma cautela que el pipeline de OpenAI. En una ejecución inicial, 20 de los 200 exploits reportados obtuvieron acceso root a través de un 0-day distinto al asignado, por lo que OpenAI implementó una verificación independiente. Compruebe el proceso que conduce al resultado, no solo el resultado final: confirme mediante &lt;code&gt;uname -r&lt;/code&gt; o su herramienta de live patching que la actualización se aplicó antes de dar por válido el informe posterior («after»).&lt;/p&gt;

&lt;p&gt;La misma ejecución con &lt;code&gt;-r junit&lt;/code&gt; se integra sin problemas en CI. Consulte &lt;a href="https://apidog.com/es/blog/apidog-cli-ci-cd-pipeline?utm_source=dev.to&amp;amp;utm_medium=wanda&amp;amp;utm_content=n8n-post-automation"&gt;la guía de CI/CD para la CLI de Apidog&lt;/a&gt;, la &lt;a href="https://apidog.com/es/blog/apidog-run-command-reference?utm_source=dev.to&amp;amp;utm_medium=wanda&amp;amp;utm_content=n8n-post-automation"&gt;referencia del comando &lt;code&gt;apidog run&lt;/code&gt;&lt;/a&gt; y nuestra introducción a las &lt;a href="https://apidog.com/es/blog/api-regression-testing?utm_source=dev.to&amp;amp;utm_medium=wanda&amp;amp;utm_content=n8n-post-automation"&gt;pruebas de regresión de API&lt;/a&gt;. El plan gratuito de Apidog admite hasta 4 usuarios.&lt;/p&gt;

&lt;p&gt;  &lt;iframe src="https://www.youtube.com/embed/UMl4Vo_RwkU" width="710" height="399"&gt;
  &lt;/iframe&gt;
&lt;/p&gt;

&lt;h2&gt;
  
  
  A qué prestar atención a partir de ahora
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Los avisos de seguridad de su distribución.&lt;/strong&gt; Llegarán más correcciones a medida que OpenAI y sus socios envíen informes, por lo que cabe esperar un goteo constante en lugar de una única actualización masiva.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Un desarrollo de exploits cada vez más rápido.&lt;/strong&gt; OpenAI anticipa que, en cuestión de pocos años, incluso modelos con menores capacidades podrán desarrollar exploits una vez que las vulnerabilidades se hagan públicas.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Preguntas frecuentes
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;¿Son remotos los 948 exploits de Linux?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;No. Son exploits de escalada local de privilegios, por lo que un atacante ya debe contar con la capacidad de ejecutar código como usuario con bajos privilegios. Un fallo remoto en su aplicación puede proporcionar ese punto de apoyo inicial, razón por la cual los equipos de API deben prestar atención.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;¿Está afectada mi versión del kernel?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;OpenAI no publica ninguna lista de versiones afectadas, por lo que nadie puede asegurarle un número de versión libre de vulnerabilidades. Instale las actualizaciones de seguridad más recientes de su distribución y reinicie el sistema con ese nuevo kernel.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;¿Se están explotando estos fallos en entornos reales?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;La publicación de OpenAI no reporta ataques activos que utilicen estos 948 fallos. Muchos de ellos aún se encuentran en proceso de notificación y parcheo. En cualquier caso, parchie cuanto antes: las correcciones públicas pueden indicar a los atacantes dónde buscar vulnerabilidades.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;¿Sustituye el live patching al reinicio?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;No. Los parches en vivo cubren exclusivamente correcciones seleccionadas, y los proveedores advierten de que ciertas soluciones solo se distribuyen en el paquete completo del kernel. Utilícelos para ganar margen de tiempo hasta su próximo reinicio.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;¿Se soluciona una vulnerabilidad del kernel actualizando la imagen del contenedor?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;No. Los contenedores comparten el kernel del host, por lo que es necesario actualizar y reiniciar el host o nodo. Actualice también sus imágenes, ya que en ellas residen las dependencias de su aplicación.&lt;/p&gt;

</description>
    </item>
    <item>
      <title>¿Tu versión de Node.js es vulnerable al RCE de Brotli? Compruébalo en 2 minutos</title>
      <dc:creator>Roobia</dc:creator>
      <pubDate>Thu, 05 Nov 2026 02:24:39 +0000</pubDate>
      <link>https://dev.to/roobia/tu-version-de-nodejs-es-vulnerable-al-rce-de-brotli-compruebalo-en-2-minutos-50b0</link>
      <guid>https://dev.to/roobia/tu-version-de-nodejs-es-vulnerable-al-rce-de-brotli-compruebalo-en-2-minutos-50b0</guid>
      <description>&lt;p&gt;Ejecuta esto ahora mismo. Si tu versión está por debajo del umbral mínimo de la tabla, la vulnerabilidad de RCE en Brotli de Node.js (CVE-2026-111497) te afecta, y los atacantes ya la están explotando activamente.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://apidog.com/?utm_source=dev.to&amp;amp;utm_medium=wanda&amp;amp;utm_content=n8n-post-automation" class="crayons-btn crayons-btn--primary"&gt;Prueba Apidog hoy&lt;/a&gt;
&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;node &lt;span class="nt"&gt;-v&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Línea de versión&lt;/th&gt;
&lt;th&gt;Vulnerable&lt;/th&gt;
&lt;th&gt;Corregida a partir de&lt;/th&gt;
&lt;th&gt;Última versión (5 nov. 2026)&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;26.x&lt;/td&gt;
&lt;td&gt;Anterior a 26.12.1&lt;/td&gt;
&lt;td&gt;26.12.1&lt;/td&gt;
&lt;td&gt;26.13.0&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;24.x&lt;/td&gt;
&lt;td&gt;Anterior a 24.22.1&lt;/td&gt;
&lt;td&gt;24.22.1&lt;/td&gt;
&lt;td&gt;24.22.2&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;22.x&lt;/td&gt;
&lt;td&gt;Anterior a 22.23.4&lt;/td&gt;
&lt;td&gt;22.23.4&lt;/td&gt;
&lt;td&gt;22.23.4&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;25.x, 20.x y anteriores&lt;/td&gt;
&lt;td&gt;Fin de ciclo de vida (EOL): sin parchear y sin evaluar&lt;/td&gt;
&lt;td&gt;No existe parche&lt;/td&gt;
&lt;td&gt;Migrar a 24 o 26&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Para obtener una segunda comprobación, consúltale directamente al binario:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;node &lt;span class="nt"&gt;-p&lt;/span&gt; &lt;span class="s2"&gt;"require('node:zlib').constants.BROTLI_DECODER_ERROR_FORMAT_BLOCK_SWITCH"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;El parche introdujo esta constante. Lo probamos en nueve compilaciones oficiales de macOS de las tres líneas con soporte: cada versión corregida devolvió &lt;code&gt;-17&lt;/code&gt;, mientras que las versiones anteriores mostraron &lt;code&gt;undefined&lt;/code&gt;. Aun así, dale prioridad a &lt;code&gt;node -v&lt;/code&gt;, ya que una distribución de Linux que incorpore el parche como backport podría no incluir esta constante.&lt;/p&gt;

&lt;p&gt;No te fíes de &lt;code&gt;process.versions.brotli&lt;/code&gt;. Mostró &lt;code&gt;1.2.0&lt;/code&gt; tanto en 24.21.0 como en 24.22.1, y &lt;code&gt;1.1.0&lt;/code&gt; tanto en 22.23.3 como en 22.23.4. Node.js aplicó el parche mediante un cherry-pick sin modificar la versión reportada, por lo que este campo no sirve para saber si tu sistema está protegido.&lt;/p&gt;

&lt;h2&gt;
  
  
  En resumen (TL;DR)
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Pregunta&lt;/th&gt;
&lt;th&gt;Respuesta&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;¿Qué es?&lt;/td&gt;
&lt;td&gt;Escritura fuera de límites (out-of-bounds write) en el decodificador de Brotli integrado en Node.js, también conocida como Node2Shell o HTTP2Shell&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Impacto&lt;/td&gt;
&lt;td&gt;Caída del proceso (crash), filtración de memoria o ejecución remota de código (RCE)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Severidad&lt;/td&gt;
&lt;td&gt;ALTA según &lt;a href="https://nodejs.org/en/blog/vulnerability/october-2026-security-releases" rel="noopener noreferrer"&gt;Node.js&lt;/a&gt;; 9.8 CRÍTICA (CVSS 3.1) según la &lt;a href="https://nvd.nist.gov/vuln/detail/CVE-2026-111497" rel="noopener noreferrer"&gt;NVD&lt;/a&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;¿Se está explotando activamente?&lt;/td&gt;
&lt;td&gt;Sí. El catálogo &lt;a href="https://www.cisa.gov/known-exploited-vulnerabilities-catalog?field_cve=CVE-2026-111497" rel="noopener noreferrer"&gt;KEV de CISA&lt;/a&gt; la incorporó el 27 de octubre de 2026&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;¿Requiere autenticación?&lt;/td&gt;
&lt;td&gt;No, según el vector del NVD y el &lt;a href="https://www.akamai.com/blog/security-research/inside-node2shell-closer-look-cve-2026-111497" rel="noopener noreferrer"&gt;análisis de Akamai&lt;/a&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;¿Quiénes están expuestos?&lt;/td&gt;
&lt;td&gt;Aplicaciones que decodifican datos Brotli que no controlan: cuerpos de petición en Express 5, respuestas de &lt;code&gt;fetch()&lt;/code&gt; o llamadas directas a &lt;code&gt;node:zlib&lt;/code&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Solución&lt;/td&gt;
&lt;td&gt;Actualizar el runtime, recompilar imágenes de contenedor y reiniciar los procesos&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;¿Existe alguna mitigación temporal?&lt;/td&gt;
&lt;td&gt;El aviso oficial de seguridad no incluye ninguna. Las medidas provisionales que detallamos abajo reducen la exposición, pero no cubren todos los escenarios&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fy6axnc6hsxnp3ek6jf4n.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fy6axnc6hsxnp3ek6jf4n.png" alt="Cronología de CVE-2026-111497: parches de Node.js el 21 de octubre, CVE publicado el 22 de octubre, tráfico de exploits detectado el 26 de octubre, inclusión en el catálogo KEV de CISA el 27 de octubre, fecha límite de KEV el 10 de noviembre, próximo lanzamiento de seguridad de Node.js el 11 de noviembre" width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://ellio.tech/en/blog/node2shell-cve-2026-111497-rce-on-stock-nodejs-builds/" rel="noopener noreferrer"&gt;ELLIO reportó tráfico de exploits&lt;/a&gt; en sus sensores el 26 de octubre, apenas cinco días después del lanzamiento del parche. La carga útil (payload) interceptada apuntaba a Node.js 24.22.0 en arquitectura x86-64. Aunque la fase final de dicho payload falló en las pruebas de ELLIO, la propia firma confirmó la ejecución de código en compilaciones estándar de la versión 24.22.0. CISA fijó el 10 de noviembre como plazo límite para que las agencias federales de EE. UU. tomen medidas, marcando su uso en ransomware como «Desconocido». Además, la telemetría de Akamai reveló que el 61 % de las redes monitoreadas aún ejecutaban versiones vulnerables el 26 de octubre.&lt;/p&gt;

&lt;h2&gt;
  
  
  Cómo funciona Node2Shell: el impacto del fallo en Brotli
&lt;/h2&gt;

&lt;p&gt;Node2Shell es una vulnerabilidad de escritura fuera de límites en el decodificador de Brotli integrado directamente en el runtime de Node.js. Al procesar un flujo comprimido con formato incorrecto, el decodificador escribe más allá de un búfer interno de ocho bytes, corrompiendo la memoria del proceso. Como consecuencia, puede provocar la caída del servidor, filtración de memoria o la ejecución remota de código bajo el control del atacante.&lt;/p&gt;

&lt;p&gt;La causa raíz radica en una clasificación incorrecta del error: ante un cambio de bloque no válido, el decodificador interpretaba «necesito más datos de entrada» en lugar de «estos datos están corruptos», por lo que seguía añadiendo bytes al pequeño búfer interno.&lt;/p&gt;

&lt;p&gt;El error reside en la biblioteca Brotli de Google, desde la versión 1.0.3 hasta la 1.2.0, por lo que no se limita exclusivamente a Node.js. El equipo de Node.js solucionó su implementación aplicando un cherry-pick del commit upstream &lt;code&gt;0ed4268a&lt;/code&gt; en la &lt;a href="https://nodejs.org/en/blog/release/v24.22.1" rel="noopener noreferrer"&gt;versión 24.22.1&lt;/a&gt; y en sus versiones equivalentes. La vulnerabilidad fue descubierta y reportada por los investigadores Khai Tran y Sylvie Mayer, de OpenAI Codex Security.&lt;/p&gt;

&lt;p&gt;Tus herramientas de análisis de dependencias no detectarán este fallo, ya que el decodificador forma parte del runtime y no de un paquete npm. De hecho, &lt;code&gt;npm install&lt;/code&gt; indicó 0 vulnerabilidades en nuestro proyecto de prueba con Express 5 ejecutándose sobre una versión vulnerable de Node.js 24.15.0.&lt;/p&gt;

&lt;h2&gt;
  
  
  Quiénes están expuestos
&lt;/h2&gt;

&lt;p&gt;Contar con un runtime vulnerable es solo una parte de la ecuación; la otra es contar con una vía que suministre datos Brotli no confiables al decodificador. En nuestro laboratorio probamos cada escenario sobre Node.js 24.22.1 enviando un cuerpo no válido e inofensivo (el texto &lt;code&gt;not-valid-brotli&lt;/code&gt;) con la cabecera &lt;code&gt;Content-Encoding: br&lt;/code&gt;, además de servir contenido Brotli válido a cada cliente.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Vía de acceso&lt;/th&gt;
&lt;th&gt;Versión probada&lt;/th&gt;
&lt;th&gt;¿Ejecuta el decodificador?&lt;/th&gt;
&lt;th&gt;Resultado observado&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Express 5 &lt;code&gt;express.json()&lt;/code&gt;
&lt;/td&gt;
&lt;td&gt;5.3.0 (body-parser 2.4.0)&lt;/td&gt;
&lt;td&gt;Sí, por defecto&lt;/td&gt;
&lt;td&gt;400, “Decompression failed”&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Express 4 &lt;code&gt;express.json()&lt;/code&gt;
&lt;/td&gt;
&lt;td&gt;4.22.3 (body-parser 1.20.9)&lt;/td&gt;
&lt;td&gt;No&lt;/td&gt;
&lt;td&gt;415, codificación no admitida&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Koa &lt;code&gt;@koa/bodyparser&lt;/code&gt;
&lt;/td&gt;
&lt;td&gt;6.1.0&lt;/td&gt;
&lt;td&gt;Sí, por defecto&lt;/td&gt;
&lt;td&gt;500, error de &lt;code&gt;BrotliDecoder&lt;/code&gt; en el registro&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Fastify con &lt;code&gt;@fastify/compress&lt;/code&gt;
&lt;/td&gt;
&lt;td&gt;9.3.0&lt;/td&gt;
&lt;td&gt;Sí, tras registrar el plugin&lt;/td&gt;
&lt;td&gt;400, &lt;code&gt;FST_CP_ERR_INVALID_CONTENT&lt;/code&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Fastify básico (sin plugins)&lt;/td&gt;
&lt;td&gt;5.12.8&lt;/td&gt;
&lt;td&gt;No&lt;/td&gt;
&lt;td&gt;400, JSON no válido&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Servidor nativo &lt;code&gt;node:http&lt;/code&gt; o llamadas con &lt;code&gt;http.get&lt;/code&gt;
&lt;/td&gt;
&lt;td&gt;24.22.1&lt;/td&gt;
&lt;td&gt;No&lt;/td&gt;
&lt;td&gt;Los bytes en bruto pasan sin procesarse&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;code&gt;fetch()&lt;/code&gt; integrado&lt;/td&gt;
&lt;td&gt;24.22.1&lt;/td&gt;
&lt;td&gt;Sí, siempre&lt;/td&gt;
&lt;td&gt;Decodificó la respuesta&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;axios, got, node-fetch&lt;/td&gt;
&lt;td&gt;1.21.0, 16.2.0, 3.3.2&lt;/td&gt;
&lt;td&gt;Sí, por defecto&lt;/td&gt;
&lt;td&gt;Decodificó la respuesta&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;code&gt;zlib.brotliDecompress*&lt;/code&gt;, &lt;code&gt;createBrotliDecompress&lt;/code&gt;
&lt;/td&gt;
&lt;td&gt;Cualquiera&lt;/td&gt;
&lt;td&gt;Sí&lt;/td&gt;
&lt;td&gt;Es la propia &lt;a href="https://nodejs.org/api/zlib.html" rel="noopener noreferrer"&gt;API del decodificador&lt;/a&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fo8h173j748hh2ncled1m.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fo8h173j748hh2ncled1m.png" alt="Diagrama de vías de acceso al decodificador Brotli en node:zlib: parsers de Express 5, parsers del body de Koa y Fastify con @fastify/compress en las peticiones entrantes; fetch, axios y got en las salientes; mientras que Express 4, Fastify estándar y node:http básico no acceden a él" width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Dos de los resultados merecen una atención especial. &lt;code&gt;fetch()&lt;/code&gt; decodificó Brotli incluso cuando la solicitud enviaba &lt;code&gt;Accept-Encoding: identity&lt;/code&gt;, dado que se guía por la cabecera de la respuesta y no por lo solicitado. Cualquier servidor externo al que llame tu aplicación puede alcanzar el decodificador, lo que deja expuestos servicios de prueba de webhooks, generadores de vistas previas de enlaces o importadores de URL. Además, una respuesta 400 por sí sola no garantiza nada: tanto Express 5 como Fastify sin plugins devuelven este código, pero solo Express 5 llegó a ejecutar el decodificador. Revisa siempre el mensaje de error.&lt;/p&gt;

&lt;p&gt;Localiza tus puntos de exposición con estos tres comandos:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Direct decoder use&lt;/span&gt;
&lt;span class="nb"&gt;grep&lt;/span&gt; &lt;span class="nt"&gt;-rnE&lt;/span&gt; &lt;span class="s2"&gt;"brotliDecompress|createBrotliDecompress"&lt;/span&gt; src/

&lt;span class="c"&gt;# Parsers that decode request bodies&lt;/span&gt;
npm &lt;span class="nb"&gt;ls &lt;/span&gt;express body-parser @koa/bodyparser @fastify/compress

&lt;span class="c"&gt;# Base images and pinned versions&lt;/span&gt;
&lt;span class="nb"&gt;grep&lt;/span&gt; &lt;span class="nt"&gt;-rnE&lt;/span&gt; &lt;span class="s2"&gt;"^FROM .*node"&lt;/span&gt; &lt;span class="nt"&gt;--include&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;'Dockerfile*'&lt;/span&gt; &lt;span class="nb"&gt;.&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Una sola llamada adicional a &lt;code&gt;fetch()&lt;/code&gt; puede cambiar por completo este escenario, por lo que estar «fuera de alcance» sigue exigiendo aplicar el parche.&lt;/p&gt;

&lt;h2&gt;
  
  
  Cómo solucionar CVE-2026-111497
&lt;/h2&gt;

&lt;p&gt;Actualiza a la versión más reciente dentro de tu línea de lanzamiento, no te quedes en el umbral mínimo. Todas estas fuentes ya contaban con versiones corregidas el 5 de noviembre:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Método de instalación&lt;/th&gt;
&lt;th&gt;Acción recomendada&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;nvm&lt;/td&gt;
&lt;td&gt;&lt;code&gt;nvm install 24 &amp;amp;&amp;amp; nvm alias default 24&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Homebrew&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;brew upgrade node&lt;/code&gt; (o &lt;code&gt;node@24&lt;/code&gt;, &lt;code&gt;node@22&lt;/code&gt;)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Docker&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;FROM node:24.22.2-slim&lt;/code&gt; y después &lt;code&gt;docker build --pull&lt;/code&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Paquetes de distribución Linux&lt;/td&gt;
&lt;td&gt;Consulta los avisos de seguridad de tu distribución, ya que podría incorporar el parche manteniendo una numeración de versión anterior&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;CI&lt;/td&gt;
&lt;td&gt;Actualiza &lt;code&gt;.nvmrc&lt;/code&gt;, &lt;code&gt;engines&lt;/code&gt; y &lt;code&gt;node-version&lt;/code&gt;, y vuelve a compilar&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Serverless&lt;/td&gt;
&lt;td&gt;Registra &lt;code&gt;process.version&lt;/code&gt; en los logs desde una función desplegada; no des por sentado que la plataforma lo haya actualizado&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Luego, asegúrate de resolver los dos descuidos más habituales:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Reinicia todos los servicios.&lt;/strong&gt; Un proceso en ejecución conserva el binario antiguo en memoria; por tanto, actualizarlo en disco no surte efecto hasta que pm2, systemd o tu orquestador lo reinicie.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Reconstruye todo lo desplegado.&lt;/strong&gt; Las imágenes antiguas mantienen el runtime vulnerable, y aquellas fijadas por digest &lt;a href="https://cycode.com/blog/node2shell-cve-2026-111497/" rel="noopener noreferrer"&gt;requieren un escaneo de imágenes&lt;/a&gt;, ya que la etiqueta no te dirá si están parcheadas.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Para finalizar, ejecuta las comprobaciones indicadas al principio de este artículo dentro del contenedor desplegado, así como en los ejecutores de CI y en los entornos de desarrollo. Para consultar la versión de seguridad más reciente de cada línea:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;curl &lt;span class="nt"&gt;-s&lt;/span&gt; https://nodejs.org/dist/index.json | jq &lt;span class="nt"&gt;-r&lt;/span&gt; &lt;span class="s1"&gt;'[.[] | select(.security == true and (.version | test("^v(22|24|26)\\.")))] | group_by(.version | split(".")[0]) | .[] | max_by(.date) | "\(.version)  \(.date)"'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;¿Sigues en Node.js 20 o 25? No existe ninguna versión corregida para ti. Consulta el &lt;a href="https://apidog.com/es/blog/nodejs-20-end-of-life-no-security-patch?utm_source=dev.to&amp;amp;utm_medium=wanda&amp;amp;utm_content=n8n-post-automation"&gt;plan de fin de ciclo de vida (EOL) de Node.js 20&lt;/a&gt; y migra cuanto antes.&lt;/p&gt;

&lt;h2&gt;
  
  
  Medidas de mitigación en Node.js si no puedes actualizar hoy
&lt;/h2&gt;

&lt;p&gt;Estas alternativas te permitirán ganar tiempo, pero ninguna sustituye a la actualización.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Rechaza &lt;code&gt;br&lt;/code&gt; en el perímetro (edge).&lt;/strong&gt; Bloquea &lt;code&gt;Content-Encoding: br&lt;/code&gt; en tu proxy inverso o balanceador de carga, asegurándote de que la coincidencia no distinga mayúsculas ni minúsculas e incluya listas como &lt;code&gt;gzip, br&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Recházalo en la aplicación.&lt;/strong&gt; Coloca este middleware antes de los parsers del cuerpo de la petición. En nuestras pruebas con Express 5 respondió con un código 415:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;use&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;req&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;next&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;encoding&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;req&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;headers&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;content-encoding&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="dl"&gt;''&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sr"&gt;/&lt;/span&gt;&lt;span class="se"&gt;\b&lt;/span&gt;&lt;span class="sr"&gt;br&lt;/span&gt;&lt;span class="se"&gt;\b&lt;/span&gt;&lt;span class="sr"&gt;/i&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;test&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;encoding&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;status&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;415&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;end&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
  &lt;span class="nf"&gt;next&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Desactiva la descompresión automática.&lt;/strong&gt; La configuración &lt;code&gt;express.json({ inflate: false })&lt;/code&gt; devolvió un 415 ante la misma petición. Ten en cuenta que también rechazará cuerpos comprimidos con gzip, así que verifica primero tus clientes.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Controla las respuestas salientes.&lt;/strong&gt; axios admite &lt;code&gt;decompress: false&lt;/code&gt;, lo que mantuvo los bytes sin decodificar durante nuestras pruebas. En cambio, &lt;code&gt;fetch()&lt;/code&gt; &lt;a href="https://www.aikido.dev/blog/python-packages-vulnerable-node2shell-brotli-cve-2026-111497" rel="noopener noreferrer"&gt;carece de un mecanismo estándar de desactivación&lt;/a&gt;, por lo que conviene limitar a qué hosts puede conectarse mediante listas blancas y reglas de egreso en el firewall.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Reduce el radio de impacto.&lt;/strong&gt; Segmenta los servicios de Node.js y restringe el acceso de lectura a los volcados de memoria (core dumps), ya que ELLIO advierte que las caídas del sistema podrían dejar expuestos datos sensibles en memoria a través de ellos.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Mantente alerta ante el patrón inicial identificado por ELLIO: ráfagas de peticiones con cuerpos codificados en Brotli orientadas a mapear qué servidores los decodifican. Un tráfico inesperado con &lt;code&gt;Content-Encoding: br&lt;/code&gt; en una API JSON o un aumento repentino en la caída de procesos worker justifican una investigación inmediata.&lt;/p&gt;

&lt;h2&gt;
  
  
  Comprueba que tu API resistió la actualización: deja que tu agente lo verifique
&lt;/h2&gt;

&lt;p&gt;El cambio de versión del runtime puede alterar el comportamiento de TLS, DNS y HTTP; de hecho, la actualización de octubre introdujo cambios en los tres. No verifiques estas diferencias manualmente: delega en tu agente de desarrollo la ejecución de &lt;a href="https://apidog.com/apidog-cli/?utm_source=dev.to&amp;amp;utm_medium=wanda&amp;amp;utm_content=n8n-post-automation"&gt;Apidog CLI&lt;/a&gt; antes y después del cambio para que reporte cualquier discrepancia.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npm &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="nt"&gt;-g&lt;/span&gt; apidog-cli@latest
apidog login &lt;span class="nt"&gt;--with-token&lt;/span&gt; &amp;lt;YOUR_TOKEN&amp;gt;
npx &lt;span class="nt"&gt;-y&lt;/span&gt; skills add https://apidog.com   &lt;span class="c"&gt;# pick your agent when prompted&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Indícale a tu agente la siguiente instrucción:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Run Apidog test suite &amp;lt;id&amp;gt; in project &amp;lt;id&amp;gt; against staging and save the
results to reports/before. After I upgrade Node.js, add a test case for
POST /orders that sends the plain text "not-valid-brotli" with
Content-Encoding: br, asserts a 4xx status, then checks GET /health
returns 200. Rerun the suite to reports/after and list every request
whose result changed.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;El agente ejecutará los siguientes comandos:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;apidog run &lt;span class="nt"&gt;--test-suite&lt;/span&gt; &amp;lt;&lt;span class="nb"&gt;id&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="nt"&gt;--project&lt;/span&gt; &amp;lt;&lt;span class="nb"&gt;id&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="nt"&gt;-e&lt;/span&gt; &amp;lt;envId&amp;gt; &lt;span class="nt"&gt;-r&lt;/span&gt; cli,junit &lt;span class="nt"&gt;--out-dir&lt;/span&gt; reports/before
apidog cli-schema get test-case-create
apidog cli-schema validate test-case-create &lt;span class="nt"&gt;--file&lt;/span&gt; &lt;span class="k"&gt;case&lt;/span&gt;.json
apidog test-case create &lt;span class="nt"&gt;--project&lt;/span&gt; &amp;lt;&lt;span class="nb"&gt;id&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="nt"&gt;--file&lt;/span&gt; &lt;span class="k"&gt;case&lt;/span&gt;.json
apidog run &lt;span class="nt"&gt;--test-case&lt;/span&gt; &amp;lt;caseId&amp;gt; &lt;span class="nt"&gt;--project&lt;/span&gt; &amp;lt;&lt;span class="nb"&gt;id&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="nt"&gt;-e&lt;/span&gt; &amp;lt;envId&amp;gt; &lt;span class="nt"&gt;-r&lt;/span&gt; cli,json
apidog run &lt;span class="nt"&gt;--test-suite&lt;/span&gt; &amp;lt;&lt;span class="nb"&gt;id&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="nt"&gt;--project&lt;/span&gt; &amp;lt;&lt;span class="nb"&gt;id&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="nt"&gt;-e&lt;/span&gt; &amp;lt;envId&amp;gt; &lt;span class="nt"&gt;-r&lt;/span&gt; cli,junit &lt;span class="nt"&gt;--out-dir&lt;/span&gt; reports/after
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Ese caso de prueba adicional funciona como un health check, no como un exploit: el cuerpo es texto plano y, en nuestras pruebas, falló con el mismo error de relleno (padding) tanto en compilaciones vulnerables como corregidas. Aun así, permite detectar un problema real: en nuestra prueba con Koa obtuvimos un error 500 debido a que el fallo de decodificación no fue capturado, cuando una API pública debería responder con un 4xx. Ejecútalo únicamente en entornos de staging.&lt;/p&gt;

&lt;p&gt;La &lt;a href="https://apidog.com/es/blog/apidog-run-command-reference?utm_source=dev.to&amp;amp;utm_medium=wanda&amp;amp;utm_content=n8n-post-automation"&gt;referencia del comando run&lt;/a&gt; detalla cada opción disponible, y la &lt;a href="https://apidog.com/es/blog/apidog-cli-ci-cd-pipeline?utm_source=dev.to&amp;amp;utm_medium=wanda&amp;amp;utm_content=n8n-post-automation"&gt;guía de CI/CD&lt;/a&gt; te muestra cómo incorporar la misma ejecución con formato JUnit en tu pipeline. El plan gratuito de Apidog admite hasta 4 usuarios.&lt;/p&gt;

&lt;h2&gt;
  
  
  Por qué la fecha clave es el 11 de noviembre
&lt;/h2&gt;

&lt;p&gt;El proyecto Node.js ha &lt;a href="https://nodejs.org/en/blog/vulnerability/november-2026-security-releases" rel="noopener noreferrer"&gt;preanunciado una nueva tanda de actualizaciones&lt;/a&gt; para las líneas 26.x, 24.x y 22.x para el 11 de noviembre de 2026 o en fechas inmediatamente posteriores, calificadas nuevamente con severidad ALTA en el nivel máximo. Todavía no se han hecho públicos los CVE correspondientes. En &lt;a href="https://apidog.com/es/blog/nodejs-november-2026-security-release?utm_source=dev.to&amp;amp;utm_medium=wanda&amp;amp;utm_content=n8n-post-automation"&gt;nuestra guía sobre el lanzamiento de noviembre&lt;/a&gt; explicamos cómo prepararte.&lt;/p&gt;

&lt;p&gt;Aplica el parche para Brotli de inmediato en lugar de posponerlo hasta ese nuevo lanzamiento. La vulnerabilidad ya cuenta con detalles públicos y tráfico de explotación activo en la actualidad; además, la actualización que realices esta semana servirá de ensayo para la siguiente: mismo inventario, misma reconstrucción de imágenes y la misma batería de pruebas. &lt;a href="https://apidog.com/es/blog/php2shell-php-vulnerability?utm_source=dev.to&amp;amp;utm_medium=wanda&amp;amp;utm_content=n8n-post-automation"&gt;PHP2Shell&lt;/a&gt; y &lt;a href="https://apidog.com/es/blog/fix-react2shell-exploit?utm_source=dev.to&amp;amp;utm_medium=wanda&amp;amp;utm_content=n8n-post-automation"&gt;React2Shell&lt;/a&gt; siguieron un patrón idéntico.&lt;/p&gt;

&lt;h2&gt;
  
  
  Preguntas frecuentes (FAQ)
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;¿Se está explotando activamente CVE-2026-111497?&lt;/strong&gt; Sí. CISA la añadió a su catálogo de vulnerabilidades explotadas conocidas (KEV) el 27 de octubre de 2026 bajo la entrada de Google Brotli, y ELLIO ya había registrado tráfico de exploits el 26 de octubre.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;¿Es de severidad alta o crítica?&lt;/strong&gt; Ambas calificaciones son válidas. Node.js la clasifica como ALTA. El NVD le otorga una puntuación de 9.8 CRÍTICA en CVSS 3.1, mientras que la puntuación emitida por Google en CVSS 4.0 es de 9.2. Planifica tus acciones considerando que ya está siendo explotada activamente.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Uso Express 4, ¿estoy a salvo?&lt;/strong&gt; Los cuerpos de tus solicitudes entrantes no llegan al decodificador, pero las respuestas procesadas mediante &lt;code&gt;fetch()&lt;/code&gt; o axios y las llamadas directas a &lt;code&gt;node:zlib&lt;/code&gt; sí lo hacen. Además, esta misma versión corrige otras nueve vulnerabilidades (CVE), por lo que debes actualizar de todos modos.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;¿Afecta a Node.js 20?&lt;/strong&gt; El proyecto no evalúa versiones que han alcanzado el fin de su ciclo de vida (EOL) y no reciben parches. Considera que 20.x y 25.x están sin parchear y sin evaluar, y migra a una versión con soporte.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;¿Afecta a otras tecnologías además de Node.js?&lt;/strong&gt; Sí. El &lt;a href="https://github.com/advisories/GHSA-9v8h-qqgm-4m35" rel="noopener noreferrer"&gt;aviso de seguridad de GitHub&lt;/a&gt; incluye los paquetes de PyPI &lt;code&gt;brotli&lt;/code&gt; y &lt;code&gt;brotlicffi&lt;/code&gt;, y diversos proveedores ya han anunciado parches para Bun 1.4.4 y .NET. Actualiza cada decodificador de forma independiente, ya que actualizar Node.js solo protege su propia copia integrada.&lt;/p&gt;

</description>
      <category>cybersecurity</category>
      <category>javascript</category>
      <category>node</category>
      <category>security</category>
    </item>
    <item>
      <title>¿Sigues usando Node.js 20? La actualización de seguridad del 11 de noviembre no te protegerá</title>
      <dc:creator>Roobia</dc:creator>
      <pubDate>Thu, 05 Nov 2026 02:09:55 +0000</pubDate>
      <link>https://dev.to/roobia/sigues-usando-nodejs-20-la-actualizacion-de-seguridad-del-11-de-noviembre-no-te-protegera-6kc</link>
      <guid>https://dev.to/roobia/sigues-usando-nodejs-20-la-actualizacion-de-seguridad-del-11-de-noviembre-no-te-protegera-6kc</guid>
      <description>&lt;p&gt;Node.js 20 no recibirá nada el 11 de noviembre de 2026. Los lanzamientos de seguridad cubrirán únicamente las ramas 26.x, 24.x y 22.x, ya que Node.js 20 llegó al final de su vida útil (End-of-Life) el 30 de abril de 2026. Su último parche fue la versión 20.20.2, compilada el 24 de marzo. Desde entonces, se han publicado 33 CVE sin ninguna compilación para 20.x. Migre a 24 o 26 esta misma semana.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://apidog.com/?utm_source=dev.to&amp;amp;utm_medium=wanda&amp;amp;utm_content=n8n-post-automation" class="crayons-btn crayons-btn--primary"&gt;Prueba Apidog hoy&lt;/a&gt;
&lt;/p&gt;

&lt;p&gt;Dichas CVE se distribuyeron en tres versiones de seguridad que dejaron fuera a la rama 20. La cuarta llegará en pocos días, y el &lt;a href="https://nodejs.org/en/blog/vulnerability/november-2026-security-releases" rel="noopener noreferrer"&gt;preanuncio&lt;/a&gt; clasifica su problema más grave como HIGH en todas las ramas con soporte.&lt;/p&gt;

&lt;h2&gt;
  
  
  Qué ocurrirá el 11 de noviembre y por qué Node.js 20 queda fuera
&lt;/h2&gt;

&lt;p&gt;El proyecto Node.js publicará nuevas compilaciones de 26.x, 24.x y 22.x el miércoles 11 de noviembre de 2026 o poco después. Por ahora no hay detalles públicos sobre las CVE, y se mantendrán en privado hasta que salgan las nuevas versiones. Nuestra &lt;a href="https://apidog.com/es/blog/nodejs-november-2026-security-release?utm_source=dev.to&amp;amp;utm_medium=wanda&amp;amp;utm_content=n8n-post-automation"&gt;guía con cuenta regresiva para el lanzamiento de noviembre&lt;/a&gt; detalla el inventario del entorno de ejecución y los comandos para el día del parche, por lo que los omitiremos en este artículo.&lt;/p&gt;

&lt;p&gt;Node.js 20 no figura en la lista porque el proyecto ha dejado de mantenerlo. Su &lt;a href="https://nodejs.org/en/about/eol" rel="noopener noreferrer"&gt;página de End-of-Life&lt;/a&gt; es tajante: cuando los nuevos lanzamientos de seguridad solucionan problemas, «incluso si la misma vulnerabilidad afecta a líneas de versiones que han llegado al final de su vida útil (EOL), no habrá ningún nuevo lanzamiento para ellas».&lt;/p&gt;

&lt;p&gt;El aviso de seguridad añade otra advertencia fundamental: «Las versiones que han llegado al final de su vida útil siempre se ven afectadas cuando se produce un lanzamiento de seguridad».&lt;/p&gt;

&lt;h2&gt;
  
  
  Lo que Node.js 20 ya se ha perdido
&lt;/h2&gt;

&lt;p&gt;Se han publicado tres versiones de seguridad desde que la rama 20 alcanzó el final de su ciclo de vida. Ninguna incluye una compilación para 20.x.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Aviso&lt;/th&gt;
&lt;th&gt;CVE&lt;/th&gt;
&lt;th&gt;Alta&lt;/th&gt;
&lt;th&gt;Media&lt;/th&gt;
&lt;th&gt;Baja&lt;/th&gt;
&lt;th&gt;Corregido en&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;a href="https://nodejs.org/en/blog/vulnerability/june-2026-security-releases" rel="noopener noreferrer"&gt;18 de junio de 2026&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;12&lt;/td&gt;
&lt;td&gt;2&lt;/td&gt;
&lt;td&gt;6&lt;/td&gt;
&lt;td&gt;4&lt;/td&gt;
&lt;td&gt;26.3.1, 24.17.0, 22.23.0&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;a href="https://nodejs.org/en/blog/vulnerability/july-2026-security-releases" rel="noopener noreferrer"&gt;29 de julio de 2026&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;11&lt;/td&gt;
&lt;td&gt;3&lt;/td&gt;
&lt;td&gt;5&lt;/td&gt;
&lt;td&gt;3&lt;/td&gt;
&lt;td&gt;26.5.1, 24.18.1, 22.23.2&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;a href="https://nodejs.org/en/blog/vulnerability/october-2026-security-releases" rel="noopener noreferrer"&gt;21 de octubre de 2026&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;10&lt;/td&gt;
&lt;td&gt;4&lt;/td&gt;
&lt;td&gt;3&lt;/td&gt;
&lt;td&gt;3&lt;/td&gt;
&lt;td&gt;26.12.1, 24.22.1, 22.23.4&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Total&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;33&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;9&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;14&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;10&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Sin compilación para 20.x&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;El código que modifican estas correcciones es exactamente el que ejecuta un servidor de API de forma continua:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Comprobaciones de nombre de host en TLS.&lt;/strong&gt; Tanto en junio como en octubre se corrigieron fallos que permitían validar un certificado para un host incorrecto.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;HTTP/2.&lt;/strong&gt; Las correcciones de severidad alta de julio incluyen una vulnerabilidad de tipo use-after-free en el heap y un fallo de agotamiento remoto de memoria.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;DNS.&lt;/strong&gt; En octubre se solucionó un problema por el cual &lt;code&gt;dns.resolve*()&lt;/code&gt; truncaba los nombres de host ante un byte NUL, lo que permitía burlar listas de permitidos.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Compresión.&lt;/strong&gt; En octubre se corrigió una escritura fuera de límites en el decodificador de Brotli que podía desembocar en ejecución remota de código. Lo analizamos en nuestra &lt;a href="https://apidog.com/es/blog/nodejs-brotli-rce-cve-2026-111497?utm_source=dev.to&amp;amp;utm_medium=wanda&amp;amp;utm_content=n8n-post-automation"&gt;revisión del RCE en Brotli&lt;/a&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Lea esa lista con atención. El proyecto no evalúa las ramas descontinuadas, por lo que sus avisos de seguridad solo mencionan las versiones con soporte oficial. Algunos de estos errores residen en código que la versión 20 podría no contener: una de las CVE de octubre es una regresión acotada exclusivamente a 26.x y 24.x. Por lo tanto, el estado real de cada CVE en Node.js 20 es &lt;strong&gt;sin parchear y sin evaluar&lt;/strong&gt;. Nadie le ha garantizado que esté a salvo, y nadie va a comprobarlo.&lt;/p&gt;

&lt;p&gt;El encadenamiento de vulnerabilidades empeora aún más la situación. La corrección de DNS de octubre completa un parche de junio, y otra corrección de julio complementa una de junio. Cada parche posterior se construye sobre una base de la que usted carece.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fvr3md0gfva7yflwxje6g.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fvr3md0gfva7yflwxje6g.png" alt="Cronología de Node.js 20: última compilación el 24 de marzo de 2026, fin de vida útil el 30 de abril, lanzamientos de seguridad el 18 de junio, 29 de julio y 21 de octubre sin corrección para 20.x, y el lanzamiento del 11 de noviembre aún pendiente" width="800" height="267"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  «Pero si todavía funciona»
&lt;/h2&gt;

&lt;p&gt;Funciona, y ese es precisamente el problema.&lt;/p&gt;

&lt;p&gt;Un entorno de ejecución descontinuado no falla de golpe. &lt;code&gt;node -v&lt;/code&gt; sigue mostrando la misma versión, las pruebas pasan y los paneles de monitorización se mantienen en verde. El riesgo aparece en lugares a los que no suele prestar atención:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;El propio parche sirve de mapa.&lt;/strong&gt; Las correcciones, los avisos y los commits se publican al mismo tiempo, por lo que cualquiera puede ver con exactitud qué cambió en una versión con soporte y comprobar si ese mismo código existe en la rama 20.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Su plataforma podría seguir desplegándolo.&lt;/strong&gt; &lt;a href="https://docs.aws.amazon.com/lambda/latest/dg/lambda-runtimes.html" rel="noopener noreferrer"&gt;AWS Lambda&lt;/a&gt; marcó &lt;code&gt;nodejs20.x&lt;/code&gt; como obsoleto el 30 de abril de 2026, pero no bloqueará la creación de funciones hasta el 29 de julio de 2027 ni las actualizaciones hasta el 31 de agosto de 2027.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Los paquetes y las auditorías avanzan.&lt;/strong&gt; El proyecto Node.js advierte de que los paquetes más populares van retirando con el tiempo el soporte para versiones descontinuadas, y muchas auditorías del sector prohíben explícitamente el uso de entornos sin mantenimiento.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Elija un destino: Node.js 24 o 26, pero no 22
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Migre a la versión 24 esta semana si necesita el camino más rápido. Elija la 26 si puede asumir más cambios ahora y busca el ciclo de vida más largo.&lt;/strong&gt; Descarte la versión 22: aunque recibirá la corrección de noviembre, su soporte concluye el 30 de abril de 2027 (en menos de seis meses), por lo que tendría que repetir todo este proceso en primavera.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Rama&lt;/th&gt;
&lt;th&gt;Estado&lt;/th&gt;
&lt;th&gt;Última versión al 5 de nov.&lt;/th&gt;
&lt;th&gt;Fin del soporte&lt;/th&gt;
&lt;th&gt;Ideal para&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;26.x «Lithium»&lt;/td&gt;
&lt;td&gt;LTS activa desde el 28 de oct. de 2026&lt;/td&gt;
&lt;td&gt;26.13.0&lt;/td&gt;
&lt;td&gt;30 de abr. de 2029&lt;/td&gt;
&lt;td&gt;Servicios que pueda volver a probar por completo ahora&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;24.x «Krypton»&lt;/td&gt;
&lt;td&gt;LTS de mantenimiento desde el 20 de oct. de 2026&lt;/td&gt;
&lt;td&gt;24.22.2&lt;/td&gt;
&lt;td&gt;30 de abr. de 2028&lt;/td&gt;
&lt;td&gt;La salida segura más rápida desde la versión 20&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;22.x «Jod»&lt;/td&gt;
&lt;td&gt;LTS de mantenimiento&lt;/td&gt;
&lt;td&gt;22.23.4&lt;/td&gt;
&lt;td&gt;30 de abr. de 2027&lt;/td&gt;
&lt;td&gt;No merece la pena migrar a ella hoy&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Las fechas proceden del &lt;a href="https://raw.githubusercontent.com/nodejs/Release/main/schedule.json" rel="noopener noreferrer"&gt;calendario de lanzamientos de Node.js&lt;/a&gt;. Compruebe su plataforma antes de dar el paso. En Lambda, por ejemplo, el entorno de ejecución de Node.js 26 se encuentra en vista previa pública y no está cubierto por su SLA, por lo que la versión 24 es actualmente la opción más segura para producción en ese entorno.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fz1d3lrd1r1s6cy19xfri.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fz1d3lrd1r1s6cy19xfri.png" alt="Gráfico de barras de las ventanas de soporte de Node.js a partir de noviembre de 2026: 22.x finaliza el 30 de abril de 2027, 24.x finaliza el 30 de abril de 2028 y 26.x finaliza el 30 de abril de 2029" width="800" height="410"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Pasos para la migración y qué cosas dejarán de funcionar
&lt;/h2&gt;

&lt;p&gt;Toda la información de esta tabla procede de las notas de lanzamiento oficiales de &lt;a href="https://nodejs.org/en/blog/release/v22.0.0" rel="noopener noreferrer"&gt;22.0.0&lt;/a&gt;, &lt;a href="https://nodejs.org/en/blog/release/v24.0.0" rel="noopener noreferrer"&gt;24.0.0&lt;/a&gt;, &lt;a href="https://nodejs.org/en/blog/release/v25.0.0" rel="noopener noreferrer"&gt;25.0.0&lt;/a&gt; y &lt;a href="https://nodejs.org/en/blog/release/v26.0.0" rel="noopener noreferrer"&gt;26.0.0&lt;/a&gt;, además de la &lt;a href="https://nodejs.org/en/blog/migrations/v22-to-v24" rel="noopener noreferrer"&gt;guía de migración de v22 a v24&lt;/a&gt;. Es una selección resumida y orientada a servicios de API, no el registro completo de cambios.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Introducido en&lt;/th&gt;
&lt;th&gt;Cambio&lt;/th&gt;
&lt;th&gt;A quién afecta&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;22&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;import ... assert { type: 'json' }&lt;/code&gt; removed; use &lt;code&gt;with&lt;/code&gt;
&lt;/td&gt;
&lt;td&gt;Código ESM que importe JSON&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;22&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;crypto.createCipher()&lt;/code&gt; and &lt;code&gt;createDecipher()&lt;/code&gt; removed&lt;/td&gt;
&lt;td&gt;Código de cifrado heredado&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;23 and 24&lt;/td&gt;
&lt;td&gt;No prebuilt 32-bit Windows or 32-bit armv7 Linux binaries; macOS 13.5 minimum&lt;/td&gt;
&lt;td&gt;Servidores antiguos y dispositivos edge&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;24&lt;/td&gt;
&lt;td&gt;OpenSSL 3.5 at security level 2: RSA, DSA, and DH keys under 2048 bits, ECC keys under 224 bits, and RC4 are prohibited&lt;/td&gt;
&lt;td&gt;mTLS y servidores upstream antiguos&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;24&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;tls.createSecurePair&lt;/code&gt; removed; &lt;code&gt;url.parse()&lt;/code&gt; runtime-deprecated&lt;/td&gt;
&lt;td&gt;Código de red heredado&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;24&lt;/td&gt;
&lt;td&gt;Stricter &lt;code&gt;fetch()&lt;/code&gt; compliance, &lt;code&gt;AbortSignal&lt;/code&gt; validation, stream and pipe errors now throw&lt;/td&gt;
&lt;td&gt;Clientes HTTP y proxies&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;24&lt;/td&gt;
&lt;td&gt;V8 13.6; addons may need C++20&lt;/td&gt;
&lt;td&gt;Módulos nativos&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;25 (if targeting 26)&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;SlowBuffer&lt;/code&gt; and &lt;code&gt;fs.F_OK&lt;/code&gt;, &lt;code&gt;R_OK&lt;/code&gt;, &lt;code&gt;W_OK&lt;/code&gt;, &lt;code&gt;X_OK&lt;/code&gt; removed; Corepack no longer ships&lt;/td&gt;
&lt;td&gt;Utilidades antiguas, Yarn o pnpm mediante Corepack&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;25 (if targeting 26)&lt;/td&gt;
&lt;td&gt;IP address as TLS &lt;code&gt;servername&lt;/code&gt; moved to End-of-Life&lt;/td&gt;
&lt;td&gt;Clientes que conecten mediante IP&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;26&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;_stream_*&lt;/code&gt; modules and &lt;code&gt;writeHeader()&lt;/code&gt; removed; &lt;code&gt;module.register()&lt;/code&gt; runtime-deprecated; Undici 8&lt;/td&gt;
&lt;td&gt;Código de streams antiguo, loaders personalizados&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;La fila de OpenSSL es la que puede dar problemas de forma silenciosa: su código no cambia en absoluto, pero el handshake con un sistema externo antiguo falla en tiempo de ejecución.&lt;/p&gt;

&lt;p&gt;En una rama, actualice &lt;code&gt;.nvmrc&lt;/code&gt;, &lt;code&gt;engines&lt;/code&gt;, su Dockerfile y su CI a la versión de destino (en un entorno limpio, consulte la &lt;a href="https://apidog.com/es/blog/how-to-install-node-js-configure-environment?utm_source=dev.to&amp;amp;utm_medium=wanda&amp;amp;utm_content=n8n-post-automation"&gt;guía de instalación de Node.js&lt;/a&gt;). Luego reinstale para recompilar los módulos nativos, busque APIs eliminadas, ejecute los codemods oficiales e inicie el servicio con el rastreo de obsolescencias activado:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;nvm &lt;span class="nb"&gt;install &lt;/span&gt;24 &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; nvm use 24
&lt;span class="nb"&gt;rm&lt;/span&gt; &lt;span class="nt"&gt;-rf&lt;/span&gt; node_modules &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; npm ci

&lt;span class="nb"&gt;grep&lt;/span&gt; &lt;span class="nt"&gt;-rnE&lt;/span&gt; &lt;span class="s2"&gt;"assert &lt;/span&gt;&lt;span class="se"&gt;\{&lt;/span&gt;&lt;span class="s2"&gt; *type|createCipher&lt;/span&gt;&lt;span class="se"&gt;\(&lt;/span&gt;&lt;span class="s2"&gt;|createDecipher&lt;/span&gt;&lt;span class="se"&gt;\(&lt;/span&gt;&lt;span class="s2"&gt;|url&lt;/span&gt;&lt;span class="se"&gt;\.&lt;/span&gt;&lt;span class="s2"&gt;parse&lt;/span&gt;&lt;span class="se"&gt;\(&lt;/span&gt;&lt;span class="s2"&gt;|fs&lt;/span&gt;&lt;span class="se"&gt;\.&lt;/span&gt;&lt;span class="s2"&gt;[FRWX]_OK|SlowBuffer|createSecurePair|_stream_[a-z]+|module&lt;/span&gt;&lt;span class="se"&gt;\.&lt;/span&gt;&lt;span class="s2"&gt;register&lt;/span&gt;&lt;span class="se"&gt;\(&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--include&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"*.js"&lt;/span&gt; &lt;span class="nt"&gt;--include&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"*.mjs"&lt;/span&gt; &lt;span class="nt"&gt;--include&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"*.ts"&lt;/span&gt; &lt;span class="nt"&gt;--exclude-dir&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;node_modules &lt;span class="nb"&gt;.&lt;/span&gt;

npx codemod run @nodejs/import-assertions-to-attributes
npx codemod run @nodejs/crypto-createcipheriv-migration
npx codemod run @nodejs/tls-create-secure-pair-to-tls-socket
npx codemod run @nodejs/fs-access-mode-constants

&lt;span class="nv"&gt;NODE_OPTIONS&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"--trace-deprecation"&lt;/span&gt; npm start
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Revise manualmente el resultado de los codemods. El de &lt;code&gt;createCipher&lt;/code&gt; es explícito: el código generado no puede descifrar datos cifrados con la API antigua, por lo que deberá planificar una migración de datos si los tiene.&lt;/p&gt;

&lt;p&gt;El sitio web de Node.js aún no cuenta con una guía de migración de 24 a 26, por lo que le recomendamos consultar las notas de las versiones 25.0.0 y 26.0.0 para ese salto.&lt;/p&gt;

&lt;h2&gt;
  
  
  Compruebe que la API se comporta igual en la nueva versión
&lt;/h2&gt;

&lt;p&gt;Las pruebas unitarias no muestran el impacto que una nueva pila TLS y un nuevo cliente HTTP tienen sobre el tráfico real. Ante un salto de dos o tres versiones mayores, conviene hacer una comparación del antes y el después con el servicio en ejecución, y esa es una tarea ideal para su agente de programación.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://apidog.com/apidog-cli/?utm_source=dev.to&amp;amp;utm_medium=wanda&amp;amp;utm_content=n8n-post-automation"&gt;Apidog CLI&lt;/a&gt; permite que Claude Code, Codex o Cursor ejecuten sus suites de pruebas de &lt;a href="https://apidog.com/?utm_source=dev.to&amp;amp;utm_medium=wanda&amp;amp;utm_content=n8n-post-automation"&gt;Apidog&lt;/a&gt; directamente desde la terminal. Solo tiene que configurarlo una vez:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npm &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="nt"&gt;-g&lt;/span&gt; apidog-cli@latest
apidog login &lt;span class="nt"&gt;--with-token&lt;/span&gt; &amp;lt;YOUR_TOKEN&amp;gt;
npx &lt;span class="nt"&gt;-y&lt;/span&gt; skills add https://apidog.com   &lt;span class="c"&gt;# pick your agent when prompted&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Luego, indíquele un único prompt a su agente:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;My service runs on Node.js 20 in staging. Run Apidog test suite &amp;lt;suiteId&amp;gt; in project
&amp;lt;projectId&amp;gt; against environment &amp;lt;envId&amp;gt; and save reports to reports/node20. When I
redeploy on Node.js 24, run the same suite into reports/node24. List every request
whose status, body, or TLS behavior changed. Then read the service logs for deprecation
warnings and check each failure against the 22, 24, and 25 release notes: removed APIs,
changed defaults, stricter fetch and AbortSignal handling, OpenSSL key size rejections.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;El agente ejecutará la misma suite en ambos extremos de la migración:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;apidog run &lt;span class="nt"&gt;--test-suite&lt;/span&gt; &amp;lt;suiteId&amp;gt; &lt;span class="nt"&gt;--project&lt;/span&gt; &amp;lt;projectId&amp;gt; &lt;span class="nt"&gt;-e&lt;/span&gt; &amp;lt;envId&amp;gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-r&lt;/span&gt; cli,junit &lt;span class="nt"&gt;--out-dir&lt;/span&gt; reports/node20

&lt;span class="c"&gt;# redeploy the service on the target line, restart it&lt;/span&gt;

apidog run &lt;span class="nt"&gt;--test-suite&lt;/span&gt; &amp;lt;suiteId&amp;gt; &lt;span class="nt"&gt;--project&lt;/span&gt; &amp;lt;projectId&amp;gt; &lt;span class="nt"&gt;-e&lt;/span&gt; &amp;lt;envId&amp;gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-r&lt;/span&gt; cli,junit &lt;span class="nt"&gt;--out-dir&lt;/span&gt; reports/node24
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Dos factores garantizan que la comparación sea fiable:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Nunca pase el parámetro &lt;code&gt;-k&lt;/code&gt;.&lt;/strong&gt; Ese flag desactiva la validación SSL, lo que ocultaría precisamente los errores de TLS que necesita detectar.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Incluya las llamadas que su servicio realiza hacia otros sistemas (upstream).&lt;/strong&gt; El rechazo de OpenSSL aparecerá como un error de API en un endpoint que dependa de un sistema externo antiguo; por lo tanto, pruebe esas rutas y no se limite a &lt;code&gt;/health&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Una vez superada la migración, mantenga la suite en su canal de CI/CD. La &lt;a href="https://apidog.com/es/blog/apidog-cli-ci-cd-pipeline?utm_source=dev.to&amp;amp;utm_medium=wanda&amp;amp;utm_content=n8n-post-automation"&gt;guía de CI/CD con Apidog CLI&lt;/a&gt; describe el flujo de trabajo, y el &lt;a href="https://apidog.com/es/blog/apidog-cli-in-claude-code?utm_source=dev.to&amp;amp;utm_medium=wanda&amp;amp;utm_content=n8n-post-automation"&gt;tutorial de Claude Code&lt;/a&gt; explica la configuración del agente.&lt;/p&gt;

&lt;h2&gt;
  
  
  Qué hacer si no puede migrar esta semana
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Adquiera versiones parcheadas.&lt;/strong&gt; La &lt;a href="https://nodejs.org/en/about/eol" rel="noopener noreferrer"&gt;página de End-of-Life de Node.js&lt;/a&gt; menciona tres partners a través del programa OpenJS Ecosystem Sustainability Program: HeroDevs ofrece Never-Ending Support con parches de seguridad; TuxCare, mediante Endless Lifecycle Support, adapta parches para versiones en fin de vida; y NodeSource ofrece evaluaciones de actualización y soporte. El proyecto califica esto como una solución temporal, y ciertamente lo es.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Reduzca la superficie de exposición del proceso.&lt;/strong&gt; Estas medidas disminuyen la exposición a los tipos de fallos descritos anteriormente, aunque no solucionan nada de raíz:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Termine TLS y HTTP/2 en un proxy o balanceador de carga con soporte activo, y comuníquese con Node.js mediante HTTP/1.1 sin cifrar en una red privada.&lt;/li&gt;
&lt;li&gt;Deje de descomprimir Brotli procedente de orígenes no confiables, tanto en las peticiones entrantes como en el contenido obtenido de forma externa.&lt;/li&gt;
&lt;li&gt;Rechace nombres de host que contengan bytes NUL o representaciones de IP no canónicas antes de cualquier comprobación de lista de permitidos o llamada saliente.&lt;/li&gt;
&lt;li&gt;Aísle el servicio: credenciales con el mínimo privilegio, tráfico de salida restringido y sin secretos compartidos con servicios parcheados.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Documente formalmente el riesgo.&lt;/strong&gt; Asigne un responsable, una fecha límite para la migración y los controles de mitigación implementados, de modo que lo «temporal» tenga un fin definido.&lt;/p&gt;

&lt;h2&gt;
  
  
  Preguntas frecuentes (FAQ)
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;¿Node.js 20 sigue teniendo soporte?&lt;/strong&gt; No. Llegó al final de su ciclo de vida (End-of-Life) el 30 de abril de 2026. La última versión es la 20.20.2 del 24 de marzo de 2026, y el proyecto no publicará ninguna otra.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;¿Es Node.js 20 vulnerable a los fallos del 11 de noviembre?&lt;/strong&gt; Los detalles de las CVE aún no son públicos, por lo que nadie puede asegurar cuáles le afectan. Sin embargo, el aviso oficial señala que las versiones descontinuadas siempre se ven afectadas cuando se produce un lanzamiento de seguridad, y el proyecto no las evalúa individualmente.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;¿Debería actualizar a Node.js 22 en su lugar?&lt;/strong&gt; No. Aunque es el salto más pequeño, su ciclo de vida concluye el 30 de abril de 2027. Migrar a 24 le proporciona un año adicional de soporte, y pasar a 26 le otorga dos años más.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;¿Node.js 24 o 26?&lt;/strong&gt; Elija la 24 si necesita salir del paso esta misma semana o si su infraestructura todavía no es totalmente compatible con la versión 26. Elija la 26 si puede probarlo todo de nuevo en este momento, ya que tendrá soporte hasta el 30 de abril de 2029.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Estoy utilizando Node.js 25. ¿Aplica esto a mi caso?&lt;/strong&gt; Sí. Node.js 25 llegó al final de su vida útil el 1 de junio de 2026, con la versión 25.9.0 como su última compilación. Tampoco recibirá correcciones en noviembre, y la versión 26 está a solo una versión mayor de distancia.&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>news</category>
      <category>node</category>
      <category>security</category>
    </item>
    <item>
      <title>Cómo encontrar y enriquecer leads con Claude Code</title>
      <dc:creator>Roobia</dc:creator>
      <pubDate>Wed, 04 Nov 2026 03:22:45 +0000</pubDate>
      <link>https://dev.to/roobia/como-encontrar-y-enriquecer-leads-con-claude-code-jb9</link>
      <guid>https://dev.to/roobia/como-encontrar-y-enriquecer-leads-con-claude-code-jb9</guid>
      <description>&lt;h1&gt;
  
  
  Cómo encontrar y enriquecer leads con Claude Code
&lt;/h1&gt;

&lt;p&gt;La API de personas de Firecrawl Alexandria permite a tu agente de programación encontrar y enriquecer personas mediante una sola clave de Firecrawl. Descubres herramientas gratis con &lt;code&gt;v2/search&lt;/code&gt;, listas candidatos con Apollo &lt;code&gt;people/search&lt;/code&gt; a 0 créditos, revelas uno con Apollo &lt;code&gt;people/match&lt;/code&gt; a 30 créditos, o enriqueces un correo electrónico conocido con People Data Labs &lt;code&gt;person/enrich&lt;/code&gt; a 60 créditos. Cada llamada pasa por &lt;code&gt;POST /v2/scrape&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://apidog.com/?utm_source=dev.to&amp;amp;utm_medium=wanda&amp;amp;utm_content=n8n-post-automation" class="crayons-btn crayons-btn--primary"&gt;Prueba Apidog hoy&lt;/a&gt;
&lt;/p&gt;

&lt;p&gt;Cada paso a continuación aparece dos veces: un prompt para Claude Code (o Codex) y el &lt;code&gt;curl&lt;/code&gt; sin procesar, para que puedas automatizarlo sin un agente.&lt;/p&gt;

&lt;h2&gt;
  
  
  Qué es la API de personas de Firecrawl Alexandria
&lt;/h2&gt;

&lt;p&gt;Alexandria es la biblioteca de proveedores de datos de terceros de Firecrawl, accesible con la clave de API que ya usas para el scraping. Según la &lt;a href="https://docs.firecrawl.dev/features/alexandria" rel="noopener noreferrer"&gt;documentación de Alexandria&lt;/a&gt;, descubres una herramienta, inspeccionas sus entradas y su precio, y luego la ejecutas con &lt;code&gt;scrape&lt;/code&gt;. El descubrimiento es gratis; la ejecución cuesta los créditos indicados en la herramienta.&lt;/p&gt;

&lt;p&gt;La categoría People contiene 12 proveedores. Dos de ellos cubren la mayor parte del trabajo de prospección:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Proveedor&lt;/th&gt;
&lt;th&gt;Capacidad&lt;/th&gt;
&lt;th&gt;Créditos por llamada&lt;/th&gt;
&lt;th&gt;Qué envías&lt;/th&gt;
&lt;th&gt;Qué obtienes&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Apollo&lt;/td&gt;
&lt;td&gt;&lt;code&gt;people/search&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;0&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;person_titles&lt;/code&gt;, &lt;code&gt;q_keywords&lt;/code&gt;, &lt;code&gt;q_organization_domains_list&lt;/code&gt;, &lt;code&gt;per_page&lt;/code&gt; (máx. 100)&lt;/td&gt;
&lt;td&gt;Vistas previas: nombre, apellido enmascarado, cargo, empresa, &lt;code&gt;has_email&lt;/code&gt;, &lt;code&gt;id&lt;/code&gt; de Apollo&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Apollo&lt;/td&gt;
&lt;td&gt;&lt;code&gt;people/match&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;30&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;id&lt;/code&gt; de la búsqueda, o &lt;code&gt;linkedin_url&lt;/code&gt;, &lt;code&gt;email&lt;/code&gt;, o &lt;code&gt;name&lt;/code&gt; más &lt;code&gt;domain&lt;/code&gt;
&lt;/td&gt;
&lt;td&gt;Una persona resuelta con cargo, historial y datos de contacto&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;People Data Labs&lt;/td&gt;
&lt;td&gt;&lt;code&gt;person/enrich&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;60&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;email&lt;/code&gt;, &lt;code&gt;profile&lt;/code&gt;, &lt;code&gt;pdl_id&lt;/code&gt; y otros; un nombre sin más datos devuelve un 400&lt;/td&gt;
&lt;td&gt;Un registro completo de la persona más &lt;code&gt;likelihood&lt;/code&gt; (1 a 10)&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Los precios son los que se muestran junto al botón Run en la &lt;a href="https://www.firecrawl.dev/alexandria/apollo" rel="noopener noreferrer"&gt;página de Apollo&lt;/a&gt; y la &lt;a href="https://www.firecrawl.dev/alexandria/people-data-labs" rel="noopener noreferrer"&gt;página de People Data Labs&lt;/a&gt; el 4 de noviembre de 2026. La página de Apollo también dice que un fallo de &lt;code&gt;people/match&lt;/code&gt; "no devuelve ninguna persona y no se factura".&lt;/p&gt;

&lt;h2&gt;
  
  
  Cuánto cuesta una búsqueda de personas en dólares
&lt;/h2&gt;

&lt;p&gt;El valor de un crédito depende de tu plan. Según la &lt;a href="https://www.firecrawl.dev/pricing" rel="noopener noreferrer"&gt;página de precios de Firecrawl&lt;/a&gt;, Hobby cuesta $19 al mes por 5,000 créditos y Standard cuesta $99 al mes por 100,000 créditos, ambos con facturación mensual.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Llamada&lt;/th&gt;
&lt;th&gt;Créditos&lt;/th&gt;
&lt;th&gt;Hobby ($0.0038/crédito)&lt;/th&gt;
&lt;th&gt;Standard ($0.00099/crédito)&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Búsqueda de descubrimiento o find-tools&lt;/td&gt;
&lt;td&gt;0&lt;/td&gt;
&lt;td&gt;$0&lt;/td&gt;
&lt;td&gt;$0&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Apollo &lt;code&gt;people/search&lt;/code&gt;
&lt;/td&gt;
&lt;td&gt;0&lt;/td&gt;
&lt;td&gt;$0&lt;/td&gt;
&lt;td&gt;$0&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Apollo &lt;code&gt;people/match&lt;/code&gt;
&lt;/td&gt;
&lt;td&gt;30&lt;/td&gt;
&lt;td&gt;$0.114&lt;/td&gt;
&lt;td&gt;$0.0297&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;PDL &lt;code&gt;person/enrich&lt;/code&gt;
&lt;/td&gt;
&lt;td&gt;60&lt;/td&gt;
&lt;td&gt;$0.228&lt;/td&gt;
&lt;td&gt;$0.0594&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Las cuentas: $19 / 5,000 = $0.0038 por crédito, y $99 / 100,000 = $0.00099. Buscar 100 vistas previas y revelar las 20 mejores cuesta 600 créditos, lo que cabe dentro de los 1,000 mensuales del plan Free. People Data Labs también te limita a 50,000 llamadas API al año por organización, compartidas entre los endpoints de persona y empresa, incluyendo reintentos.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fgx3dlqs53k0ppj1ztvb8.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fgx3dlqs53k0ppj1ztvb8.png" alt="Flow of a people lookup on Firecrawl Alexandria: free discovery search, Apollo people/search at 0 credits, Apollo people/match at 30 credits, People Data Labs person/enrich at 60 credits, and feedback refunding 1 credit" width="800" height="410"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Paso 1: Conecta Claude Code a Firecrawl
&lt;/h2&gt;

&lt;p&gt;La ruta más rápida es el instalador de agentes de Firecrawl. Añade las habilidades de Firecrawl a cada agente de programación que detecta y te inicia sesión a través del navegador:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npx &lt;span class="nt"&gt;-y&lt;/span&gt; firecrawl-cli@latest init &lt;span class="nt"&gt;--all&lt;/span&gt; &lt;span class="nt"&gt;--browser&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Reinicia tu agente después. De forma manual, es &lt;code&gt;npm install -g firecrawl-cli&lt;/code&gt; y &lt;code&gt;firecrawl login&lt;/code&gt;. Nuestra &lt;a href="https://apidog.com/es/blog/how-to-install-and-use-firecrawl-cli?utm_source=dev.to&amp;amp;utm_medium=wanda&amp;amp;utm_content=n8n-post-automation"&gt;guía de Firecrawl CLI&lt;/a&gt; cubre ambos, y el &lt;a href="https://apidog.com/es/blog/firecrawl-mcp-llms-txt?utm_source=dev.to&amp;amp;utm_medium=wanda&amp;amp;utm_content=n8n-post-automation"&gt;recorrido de Firecrawl MCP&lt;/a&gt; cubre el servidor MCP, que expone el mismo bucle como &lt;code&gt;firecrawl_search&lt;/code&gt;, &lt;code&gt;firecrawl_find_tools&lt;/code&gt; y &lt;code&gt;firecrawl_scrape&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Para los ejemplos de &lt;code&gt;curl&lt;/code&gt; a continuación, exporta tu clave una vez:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;export &lt;/span&gt;&lt;span class="nv"&gt;FIRECRAWL_API_KEY&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"fc-..."&lt;/span&gt;   &lt;span class="c"&gt;# never commit this&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Paso 2: Descubre las herramientas de personas gratis
&lt;/h2&gt;

&lt;p&gt;Pregunta primero a tu agente, ya que el descubrimiento no cuesta nada:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Use Firecrawl Alexandria to find tools that search people by job title and
company, and tools that enrich a person from an email. Inspect Apollo and
People Data Labs with find-tools and show me each capability's inputs and
credit price before you run anything.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;En realidad, eso es una búsqueda con &lt;code&gt;sources&lt;/code&gt; establecido solo en &lt;code&gt;["alexandria"]&lt;/code&gt;. Omitir &lt;code&gt;"web"&lt;/code&gt; la mantiene gratis, porque los resultados web se facturan:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;curl https://api.firecrawl.dev/v2/search &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s2"&gt;"Authorization: Bearer &lt;/span&gt;&lt;span class="nv"&gt;$FIRECRAWL_API_KEY&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s2"&gt;"Content-Type: application/json"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-d&lt;/span&gt; &lt;span class="s1"&gt;'{"query": "find people by job title and company", "sources": ["alexandria"], "limit": 5}'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;La respuesta lista &lt;code&gt;tools&lt;/code&gt; clasificadas, cada una con un proveedor, una capacidad y una descripción. Para leer entradas y precios, el agente ejecuta find-tools:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;firecrawl find-tools &lt;span class="nt"&gt;--options&lt;/span&gt; &lt;span class="s1"&gt;'{"providers":["apollo","people-data-labs"],"level":"tools","expand":["options","response"]}'&lt;/span&gt; &lt;span class="nt"&gt;--include-costs&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Paso 3: Busca candidatos en Apollo a 0 créditos
&lt;/h2&gt;

&lt;p&gt;La página de Apollo indica a los agentes que siempre empiecen aquí: es gratis y muestra quién existe antes de que gastes nada.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Run Apollo people/search through Firecrawl Alexandria for "VP of Sales" and
"Head of Revenue" at stripe.com and linear.app, 25 per page. Show name,
title, company and has_email. Don't reveal anyone yet.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;La llamada sin procesar:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;curl https://api.firecrawl.dev/v2/scrape &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s2"&gt;"Authorization: Bearer &lt;/span&gt;&lt;span class="nv"&gt;$FIRECRAWL_API_KEY&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s2"&gt;"Content-Type: application/json"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-d&lt;/span&gt; &lt;span class="s1"&gt;'{
    "alexandria": {
      "provider": "apollo",
      "capability": "people/search",
      "options": {
        "person_titles": ["VP of Sales", "Head of Revenue"],
        "q_organization_domains_list": ["stripe.com", "linear.app"],
        "page": 1,
        "per_page": 25
      }
    }
  }'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Cada vista previa lleva un apellido enmascarado y un &lt;code&gt;id&lt;/code&gt; de Apollo, la entrada más fiable para el siguiente paso.&lt;/p&gt;

&lt;h2&gt;
  
  
  Paso 4: Revela una persona con people/match
&lt;/h2&gt;

&lt;p&gt;Ahora paga solo por las personas que vale la pena contactar, a 30 créditos por coincidencia:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;For the 3 previews with has_email true, run Apollo people/match with their
id. Don't set reveal_personal_emails or reveal_phone_number.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;curl https://api.firecrawl.dev/v2/scrape &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s2"&gt;"Authorization: Bearer &lt;/span&gt;&lt;span class="nv"&gt;$FIRECRAWL_API_KEY&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s2"&gt;"Content-Type: application/json"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-d&lt;/span&gt; &lt;span class="s1"&gt;'{"alexandria": {"provider": "apollo", "capability": "people/match", "options": {"id": "&amp;lt;apollo_id&amp;gt;"}}}'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Deja las dos flags de revelado desactivadas a menos que las necesites. La página de Apollo dice que un correo personal "cuesta extra" y que un número de teléfono es "sustancialmente más caro que la coincidencia base".&lt;/p&gt;

&lt;h2&gt;
  
  
  Paso 5: Enriquece un correo conocido con People Data Labs
&lt;/h2&gt;

&lt;p&gt;Cuando ya tienes un correo electrónico, por ejemplo de un registro entrante, &lt;code&gt;person/enrich&lt;/code&gt; devuelve un perfil más completo: correo de trabajo, cargo, empresa, URL de LinkedIn, experiencia y habilidades.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Enrich jane@example.com with People Data Labs person/enrich through
Firecrawl Alexandria. Set min_likelihood to 6 so a weak match comes back
as a 404 instead of a wrong record.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;curl https://api.firecrawl.dev/v2/scrape &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s2"&gt;"Authorization: Bearer &lt;/span&gt;&lt;span class="nv"&gt;$FIRECRAWL_API_KEY&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s2"&gt;"Content-Type: application/json"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-d&lt;/span&gt; &lt;span class="s1"&gt;'{"alexandria": {"provider": "people-data-labs", "capability": "person/enrich", "options": {"email": "jane@example.com", "min_likelihood": 6}}}'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;min_likelihood&lt;/code&gt; va de 1 a 10 con un valor predeterminado de 2. La página del proveedor plantea el equilibrio con claridad: un 404 "es gratis aquí y un registro incorrecto no lo es". Súbelo antes de recorrer una lista.&lt;/p&gt;

&lt;h2&gt;
  
  
  Maneja THIRD_PARTY_DATA_TERMS_REQUIRED
&lt;/h2&gt;

&lt;p&gt;Tu primera llamada de pago a un proveedor puede fallar con &lt;code&gt;THIRD_PARTY_DATA_TERMS_REQUIRED&lt;/code&gt;. Según la documentación, el error incluye una &lt;code&gt;requiresAction.url&lt;/code&gt;, y un administrador de la organización tiene que abrirla y aceptar los términos de ese proveedor antes de que se realice cualquier llamada.&lt;/p&gt;

&lt;p&gt;No dejes que el agente haga clic en ella. La documentación dice que los agentes necesitan autorización explícita del usuario antes de aceptar términos, que rigen cómo puedes usar datos personales. Añade una línea a tu &lt;code&gt;CLAUDE.md&lt;/code&gt;: "Si una llamada devuelve THIRD_PARTY_DATA_TERMS_REQUIRED, detente y muéstrame requiresAction.url."&lt;/p&gt;

&lt;h2&gt;
  
  
  Lee el payload de alexandria[].data
&lt;/h2&gt;

&lt;p&gt;Los resultados vuelven en un array &lt;code&gt;alexandria&lt;/code&gt;, una entrada por llamada de herramienta, con el payload del proveedor bajo &lt;code&gt;data&lt;/code&gt;. HTTP sin procesar envuelve todo el resultado del SDK en un &lt;code&gt;data&lt;/code&gt; de nivel superior, así que en una respuesta de &lt;code&gt;curl&lt;/code&gt; la coincidencia de Apollo está en &lt;code&gt;data.alexandria[0].data.person&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;curl &lt;span class="nt"&gt;-s&lt;/span&gt; https://api.firecrawl.dev/v2/scrape ... | jq &lt;span class="s1"&gt;'.data.alexandria[0].data.person | {name, title, email, linkedin_url}'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Dos comprobaciones evitan que filas incorrectas entren en tu CRM:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Comprueba si hay errores en cada resultado&lt;/strong&gt; antes de leer &lt;code&gt;data&lt;/code&gt;. La documentación lo dice explícitamente; una sola llamada puede fallar mientras la solicitud HTTP tiene éxito.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Trata los correos de marcador de posición como ausentes.&lt;/strong&gt; Apollo señala que un correo no revelado puede volver como el literal &lt;code&gt;email_not_unlocked@domain.com&lt;/code&gt;, incluso cuando &lt;code&gt;email_status&lt;/code&gt; dice verificado.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Para People Data Labs, la persona está bajo &lt;code&gt;data&lt;/code&gt; dentro del resultado, junto al &lt;code&gt;status&lt;/code&gt; y &lt;code&gt;likelihood&lt;/code&gt; del envelope.&lt;/p&gt;

&lt;h2&gt;
  
  
  Envía feedback y recupera un crédito
&lt;/h2&gt;

&lt;p&gt;Alexandria te paga por feedback. Cada envío reembolsa 1 crédito por cualquier valoración, con un límite por día UTC de 10 créditos por sitio web y 100 por equipo. Tienes 20 minutos desde la última llamada a Alexandria de tu equipo; después de eso recibes &lt;code&gt;FEEDBACK_WINDOW_EXPIRED&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Desde la CLI, ejecuta &lt;code&gt;firecrawl alexandria feedback&lt;/code&gt; (consulta &lt;code&gt;--help&lt;/code&gt; para las opciones). Por MCP, el agente llama a &lt;code&gt;firecrawl_feedback&lt;/code&gt; con &lt;code&gt;endpoint: "alexandria"&lt;/code&gt;. Una línea de prompt funciona bien: "Si un resultado parece incorrecto o vacío, envía feedback a Alexandria describiéndolo."&lt;/p&gt;

&lt;h2&gt;
  
  
  Deja que Claude Code proteja estas llamadas con Apidog CLI
&lt;/h2&gt;

&lt;p&gt;Una vez que un script depende de que &lt;code&gt;people/search&lt;/code&gt; devuelva un &lt;code&gt;id&lt;/code&gt; que &lt;code&gt;people/match&lt;/code&gt; acepte, un campo renombrado lo rompe silenciosamente. Tu agente puede convertir las llamadas de esta guía en un escenario de regresión en &lt;a href="https://apidog.com/apidog-cli/?utm_source=dev.to&amp;amp;utm_medium=wanda&amp;amp;utm_content=n8n-post-automation"&gt;Apidog CLI&lt;/a&gt; y ejecutarlo según una programación. Tú escribes un prompt.&lt;/p&gt;

&lt;p&gt;Configura la CLI y su skill de agente una vez:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npm &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="nt"&gt;-g&lt;/span&gt; apidog-cli@latest
apidog auth login &lt;span class="nt"&gt;--with-token&lt;/span&gt; &amp;lt;YOUR_APIDOG_TOKEN&amp;gt;
npx &lt;span class="nt"&gt;-y&lt;/span&gt; skills add https://apidog.com   &lt;span class="c"&gt;# pick Claude Code or Codex when prompted&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Luego dale a Claude Code este [REDACTED PROMPT]&lt;br&gt;
Write an OpenAPI 3 file for three Firecrawl calls from this guide:&lt;br&gt;
POST /v2/search with sources ["alexandria"], POST /v2/scrape for apollo&lt;br&gt;
people/search (per_page 1), and POST /v2/scrape for apollo people/match.&lt;br&gt;
All send Authorization: Bearer {{FIRECRAWL_API_KEY}}. Import it into Apidog&lt;br&gt;
project  and create a "Firecrawl" environment for&lt;br&gt;
&lt;a href="https://api.firecrawl.dev" rel="noopener noreferrer"&gt;https://api.firecrawl.dev&lt;/a&gt;. Build a test scenario that runs the three in&lt;br&gt;
order, saves data.alexandria[0].data.people[0].id as personId and passes it&lt;br&gt;
to people/match, and asserts status 200, no result error, and a person&lt;br&gt;
object on the match. Run it and summarize failures.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;
El agente lee el esquema de cada payload, lo valida y luego ejecuta comandos como estos:

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;&lt;br&gt;
bash&lt;br&gt;
apidog import --project  --format openapi --file ./firecrawl-people.json&lt;br&gt;
apidog environment create Firecrawl --project  --base-url &lt;a href="https://api.firecrawl.dev" rel="noopener noreferrer"&gt;https://api.firecrawl.dev&lt;/a&gt;&lt;br&gt;
apidog test-scenario create --project  --name "Alexandria people" --folder-id  --priority &lt;br&gt;
apidog cli-schema get test-scenario-update&lt;br&gt;
apidog cli-schema validate test-scenario-update --file ./people-scenario.json&lt;br&gt;
apidog test-scenario update  --project  --file ./people-scenario.json&lt;br&gt;
apidog run -t  --project  -e  \&lt;br&gt;
  --env-var "FIRECRAWL_API_KEY=$FIRECRAWL_API_KEY" -r cli,junit&lt;/p&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;


![Diagram of an Apidog test scenario chaining Firecrawl v2/search, Apollo people/search and Apollo people/match, run by a coding agent with apidog run and producing a test report](https://assets.apidog.com/blog-next/2026/11/firecrawl-alexandria-people-api-apidog-scenario.png)

Cada ejecución completa cuesta 30 créditos por la coincidencia, así que prográmala a diario en lugar de en cada commit. La [referencia de apidog run](https://apidog.com/es/blog/apidog-run-command-reference?utm_source=dev.to&amp;amp;utm_medium=wanda&amp;amp;utm_content=n8n-post-automation) lista las flags de informe e iteración, y [Apidog CLI en Claude Code](https://apidog.com/es/blog/apidog-cli-in-claude-code?utm_source=dev.to&amp;amp;utm_medium=wanda&amp;amp;utm_content=n8n-post-automation) muestra la configuración con más profundidad. El plan Free de Apidog cubre hasta 4 usuarios.

  &lt;iframe src="https://www.youtube.com/embed/UMl4Vo_RwkU" width="710" height="399"&gt;
  &lt;/iframe&gt;


## Preguntas frecuentes

**¿La API de personas de Firecrawl Alexandria es gratis?** El descubrimiento es gratis, y Apollo `people/search` mostraba 0 créditos el 4 de noviembre de 2026. Revelar una persona cuesta créditos: 30 para Apollo `people/match` y 60 para People Data Labs `person/enrich`. El plan Free incluye 1,000 créditos al mes sin tarjeta.

**¿Necesito cuentas separadas de Apollo o People Data Labs?** No. Alexandria ejecuta ambos a través de tu clave de API de Firecrawl y factura en créditos de Firecrawl. Un administrador de la organización sí necesita aceptar los términos de cada proveedor una vez, que es lo que pide `THIRD_PARTY_DATA_TERMS_REQUIRED`.

**¿Por qué mi respuesta de people/match muestra [email_not_unlocked@domain.com](mailto:email_not_unlocked@domain.com)?** Ese es el marcador de posición de Apollo para un correo que no se reveló. Trátalo como no disponible, incluso si `email_status` dice verificado.

**¿Pueden Codex o Cursor ejecutar esto en lugar de Claude Code?** Sí. `npx -y firecrawl-cli@latest init --all` configura cada agente detectado, y las herramientas MCP funcionan en cualquier cliente MCP. Las llamadas de `curl` funcionan sin ningún agente.

**¿Cómo evito pagar por coincidencias incorrectas?** Busca antes de hacer match, haz match por `id` de Apollo en lugar de por nombre, y establece `min_likelihood` en 6 o más en People Data Labs. Apollo no factura un fallo, y un 404 de PDL es gratis.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

</description>
      <category>ai</category>
      <category>api</category>
      <category>automation</category>
      <category>spanish</category>
    </item>
    <item>
      <title>Reseña de FinFeedAPI: API de datos de mercados de predicción multi-exchange</title>
      <dc:creator>Roobia</dc:creator>
      <pubDate>Tue, 03 Nov 2026 10:18:21 +0000</pubDate>
      <link>https://dev.to/roobia/resena-de-finfeedapi-api-de-datos-de-mercados-de-prediccion-multi-exchange-1b72</link>
      <guid>https://dev.to/roobia/resena-de-finfeedapi-api-de-datos-de-mercados-de-prediccion-multi-exchange-1b72</guid>
      <description>&lt;h1&gt;
  
  
  Reseña de FinFeedAPI: API de datos de mercados de predicción multi-exchange
&lt;/h1&gt;

&lt;p&gt;Imagina que quieres seguir cómo el mercado valora un único evento económico en Kalshi, Polymarket y ForecastEx. Sobre el papel, suena como un panel sencillo. En la práctica, implica tres API diferentes, tres formas de identificar el mismo mercado y tres formatos de respuesta que conciliar antes de poder dibujar un solo gráfico.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://apidog.com/?utm_source=dev.to&amp;amp;utm_medium=wanda&amp;amp;utm_content=n8n-post-automation" class="crayons-btn crayons-btn--primary"&gt;Prueba Apidog hoy&lt;/a&gt;
&lt;/p&gt;

&lt;p&gt;Ese problema crece con cada nueva plataforma. Los mercados de predicción ahora abarcan exchanges regulados de EE. UU., protocolos en cadena, comunidades de dinero ficticio y contratos de eventos de plataformas cripto establecidas, y ninguno comparte un modelo de datos común.&lt;/p&gt;

&lt;p&gt;Esta es la brecha que &lt;a href="https://www.finfeedapi.com/" rel="noopener noreferrer"&gt;FinFeedAPI&lt;/a&gt; está diseñada para cubrir. Su API de mercados de predicción reúne nueve plataformas bajo un único esquema estandarizado, para que los desarrolladores puedan consultar mercados, operaciones, libros de órdenes e historial de la misma forma, sin importar de dónde vengan los datos.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fzm93obcjkf26jfx6p5o2.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fzm93obcjkf26jfx6p5o2.png" alt="Mercados de predicción en varias plataformas" width="800" height="544"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Para los desarrolladores, ese crecimiento viene con una verdad incómoda. Cada plataforma expone su propia API, sus propios identificadores de mercado, sus propias convenciones de nombres y su propia idea de cómo es un "mercado". ¿Quieres un panel que siga el mismo evento en tres plataformas? Ahora mantienes tres integraciones, tres modelos de datos y tres conjuntos de casos límite.&lt;/p&gt;

&lt;p&gt;Ese es exactamente el problema que &lt;a href="https://www.finfeedapi.com/products/prediction-markets-api" rel="noopener noreferrer"&gt;FinFeedAPI&lt;/a&gt; intenta resolver.&lt;/p&gt;

&lt;p&gt;En esta reseña, repasaré qué cubre la API de mercados de predicción de FinFeedAPI, qué datos obtienes realmente, cómo se ven los endpoints en la práctica, cuánto cuesta y en qué se queda corta, para que puedas decidir si encaja en tu stack.&lt;/p&gt;

&lt;h2&gt;
  
  
  TL;DR
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;&lt;/th&gt;
&lt;th&gt;&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Proveedor&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;FinFeedAPI de API Bricks (también detrás de CoinAPI)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Plataformas cubiertas&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;9 plataformas de mercados de predicción&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Datos&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Mercados y metadatos, operaciones, cotizaciones, libros de órdenes, OHLCV, archivos planos históricos&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Acceso&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;REST, JSON-RPC, servidor MCP alojado, archivos planos (S3)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Modo&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Datos de mercado de solo lectura, solicitud-respuesta (sin stream WebSocket)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Precios&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Créditos gratis para empezar, luego pago por uso desde $1 por cada 1000 solicitudes&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Ideal para&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Paneles entre plataformas, investigación, backtesting, agentes de IA&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h2&gt;
  
  
  ¿Qué es FinFeedAPI?
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fsvva9f70dre2sl3l613g.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fsvva9f70dre2sl3l613g.png" alt="Qué es FinFeedAPI" width="800" height="582"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://www.finfeedapi.com/" rel="noopener noreferrer"&gt;FinFeedAPI&lt;/a&gt; es un proveedor de datos financieros creado por &lt;strong&gt;API Bricks&lt;/strong&gt;, la misma empresa detrás de CoinAPI. Junto con sus API de acciones, divisas y SEC, ofrece una &lt;strong&gt;API de mercados de predicción&lt;/strong&gt; que te da acceso estandarizado a datos de mercado de nueve plataformas de mercados de predicción mediante una sola integración.&lt;/p&gt;

&lt;p&gt;La idea es sencilla: en lugar de aprender nueve API, aprendes una. Los ID de mercado, los resultados, las marcas de tiempo y las estructuras de respuesta siguen el mismo esquema sin importar de qué plataforma provengan los datos.&lt;/p&gt;

&lt;p&gt;Algunos detalles de ingeniería me llamaron la atención al revisar la documentación:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Modelo de datos unificado&lt;/strong&gt; en todas las plataformas compatibles&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;ID de mercado estandarizados&lt;/strong&gt; que incluyen el resultado, por ejemplo &lt;code&gt;..._YES&lt;/code&gt; y &lt;code&gt;..._NO&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Marcas de tiempo ISO 8601 UTC&lt;/strong&gt; en todos los endpoints&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Precisión numérica consistente&lt;/strong&gt;, de hasta 19 dígitos con 9 decimales&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Cuatro formas de acceso&lt;/strong&gt;: REST, JSON-RPC, un servidor MCP alojado y archivos planos&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Algo que conviene aclarar desde el principio: FinFeedAPI es una &lt;strong&gt;capa de datos de mercado de solo lectura&lt;/strong&gt;. No coloca órdenes. Si tu producto necesita ejecución, seguirás usando la API nativa de cada plataforma para esa parte.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Ffd7z9i9x9mb4hsyl06r1.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Ffd7z9i9x9mb4hsyl06r1.png" alt="Vista general de FinFeedAPI" width="800" height="490"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Plataformas de mercados de predicción compatibles
&lt;/h2&gt;

&lt;p&gt;Actualmente, FinFeedAPI cubre nueve plataformas, que abarcan exchanges regulados, protocolos descentralizados, mercados de resultados en cadena y una comunidad de dinero ficticio.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Plataforma&lt;/th&gt;
&lt;th&gt;Tipo&lt;/th&gt;
&lt;th&gt;Qué cubre&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Polymarket&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Descentralizado&lt;/td&gt;
&lt;td&gt;Política, economía, cripto, deportes y eventos globales&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Kalshi&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Regulado (CFTC)&lt;/td&gt;
&lt;td&gt;Contratos de eventos de EE. UU. sobre indicadores económicos, elecciones, clima, deportes y más&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;ForecastEx&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Regulado (CFTC)&lt;/td&gt;
&lt;td&gt;Contratos de eventos de EE. UU., incluidos resultados económicos y financieros&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Gemini Prediction Markets&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Regulado&lt;/td&gt;
&lt;td&gt;Contratos de eventos sobre deportes, cripto, economía, política y otros temas&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;&lt;a href="https://www.crypto.com/" rel="noopener noreferrer"&gt;Crypto.com&lt;/a&gt; Prediction Markets&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Regulado&lt;/td&gt;
&lt;td&gt;Contratos basados en eventos en la plataforma de mercados de predicción de &lt;a href="https://www.crypto.com/" rel="noopener noreferrer"&gt;Crypto.com&lt;/a&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Myriad&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Descentralizado&lt;/td&gt;
&lt;td&gt;Cripto, eventos de actualidad y otros resultados&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Pascal&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Descentralizado&lt;/td&gt;
&lt;td&gt;Mercados de predicción sin custodia construidos sobre Solana&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Hyperliquid Outcome Markets (HIP-4)&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Mercados de resultados en cadena&lt;/td&gt;
&lt;td&gt;Contratos de eventos binarios y de múltiples resultados sobre la infraestructura nativa de Hyperliquid&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Manifold Markets&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Social, dinero ficticio&lt;/td&gt;
&lt;td&gt;Mercados impulsados por la comunidad sobre una amplia variedad de temas&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;La combinación es lo que hace esto interesante. Comparar cómo una plataforma regulada, una nativa de cripto y una multitud de dinero ficticio valoran el mismo evento es donde la investigación entre plataformas se vuelve valiosa. También es donde un esquema normalizado ahorra más tiempo.&lt;/p&gt;

&lt;h2&gt;
  
  
  ¿A qué datos puedes acceder?
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fpge5l1j10fc4iyrrhsvt.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fpge5l1j10fc4iyrrhsvt.png" alt="Datos disponibles en FinFeedAPI" width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Aquí es donde FinFeedAPI se gana su lugar. La mayoría de las herramientas de mercados de predicción se detienen en el último precio. FinFeedAPI expone el &lt;strong&gt;mercado completo&lt;/strong&gt;, desde el descubrimiento hasta la profundidad del libro de órdenes y el historial.&lt;/p&gt;

&lt;p&gt;Todos los endpoints REST se encuentran bajo &lt;code&gt;https://api.prediction-markets.finfeedapi.com/v1&lt;/code&gt;.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Conjunto de datos&lt;/th&gt;
&lt;th&gt;Endpoint&lt;/th&gt;
&lt;th&gt;Qué obtienes&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Exchanges&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;GET /exchanges&lt;/code&gt; y &lt;code&gt;/exchanges/{exchange_id}&lt;/code&gt;
&lt;/td&gt;
&lt;td&gt;Plataformas compatibles, ID de exchange, descripciones, sitios web&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Mercados activos&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;GET /markets/{exchange_id}/active&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Una lista compacta de ID de mercados actualmente activos&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Listados de mercados&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;GET /markets/{exchange_id}/history&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Registros completos de mercados con paginación basada en cursor: títulos, descripciones, resultados, precios, estado&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Mercado individual&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;GET /markets/{exchange_id}/{market_id}&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Metadatos de un mercado&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Actividad actual&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;GET /activity/{exchange_id}/{market_id}/current&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Última operación más el último bid y ask&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Actividad reciente&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;GET /activity/{exchange_id}/{market_id}/latest&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Operaciones recientes y actualizaciones de cotizaciones&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Operaciones y cotizaciones históricas&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;GET /activity/{exchange_id}/{market_id}/history/trades&lt;/code&gt; y &lt;code&gt;/history/quotes&lt;/code&gt;
&lt;/td&gt;
&lt;td&gt;Registros históricos servidos desde archivos planos&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Libro de órdenes actual&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;GET /orderbook/{exchange_id}/{market_id}/current&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Bids y asks para un resultado de mercado&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Libro de órdenes histórico&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;GET /orderbook/{exchange_id}/{market_id}/history&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Eventos brutos de órdenes limitadas (altas, actualizaciones, eliminaciones) para reconstruir el libro&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;OHLCV&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;GET /ohlcv/periods&lt;/code&gt;, &lt;code&gt;/ohlcv/{exchange_id}/{market_id}/history&lt;/code&gt;, &lt;code&gt;/latest&lt;/code&gt;, &lt;code&gt;/ohlcv/{exchange_id}/history&lt;/code&gt;
&lt;/td&gt;
&lt;td&gt;Velas con apertura, máximo, mínimo, cierre, volumen y número de operaciones&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Algunas cosas que conviene saber:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;El descubrimiento es en dos pasos.&lt;/strong&gt; El endpoint &lt;code&gt;/active&lt;/code&gt; solo devuelve ID, porque se deriva de cotizaciones y operaciones recientes. Para obtener todos los detalles, llama a &lt;code&gt;/history&lt;/code&gt; o al endpoint de mercado individual.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Los periodos OHLCV van desde segundos hasta años&lt;/strong&gt;, y las velas históricas se devuelven en orden temporal ascendente, que es lo que quieres para backtesting.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Los datos históricos del libro de órdenes son a nivel de evento&lt;/strong&gt;, no solo instantáneas. Eso abre la puerta a la reproducción de mercado y la investigación de liquidez.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Los datos de ciclo de vida y resolución&lt;/strong&gt; cubren estados abiertos, cerrados, resueltos y suspendidos, con información de resolución donde la plataforma de origen la admite.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Primeros pasos: tus primeras solicitudes
&lt;/h2&gt;

&lt;p&gt;El registro es rápido. Creas una cuenta gratuita, generas una clave de API desde la consola y empiezas con créditos gratis.&lt;/p&gt;

&lt;p&gt;Para REST y JSON-RPC, pasas la clave en el encabezado &lt;code&gt;Authorization&lt;/code&gt;. La documentación también acepta &lt;code&gt;X-APIKey&lt;/code&gt;, &lt;code&gt;X-APIBricks-Key&lt;/code&gt; y &lt;code&gt;X-CoinAPI-Key&lt;/code&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  1. Lista los exchanges compatibles
&lt;/h3&gt;

&lt;p&gt;Empieza aquí para obtener los valores exactos de &lt;code&gt;exchange_id&lt;/code&gt; que usarás en todo lo demás.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;curl &lt;span class="nt"&gt;-X&lt;/span&gt; GET &lt;span class="s2"&gt;"https://api.prediction-markets.finfeedapi.com/v1/exchanges"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s2"&gt;"[REDACTED CREDENTIAL]
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  2. Descubre mercados activos
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;curl &lt;span class="nt"&gt;-X&lt;/span&gt; GET &lt;span class="s2"&gt;"https://api.prediction-markets.finfeedapi.com/v1/markets/POLYMARKET/active?limit=10"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s2"&gt;"[REDACTED CREDENTIAL]
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Esto devuelve una lista simple de ID de mercado, cada uno con su resultado incorporado:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="s2"&gt;"WILL-TRUMP-SELL-10K-25K-GOLD-CARDS-IN-2025_YES"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="s2"&gt;"WILL-TRUMP-SELL-10K-25K-GOLD-CARDS-IN-2025_NO"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="s2"&gt;"NFL-PIT-CAR-2025-08-21-SPREAD-AWAY-5PT5_YES"&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  3. Obtén la última operación y cotización
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;curl &lt;span class="nt"&gt;-X&lt;/span&gt; GET &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="s2"&gt;"https://api.prediction-markets.finfeedapi.com/v1/activity/POLYMARKET/WILL-TRUMP-SELL-10K-25K-GOLD-CARDS-IN-2025_YES/current"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s2"&gt;"[REDACTED CREDENTIAL]
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;La respuesta te da la última operación junto con el último bid y ask para ese resultado.&lt;/p&gt;

&lt;h3&gt;
  
  
  4. Extrae OHLCV histórico en Python
&lt;/h3&gt;

&lt;p&gt;Esta es la llamada a la que recurriría primero al crear un gráfico de probabilidad o un backtest.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;requests&lt;/span&gt;

&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;REDACTED&lt;/span&gt; &lt;span class="n"&gt;CREDENTIAL&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="n"&gt;BASE&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;https://api.prediction-markets.finfeedapi.com/v1&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
&lt;span class="n"&gt;headers&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{[&lt;/span&gt;&lt;span class="n"&gt;REDACTED&lt;/span&gt; &lt;span class="n"&gt;CREDENTIAL&lt;/span&gt;&lt;span class="p"&gt;]}&lt;/span&gt;

&lt;span class="n"&gt;market_id&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;WILL-TRUMP-SELL-10K-25K-GOLD-CARDS-IN-2025_YES&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;

&lt;span class="n"&gt;resp&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;requests&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;BASE&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt;/ohlcv/POLYMARKET/&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;market_id&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt;/history&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;headers&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;headers&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;params&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;period_id&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;1DAY&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;limit&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;30&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;resp&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;raise_for_status&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

&lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;candle&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;resp&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;json&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt;
    &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;candle&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;time_period_start&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="n"&gt;candle&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;price_close&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="n"&gt;candle&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;volume_traded&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Cada vela incluye &lt;code&gt;time_period_start&lt;/code&gt;, &lt;code&gt;time_period_end&lt;/code&gt;, &lt;code&gt;price_open&lt;/code&gt;, &lt;code&gt;price_high&lt;/code&gt;, &lt;code&gt;price_low&lt;/code&gt;, &lt;code&gt;price_close&lt;/code&gt;, &lt;code&gt;volume_traded&lt;/code&gt; y &lt;code&gt;trades_count&lt;/code&gt;. Llama a &lt;code&gt;/ohlcv/periods&lt;/code&gt; para ver todos los &lt;code&gt;period_id&lt;/code&gt; compatibles.&lt;/p&gt;

&lt;h3&gt;
  
  
  5. Consulta la profundidad del libro de órdenes
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;curl &lt;span class="nt"&gt;-X&lt;/span&gt; GET &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="s2"&gt;"https://api.prediction-markets.finfeedapi.com/v1/orderbook/POLYMARKET/WILL-TRUMP-SELL-10K-25K-GOLD-CARDS-IN-2025_YES/current"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s2"&gt;"[REDACTED CREDENTIAL]
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;La instantánea devuelve &lt;code&gt;exchange_id&lt;/code&gt;, &lt;code&gt;market_id&lt;/code&gt;, &lt;code&gt;time_exchange&lt;/code&gt;, &lt;code&gt;time_coinapi&lt;/code&gt;, además de los arrays &lt;code&gt;bids&lt;/code&gt; y &lt;code&gt;asks&lt;/code&gt;. Eso es suficiente para calcular spreads y desequilibrio en la parte superior del libro.&lt;/p&gt;

&lt;p&gt;Si prefieres no escribir HTTP sin procesar, API Bricks publica SDK oficiales (Python, Node.js, Go, C# y otros) en su &lt;a href="https://github.com/api-bricks/api-bricks-sdk" rel="noopener noreferrer"&gt;repositorio de SDK en GitHub&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Más allá de REST: MCP, JSON-RPC y archivos planos
&lt;/h2&gt;

&lt;p&gt;Cada interfaz expone los mismos conjuntos de datos estandarizados. Tú eliges la que se adapte a tu arquitectura.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Interfaz&lt;/th&gt;
&lt;th&gt;Encabezado de autenticación&lt;/th&gt;
&lt;th&gt;Ideal para&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;API REST&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;Authorization&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Paneles, analítica, aplicaciones en producción&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;API JSON-RPC&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;Authorization&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Servicios que prefieren llamadas estilo RPC sobre los mismos datos&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Servidor MCP alojado&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;X-APIKey&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Asistentes de IA, agentes de programación, flujos de trabajo de investigación&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Archivos planos (S3)&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Credenciales compatibles con S3&lt;/td&gt;
&lt;td&gt;Historial masivo para backtesting y machine learning&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h3&gt;
  
  
  El servidor MCP es lo más destacado
&lt;/h3&gt;

&lt;p&gt;Desde mi perspectiva, esta es la parte más visionaria del producto. En lugar de enseñarle a un agente tu documentación de API, lo apuntas a un endpoint MCP alojado y él descubre las herramientas por sí mismo.&lt;/p&gt;

&lt;p&gt;La configuración son unas pocas líneas en Cursor, Claude Desktop o cualquier cliente compatible con MCP:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"mcpServers"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"FinFeedAPI-Prediction-Markets"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"url"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"https://api.prediction-markets.finfeedapi.com/mcp"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"headers"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="err"&gt;REDACTED&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;CREDENTIAL&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Actualmente, el servidor expone herramientas para:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Descubrimiento de exchanges&lt;/strong&gt;: &lt;code&gt;exchanges_list&lt;/code&gt;, &lt;code&gt;exchanges_get&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Descubrimiento de mercados&lt;/strong&gt;: &lt;code&gt;markets_get_active&lt;/code&gt;, &lt;code&gt;markets_get_history&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Actividad en vivo&lt;/strong&gt;: &lt;code&gt;activity_get_current&lt;/code&gt;, &lt;code&gt;activity_get_latest&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Operaciones y cotizaciones históricas&lt;/strong&gt;: &lt;code&gt;activity_get_trades_history&lt;/code&gt;, &lt;code&gt;activity_get_quotes_history&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;OHLCV&lt;/strong&gt;: &lt;code&gt;ohlcv_list_periods&lt;/code&gt;, &lt;code&gt;ohlcv_get_latest_market&lt;/code&gt;, &lt;code&gt;ohlcv_get_history_market&lt;/code&gt;, &lt;code&gt;ohlcv_get_history_exchange&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Libros de órdenes&lt;/strong&gt;: &lt;code&gt;orderbook_get_current&lt;/code&gt;, &lt;code&gt;orderbook_get_history&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Eso significa que puedes pedirle a un agente algo como "encuentra los mercados de Kalshi más activos y muéstrame cómo se movieron sus probabilidades esta semana" y puede encadenar por su cuenta llamadas de descubrimiento, actividad y OHLCV.&lt;/p&gt;

&lt;p&gt;Una nota si configuras una conexión MCP de FinFeedAPI más antigua: el endpoint pasó de &lt;code&gt;/sse&lt;/code&gt; a &lt;code&gt;/mcp&lt;/code&gt;, así que las configuraciones antiguas deben actualizarse.&lt;/p&gt;

&lt;h3&gt;
  
  
  Archivos planos para historial pesado
&lt;/h3&gt;

&lt;p&gt;Para investigación a gran escala, extraer años de datos mediante llamadas REST paginadas es lento. Los archivos planos te dan operaciones, cotizaciones, libros de órdenes y OHLCV de forma masiva a través de una API compatible con S3, para que puedas usar las herramientas y SDK de S3 que ya conoces.&lt;/p&gt;

&lt;h2&gt;
  
  
  Precios
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fo3ockifchk09k4b7u1x5.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fo3ockifchk09k4b7u1x5.png" alt="Precios de FinFeedAPI" width="800" height="462"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;FinFeedAPI usa &lt;a href="https://www.coinapi.io/products/flat-files/docs/use-cases" rel="noopener noreferrer"&gt;precios basados en el uso&lt;/a&gt; y en créditos. Empiezas con créditos gratis y luego pagas por solicitud.&lt;/p&gt;

&lt;p&gt;En Pago por uso, las &lt;strong&gt;primeras 1000 solicitudes por día cuestan $5 por cada 1000&lt;/strong&gt;, y todo lo que &lt;strong&gt;supere las 1000 por día baja a $1 por cada 1000&lt;/strong&gt;. Los planes comprometidos reducen esa tarifa.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Plan&lt;/th&gt;
&lt;th&gt;Mensual&lt;/th&gt;
&lt;th&gt;Tarifa por crédito&lt;/th&gt;
&lt;th&gt;Extras destacados&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Pago por uso&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Sin compromiso&lt;/td&gt;
&lt;td&gt;$1.00&lt;/td&gt;
&lt;td&gt;Soporte por IA y correo electrónico, registro autoservicio&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Comprometido 64&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;$64&lt;/td&gt;
&lt;td&gt;$0.85&lt;/td&gt;
&lt;td&gt;Registro asistido por IA&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Comprometido 256&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;$256&lt;/td&gt;
&lt;td&gt;$0.75&lt;/td&gt;
&lt;td&gt;Registro asistido por IA&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Comprometido 512&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;$512&lt;/td&gt;
&lt;td&gt;$0.70&lt;/td&gt;
&lt;td&gt;Soporte por Slack, canal de Slack dedicado&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Comprometido 1024&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;$1,024&lt;/td&gt;
&lt;td&gt;$0.65&lt;/td&gt;
&lt;td&gt;SLA de disponibilidad del 99.9%, representante de éxito del cliente, registro con asistencia humana&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Enterprise&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Personalizado&lt;/td&gt;
&lt;td&gt;Personalizado&lt;/td&gt;
&lt;td&gt;SLA personalizados, optimizaciones de latencia, infraestructura dedicada&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Los planes comprometidos no reducen lo que usas. Te dan más créditos por el mismo gasto, y una vez que se agotan esos créditos, el uso adicional se factura a la tarifa de Pago por uso. También hay facturación anual disponible.&lt;/p&gt;

&lt;p&gt;Mi opinión: para prototipos e investigación, Pago por uso está bien. Si consultas muchos mercados cada pocos segundos, calcula primero los números. FinFeedAPI publica &lt;a href="https://www.finfeedapi.com/products/prediction-markets-api/docs/use-cases" rel="noopener noreferrer"&gt;casos de uso de precios&lt;/a&gt; para paneles, monitoreo de libros de órdenes y rellenos históricos OHLCV que hacen que estimar sea mucho más fácil.&lt;/p&gt;

&lt;h2&gt;
  
  
  Dónde se queda corta FinFeedAPI
&lt;/h2&gt;

&lt;p&gt;Ninguna API es perfecta, y una reseña que omite las desventajas no sirve de mucho. Esto es lo que debes tener en cuenta:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Sin ejecución de órdenes.&lt;/strong&gt; Es solo una capa de datos. Los bots de trading aún necesitan las API nativas de las plataformas para colocar órdenes.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Sin stream WebSocket para mercados de predicción.&lt;/strong&gt; Los datos actuales llegan mediante llamadas de solicitud-respuesta, así que "en vivo" significa polling. Para estrategias sensibles a la latencia, eso es una restricción real, y el polling frecuente aumenta tu factura.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Las primeras 1000 solicitudes diarias son las más caras.&lt;/strong&gt; A $5 por cada 1000 frente a $1 por cada 1000 después, los proyectos muy pequeños pagan una tarifa efectiva más alta que los que tienen mucho tráfico.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Los datos de resolución dependen de la fuente.&lt;/strong&gt; Los detalles del ciclo de vida y la resolución son tan completos como lo que expone cada plataforma.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;La normalización es un compromiso.&lt;/strong&gt; Un esquema unificado es el objetivo, pero si dependes de un campo único de una plataforma, revisa las &lt;a href="https://www.finfeedapi.com/products/prediction-markets-api/data-samples" rel="noopener noreferrer"&gt;muestras de datos&lt;/a&gt; antes de comprometerte.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Ninguna de estas es un impedimento para casos de uso de analítica, investigación o IA. Importan más si estás construyendo un sistema de trading de alta frecuencia.&lt;/p&gt;

&lt;h2&gt;
  
  
  ¿Quién debería usar FinFeedAPI?
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Puntos fuertes
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Nueve plataformas de mercados de predicción tras un solo esquema&lt;/li&gt;
&lt;li&gt;Ciclo de vida completo del mercado: descubrimiento, operaciones, cotizaciones, libros de órdenes, OHLCV, historial&lt;/li&gt;
&lt;li&gt;Datos históricos del libro de órdenes a nivel de evento para reproducción&lt;/li&gt;
&lt;li&gt;Servidor MCP alojado que funciona con Cursor y Claude Desktop&lt;/li&gt;
&lt;li&gt;Archivos planos masivos para investigación y machine learning&lt;/li&gt;
&lt;li&gt;Precios basados en uso con créditos gratis para empezar&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Ideal para
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Paneles multiplataforma&lt;/strong&gt; que comparan probabilidades entre plataformas&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Investigadores y analistas cuantitativos&lt;/strong&gt; que hacen backtesting de estrategias de mercados de predicción&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Equipos de pronóstico y ML&lt;/strong&gt; que necesitan OHLCV histórico limpio&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Analítica de liquidez&lt;/strong&gt; basada en la profundidad del libro de órdenes y los spreads&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Equipos de IA&lt;/strong&gt; que crean agentes que razonan sobre eventos del mundo real&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Investigación académica y económica&lt;/strong&gt; sobre cómo las multitudes valoran los resultados&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Probablemente no para
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Bots que necesitan &lt;strong&gt;colocar órdenes&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;Estrategias que necesitan un &lt;strong&gt;stream push de subsegundo&lt;/strong&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Reflexiones finales
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F4u3xbq2jn0meuy6k7l3l.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F4u3xbq2jn0meuy6k7l3l.png" alt="Reflexiones finales sobre FinFeedAPI" width="800" height="466"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Los mercados de predicción crecen más rápido de lo que la mayoría de los equipos puede integrarlos. Cada nueva plataforma trae nuevos identificadores, nuevos formatos y nuevo trabajo de mantenimiento.&lt;/p&gt;

&lt;p&gt;FinFeedAPI no intenta ser un exchange. Se centra en una sola tarea: convertir nueve plataformas fragmentadas en una capa de datos consistente. Mercados, operaciones, cotizaciones, libros de órdenes, OHLCV e historial profundo vuelven todos con la misma forma, a través de REST, JSON-RPC, MCP o archivos planos.&lt;/p&gt;

&lt;p&gt;Ten en cuenta desde el principio que es de solo lectura y de solicitud-respuesta, y encaja en una amplia variedad de productos, desde paneles de pronóstico hasta agentes de investigación con IA.&lt;/p&gt;

&lt;p&gt;Nueve plataformas. Un esquema. Una clave de API. Menos fontanería, más construcción.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Sitio web:&lt;/strong&gt; &lt;a href="https://www.finfeedapi.com/products/prediction-markets-api" rel="noopener noreferrer"&gt;finfeedapi.com/products/prediction-markets-api&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Documentación de la API:&lt;/strong&gt; &lt;a href="https://www.finfeedapi.com/products/prediction-markets-api/docs/rest-api" rel="noopener noreferrer"&gt;Documentación de la API REST de mercados de predicción&lt;/a&gt;&lt;/p&gt;

</description>
    </item>
  </channel>
</rss>
