GET /v1/eol/products
The EOL catalog lists all products referenced in TechWatchAlert with their version cycles and end-of-life dates. This data is independent of your projects — it is the global reference base.
List Products
Section titled “List Products”GET /api/v1/eol/productsAuthorization: Bearer twa_your_key_hereQuery Parameters
Section titled “Query Parameters”| Parameter | Type | Default | Description |
|---|---|---|---|
q | string | — | Text search on product ID and name |
page | integer ≥ 1 | 1 | Page number |
page_size | integer 1–100 | 20 | Products per page |
Response 200 OK
Section titled “Response 200 OK”{ "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}Fields
Section titled “Fields”| Field | Type | Description |
|---|---|---|
items | array | Products on the current page |
total | integer | Total products in the catalog |
page | integer | Current page |
page_size | integer | Page size used |
items[].id | string | Technical product identifier (e.g. nodejs, ubuntu, spring-boot) — use in other endpoints |
items[].name | string | Human-readable name |
items[].description | string | null | Short description |
Product Life Cycles
Section titled “Product Life Cycles”GET /api/v1/eol/products/{product_id}/cyclesAuthorization: Bearer twa_your_key_herePath Parameters
Section titled “Path Parameters”| Parameter | Type | Description |
|---|---|---|
product_id | string | Product identifier (e.g. nodejs, ubuntu) |
Response 200 OK
Section titled “Response 200 OK”{ "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" } ]}Fields — Cycle
Section titled “Fields — Cycle”| Field | Type | Description |
|---|---|---|
cycle | string | Version identifier (e.g. "18", "22.04 LTS") |
release_date | string (YYYY-MM-DD) | null | Initial release date |
eol | string (YYYY-MM-DD) | boolean | null | End-of-life: ISO date, false (not yet EOL), true (already EOL without precise date), or null (unknown) |
lts | string (YYYY-MM-DD) | boolean | null | LTS support start (same logic as eol) |
support | string (YYYY-MM-DD) | boolean | null | Active support end (same logic) |
latest | string | null | Latest release in this cycle |
link | string | null | Official release notes URL |
Interpreting date/boolean fields
Section titled “Interpreting date/boolean fields”The eol, lts, and support fields can take three forms:
| Value | Meaning |
|---|---|
"2025-04-30" | Known precise date |
true | Status reached but without a precise date |
false | Status not yet reached |
null | Information unavailable |
Errors
Section titled “Errors”| Code | Detail | Cause |
|---|---|---|
404 | Produit introuvable | product_id does not exist in the catalog |
Examples
Section titled “Examples”Search for all “python” products
curl -s \ -H "Authorization: Bearer twa_your_key_here" \ "https://app.techwatchalert.com/api/v1/eol/products?q=python" \ | jq '.items[] | {id, name}'Get active Python cycles (not yet EOL)
curl -s \ -H "Authorization: Bearer twa_your_key_here" \ "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}'Full EOL dashboard for your stack
import httpxfrom datetime import date
BASE = "https://app.techwatchalert.com/api/v1"headers = {"Authorization": "Bearer twa_your_key_here"}project_id = "018e1234-abcd-7000-8000-000000000010"
subs = httpx.get(f"{BASE}/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({ "product": detail["name"], "version": sub["cycle"], "EOL": str(eol_date) if eol_date else ("reached" if eol is True else "N/A"), "days_left": days_left, "latest": cycle_data.get("latest"), })
rows.sort(key=lambda r: r["days_left"] if r["days_left"] is not None else 9999)
for r in rows: status = f"⚠ {r['days_left']}d" if r["days_left"] and r["days_left"] < 90 else r["EOL"] print(f"{r['product']:20} {r['version']:10} EOL: {status:15} latest: {r['latest']}")