API de Hacker News: cómo armar tu propio lector

API de Hacker News: cómo armar tu propio lector

@programacion

Lo esencial

  • La API de Hacker News es gratuita, sin clave ni registro, y vive en hacker-news.firebaseio.com/v0.
  • Expone 10 endpoints: item, user, maxitem, topstories, newstories, beststories, askstories, showstories, jobstories y updates.
  • Cada historia se consulta como item/<id>.json; las listas devuelven arreglos de ids, no los objetos completos.
  • La API de Algolia (hn.algolia.com/api) agrega búsqueda de texto completo que Firebase no ofrece.
  • Hacker Times, un proyecto reciente mostrado en Show HN, usa esta misma API para armar un diseño tipo periódico con ediciones por hora.

Qué es la API de Hacker News

Armar un lector propio de Hacker News no exige pedir una clave ni registrarse en ningún formulario. Alcanza con hacer peticiones GET contra un dominio de Firebase, sin autenticación ni cuotas visibles de por medio.

Y Combinator mantiene esta API pública desde 2014, documentada en el repositorio oficial en GitHub. Es la misma fuente de datos que usa la web oficial de Hacker News para pintar su portada.

Un ejemplo reciente de hasta dónde llega esto es Hacker Times, un proyecto que se presentó en un Show HN y que toma las mismas historias de la API para mostrarlas con maquetación de periódico y ediciones que se actualizan cada hora. Si ese formato se puede construir encima de la API pública, cualquier desarrollador puede armar su propia versión con otros criterios de filtrado.

Los 10 endpoints que necesitás conocer

Todos los endpoints cuelgan de la misma base: https://hacker-news.firebaseio.com/v0/. A partir de ahí hay dos familias: las que devuelven un listado de ids y las que devuelven un objeto completo.

  • topstories.json: hasta 500 ids de las historias en portada, ordenadas por ranking.
  • newstories.json: las últimas historias enviadas, sin filtrar por puntaje.
  • beststories.json: las historias con mejor puntaje de un período reciente.
  • askstories.json, showstories.json y jobstories.json: los ids de cada sección (Ask HN, Show HN y empleos).
  • item/<id>.json: el objeto completo de una historia, comentario, poll o job.
  • user/<id>.json: perfil público de un usuario, con la lista de ids que envió.
  • maxitem.json: el id más alto registrado hasta el momento, útil para recorrer todo el histórico.
  • updates.json: ids de items y perfiles que cambiaron recientemente, para detectar ediciones.

Ninguno de estos endpoints acepta parámetros de filtro. Si querés historias de una fecha concreta o con cierta palabra en el título, el filtrado corre por tu cuenta, después de descargar los objetos.

Anatomía de un ítem: los campos del JSON

Cada objeto que devuelve item/<id>.json trae un campo type (story, comment, job, poll o pollopt), un by con el usuario que lo envió y un time en formato unix timestamp. Las historias suman title, url, score y descendants (cantidad total de comentarios, contando respuestas anidadas).

El campo kids trae los ids de los comentarios directos, en el orden en que Hacker News los muestra, que no siempre coincide con el orden cronológico. Este es el objeto real que devuelve la API para la historia original de Dropbox en Y Combinator:

{
"by": "dhouston",
"descendants": 71,
"id": 8863,
"kids": [8952, 9224, 8917, 8884],
"score": 111,
"time": 1175714200,
"title": "My YC app: Dropbox - Throw away your USB drive",
"type": "story",
"url": "http://www.getdropbox.com/u/2/screencast.html"
}

Para leer los comentarios hay que repetir la misma llamada sobre cada id de kids: un comentario es, para la API, un ítem igual que una historia, solo que con type igual a comment y un campo parent en vez de url.

Construir un lector mínimo en JavaScript

Un lector básico necesita dos pasos: pedir la lista de ids y después pedir cada ítem por separado. Así se ve con fetch nativo en Node.js:

const BASE_URL = 'https://hacker-news.firebaseio.com/v0';

async function obtenerHistoriasTop(minPuntaje = 100, limite = 10) {
const idsResponse = await fetch(`${BASE_URL}/topstories.json`);
const ids = await idsResponse.json();

const historias = [];
for (const id of ids.slice(0, 50)) {
const itemResponse = await fetch(`${BASE_URL}/item/${id}.json`);
const item = await itemResponse.json();
if (item && item.score >= minPuntaje) {
historias.push(item);
}
if (historias.length >= limite) break;
}
return historias;
}

obtenerHistoriasTop(150, 5).then(console.log);

Esta función recorre los primeros 50 ids de portada, pide cada ítem y se queda solo con los que superan 150 puntos, hasta reunir 5 historias. El resultado es un arreglo de objetos listos para renderizar en una lista o en una tabla.

El problema es la velocidad: 50 llamadas secuenciales a item/<id>.json tardan varios segundos porque cada una espera a la anterior. Agrupar las peticiones con Promise.all en lotes de 10 o 15 reduce el tiempo total sin abrir cientos de conexiones de golpe.

Filtrar y rankear tu propio feed

La gracia de armar tu lector es aplicar criterios que el sitio oficial no ofrece. Por ejemplo, descartar historias cuyo dominio ya viste, o priorizar las que tienen más comentarios por punto de score (señal de debate activo, no solo de voto rápido).

function filtrarPorRelevancia(historias, dominiosVistos) {
return historias
.filter((h) => h.url && !dominiosVistos.has(new URL(h.url).hostname))
.sort((a, b) => (b.descendants / b.score) - (a.descendants / a.score));
}

Ese ratio comentarios/score es una heurística simple para separar historias que generan discusión real de las que solo acumulan votos. No viene calculado en la API: hay que armarlo con los campos score y descendants que ya trae cada ítem.

Cuando Firebase no alcanza: la búsqueda de Algolia

La API de Firebase no tiene búsqueda por palabra clave. Para eso existe una segunda API, mantenida por Algolia, que indexa todo el histórico de Hacker News y sí permite buscar texto completo:

curl "https://hn.algolia.com/api/v1/search?query=rust&tags=story"

El parámetro tags filtra por tipo (story, comment, poll, show_hn, ask_hn) y se puede combinar con numericFilters para acotar por fecha o por puntaje mínimo. La documentación completa está en hn.algolia.com/api, también gratuita y sin clave.

Límites y cosas que la API no te dice

Firebase no documenta un rate limit explícito: abrís demasiadas conexiones en paralelo y empieza a demorar las respuestas en lugar de devolver un error claro. Por eso conviene limitar la concurrencia desde el cliente, no confiar en que el servidor te va a avisar.

Tampoco hay un endpoint para pedir historias de un usuario filtradas por fecha: user/<id>.json devuelve todos los ids que envió, sin paginar, y hay que cruzarlos uno por uno con item para saber cuándo se publicó cada uno. Y no existen webhooks: enterarte de historias nuevas significa hacer polling sobre newstories.json o updates.json cada cierto tiempo.

Conclusión

La API de Hacker News no tiene nada exótico: es JSON plano sobre HTTP, sin clave y con una curva de aprendizaje de minutos. Lo que cambia es qué hacés con esos datos una vez que los tenés en tu código: un filtro por tema, un ranking propio o, como hizo Hacker Times, un formato de lectura completamente distinto al del sitio original.

📖 Versión extendida con más detalle: https://elsolitario.org/2026/11/03/api-de-hacker-news-como-armar-tu-lector/?utm_source=telegraph&utm_medium=instant_view&utm_campaign=programacion

Report Page