U.S. EPA Enforcement and Compliance History Online (ECHO) - Safe Drinking Water Act
epa · Government
Enforcement and Compliance History Online (ECHO) is a tool developed and maintained by EPA's Office of Enforcement and Compliance Assurance for public use. ECHO provides integrated compliance and enforcement information for over 1 million regulated facilities nationwide. SDW Rest Services provides multiple service endpoints, each with specific capabilities, to search and retrieve data on public water systems regulated under the Safe Drinking Water Act (SDWA). The returned results reflect dat
Authentication
Sample Requests
Based on the QID obtained from a get_systems query, return a comma separated value (CSV) file of the water systems found.
Hover any highlighted part to learn what it does
curl -X GET "https://api.apis.guru/v2/specs/epa.gov/sdw/2019.10.15/sdw_rest_services.get_download?qid=example&output=json&qcolumns=example"
import requests
params = {
"qid": "example",
"output": "json",
"qcolumns": "example"
}
response = requests.get(
"https://api.apis.guru/v2/specs/epa.gov/sdw/2019.10.15/sdw_rest_services.get_download",
params=params,
)
print(response.json())const url = new URL('https://api.apis.guru/v2/specs/epa.gov/sdw/2019.10.15/sdw_rest_services.get_download');
url.searchParams.set('qid', 'example');
url.searchParams.set('output', 'json');
url.searchParams.set('qcolumns', 'example');
const response = await fetch(url);
const data = await response.json();
console.log(data);package main
import (
"fmt"
"io"
"net/http"
"net/url"
)
func main() {
baseURL, _ := url.Parse("https://api.apis.guru/v2/specs/epa.gov/sdw/2019.10.15/sdw_rest_services.get_download")
q := baseURL.Query()
q.Set("qid", "example")
q.Set("output", "json")
q.Set("qcolumns", "example")
baseURL.RawQuery = q.Encode()
targetURL := baseURL.String()
req, _ := http.NewRequest("GET", targetURL, nil)
client := &http.Client{}
resp, _ := client.Do(req)
defer resp.Body.Close()
body, _ := io.ReadAll(resp.Body)
fmt.Println(string(body))
}require "net/http"
require "json"
uri = URI("https://api.apis.guru/v2/specs/epa.gov/sdw/2019.10.15/sdw_rest_services.get_download")
uri.query = URI.encode_www_form({
"qid" => "example",
"output" => "json",
"qcolumns" => "example"
})
http = Net::HTTP.new(uri.host, uri.port)
http.use_ssl = uri.scheme == "https"
req = Net::HTTP::Get.new(uri)
res = http.request(req)
puts JSON.parse(res.body)<?php
$url = "https://api.apis.guru/v2/specs/epa.gov/sdw/2019.10.15/sdw_rest_services.get_download?" . http_build_query([
"qid" => "example",
"output" => "json",
"qcolumns" => "example"
]);
$opts = ["http" => [
"method" => "GET",
]];
$ctx = stream_context_create($opts);
$res = file_get_contents($url, false, $ctx);
print_r(json_decode($res, true));GET_QID is passed with a query ID corresponding to a previously run get_systems query. It then returns a Systems object containing all matching water systems. The main purpose of GET_QID is for large querysets that contain multiple pages (responsesets) of output. GET_QID allows for pagination and fo
Hover any highlighted part to learn what it does
curl -X GET "https://api.apis.guru/v2/specs/epa.gov/sdw/2019.10.15/sdw_rest_services.get_qid?qid=example&output=JSONP&pageno=1&newsort=1&callback=example&qcolumns=example&descending=Y"
import requests
params = {
"qid": "example",
"output": "JSONP",
"pageno": "1",
"newsort": "1",
"callback": "example",
"qcolumns": "example",
"descending": "Y"
}
response = requests.get(
"https://api.apis.guru/v2/specs/epa.gov/sdw/2019.10.15/sdw_rest_services.get_qid",
params=params,
)
print(response.json())const url = new URL('https://api.apis.guru/v2/specs/epa.gov/sdw/2019.10.15/sdw_rest_services.get_qid');
url.searchParams.set('qid', 'example');
url.searchParams.set('output', 'JSONP');
url.searchParams.set('pageno', '1');
url.searchParams.set('newsort', '1');
url.searchParams.set('callback', 'example');
url.searchParams.set('qcolumns', 'example');
url.searchParams.set('descending', 'Y');
const response = await fetch(url);
const data = await response.json();
console.log(data);package main
import (
"fmt"
"io"
"net/http"
"net/url"
)
func main() {
baseURL, _ := url.Parse("https://api.apis.guru/v2/specs/epa.gov/sdw/2019.10.15/sdw_rest_services.get_qid")
q := baseURL.Query()
q.Set("qid", "example")
q.Set("output", "JSONP")
q.Set("pageno", "1")
q.Set("newsort", "1")
q.Set("callback", "example")
q.Set("qcolumns", "example")
q.Set("descending", "Y")
baseURL.RawQuery = q.Encode()
targetURL := baseURL.String()
req, _ := http.NewRequest("GET", targetURL, nil)
client := &http.Client{}
resp, _ := client.Do(req)
defer resp.Body.Close()
body, _ := io.ReadAll(resp.Body)
fmt.Println(string(body))
}require "net/http"
require "json"
uri = URI("https://api.apis.guru/v2/specs/epa.gov/sdw/2019.10.15/sdw_rest_services.get_qid")
uri.query = URI.encode_www_form({
"qid" => "example",
"output" => "JSONP",
"pageno" => "1",
"newsort" => "1",
"callback" => "example",
"qcolumns" => "example",
"descending" => "Y"
})
http = Net::HTTP.new(uri.host, uri.port)
http.use_ssl = uri.scheme == "https"
req = Net::HTTP::Get.new(uri)
res = http.request(req)
puts JSON.parse(res.body)<?php
$url = "https://api.apis.guru/v2/specs/epa.gov/sdw/2019.10.15/sdw_rest_services.get_qid?" . http_build_query([
"qid" => "example",
"output" => "JSONP",
"pageno" => "1",
"newsort" => "1",
"callback" => "example",
"qcolumns" => "example",
"descending" => "Y"
]);
$opts = ["http" => [
"method" => "GET",
]];
$ctx = stream_context_create($opts);
$res = file_get_contents($url, false, $ctx);
print_r(json_decode($res, true));Returns an array of public water systems that meet the specified search criteria.
Hover any highlighted part to learn what it does
curl -X GET "https://api.apis.guru/v2/specs/epa.gov/sdw/2019.10.15/sdw_rest_services.get_systems?p_co=example&p_cs=example&p_ct=example&p_fn=example&p_mr=Y&p_pn=Y&p_qs=example&p_st=example&p_sv=Y&p_act=Y&p_cuv=example&p_fea=W&p_ico=Y&p_iea=W&p_pbv=example&p_pid=example&p_qis=Z&p_qiv=0&p_reg=01&p_sdc=example&p_sfs=example&p_trb=example&p_ysl=W&p_zip=example&output=JSONP&p_feaa=A&p_feay=1&p_fips=example&p_idt1=example&p_idt2=example&p_ieaa=E&p_ieay=1&p_lcrv=example&p_owop=F&p_ysla=E&p_ysly=1&p_cuale=example&p_other=Y&p_pbale=example&p_pfeat=example&p_popsv=example&p_ss5yr=example&p_swtyp=SW&callback=example&p_cntysv=example&p_health=Y&p_pfead1=example&p_pfead2=example&p_pswpol=example&p_pswvio=Y&p_rc350v=example&p_systyp=CWS&qcolumns=example&queryset=1&p_sdc_ils=example&p_cms_flag=example&responseset=1"
import requests
params = {
"p_co": "example",
"p_cs": "example",
"p_ct": "example",
"p_fn": "example",
"p_mr": "Y",
"p_pn": "Y",
"p_qs": "example",
"p_st": "example",
"p_sv": "Y",
"p_act": "Y",
"p_cuv": "example",
"p_fea": "W",
"p_ico": "Y",
"p_iea": "W",
"p_pbv": "example",
"p_pid": "example",
"p_qis": "Z",
"p_qiv": "0",
"p_reg": "01",
"p_sdc": "example",
"p_sfs": "example",
"p_trb": "example",
"p_ysl": "W",
"p_zip": "example",
"output": "JSONP",
"p_feaa": "A",
"p_feay": "1",
"p_fips": "example",
"p_idt1": "example",
"p_idt2": "example",
"p_ieaa": "E",
"p_ieay": "1",
"p_lcrv": "example",
"p_owop": "F",
"p_ysla": "E",
"p_ysly": "1",
"p_cuale": "example",
"p_other": "Y",
"p_pbale": "example",
"p_pfeat": "example",
"p_popsv": "example",
"p_ss5yr": "example",
"p_swtyp": "SW",
"callback": "example",
"p_cntysv": "example",
"p_health": "Y",
"p_pfead1": "example",
"p_pfead2": "example",
"p_pswpol": "example",
"p_pswvio": "Y",
"p_rc350v": "example",
"p_systyp": "CWS",
"qcolumns": "example",
"queryset": "1",
"p_sdc_ils": "example",
"p_cms_flag": "example",
"responseset": "1"
}
response = requests.get(
"https://api.apis.guru/v2/specs/epa.gov/sdw/2019.10.15/sdw_rest_services.get_systems",
params=params,
)
print(response.json())const url = new URL('https://api.apis.guru/v2/specs/epa.gov/sdw/2019.10.15/sdw_rest_services.get_systems');
url.searchParams.set('p_co', 'example');
url.searchParams.set('p_cs', 'example');
url.searchParams.set('p_ct', 'example');
url.searchParams.set('p_fn', 'example');
url.searchParams.set('p_mr', 'Y');
url.searchParams.set('p_pn', 'Y');
url.searchParams.set('p_qs', 'example');
url.searchParams.set('p_st', 'example');
url.searchParams.set('p_sv', 'Y');
url.searchParams.set('p_act', 'Y');
url.searchParams.set('p_cuv', 'example');
url.searchParams.set('p_fea', 'W');
url.searchParams.set('p_ico', 'Y');
url.searchParams.set('p_iea', 'W');
url.searchParams.set('p_pbv', 'example');
url.searchParams.set('p_pid', 'example');
url.searchParams.set('p_qis', 'Z');
url.searchParams.set('p_qiv', '0');
url.searchParams.set('p_reg', '01');
url.searchParams.set('p_sdc', 'example');
url.searchParams.set('p_sfs', 'example');
url.searchParams.set('p_trb', 'example');
url.searchParams.set('p_ysl', 'W');
url.searchParams.set('p_zip', 'example');
url.searchParams.set('output', 'JSONP');
url.searchParams.set('p_feaa', 'A');
url.searchParams.set('p_feay', '1');
url.searchParams.set('p_fips', 'example');
url.searchParams.set('p_idt1', 'example');
url.searchParams.set('p_idt2', 'example');
url.searchParams.set('p_ieaa', 'E');
url.searchParams.set('p_ieay', '1');
url.searchParams.set('p_lcrv', 'example');
url.searchParams.set('p_owop', 'F');
url.searchParams.set('p_ysla', 'E');
url.searchParams.set('p_ysly', '1');
url.searchParams.set('p_cuale', 'example');
url.searchParams.set('p_other', 'Y');
url.searchParams.set('p_pbale', 'example');
url.searchParams.set('p_pfeat', 'example');
url.searchParams.set('p_popsv', 'example');
url.searchParams.set('p_ss5yr', 'example');
url.searchParams.set('p_swtyp', 'SW');
url.searchParams.set('callback', 'example');
url.searchParams.set('p_cntysv', 'example');
url.searchParams.set('p_health', 'Y');
url.searchParams.set('p_pfead1', 'example');
url.searchParams.set('p_pfead2', 'example');
url.searchParams.set('p_pswpol', 'example');
url.searchParams.set('p_pswvio', 'Y');
url.searchParams.set('p_rc350v', 'example');
url.searchParams.set('p_systyp', 'CWS');
url.searchParams.set('qcolumns', 'example');
url.searchParams.set('queryset', '1');
url.searchParams.set('p_sdc_ils', 'example');
url.searchParams.set('p_cms_flag', 'example');
url.searchParams.set('responseset', '1');
const response = await fetch(url);
const data = await response.json();
console.log(data);package main
import (
"fmt"
"io"
"net/http"
"net/url"
)
func main() {
baseURL, _ := url.Parse("https://api.apis.guru/v2/specs/epa.gov/sdw/2019.10.15/sdw_rest_services.get_systems")
q := baseURL.Query()
q.Set("p_co", "example")
q.Set("p_cs", "example")
q.Set("p_ct", "example")
q.Set("p_fn", "example")
q.Set("p_mr", "Y")
q.Set("p_pn", "Y")
q.Set("p_qs", "example")
q.Set("p_st", "example")
q.Set("p_sv", "Y")
q.Set("p_act", "Y")
q.Set("p_cuv", "example")
q.Set("p_fea", "W")
q.Set("p_ico", "Y")
q.Set("p_iea", "W")
q.Set("p_pbv", "example")
q.Set("p_pid", "example")
q.Set("p_qis", "Z")
q.Set("p_qiv", "0")
q.Set("p_reg", "01")
q.Set("p_sdc", "example")
q.Set("p_sfs", "example")
q.Set("p_trb", "example")
q.Set("p_ysl", "W")
q.Set("p_zip", "example")
q.Set("output", "JSONP")
q.Set("p_feaa", "A")
q.Set("p_feay", "1")
q.Set("p_fips", "example")
q.Set("p_idt1", "example")
q.Set("p_idt2", "example")
q.Set("p_ieaa", "E")
q.Set("p_ieay", "1")
q.Set("p_lcrv", "example")
q.Set("p_owop", "F")
q.Set("p_ysla", "E")
q.Set("p_ysly", "1")
q.Set("p_cuale", "example")
q.Set("p_other", "Y")
q.Set("p_pbale", "example")
q.Set("p_pfeat", "example")
q.Set("p_popsv", "example")
q.Set("p_ss5yr", "example")
q.Set("p_swtyp", "SW")
q.Set("callback", "example")
q.Set("p_cntysv", "example")
q.Set("p_health", "Y")
q.Set("p_pfead1", "example")
q.Set("p_pfead2", "example")
q.Set("p_pswpol", "example")
q.Set("p_pswvio", "Y")
q.Set("p_rc350v", "example")
q.Set("p_systyp", "CWS")
q.Set("qcolumns", "example")
q.Set("queryset", "1")
q.Set("p_sdc_ils", "example")
q.Set("p_cms_flag", "example")
q.Set("responseset", "1")
baseURL.RawQuery = q.Encode()
targetURL := baseURL.String()
req, _ := http.NewRequest("GET", targetURL, nil)
client := &http.Client{}
resp, _ := client.Do(req)
defer resp.Body.Close()
body, _ := io.ReadAll(resp.Body)
fmt.Println(string(body))
}require "net/http"
require "json"
uri = URI("https://api.apis.guru/v2/specs/epa.gov/sdw/2019.10.15/sdw_rest_services.get_systems")
uri.query = URI.encode_www_form({
"p_co" => "example",
"p_cs" => "example",
"p_ct" => "example",
"p_fn" => "example",
"p_mr" => "Y",
"p_pn" => "Y",
"p_qs" => "example",
"p_st" => "example",
"p_sv" => "Y",
"p_act" => "Y",
"p_cuv" => "example",
"p_fea" => "W",
"p_ico" => "Y",
"p_iea" => "W",
"p_pbv" => "example",
"p_pid" => "example",
"p_qis" => "Z",
"p_qiv" => "0",
"p_reg" => "01",
"p_sdc" => "example",
"p_sfs" => "example",
"p_trb" => "example",
"p_ysl" => "W",
"p_zip" => "example",
"output" => "JSONP",
"p_feaa" => "A",
"p_feay" => "1",
"p_fips" => "example",
"p_idt1" => "example",
"p_idt2" => "example",
"p_ieaa" => "E",
"p_ieay" => "1",
"p_lcrv" => "example",
"p_owop" => "F",
"p_ysla" => "E",
"p_ysly" => "1",
"p_cuale" => "example",
"p_other" => "Y",
"p_pbale" => "example",
"p_pfeat" => "example",
"p_popsv" => "example",
"p_ss5yr" => "example",
"p_swtyp" => "SW",
"callback" => "example",
"p_cntysv" => "example",
"p_health" => "Y",
"p_pfead1" => "example",
"p_pfead2" => "example",
"p_pswpol" => "example",
"p_pswvio" => "Y",
"p_rc350v" => "example",
"p_systyp" => "CWS",
"qcolumns" => "example",
"queryset" => "1",
"p_sdc_ils" => "example",
"p_cms_flag" => "example",
"responseset" => "1"
})
http = Net::HTTP.new(uri.host, uri.port)
http.use_ssl = uri.scheme == "https"
req = Net::HTTP::Get.new(uri)
res = http.request(req)
puts JSON.parse(res.body)<?php
$url = "https://api.apis.guru/v2/specs/epa.gov/sdw/2019.10.15/sdw_rest_services.get_systems?" . http_build_query([
"p_co" => "example",
"p_cs" => "example",
"p_ct" => "example",
"p_fn" => "example",
"p_mr" => "Y",
"p_pn" => "Y",
"p_qs" => "example",
"p_st" => "example",
"p_sv" => "Y",
"p_act" => "Y",
"p_cuv" => "example",
"p_fea" => "W",
"p_ico" => "Y",
"p_iea" => "W",
"p_pbv" => "example",
"p_pid" => "example",
"p_qis" => "Z",
"p_qiv" => "0",
"p_reg" => "01",
"p_sdc" => "example",
"p_sfs" => "example",
"p_trb" => "example",
"p_ysl" => "W",
"p_zip" => "example",
"output" => "JSONP",
"p_feaa" => "A",
"p_feay" => "1",
"p_fips" => "example",
"p_idt1" => "example",
"p_idt2" => "example",
"p_ieaa" => "E",
"p_ieay" => "1",
"p_lcrv" => "example",
"p_owop" => "F",
"p_ysla" => "E",
"p_ysly" => "1",
"p_cuale" => "example",
"p_other" => "Y",
"p_pbale" => "example",
"p_pfeat" => "example",
"p_popsv" => "example",
"p_ss5yr" => "example",
"p_swtyp" => "SW",
"callback" => "example",
"p_cntysv" => "example",
"p_health" => "Y",
"p_pfead1" => "example",
"p_pfead2" => "example",
"p_pswpol" => "example",
"p_pswvio" => "Y",
"p_rc350v" => "example",
"p_systyp" => "CWS",
"qcolumns" => "example",
"queryset" => "1",
"p_sdc_ils" => "example",
"p_cms_flag" => "example",
"responseset" => "1"
]);
$opts = ["http" => [
"method" => "GET",
]];
$ctx = stream_context_create($opts);
$res = file_get_contents($url, false, $ctx);
print_r(json_decode($res, true));Postman Setup Guide
- See official documentation for authentication and setup.
What can you build with U.S. EPA Enforcement and Compliance History Online (ECHO) - Safe Drinking Water Act?
U.S. EPA Enforcement and Compliance History Online (ECHO) - Safe Drinking Water Act is a Government API. Developers commonly use government APIs for:
- surfacing public datasets in citizen-facing apps
- building transparency and civic engagement tools
- accessing legislation, court records, and official data
- powering research and journalism tools
- creating compliance and regulatory monitoring dashboards
No authentication required. This API is open — no signup or key needed. Ideal for quick prototypes and public-facing features. U.S. EPA Enforcement and Compliance History Online (ECHO) - Safe Drinking Water Act is free to use, making it a low-risk choice to experiment with.
New to APIs? Read our beginner's guide · Learn about API keys · What is REST?