endoflife.ai Sbom API
The Sbom API from endoflife.ai — 2 operation(s) for sbom.
Operations 2
POST
/v1/sbom/watch
Watch this SBOM: subscribe the document's resolved lines to EOL and KEV alerts
#
The Sbom API from endoflife.ai — 2 operation(s) for sbom.
Every API here is available over the APIs.io API and to AI agents over MCP.
One button, every client — Claude, Cursor, VS Code and the rest.
https://apis.io/mcp
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.curl "https://apis.io/api/v1/apis/endoflife-ai:endoflife-ai-sbom-api"
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.
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: 3.2.0
info:
title: Endoflife Ai Sbom API
version: 1.4.0
contact:
email: partners@endoflife.ai
url: https://endoflife.ai/api
description: 'Operations tagged Sbom 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: Sbom
paths:
/v1/sbom:
post:
summary: 'Audit an SBOM or AI-BOM: resolve every component by package URL or model id and…'
description: 'Body: a CycloneDX JSON or SPDX JSON document, either as the whole body or under a top-level "sbom" key. Limits: 5 MB body, 5,000 components, 32 levels of nesting (413 above any of them). Components carrying a purl resolve only by purl (exact, via endoflife.ai/purl-map.json); components without one resolve by name. Unmatched components are listed with a reason, never guessed. Resolution and counts cover the whole document; scoring is capped at the tier''s batch size (anonymous 3, free key 5, Starter 25, Pro 50). With ?enrich=1 (or "enrich": true beside "sbom") the response is the SAME document with lifecycle facts written onto every component: CycloneDX gets properties in the endoflife: namespace (status, product, cycle, eol_date, days_until_eol / days_past_eol, matched_by, score_url; risk_score, risk_grade, risk_band and kev_exposed on the scored subset; status=not-tracked with a reason otherwise) plus a metadata summary and a tools entry; SPDX gets one annotation per package from "Tool: endoflife.ai API" and one document-level annotation. Idempotent - re-enriching replaces earlier endoflife entries. Content-Type is application/vnd.cyclonedx+json or application/spdx+json; the X-Endoflife-Summary header carries the counts.'
parameters:
- name: enrich
in: query
required: false
schema:
type: string
enum:
- '1'
description: Return the enriched SBOM document instead of the JSON report
- name: strict
in: query
required: false
schema:
type: string
enum:
- '1'
description: 'Purl-only resolution: components without a package URL are reported as not tracked (reason ''no purl (strict mode)'') instead of being matched by name'
- name: warn_days
in: query
required: false
schema:
type: integer
default: 90
description: 'Enrich mode gate: the document-level endoflife:gate is ''fail'' when any resolved line is past end of life, ''warn'' when any reaches it within this many days, else ''pass'''
requestBody:
required: true
content:
application/json:
schema:
type: object
description: 'CycloneDX or SPDX JSON, or { sbom: <document> }'
responses:
'200':
description: format, component/matched/scored counts, matched_by {purl,cpe,name,model}, low_confidence_matches, summary {past_eol, kev_exposed}, results (Score objects + component + matched_by; match_confidence 'low' and match_note on name-only matches of library-type components), unmatched [{component, reason}]
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'
'400':
description: Not a CycloneDX/SPDX JSON document
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'
'413':
description: Body over 5 MB, more than 5,000 components, or nesting deeper than 32 levels
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:
- Sbom
operationId: postV1Sbom
x-operation-id-source: derived
servers:
- url: https://api.endoflife.ai
/v1/sbom/watch:
post:
summary: 'Watch this SBOM: subscribe the document''s resolved lines to EOL and KEV alerts'
description: 'Body: { "email": "...", "sbom": , "strict": false }. Every component is resolved the same way /v1/sbom resolves it (purl exact, name only without a purl, never a guess) and each resolved product line (slug:cycle) joins the subscriber''s watch list on the existing alert system: a confirmation email first (double opt-in), then emails when a watched line comes inside 12 months of end of life, at 90/60/30/7 days, on the day it passes, and immediately when a CISA known-exploited CVE lands on a watched end-of-life line. Only the slug:cycle lines are stored - never the document. The list replaces the subscriber''s previous watch list; 50 lines maximum.'
requestBody:
required: true
content:
application/json:
schema:
type: object
required:
- email
- sbom
properties:
email:
type: string
sbom:
type: object
strict:
type: boolean
responses:
'200':
description: ok, watching (slug:cycle list), confirmed, message, sbom {format, components, lines_resolved, lines_watched, lines_dropped, not_tracked, version_not_tracked}
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'
'400':
description: Invalid body, or no component resolves to a tracked line
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
'413':
description: Body over 5 MB, more than 5,000 components, or nesting deeper than 32 levels
'429':
description: Signup limit (10 a day per address) or daily quota
'503':
description: Alert storage unavailable
tags:
- Sbom
operationId: postV1SbomWatch
x-operation-id-source: derived
servers:
- url: https://api.endoflife.ai
components:
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.
schemas:
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
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