endoflife.ai Batch API

The Batch API from endoflife.ai — 1 operation(s) for batch.

GitHub OpenAPI

Operations 1

POST /v1/batch Score multiple products in one request #

Work with this as data

Every API here is available over the APIs.io API and to AI agents over MCP.

MCP server

One button, every client — Claude, Cursor, VS Code and the rest.

https://apis.io/mcp

Tools for apis

7 MCP tools reach this
  • find_apisBrowse and filter every API in the catalog.
  • get_api_artifactsOne API's artifacts, grouped by type.
  • get_openapiThe primary OpenAPI for this API.
  • find_similar_apisAPIs that look like this one.
  • apis_io_searchSTART HERE — APIs, providers and tags for one query, each with its total.
  • resolveTurn a domain, URL or GitHub org into the provider it belongs to.
  • find_cohortsEvery scored population of providers in the catalog.
All 92 tools →

Call it yourself

curl for this page
This API
curl "https://apis.io/api/v1/apis/endoflife-ai:endoflife-ai-batch-api"
All apis
curl "https://apis.io/api/v1/apis?limit=25"

Calls without X-API-Key need no key. Calls with it need a paid plan — get a key.

Get an API key

Free tier, no form to fill in. Signing in shares your email address with us — we store it to create your key and to recognise you if you sign in with another provider. See our Privacy Policy and Terms.

A second provider on the same verified email joins the account you already have.

OpenAPI Specification

endoflife-ai-batch-api-openapi.yml Raw ↑
openapi: 3.2.0
info:
  title: Endoflife Ai Batch API
  version: 1.4.0
  contact:
    email: partners@endoflife.ai
    url: https://endoflife.ai/api
  description: 'Operations tagged Batch across 2 of this provider''s published API definitions: openapi.json, endoflife-ai-openapi.json. Each path carries the servers of the definition it was published in.'
