module

EPSS

JSON serialization for EPSS::Score and the FIRST API envelope.

A Score round-trips through the same row shape the FIRST EPSS API returns:

{
  "cve": "CVE-2022-27225",
  "epss": "0.001870000",
  "percentile": "0.401290000",
  "date": "2026-05-18"
}

Numeric fields are emitted as strings (matching the upstream API), so a Score#to_json payload can be replayed against any consumer that already parses the FIRST format. EPSS.from_json accepts both bare-row JSON and full-envelope JSON so a serialized stream from either source is consumable.

Constants

VERSION = "0.2.0"

Class methods

above(threshold : Float64 = 0.95) : Array(Score)

CVEs whose EPSS probability is strictly above threshold. Streams all matching pages through the API and materializes them into an array. Be aware that loose thresholds produce large result sets; use EPSS.client.each_score(Query.above(...)) directly to stream.

Source
band(cve : String) : Band | Nil

Convenience: just the EPSS::Band for one CVE. Returns nil when the API has no published score.

Source
client

Lazily-constructed default Client used by the module-level convenience helpers. Override via EPSS.client= to inject a configured client or a stub during tests. The mutex protects against duplicate construction when multiple fibers race the first call.

Source
client=(client : Client) : Client
Source
epss(cve : String) : Float64 | Nil

Convenience: just the EPSS probability for one CVE.

Source
feed(date : Time) : CSV::Feed

Download the daily CSV feed for date. Equivalent to EPSS::CSV.fetch(date); provided at module scope so callers don't need to remember the submodule path.

Source
from_json(input : String | IO) : Array(Score)

Parse either a bare row ({"cve": ..., "epss": ..., "percentile": ...}) or a full API envelope ({"status": "OK", "data": [...]}). Returns an Array(Score) in both cases.

Source
from_json?(input : String | IO) : Array(Score) | Nil

Parse a non-raising form. Returns nil for any malformed input.

Source
percentile(cve : String) : Float64 | Nil

Convenience: just the percentile rank for one CVE.

Source
reset_client

Reset the cached default client. Mainly useful after replacing transport/base URI in tests.

Source
score(cve : String, *, date : Time | Nil = nil) : Score | Nil

Convenience: look up the latest EPSS score for one CVE.

if s = EPSS.score("CVE-2022-27225")
  puts "epss=#{s.epss} percentile=#{s.percentile}"
end
Source
scores(cves : Enumerable(String), *, date : Time | Nil = nil) : Array(Score)

Convenience: batch lookup for many CVEs in one (or several batched) request(s). Returns the parsed Score objects in the order the API returned them.

Source
search(text : String, *, limit : Int32 = 100) : Array(Score)

Free-text search ordered by EPSS descending.

Source
today_feed

Download today's UTC feed. The feed is published once per day; if called before the day's file has been minted the request will surface as EPSS::APIError with a 404 status.

Source
top(n : Int32) : Array(Score)

Top-N highest-EPSS CVEs across the entire population.

EPSS.top(10).each { |s| puts s }
Source

Nested types