Aller au contenu

GET /v1/eol/products

Le catalogue EOL liste tous les produits référencés dans TechWatchAlert avec leurs cycles de version et dates de fin de vie. Ces données sont indépendantes de vos projets — c’est la base de référence globale.


GET /api/v1/eol/products
Authorization: Bearer twa_votre_cle_ici
Paramètre Type Défaut Description
q string — Recherche textuelle sur l’identifiant et le nom du produit
page integer ≥ 1 1 Numéro de page
page_size integer 1–100 20 Nombre de produits par page
{
"items": [
{
"id": "nodejs",
"name": "Node.js",
"description": "Node.js is a JavaScript runtime built on Chrome's V8 engine"
},
{
"id": "postgresql",
"name": "PostgreSQL",
"description": "PostgreSQL is an advanced, enterprise-class open-source relational database"
}
],
"total": 312,
"page": 1,
"page_size": 20
}
Champ Type Description
items array Produits de la page courante
total integer Nombre total de produits dans le catalogue
page integer Page courante
page_size integer Taille de page utilisée
items[].id string Identifiant technique du produit (ex : nodejs, ubuntu, spring-boot) — à utiliser dans les autres endpoints
items[].name string Nom lisible
items[].description string | null Description courte

GET /api/v1/eol/products/{product_id}/cycles
Authorization: Bearer twa_votre_cle_ici
Paramètre Type Description
product_id string Identifiant du produit (ex : nodejs, ubuntu)
{
"id": "nodejs",
"name": "Node.js",
"description": "Node.js is a JavaScript runtime built on Chrome's V8 engine",
"cycles": [
{
"cycle": "22",
"release_date": "2024-04-24",
"eol": "2027-04-30",
"lts": "2024-10-29",
"support": null,
"latest": "22.9.0",
"link": "https://nodejs.org/en/blog/release/v22.0.0"
},
{
"cycle": "20",
"release_date": "2023-04-18",
"eol": "2026-04-30",
"lts": "2023-10-24",
"support": null,
"latest": "20.18.0",
"link": "https://nodejs.org/en/blog/release/v20.0.0"
},
{
"cycle": "18",
"release_date": "2022-04-19",
"eol": "2025-04-30",
"lts": "2022-10-25",
"support": null,
"latest": "18.20.4",
"link": "https://nodejs.org/en/blog/release/v18.0.0"
}
]
}
Champ Type Description
cycle string Identifiant de la version (ex : "18", "22.04 LTS")
release_date string (YYYY-MM-DD) | null Date de sortie initiale
eol string (YYYY-MM-DD) | boolean | null Fin de vie : date ISO, false (pas encore en EOL), true (déjà en EOL sans date précise), ou null (inconnu)
lts string (YYYY-MM-DD) | boolean | null Début du support LTS (même logique que eol)
support string (YYYY-MM-DD) | boolean | null Fin du support actif (même logique)
latest string | null Dernière version dans ce cycle
link string | null URL de la release notes officielle

Les champs eol, lts et support peuvent avoir trois formes :

Valeur Signification
"2025-04-30" Date précise connue
true Statut atteint mais sans date précise
false Statut non encore atteint
null Information non disponible
Code Détail Cause
404 Produit introuvable product_id inexistant dans le catalogue

Rechercher tous les produits “python”

Fenêtre de terminal
curl -s \
-H "Authorization: Bearer twa_votre_cle_ici" \
"https://app.techwatchalert.com/api/v1/eol/products?q=python" \
| jq '.items[] | {id, name}'

Obtenir les cycles actifs de Python (non encore en EOL)

Fenêtre de terminal
curl -s \
-H "Authorization: Bearer twa_votre_cle_ici" \
"https://app.techwatchalert.com/api/v1/eol/products/python/cycles" \
| jq '.cycles[] | select(.eol != true and (.eol == false or (.eol | type) == "string")) | {version: .cycle, eol: .eol, latest: .latest}'

Tableau de bord EOL complet de votre stack

import httpx
from datetime import date
BASE = "https://app.techwatchalert.com/api/v1"
headers = {"Authorization": "Bearer twa_votre_cle_ici"}
org_id = "018e5678-abcd-7000-8000-000000000001"
project_id = "018e1234-abcd-7000-8000-000000000010"
# Abonnements du projet
subs = httpx.get(f"{BASE}/organizations/{org_id}/projects/{project_id}/eol", headers=headers).json()
today = date.today()
rows = []
for sub in subs:
if sub["cycle"] is None:
continue
detail = httpx.get(f"{BASE}/eol/products/{sub['product_id']}/cycles", headers=headers).json()
cycle_data = next((c for c in detail["cycles"] if c["cycle"] == sub["cycle"]), None)
if not cycle_data:
continue
eol = cycle_data.get("eol")
eol_date = date.fromisoformat(eol) if isinstance(eol, str) else None
days_left = (eol_date - today).days if eol_date else None
rows.append({
"produit": detail["name"],
"version": sub["cycle"],
"EOL": str(eol_date) if eol_date else ("déjà" if eol is True else "N/A"),
"jours_restants": days_left,
"latest": cycle_data.get("latest"),
})
rows.sort(key=lambda r: r["jours_restants"] if r["jours_restants"] is not None else 9999)
for r in rows:
status = f"⚠ {r['jours_restants']}j" if r["jours_restants"] and r["jours_restants"] < 90 else r["EOL"]
print(f"{r['produit']:20} {r['version']:10} EOL: {status:15} latest: {r['latest']}")