{
  "openapi": "3.1.0",
  "info": {
    "title": "EPA ECHO Facility Violation History & Risk Score",
    "version": "1.0.0",
    "summary": "Look up a U.S. facility's environmental compliance history — EPA's alleged violations and formal enforcement — and get one risk score with a plain-English summary.",
    "description": "Screen a US company or facility against EPA ECHO — alleged violations, formal enforcement and penalties — and get one risk score with a plain-English summary.\n\nGenerated from the service's own TypeScript contract types, so this document describes what the API actually returns. Operated by EAC Ventures, LLC.\n\nSubscribe, including the free tier: https://rapidapi.com/aervik-labs-aervik-labs-default/api/epa-echo-compliance-history-ai-risk-score-api\n\nKnown limits:\n- Advisory only. ECHO aggregates state and federal reporting with lags, so a facility’s current status can differ from what ECHO shows.\n- A name or address that matches more than one facility returns a match_count, and only the first is scored; narrow the query or send epa_id rather than assume the first result.\n- An ECHO flag or count left blank for a facility adds no points and is named in unreadable_inputs; it is never read as “no”.\n- DOL is searched for the longest part of the name that survives removing legal-form suffixes and punctuation, in the name’s own case and in upper case. A name typed all in lower case can miss Wage and Hour records, which DOL stores as filed.\n- On /company-risk-screen, a source holding more records for the name than the screen reads is named in that section's truncated list, and its counts are lower bounds.\n\nSources, freshness and live health: https://aerviklabs.com/sources.json (https://aerviklabs.com/data-sources/#epa-compliance-risk). What we do when something cannot be established: https://aerviklabs.com/trust/\n\nThis OpenAPI document is available under the MIT License (Copyright (c) 2026 EAC Ventures, LLC). Use of the API itself is governed by its Terms of Service, not by that license.",
    "contact": {
      "name": "Aervik Labs",
      "url": "https://aerviklabs.com/about/"
    },
    "x-aervik-provenance": {
      "sources_json": "https://aerviklabs.com/sources.json",
      "data_sources_page": "https://aerviklabs.com/data-sources/#epa-compliance-risk",
      "trust_page": "https://aerviklabs.com/trust/",
      "read_method": "live",
      "known_limits": [
        "Advisory only. ECHO aggregates state and federal reporting with lags, so a facility’s current status can differ from what ECHO shows.",
        "A name or address that matches more than one facility returns a match_count, and only the first is scored; narrow the query or send epa_id rather than assume the first result.",
        "An ECHO flag or count left blank for a facility adds no points and is named in unreadable_inputs; it is never read as “no”.",
        "DOL is searched for the longest part of the name that survives removing legal-form suffixes and punctuation, in the name’s own case and in upper case. A name typed all in lower case can miss Wage and Hour records, which DOL stores as filed.",
        "On /company-risk-screen, a source holding more records for the name than the screen reads is named in that section's truncated list, and its counts are lower bounds."
      ]
    },
    "termsOfService": "https://compliance.aerviklabs.com/terms"
  },
  "externalDocs": {
    "description": "Product page",
    "url": "https://aerviklabs.com/apis/epa-compliance-risk/"
  },
  "servers": [
    {
      "url": "https://epa-echo-compliance-history-ai-risk-score-api.p.rapidapi.com",
      "description": "RapidAPI gateway"
    }
  ],
  "security": [
    {
      "RapidApiKey": []
    }
  ],
  "paths": {
    "/risk-score": {
      "get": {
        "operationId": "getFacilityRiskScore",
        "summary": "Look up one EPA-regulated facility's compliance history, alleged violations and enforcement, with a 0-100 risk score",
        "parameters": [
          {
            "$ref": "#/components/parameters/RapidApiHost"
          },
          {
            "name": "facility_name",
            "in": "query",
            "required": false,
            "description": "Facility name to search EPA ECHO for. One of facility_name, address or epa_id is required; when more than one is given, epa_id is used first, then address.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "address",
            "in": "query",
            "required": false,
            "description": "Street address to search EPA ECHO for. Used instead of facility_name when both are given.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "epa_id",
            "in": "query",
            "required": false,
            "description": "EPA FRS Registry ID, an exact lookup. Used instead of address or facility_name, and city, state and zip are ignored with it.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "city",
            "in": "query",
            "required": false,
            "description": "Narrows a facility_name or address search.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "state",
            "in": "query",
            "required": false,
            "description": "Two-letter state code. Narrows a facility_name or address search.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "zip",
            "in": "query",
            "required": false,
            "description": "Narrows an address search. Not used with facility_name.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Success",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/RiskScoreResponse"
                }
              }
            }
          },
          "400": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "404": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "405": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "500": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "502": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/company-risk-screen": {
      "get": {
        "operationId": "screenCompanyRisk",
        "summary": "Screen a company name across EPA, OSHA, DOL, openFDA and CPSC records, with one cross-agency risk score",
        "parameters": [
          {
            "$ref": "#/components/parameters/RapidApiHost"
          },
          {
            "name": "company_name",
            "in": "query",
            "required": true,
            "description": "Company name to screen. DOL, openFDA and CPSC are searched by this name alone. It is also the EPA facility-name search unless epa_id is given.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "state",
            "in": "query",
            "required": false,
            "description": "Two-letter state code. Narrows the EPA facility-name search and filters OSHA inspections.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "city",
            "in": "query",
            "required": false,
            "description": "Narrows the EPA facility-name search.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "epa_id",
            "in": "query",
            "required": false,
            "description": "EPA FRS Registry ID. Resolves the EPA section by exact lookup instead of a name search.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "address",
            "in": "query",
            "required": false,
            "description": "Echoed back in input. Not used to search any section.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "zip",
            "in": "query",
            "required": false,
            "description": "Echoed back in input. Not used to search any section.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Success",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CompanyRiskScreenResponse"
                }
              }
            }
          },
          "400": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "405": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "500": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    }
  },
  "components": {
    "securitySchemes": {
      "RapidApiKey": {
        "type": "apiKey",
        "in": "header",
        "name": "X-RapidAPI-Key",
        "description": "Your RapidAPI application key."
      }
    },
    "parameters": {
      "RapidApiHost": {
        "name": "X-RapidAPI-Host",
        "in": "header",
        "required": true,
        "schema": {
          "type": "string",
          "const": "epa-echo-compliance-history-ai-risk-score-api.p.rapidapi.com"
        }
      }
    },
    "schemas": {
      "AgencyMatchStatus": {
        "type": "string",
        "enum": [
          "match",
          "possible_match",
          "no_match",
          "error"
        ]
      },
      "AgencyMatchType": {
        "type": "string",
        "enum": [
          "exact",
          "fuzzy"
        ]
      },
      "CompanyRiskScreenInput": {
        "type": "object",
        "properties": {
          "company_name": {
            "type": "string"
          },
          "address": {
            "type": [
              "string",
              "null"
            ]
          },
          "city": {
            "type": [
              "string",
              "null"
            ]
          },
          "state": {
            "type": [
              "string",
              "null"
            ]
          },
          "zip": {
            "type": [
              "string",
              "null"
            ]
          },
          "epa_id": {
            "type": [
              "string",
              "null"
            ]
          }
        },
        "required": [
          "company_name",
          "address",
          "city",
          "state",
          "zip",
          "epa_id"
        ]
      },
      "CompanyRiskScreenResponse": {
        "type": "object",
        "properties": {
          "input": {
            "$ref": "#/components/schemas/CompanyRiskScreenInput"
          },
          "epa": {
            "$ref": "#/components/schemas/EpaSection"
          },
          "osha": {
            "$ref": "#/components/schemas/OshaSection"
          },
          "dol": {
            "$ref": "#/components/schemas/DolSection"
          },
          "fda": {
            "$ref": "#/components/schemas/FdaSection"
          },
          "cpsc": {
            "$ref": "#/components/schemas/CpscSection"
          },
          "cross_agency_risk_score": {
            "type": "number",
            "description": "0 to 100, computed by a deterministic formula over the sections below. AI writes only cross_agency_summary, never the score or tier."
          },
          "cross_agency_risk_tier": {
            "$ref": "#/components/schemas/RiskTier"
          },
          "cross_agency_summary": {
            "type": "string"
          },
          "incomplete_coverage": {
            "type": "boolean",
            "description": "True unless every agency section is live, was checked without error and read to the end (truncated is empty), and the EPA section resolved to exactly one facility that counts toward the score. Also true when company_name was sent as a single word with no spaces and nothing was found anywhere -- see coverage_note. When true, a section that was not checked is unknown, not clean, and a truncated section's records are a partial list."
          },
          "coverage_note": {
            "type": [
              "string",
              "null"
            ],
            "description": "Why coverage is incomplete for this query as a whole, or null. Today it carries one case: company_name arrived as a single word with no spaces and no agency returned anything. These sources search by substring or by adjacent words, so a joined or compacted spelling can retrieve nothing even when the company has records -- such a result is not sufficient to establish a clean screen, and the risk score should not be read as an all-clear. Re-screen with the spaced legal or company name. Each agency section carries its own coverage_note about that section's read; this one is about the input."
          },
          "disclaimer": {
            "type": "string"
          },
          "generated_at": {
            "type": "string"
          }
        },
        "required": [
          "input",
          "epa",
          "osha",
          "dol",
          "fda",
          "cpsc",
          "cross_agency_risk_score",
          "cross_agency_risk_tier",
          "cross_agency_summary",
          "incomplete_coverage",
          "coverage_note",
          "disclaimer",
          "generated_at"
        ]
      },
      "ComplianceStatus": {
        "type": "object",
        "properties": {
          "program": {
            "$ref": "#/components/schemas/ProgramCode"
          },
          "status": {
            "type": "string"
          },
          "classification": {
            "$ref": "#/components/schemas/ComplianceStatusClass",
            "description": "alleged_violation: ECHO's status alleges a violation. no_violation_identified: ECHO's status is No Violation Identified. not_a_compliance_finding: Terminated Permit, Not Applicable, Inactive, Unknown or Not Available, which allege nothing. unrecognized: a status this API has no mapping for; it is counted neither as a violation nor as clean, so read status."
          }
        },
        "required": [
          "program",
          "status",
          "classification"
        ]
      },
      "ComplianceStatusClass": {
        "type": "string",
        "enum": [
          "alleged_violation",
          "no_violation_identified",
          "not_a_compliance_finding",
          "unrecognized"
        ]
      },
      "CpscCandidate": {
        "type": "object",
        "properties": {
          "matched_name": {
            "type": "string"
          },
          "match_type": {
            "$ref": "#/components/schemas/AgencyMatchType"
          },
          "score": {
            "type": "number",
            "description": "Name similarity from deterministic text matching, 0 to 1. A close name match is not proof of legal entity identity."
          },
          "record_count": {
            "type": "number"
          },
          "records": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/CpscRecall"
            }
          }
        },
        "required": [
          "match_type",
          "matched_name",
          "record_count",
          "records",
          "score"
        ]
      },
      "CpscRecall": {
        "type": "object",
        "properties": {
          "recall_id": {
            "type": "number"
          },
          "recall_number": {
            "type": "string"
          },
          "recall_date": {
            "type": [
              "string",
              "null"
            ]
          },
          "title": {
            "type": "string"
          },
          "manufacturer_names": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "number_of_units": {
            "type": [
              "string",
              "null"
            ]
          },
          "url": {
            "type": "string"
          }
        },
        "required": [
          "recall_id",
          "recall_number",
          "recall_date",
          "title",
          "manufacturer_names",
          "number_of_units",
          "url"
        ]
      },
      "CpscSection": {
        "type": "object",
        "properties": {
          "status": {
            "$ref": "#/components/schemas/AgencyMatchStatus",
            "description": "match, possible_match, no_match, or error. error means this agency could not be checked for this request; it is never the same as no_match, which means it was checked and no name matched closely enough."
          },
          "error": {
            "type": "string",
            "description": "Present only when status is error. Treat this section as not checked, not as nothing found."
          },
          "source": {
            "$ref": "#/components/schemas/SourceManifest"
          },
          "truncated": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/TruncatedQuery"
            },
            "description": "Source queries this section read only part of: the source holds more rows than this screen reads, or reported no count that shows it holds no more. Always present; empty when every query was read to the end. Any entry makes this section's records and counts a partial list and incomplete_coverage true."
          },
          "records_below_match_threshold": {
            "type": "number"
          },
          "candidates": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/CpscCandidate"
            }
          }
        },
        "required": [
          "candidates",
          "records_below_match_threshold",
          "source",
          "status",
          "truncated"
        ]
      },
      "DolAgency": {
        "type": "string",
        "enum": [
          "WHD",
          "OSHA",
          "MSHA",
          "EBSA"
        ]
      },
      "DolCandidate": {
        "type": "object",
        "properties": {
          "matched_name": {
            "type": "string"
          },
          "match_type": {
            "$ref": "#/components/schemas/AgencyMatchType"
          },
          "score": {
            "type": "number",
            "description": "Name similarity from deterministic text matching, 0 to 1. A close name match is not proof of legal entity identity."
          },
          "record_count": {
            "type": "number"
          },
          "records": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/DolCase"
            }
          }
        },
        "required": [
          "match_type",
          "matched_name",
          "record_count",
          "records",
          "score"
        ]
      },
      "DolCase": {
        "type": "object",
        "properties": {
          "case_id": {
            "type": "string"
          },
          "agency": {
            "$ref": "#/components/schemas/DolAgency"
          },
          "employer_name": {
            "type": "string"
          },
          "city": {
            "type": [
              "string",
              "null"
            ]
          },
          "state": {
            "type": [
              "string",
              "null"
            ]
          },
          "violation_type": {
            "type": [
              "string",
              "null"
            ]
          },
          "finding_date": {
            "type": [
              "string",
              "null"
            ]
          },
          "back_wages_usd": {
            "type": [
              "number",
              "null"
            ]
          },
          "penalty_usd": {
            "type": [
              "number",
              "null"
            ]
          },
          "employees_affected": {
            "type": [
              "number",
              "null"
            ]
          }
        },
        "required": [
          "case_id",
          "agency",
          "employer_name",
          "city",
          "state",
          "violation_type",
          "finding_date",
          "back_wages_usd",
          "penalty_usd",
          "employees_affected"
        ]
      },
      "DolSection": {
        "type": "object",
        "properties": {
          "status": {
            "$ref": "#/components/schemas/AgencyMatchStatus",
            "description": "match, possible_match, no_match, or error. error means this agency could not be checked for this request; it is never the same as no_match, which means it was checked and no name matched closely enough."
          },
          "error": {
            "type": "string",
            "description": "Present only when status is error. Treat this section as not checked, not as nothing found."
          },
          "source": {
            "$ref": "#/components/schemas/SourceManifest"
          },
          "truncated": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/TruncatedQuery"
            },
            "description": "Source queries this section read only part of: the source holds more rows than this screen reads, or reported no count that shows it holds no more. Always present; empty when every query was read to the end. Any entry makes this section's records and counts a partial list and incomplete_coverage true."
          },
          "records_below_match_threshold": {
            "type": "number"
          },
          "withheld_possible_individual": {
            "type": "boolean"
          },
          "coverage_note": {
            "type": [
              "string",
              "null"
            ]
          },
          "candidates": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/DolCandidate"
            }
          }
        },
        "required": [
          "candidates",
          "coverage_note",
          "records_below_match_threshold",
          "source",
          "status",
          "truncated",
          "withheld_possible_individual"
        ]
      },
      "EchoScoreInput": {
        "type": "string",
        "enum": [
          "CurrSvFlag",
          "CurrVioFlag",
          "ViolFlag",
          "CAAHpvFlag",
          "CWASNCFlag",
          "RCRASNCFlag",
          "SDWASNCFlag",
          "FacFormalActionCount",
          "FacTotalPenalties",
          "FacQtrsWithNC",
          "FacDateLastFormalAction"
        ]
      },
      "EnforcementAction": {
        "type": "object",
        "properties": {
          "program": {
            "$ref": "#/components/schemas/ProgramCode"
          },
          "type": {
            "type": "string",
            "enum": [
              "formal",
              "informal"
            ]
          },
          "count": {
            "type": [
              "number",
              "null"
            ],
            "description": "Null: ECHO's summary data gives a penalty total per program, not a per-program action count. Facility-wide counts are total_formal_actions and total_informal_actions."
          },
          "most_recent_date": {
            "type": [
              "string",
              "null"
            ],
            "description": "Null: ECHO's summary data dates formal actions for the facility as a whole, not per program. The facility-wide date is last_formal_action_date."
          },
          "penalty_total_usd": {
            "type": [
              "number",
              "null"
            ]
          }
        },
        "required": [
          "program",
          "type",
          "count",
          "most_recent_date",
          "penalty_total_usd"
        ]
      },
      "EpaSection": {
        "type": "object",
        "properties": {
          "resolved": {
            "type": "boolean",
            "description": "True when an EPA ECHO facility was found. It counts toward cross_agency_risk_score only when it was looked up by epa_id or its name matches company_name at the same 0.92 similarity every agency section needs; note says when it does not. False when none matched, the search was too broad, or the lookup failed; note says which."
          },
          "facility": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/Facility"
              },
              {
                "type": "null"
              }
            ]
          },
          "risk_score": {
            "type": [
              "number",
              "null"
            ]
          },
          "risk_tier": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/RiskTier"
              },
              {
                "type": "null"
              }
            ]
          },
          "match_count": {
            "type": [
              "number",
              "null"
            ],
            "description": "How many EPA ECHO facility records matched; only the first is considered. Null when the section did not resolve. Above 1, the others are not scored and incomplete_coverage is true; narrow the query with state, city or epa_id."
          },
          "unreadable_inputs": {
            "anyOf": [
              {
                "type": "array",
                "items": {
                  "$ref": "#/components/schemas/EchoScoreInput"
                }
              },
              {
                "type": "null"
              }
            ],
            "description": "ECHO columns the EPA risk_score reads that ECHO left blank or unreadable for this facility. Each contributed no points, and none is treated as a stated no or zero. Null when no facility resolved."
          },
          "note": {
            "type": "string",
            "description": "Why the EPA section did or did not resolve, stated for the search that was actually sent."
          }
        },
        "required": [
          "resolved",
          "facility",
          "risk_score",
          "risk_tier",
          "match_count",
          "unreadable_inputs",
          "note"
        ]
      },
      "ErrorResponse": {
        "type": "object",
        "properties": {
          "error": {
            "type": "string"
          },
          "message": {
            "type": "string"
          }
        },
        "required": [
          "error",
          "message"
        ],
        "description": "Every non-2xx JSON response from the API itself. `error` is a stable machine-readable code; `message` is for humans and may change. Codes this API can return: `echo_api_error`, `facility_not_found`, `internal_error`, `method_not_allowed`, `missing_input`, `not_found`, `provider_misconfigured`, `query_too_broad`, `unauthorized`. RapidAPI answers authentication, subscription and rate-limit failures itself, in its own format."
      },
      "Facility": {
        "type": "object",
        "properties": {
          "name": {
            "type": "string"
          },
          "address": {
            "type": [
              "string",
              "null"
            ]
          },
          "city": {
            "type": [
              "string",
              "null"
            ]
          },
          "state": {
            "type": [
              "string",
              "null"
            ]
          },
          "zip": {
            "type": [
              "string",
              "null"
            ]
          },
          "epa_registry_id": {
            "type": "string"
          },
          "epa_region": {
            "type": [
              "string",
              "null"
            ]
          },
          "is_major_facility": {
            "type": [
              "boolean",
              "null"
            ],
            "description": "As ECHO's major-facility flag states it. Null when ECHO left the flag blank, which ECHO does not define as no."
          },
          "detailed_report_url": {
            "type": [
              "string",
              "null"
            ]
          }
        },
        "required": [
          "name",
          "address",
          "city",
          "state",
          "zip",
          "epa_registry_id",
          "epa_region",
          "is_major_facility",
          "detailed_report_url"
        ]
      },
      "FdaCandidate": {
        "type": "object",
        "properties": {
          "matched_name": {
            "type": "string"
          },
          "match_type": {
            "$ref": "#/components/schemas/AgencyMatchType"
          },
          "score": {
            "type": "number",
            "description": "Name similarity from deterministic text matching, 0 to 1. A close name match is not proof of legal entity identity."
          },
          "record_count": {
            "type": "number"
          },
          "records": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/FdaRecall"
            }
          }
        },
        "required": [
          "match_type",
          "matched_name",
          "record_count",
          "records",
          "score"
        ]
      },
      "FdaClassification": {
        "type": "string",
        "enum": [
          "Class I",
          "Class II",
          "Class III"
        ]
      },
      "FdaProductType": {
        "type": "string",
        "enum": [
          "food",
          "drug",
          "device"
        ]
      },
      "FdaRecall": {
        "type": "object",
        "properties": {
          "recall_number": {
            "type": "string"
          },
          "event_id": {
            "type": [
              "string",
              "null"
            ]
          },
          "recalling_firm": {
            "type": "string"
          },
          "product_type": {
            "$ref": "#/components/schemas/FdaProductType"
          },
          "classification": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/FdaClassification"
              },
              {
                "type": "null"
              }
            ]
          },
          "status": {
            "type": [
              "string",
              "null"
            ]
          },
          "product_description": {
            "type": "string"
          },
          "reason_for_recall": {
            "type": [
              "string",
              "null"
            ]
          },
          "recall_initiation_date": {
            "type": [
              "string",
              "null"
            ]
          },
          "report_date": {
            "type": [
              "string",
              "null"
            ]
          },
          "state": {
            "type": [
              "string",
              "null"
            ]
          },
          "country": {
            "type": [
              "string",
              "null"
            ]
          }
        },
        "required": [
          "recall_number",
          "event_id",
          "recalling_firm",
          "product_type",
          "classification",
          "status",
          "product_description",
          "reason_for_recall",
          "recall_initiation_date",
          "report_date",
          "state",
          "country"
        ]
      },
      "FdaSection": {
        "type": "object",
        "properties": {
          "status": {
            "$ref": "#/components/schemas/AgencyMatchStatus",
            "description": "match, possible_match, no_match, or error. error means this agency could not be checked for this request; it is never the same as no_match, which means it was checked and no name matched closely enough."
          },
          "error": {
            "type": "string",
            "description": "Present only when status is error. Treat this section as not checked, not as nothing found."
          },
          "source": {
            "$ref": "#/components/schemas/SourceManifest"
          },
          "truncated": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/TruncatedQuery"
            },
            "description": "Source queries this section read only part of: the source holds more rows than this screen reads, or reported no count that shows it holds no more. Always present; empty when every query was read to the end. Any entry makes this section's records and counts a partial list and incomplete_coverage true."
          },
          "records_below_match_threshold": {
            "type": "number"
          },
          "candidates": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/FdaCandidate"
            }
          }
        },
        "required": [
          "candidates",
          "records_below_match_threshold",
          "source",
          "status",
          "truncated"
        ]
      },
      "OshaCandidate": {
        "type": "object",
        "properties": {
          "matched_name": {
            "type": "string"
          },
          "match_type": {
            "$ref": "#/components/schemas/AgencyMatchType"
          },
          "score": {
            "type": "number",
            "description": "Name similarity from deterministic text matching, 0 to 1. A close name match is not proof of legal entity identity."
          },
          "record_count": {
            "type": "number"
          },
          "records": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/OshaInspection"
            }
          }
        },
        "required": [
          "match_type",
          "matched_name",
          "record_count",
          "records",
          "score"
        ]
      },
      "OshaInspection": {
        "type": "object",
        "properties": {
          "inspection_nr": {
            "type": "string"
          },
          "establishment_name": {
            "type": "string"
          },
          "date_opened": {
            "type": [
              "string",
              "null"
            ]
          },
          "office_id": {
            "type": [
              "string",
              "null"
            ]
          },
          "state": {
            "type": [
              "string",
              "null"
            ]
          },
          "inspection_type": {
            "type": [
              "string",
              "null"
            ]
          },
          "scope": {
            "type": [
              "string",
              "null"
            ]
          },
          "sic": {
            "type": [
              "string",
              "null"
            ]
          },
          "naics": {
            "type": [
              "string",
              "null"
            ]
          },
          "violations_count": {
            "type": [
              "number",
              "null"
            ],
            "description": "Alleged violations the source records for this inspection. Null when not stated. 0 means none were found in the source, not a statement that none were issued. When the OSHA section's truncated lists OSHA/Violation, the citation read was cut short, so this is a lower bound and a 0 may be citations that were not read."
          },
          "detail_url": {
            "type": "string"
          }
        },
        "required": [
          "inspection_nr",
          "establishment_name",
          "date_opened",
          "office_id",
          "state",
          "inspection_type",
          "scope",
          "sic",
          "naics",
          "violations_count",
          "detail_url"
        ]
      },
      "OshaSection": {
        "type": "object",
        "properties": {
          "status": {
            "$ref": "#/components/schemas/AgencyMatchStatus",
            "description": "match, possible_match, no_match, or error. error means this agency could not be checked for this request; it is never the same as no_match, which means it was checked and no name matched closely enough."
          },
          "error": {
            "type": "string",
            "description": "Present only when status is error. Treat this section as not checked, not as nothing found."
          },
          "source": {
            "$ref": "#/components/schemas/SourceManifest"
          },
          "truncated": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/TruncatedQuery"
            },
            "description": "Source queries this section read only part of: the source holds more rows than this screen reads, or reported no count that shows it holds no more. Always present; empty when every query was read to the end. Any entry makes this section's records and counts a partial list and incomplete_coverage true."
          },
          "records_below_match_threshold": {
            "type": "number"
          },
          "withheld_possible_individual": {
            "type": "boolean"
          },
          "coverage_note": {
            "type": [
              "string",
              "null"
            ]
          },
          "candidates": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/OshaCandidate"
            }
          }
        },
        "required": [
          "candidates",
          "coverage_note",
          "records_below_match_threshold",
          "source",
          "status",
          "truncated",
          "withheld_possible_individual"
        ]
      },
      "ProgramCode": {
        "type": "string",
        "enum": [
          "CAA",
          "CWA",
          "RCRA",
          "SDWA"
        ]
      },
      "RiskScoreResponse": {
        "type": "object",
        "properties": {
          "facility": {
            "$ref": "#/components/schemas/Facility"
          },
          "match_count": {
            "type": "number",
            "description": "How many EPA ECHO facility records matched the search; the first one is scored. When this is above 1, narrow the query with state, city or epa_id."
          },
          "risk_score": {
            "type": "number",
            "description": "0 to 100, computed by a deterministic point-based rubric over the ECHO record. AI writes only ai_summary, never the score or tier."
          },
          "risk_tier": {
            "$ref": "#/components/schemas/RiskTier"
          },
          "active_violations": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "description": "One line per program whose ECHO compliance status alleges a violation (classification alleged_violation in compliance_statuses), or that ECHO flags as a High Priority Violator / Significant Noncomplier."
          },
          "enforcement_actions": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/EnforcementAction"
            }
          },
          "total_formal_actions": {
            "type": [
              "number",
              "null"
            ]
          },
          "total_informal_actions": {
            "type": [
              "number",
              "null"
            ]
          },
          "total_penalties_usd": {
            "type": [
              "number",
              "null"
            ]
          },
          "penalty_count": {
            "type": [
              "number",
              "null"
            ]
          },
          "last_formal_action_date": {
            "type": [
              "string",
              "null"
            ],
            "description": "The facility's most recent formal enforcement action date as ECHO reports it (FacDateLastFormalAction), for the facility as a whole. Null when ECHO gives none."
          },
          "programs_flagged": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/ProgramCode"
            },
            "description": "Programs with a compliance status classified alleged_violation, or a High Priority Violator / Significant Noncomplier flag of Y in ECHO."
          },
          "programs_regulated_under": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/ProgramCode"
            }
          },
          "compliance_statuses": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/ComplianceStatus"
            },
            "description": "Each program's current compliance status as ECHO states it, verbatim, with how this API classified it. Only alleged_violation statuses count in active_violations and programs_flagged."
          },
          "unreadable_inputs": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/EchoScoreInput"
            },
            "description": "ECHO columns the score reads that ECHO left blank or unreadable for this facility. Each contributed no points, and none is treated as a stated no or zero. Empty when every input was readable."
          },
          "ai_summary": {
            "type": "string"
          },
          "disclaimer": {
            "type": "string"
          },
          "provider": {
            "type": "string"
          },
          "data_source": {
            "type": "string",
            "description": "Where the data comes from and how fresh it is, in EPA ECHO's own terms: typically refreshed weekly from EPA source databases, with drinking-water data extracted less often. ECHO is queried live on each request."
          },
          "generated_at": {
            "type": "string"
          }
        },
        "required": [
          "facility",
          "match_count",
          "risk_score",
          "risk_tier",
          "active_violations",
          "enforcement_actions",
          "total_formal_actions",
          "total_informal_actions",
          "total_penalties_usd",
          "penalty_count",
          "last_formal_action_date",
          "programs_flagged",
          "programs_regulated_under",
          "compliance_statuses",
          "unreadable_inputs",
          "ai_summary",
          "disclaimer",
          "provider",
          "data_source",
          "generated_at"
        ]
      },
      "RiskTier": {
        "type": "string",
        "enum": [
          "low",
          "medium",
          "high",
          "critical"
        ]
      },
      "SourceBasis": {
        "type": "string",
        "enum": [
          "live",
          "mock",
          "mock-pending-key"
        ]
      },
      "SourceManifest": {
        "type": "object",
        "properties": {
          "name": {
            "type": "string"
          },
          "url": {
            "type": "string"
          },
          "basis": {
            "$ref": "#/components/schemas/SourceBasis",
            "description": "live: this section came from the named source. mock or mock-pending-key: it came from a fixed synthetic fixture, so it is not a real check of that agency and incomplete_coverage is true."
          },
          "as_of": {
            "type": [
              "string",
              "null"
            ],
            "description": "The data's date as the source itself dates it, or null when the source publishes no date. It is never the date of your request. For a fixture section, the fixture's fixed date."
          },
          "note": {
            "type": "string"
          }
        },
        "required": [
          "name",
          "url",
          "basis",
          "as_of",
          "note"
        ]
      },
      "TruncatedQuery": {
        "type": "object",
        "properties": {
          "dataset": {
            "type": "string",
            "description": "The source dataset or endpoint that held more rows than were read, for example WHD/Enforcement, OSHA/Inspection, OSHA/Violation, food/enforcement or Recall/Importer."
          },
          "limit": {
            "type": "number",
            "description": "For a source with a row cap, the cap this screen applied to that query; the source holds more rows than this, or reported no count that shows it holds no more. For CPSC Recall/* entries, which have no row cap, the number of recalls this screen read from a narrower fallback search after the first answer exceeded the size this screen reads, or 0 when none were read."
          }
        },
        "required": [
          "dataset",
          "limit"
        ]
      }
    }
  }
}