servers:
- url: https://api.endoflife.ai
security:
- {}
- ApiKeyAuth: []
- BearerAuth: []
tags:
- name: Batch
paths:
  /v1/batch:
    post:
      summary: Score multiple products in one request
      description: 'Batch limits per request: anonymous 3, free key 5, Starter 25, Pro 50 products. Each item is {slug, version?} or {purl} (a package URL such as pkg:npm/webpack@5.110.3; resolved exactly via purl-map.json, version taken from the purl unless given). Items that do not resolve come back in results with an error field; one failing item never fails the request.'
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                products:
                  type: array
                  items:
                    $ref: '#/components/schemas/BatchItem'
              required:
              - products
      responses:
        '200':
          description: Score objects in request order
          headers:
            X-RateLimit-Limit:
              $ref: '#/components/headers/X-RateLimit-Limit'
            X-RateLimit-Remaining:
              $ref: '#/components/headers/X-RateLimit-Remaining'
            X-RateLimit-Reset:
              $ref: '#/components/headers/X-RateLimit-Reset'
            X-EOL-Key-Status:
              $ref: '#/components/headers/X-EOL-Key-Status'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/BatchResponse'
        '400':
          description: Invalid JSON, no products array, or (Pro) more items than the cap
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '401':
          description: No valid X-API-Key, from 2026-11-16T00:00:00Z (keyless access ends then). The body says how to get a free key (https://endoflife.ai/api#free-key); X-EOL-Key-Status names why a sent key was not honoured.
          headers:
            X-EOL-Key-Status:
              $ref: '#/components/headers/X-EOL-Key-Status'
            WWW-Authenticate:
              schema:
                type: string
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '403':
          description: More items than the caller's tier allows (anonymous, free, Starter)
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '413':
          description: Body larger than the 5 MB cap
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '429':
          description: Daily quota exhausted for this tier (anonymous per IP, keyed per key). Retry-After says when the counter resets (next UTC midnight).
          headers:
            X-RateLimit-Limit:
              $ref: '#/components/headers/X-RateLimit-Limit'
            X-RateLimit-Remaining:
              $ref: '#/components/headers/X-RateLimit-Remaining'
            X-RateLimit-Reset:
              $ref: '#/components/headers/X-RateLimit-Reset'
            X-EOL-Key-Status:
              $ref: '#/components/headers/X-EOL-Key-Status'
            Retry-After:
              schema:
                type: integer
              description: Seconds until the daily counter resets
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
      tags:
      - Batch
      operationId: postV1Batch
      x-operation-id-source: derived
    servers:
    - url: https://api.endoflife.ai
components:
  schemas:
    Score:
      type: object
      description: One version's lifecycle facts and EOL Risk Score. The same object is returned by /v1/score, inside /v1/product versions[], /v1/batch results[] and /v1/sbom results[].
      properties:
        product:
          type: string
          example: nodejs
        version:
          type: string
          example: '18'
          description: The release cycle answered. When the request named a patch or build, requested_version and version_matched_by are present too.
        alias_of:
          type: string
          description: 'Only when the slug sent is an alias of a tracked product (fortigate, weblogic, ios-xe): the slug as sent; product is the tracked slug it resolved to.'
        requested_version:
          type: string
          description: 'Only when the version was resolved to its release line: the version as sent.'
        version_matched_by:
          type: string
          enum:
          - release-line
          - model-name
          description: 'Only when the version was not matched exactly: release-line (a patch or build resolved to its release line) or model-name (a device model sent without its family prefix, e.g. 60E for FortiGate-60E).'
        latest_release:
          type:
          - string
          - 'null'
        release_date:
          type:
          - string
          - 'null'
          format: date
        eol_date:
          type:
          - string
          - 'null'
          format: date
          description: null when the vendor has published no date, or has only said the line is already end of life (see eol_boolean).
        eol_boolean:
          type:
          - boolean
          - 'null'
          description: true = end of life with no exact date published; false = not end of life, no date published; null = a date is given in eol_date.
        status:
          type: string
          enum:
          - active
          - warn
          - eol
          - unknown
          description: warn = within 180 days of end of life, still supported; unknown = the published date could not be read
        is_supported:
          type: boolean
          description: 'true when the vendor still ships fixes today: status active or warn. false for eol and unknown.'
        days_until_eol:
          type:
          - integer
          - 'null'
          description: 'Counted to eol_date. When eol_date_precision is month or quarter, that is the period''s last day: show the month, not the count.'
        days_past_eol:
          type:
          - integer
          - 'null'
        eol_date_precision:
          type:
          - string
          - 'null'
          enum:
          - day
          - month
          - quarter
          - null
          description: 'How precisely the vendor publishes eol_date: day = the vendor names the day; month or quarter = the vendor names only the month (quarter), so eol_date is that period''s LAST day, kept for sorting and comparison; display the period ("October 2026"), not the day. null when eol_date is null.'
        support_date:
          type:
          - string
          - 'null'
          format: date
          description: End of the vendor's active (full or standard) support phase for this line, where one is published. The risk score's eol_recency factor reads it. null where none is recorded.
        support_date_precision:
          type:
          - string
          - 'null'
          enum:
          - day
          - month
          - quarter
          - null
          description: 'How precisely the vendor publishes support_date: day = the vendor names the day; month or quarter = the vendor names only the month (quarter), so support_date is that period''s LAST day, kept for sorting and comparison; display the period ("October 2026"), not the day. null when support_date is null.'
        extended_support_date_precision:
          type:
          - string
          - 'null'
          enum:
          - day
          - month
          - quarter
          - null
          description: 'How precisely the vendor publishes extended_support_date: day = the vendor names the day; month or quarter = the vendor names only the month (quarter), so extended_support_date is that period''s LAST day, kept for sorting and comparison; display the period ("October 2026"), not the day. null when extended_support_date is null.'
        date_precision_note:
          type: string
          description: 'Present only when a date above is month or quarter precision: which date, the period it stands for, and that it is stored as the period''s last day.'
        score:
          type: integer
          minimum: 0
          maximum: 100
          description: EOL Risk Score (higher = riskier)
        grade:
          type: string
          example: F
        grade_label:
          type: string
          example: Critical risk
        band:
          type: string
          example: Critical
        factors:
          type: object
          properties:
            eol_recency:
              type: integer
            attack_surface:
              type: integer
            cisa_kev_exposure:
              type: integer
            extended_support:
              type: integer
          description: The four components of the score; methodology at methodology_url.
        cpe:
          type:
          - array
          - 'null'
          items:
            type: string
          example:
          - cpe:2.3:a:nodejs:node.js
          description: Verified CPE 2.3 identifier(s) for joining this product to scanner and CVE data. null where no identifier has been verified — we publish none rather than a guess. For a hardware product whose versions are models (cpe_scope model), only the identifiers that name this model.
        cpe_scope:
          type: string
          enum:
          - model
          description: 'Present for hardware products whose versions are models: cpe lists only this model''s identifiers, never the other models on the vendor page.'
        cpe_note:
          type: string
          description: Present when cpe_scope is model and no NIST CPE names this model, so cpe is null.
        purl:
          type:
          - array
          - 'null'
          items:
            type: string
          example:
          - pkg:generic/node
          - pkg:docker/library/node
          - pkg:rpm/redhat/nodejs
          description: Package URL(s) that resolve an SBOM component to this product (endoflife.ai/purl-map.json). null where none is known.
        extended_support_available:
          type: boolean
        extended_support_vendor:
          type:
          - object
          - 'null'
          description: A featured extended-support vendor for this product where one is listed; null otherwise.
        score_card_url:
          type: string
          format: uri
          description: 'The score card page on endoflife.ai. The cycle is written as the site writes it: every character outside letters, digits, dot, dash and underscore becomes a dash.'
        product_url:
          type: string
          format: uri
        methodology_url:
          type: string
          format: uri
        data_source:
          type: string
          format: uri
          description: 'Where the served eol_date was read from: the vendor page for a vendor-sourced date, https://endoflife.date for an upstream date, https://endoflife.ai/how-it-works for our own catalog.'
        generated_at:
          type: string
          format: date-time
        extended_support_date:
          type:
          - string
          - 'null'
          format: date
          description: End of the vendor's own extended or paid support phase for this line where one is published (Microsoft ESU, Oracle Extended Support, Red Hat ELS, Ubuntu ESM). A line past eol_date may still be covered until this date under that program, unless extended_support_ships_fixes is false. null where none is recorded. The eol_date_source and eol_date_confidence fields describe eol_date only; this date comes from the same lifecycle record but is not covered by them, so confirm it with the vendor before relying on it for a contract.
        extended_support_ships_fixes:
          type:
          - boolean
          - 'null'
          description: 'false where the vendor ships no fixes in the phase that ends on extended_support_date (support services or advice only: Cisco Last Date of Support, Hazelcast Extended Support, Ivanti Customer care, Zyxel End of Life), so a line past eol_date receives no patches from the vendor even though that phase is still open. null where no such statement is recorded.'
        eol_date_source:
          type:
          - string
          - 'null'
          enum:
          - vendor-override
          - vendor-fetched
          - vendor-verified
          - custom
          - upstream
          - discrepancy
          - null
          description: 'Where eol_date comes from: vendor-override (set from the vendor''s own publication), vendor-fetched (our adapter read the vendor''s lifecycle page and it agrees), vendor-verified (a human cross-check covers this version), custom (our own catalog), upstream (endoflife.date only), discrepancy (the vendor page disagrees with the served value; under review). Full report: https://endoflife.ai/verification.json'
        eol_date_source_url:
          type:
          - string
          - 'null'
          description: The vendor page or record the label rests on.
        eol_date_verified_at:
          type:
          - string
          - 'null'
          format: date
          description: 'When the label was last established: the vendor feed''s read date, the human check date, or the day the correction was applied.'
        eol_date_status:
          type:
          - string
          - 'null'
          enum:
          - ok
          - fallback
          - mismatch
          - human
          - upstream
          - custom
          - null
          description: ok = vendor feed read within 14 days and agreeing; fallback = feed older than 14 days (last good value); mismatch = the vendor feed disagrees with the served value; human = a recorded correction or human verification; upstream = endoflife.date only; custom = our own catalog.
        eol_date_agreement:
          type:
          - integer
          - 'null'
          description: 'How many independent source classes agree with eol_date: the vendor''s own feed, a human decision (correction or verification record), the upstream dataset.'
        eol_date_confidence:
          type:
          - string
          - 'null'
          enum:
          - high
          - medium
          - low
          - null
          description: high = two or more sources agree; medium = one source; low = the vendor feed disagrees with the served value, or a stale feed is the only source.
        keyless_access_notice:
          type: object
          description: 'Only on answers to anonymous calls before 2026-11-16T00:00:00Z: message, keyless_access_ends (ISO date-time), get_free_key (URL). From then such calls are 401.'
          properties:
            message:
              type: string
            keyless_access_ends:
              type: string
              format: date-time
            get_free_key:
              type: string
              format: uri
    Error:
      type: object
      description: 'Every error carries error and docs. Some add detail: reason, candidates (sibling cycles of a split line), cycle and last_published (a version above an ended line''s last patch), did_you_mean (closest tracked slugs), not_tracked, see_products, tracked_products, upgrade, get_free_key, key_status, limit_bytes.'
      properties:
        error:
          type: string
        docs:
          type: string
      additionalProperties: true
    BatchItem:
      type: object
      description: 'One of: {slug, version?} or {purl, version?}. A purl (pkg:npm/webpack@5.110.3) resolves exactly via purl-map.json and supplies the version unless one is given.'
      properties:
        slug:
          type: string
        version:
          type: string
        purl:
          type: string
    BatchResponse:
      type: object
      properties:
        count:
          type: integer
        results:
          type: array
          items:
            description: A Score object, or {slug, version?, error, ...} for an item that did not resolve (error names the reason; candidates lists the sibling cycles when a line is split).
            oneOf:
            - $ref: '#/components/schemas/Score'
            - $ref: '#/components/schemas/Error'
        tier:
          type: string
        kev_catalog:
          type: object
          description: 'The CISA KEV catalog this deployment scores against: generated, named, ecosystem, fingerprint.'
        keyless_access_notice:
          type: object
          description: 'Only on answers to anonymous calls before 2026-11-16T00:00:00Z: message, keyless_access_ends (ISO date-time), get_free_key (URL). From then such calls are 401.'
          properties:
            message:
              type: string
            keyless_access_ends:
              type: string
              format: date-time
            get_free_key:
              type: string
              format: uri
        docs:
          type: string
  headers:
    X-RateLimit-Remaining:
      schema:
        type: integer
      description: Requests left today after this one. Absent on a Pro key.
    X-EOL-Key-Status:
      schema:
        type: string
        enum:
        - unknown
        - inactive
      description: 'Present only when an X-API-Key was sent and not honoured: unknown (no such key), inactive (subscription cancelled or refunded). Until 2026-11-16 the request was answered as anonymous; from then it is refused with 401. Free keys do not expire.'
    X-RateLimit-Reset:
      schema:
        type: integer
      description: 'Unix time (seconds) when the daily counter resets: the next UTC midnight. Absent on a Pro key.'
    X-RateLimit-Limit:
      schema:
        type: string
      description: Requests allowed per UTC day for the caller's tier (anonymous per IP; keyed per key), or the word unlimited on a Pro key.
  securitySchemes:
    ApiKeyAuth:
      type: apiKey
      in: header
      name: X-API-Key
    BearerAuth:
      type: http
      scheme: bearer
      description: 'The same API key sent as Authorization: Bearer <key>, for clients that cannot set X-API-Key (Prometheus before 3.0).'
x-refined-from:
- openapi.json
- endoflife-ai-openapi.json