Both halves of the definition are decisions, and the denominator is the one people forget to make.
# good events
sum(rate(http_requests_total{route="checkout",status=~"2..|3.."}[5m]))
/
# VALID events — 4xx excluded: a client sending nonsense is
# not our availability problem
sum(rate(http_requests_total{route="checkout",status!~"4.."}[5m]))
Excluding 4xx from the denominator is defensible and is a decision somebody has to agree to, because it means a bug that returns 400 for a valid request looks like perfect availability. The alternative — counting everything — makes a scripted attack look like an outage. Writing down which was chosen and why is the part that survives a handover.