Objetivo

Leer el corpus del changelog gestionado (docs/releases/*.yaml) sobre HTTP para renderizar tu propia página de release notes, mover un bot de CI o sincronizar entradas en un CRM. El endpoint sirve los mismos datos que consume el widget del docs-site.

Prerrequisitos

Ninguno — el endpoint sirve entradas de audiencia public a llamadores anónimos. Autentícate con sesión cookie + permiso docs:read para recibir también las entradas audience=admin.

Pasos

1. Listar las últimas entradas

curl -X GET 'https://api.example.com/v1/public/changelog?lang=es&limit=25'

Respuesta (200):

{
  "data": [
    {
      "id": "url-convention",
      "schema_version": 1,
      "release_version": "1.49.6",
      "audience": ["public"],
      "category": "breaking",
      "severity": "medium",
      "breaking": true,
      "title": {
        "es": "Convención de URL formalizada + 13 paths movidos",
        "en": "URL convention formalized + 13 path moves"
      },
      "summary": { "es": "...", "en": "..." },
      "permalink": "/changelog/v1.49.6/url-convention",
      "tags": ["api", "openapi", "routes"]
    }
  ],
  "meta": {
    "pagination": {
      "total": 1,
      "limit": 25,
      "has_more": false,
      "next_cursor": null
    },
    "audience": "public",
    "lang": "es"
  }
}

2. Filtrar por categoría, rango de fechas o idioma

ParámetroDescripción
langen o es. Los campos bilingües se reducen al locale solicitado.
audiencepublic (default para anon) o admin (requiere cookie + docs:read).
categoryfeat, fix, breaking, deprecation, security, docs, infra, refactor.
since / untilLímites ISO 8601 (filtra por published_at del release).
limit1–100, default 25.
cursorCursor opaco base64 de meta.pagination.next_cursor.
includesummary (default) o body (añade Markdown crudo).
# Solo cambios breaking desde el inicio del año
curl 'https://api.example.com/v1/public/changelog?category=breaking&since=2026-01-01T00:00:00Z'

3. Paginar

La respuesta incluye meta.pagination.next_cursor. Pásalo como ?cursor=… en el siguiente request para obtener la siguiente página. El cursor es opaco (internamente JSON base64) — no lo parsees client-side.

curl 'https://api.example.com/v1/public/changelog?limit=10&cursor=eyJyZWxlYXNlX3ZlcnNpb24iOiIxLjQ3LjEi…'

4. Negociación ETag

El endpoint devuelve un header ETag débil. Envíalo de vuelta como If-None-Match en un request posterior para recibir 304 Not Modified sin cuerpo cuando el corpus no haya cambiado:

curl -H 'If-None-Match: W/"a1b2c3d4"' \
     'https://api.example.com/v1/public/changelog'

Úsalo para polling ligero sin redescargar el payload cada ciclo.

Errores

EstadoCódigoCausa
400invalid_cursorCursor mal formado (truncado o alterado).
400invalid_since / invalid_untilParámetro fecha no es ISO 8601.
401unauthorizedPediste audience=admin sin auth por cookie.
403forbiddenCookie presente pero sin permiso docs:read.
429rate_limitedPolling demasiado agresivo.

Notas

  • Las entradas con embargo (embargo_until en el futuro) se excluyen para requests anónimos y de audiencia public. Los admin las ven.
  • Las entradas no publicadas (published_at: null) se excluyen para requests de audiencia public. Los admin las ven.
  • Ver ADR-0090 (Convención de URL) para el razonamiento detrás del namespace /v1/public/*.

Nuevo en v1.49.6 — ver ADR-0090.