eol.network API

v1 · REST · JSON · one tier, currently free

TL;DR

  1. Register, verify your email.
  2. Mint an API key from /account. You see the plaintext once. Keep it.
  3. Send it as Authorization: Bearer <key> or X-API-Key: <key>.
  4. Hit the endpoints below. JSON in, JSON out. 60 req/min, 5000/day.

Authentication

Every /api/v1/* call needs a key. No key → 401 missing_key. Revoked or bogus key → 401 invalid_key. Unverified email → 403 email_unverified.

curl -H "Authorization: Bearer eol_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" \
     https://eol.network/api/v1/vendors

Keys never expire. Rotate them yourself if one leaks — revoke the old key in /account and mint a new one. I don't do automatic rotation, you're adults.

Rate limits

If you actually need more, tell me what you're building. Paid tiers may happen; probably not.

Response shape

All success responses are { "data": ..., "meta": { ... } }. Errors are { "error": { "code": "...", "message": "..." } }. The code field is stable; branch on it, not on the message text.

Endpoints

GET/api/v1/vendors

All vendors, with product count + last generated timestamp.

GET /api/v1/vendors

{
  "data": [
    { "slug": "juniper",   "name": "Juniper",   "count": 3519, "generated_at": "2026-04-14T02:37:16Z", ... },
    { "slug": "arista",    "name": "Arista",    "count": 736,  ... },
    ...
  ]
}

GET/api/v1/vendors/{vendor}

Vendor summary: series list, product-type counts, lifecycle-status breakdown.

GET/api/v1/vendors/{vendor}/products

Paginated product list. Default per_page=100, max 500.

QueryValuesNotes
typechassis, optic, appliance, line-card, …exact match on product_type
seriese.g. MX, EX, 7280r3case-insensitive, matches any of applicable_series
statusactive, announced, eos, eollifecycle_status derived from dates
pageint ≥ 11-indexed
per_page1 – 500default 100
GET /api/v1/vendors/juniper/products?type=chassis&per_page=3

{
  "data": [
    {
      "product_id": "MX480",
      "product_name": "MX480 Universal Routing Platform",
      "product_type": "chassis",
      "applicable_series": ["MX"],
      "lifecycle_status": "announced",
      "end_of_sale_date": "2028-12-31",
      "last_date_of_support": "2033-12-31",
      ...
    },
    ...
  ],
  "meta": { "total": 147, "page": 1, "per_page": 3 }
}

GET/api/v1/vendors/{vendor}/products/{product_id}

Single product. product_id is URL-path-encoded and may contain slashes (route captures the rest of the path).

Returns 404 product not found for unknown IDs.

GET/api/v1/search?q=...

SKU / model / name fuzzy search across all vendors. Minimum 2-char query. Optional vendor= to scope.

GET /api/v1/search?q=MX480

{
  "data": [
    { "vendor_slug": "juniper", "product_id": "MX480", "product_name": "...", "end_of_sale_date": "..." },
    ...
  ],
  "meta": { "total": 4 }
}

GET/api/v1/lifecycle/upcoming

What's about to go bad inside a window. Useful for cron-driven asset-refresh reminders.

QueryValuesDefault
kindany, eos, eol, eoswany
within7d, 30d, 90d, 180d, 365d90d
vendorslug(all vendors)
GET /api/v1/lifecycle/upcoming?kind=eos&within=90d&vendor=arista

{
  "data": [
    {
      "vendor_slug": "arista",
      "vendor_name": "Arista",
      "product_id": "DCS-7280QR-C36",
      "product_name": "...",
      "product_type": "chassis",
      "milestone": "eos",
      "date": "2026-05-01"
    },
    ...
  ],
  "meta": { "total": 17, "within": "90d", "kind": "eos" }
}

GET/api/v1/events?year=&month=

All lifecycle events in a calendar month. Same data that powers /calendar.

Fields you'll see on a product

product_idVendor SKU / part number. Stable URL key.
product_nameShort human-recognizable model / display name.
applicable_seriesArray of series slugs for grouping (MX, 7280r3, PA-5200…).
product_typechassis, line-card, optic, appliance, fan, power-supply, software-license, …
categoryDerived from type (never stored independently).
end_of_sale_dateEOS. Last day the vendor will take a PO for the SKU.
end_of_software_support_dateEOSW. Last software / security updates.
last_date_of_supportEOL. Last day of any hardware support contract.
replacement_productVendor-suggested successor SKU, if published.
lifecycle_statusactive | announced | eos | eol — derived from the above against today.
extraVendor-specific extras (notes, disclaimers, series-level metadata).

What this API won't give you

Errors you'll see

HTTPerror.codeMeaning
401missing_keyNo Authorization header or X-API-Key.
401invalid_keyKey not recognized or revoked.
403email_unverifiedUser hasn't clicked the verify link yet.
403user_inactiveAccount disabled.
404Vendor or product not found.
400bad_within / bad_kindParameter out of the allowed set.
429rate_limit_minuteBack off for 60s.
429quota_exhaustedDaily quota gone. Resets 00:00 UTC.
503db_unavailableDatabase pool not ready. Retry.

Etiquette

Ready? Register → verify email → mint a key → go.
↑ Top