About the API
The USWTDB API allows for programmatic access to the U.S. Wind Turbine Database. Creation of the USWTDB API was meant to extend USWTDB visibility, expand user base, and create more productive internal workflows. The availability of the public API makes it possible for third party developers to build value-added applications leveraging the USWTDB. The API is HTTP-based (over SSL), and is compatible with any programming language that has an HTTP library (including directly in your browser). In this documentation, we'll show some examples of USWTDB API requests using cURL, a command-line tool and library for transferring data with different parameters and methods. cURL provides a generic way to demonstrate HTTP requests and responses and allows users to translate similar requests into their specific language of choice. The USWTDB API endpoint conforms to the design principles of Representational State Transfer (REST) and uses the JSON data format for responses. Retrieval of turbine data from the USWTDB API requires a standard GET request. Additional methods that submit or change USWTDB data require token-based authentication.
Resource Endpoint
Resource endpoints referenced in this documentation are only accessible via https and have a base path of https://eersc.usgs.gov/api/uswtdb/v1/. The base path, when combined with additional query parameters, constitute the full endpoint request. As an example, let’s say you wanted to get turbine level information from the USWTDB for turbine ID 3038257. To do this, you'd simply combine the base path https://eersc.usgs.gov/api/uswtdb/v1, with the desired resource /turbines, and append your query string ?&case_id=eq.3038257. The full request is shown below (if you don't have cURL, simply paste the URL in quotes below into your browser to see the response).
curl -i -X GET "https://eersc.usgs.gov/api/uswtdb/v1/turbines?&case_id=eq.3038257"
API Response
The response to the above request (below) is returned as JavaScript Object Notation (JSON) data. JSON is a light-weight, human readable, language-independent format for structuring data. It is used primarily to transmit data between the server and client web application. From our above query, we're requesting data for a single object (case_id = 3038257). An object is indicated by curly brackets, where everything inside of the curly brackets is part of the object.
{
"case_id": 3038257,
"faa_ors": "19-022348",
"faa_asn": "2011-WTE-22311-OE",
"usgs_pr_id": 20977,
"eia_id": null,
"t_state": "IA",
"t_county": "Story County",
"t_fips": "19169",
"p_name": "AG Land 4",
"p_year": 2012,
"p_tnum": 1,
"p_cap": 1.6,
"t_manu": "GE Wind",
"t_model": "GE1.6-82.5",
"t_cap": 1600,
"t_hh": 80,
"t_rd": 82.5,
"t_rsa": 5345.62,
"t_ttlh": 121.3,
"t_retrofit": 0,
"t_retro_yr": null
"t_conf_atr": 3,
"t_conf_loc": 3,
"t_img_date": "1/1/2013",
"t_img_src": "NAIP",
"xlong": -93.3549,
"ylat": 41.90419
}
The two significant parts that make up JSON are keys and values. Together they make a key/value pair. We can see the returned turbine object above has 24 key/value pairs. Key value pairs are comma separated and follow a specific syntax, with the key, followed by a colon, followed by the value. The first line from the return above is key/value pair "case_id": 3038257. The key is "case_id" and the value is 3038257. A key is always a string enclosed in quotation marks, whereas a value can be a string, number, Boolean expression, array, or object.
Key/Value Codes
Upon a successful response (see Status Codes section), the USWTDB API will return turbine objects consisting of key/value pairs. Below is a list of USWTDB keys, related value types, and an explanation of what each key means. Turbine attribute data were gathered from the Federal Aviation Administration's Digital Obstacle File (DOF) and Obstruction Evaluation Airport Airspace Analysis Dataset (OE-AAA), the American Clean Power Association (ACP), Lawrence Berkeley National Laboratory, the U.S. Geological Survey, and additional online sources. In cases where data from these sources were unknown or missing, a "null" value was assigned to the key.
Key | Value Type | Key Description |
---|---|---|
case_id | number (integer) | Unique stable identification number. |
faa_ors | string | Unique identifier for cross-reference to the Federal Aviation Administration (FAA) digital obstacle files. |
faa_asn | string | Unique identifier for cross-reference to the FAA obstruction evaluation airport airspace analysis dataset. |
usgs_pr_id | number (integer) | Unique identifier for cross-reference to the 2014 USGS turbine dataset. |
eia_id | number (integer) | Plant ID from Energy Information Administration (EIA). |
t_state | string | State where turbine is located. |
t_county | string | County where turbine is located. |
t_fips | string | State and county fips where turbine is located, based on spatial join of turbine points with US state and county. |
p_name | string | Name of the wind power project that the turbine is a part of. Project names are typically provided by the developer; some names are identified via other internet resources, and others are created by the authors to differentiate them from previous projects. Values are that were unknown were assigned a name based on the county where the turbine is located. |
p_year | number (integer) | Year that the turbine became operational and began providing power. Note this may differ from the year that construction began. |
p_tnum | number (integer) | Number of turbines in the wind power project. |
p_cap | number (float) | Cumulative capacity of all turbines in the wind power project in megawatts (MW). |
t_manu | string | Turbine manufacturer - name of the original equipment manufacturer of the turbine. |
t_model | string | Turbine model - manufacturer's model name of each turbine. |
t_cap | number (integer) | Turbine rated capacity - stated output power at rated wind speed from manufacturer, ACP, and/or internet resources in kilowatts (kW). |
t_hh | number (float) | Turbine hub height in meters (m). |
t_rd | number (float) | Turbine rotor diameter in meters (m). |
t_rsa | number (float) | Turbine rotor swept area in square meters (m2). |
t_ttlh | number (float) | Turbine total height from ground to tip of a blade at its apex in meters (m). |
t_offshore | number (integer) | Indicator of whether the turbine is offshore. 0—indicates turbine is not offshore. 1—indicates turbine is offshore. |
t_retrofit | number (integer) | Indicator of whether the turbine has been partially retrofit after initial construction (e.g., rotor and/or nacelle replacement). 0 indicates no known retrofit. 1 indicates yes known retrofit. |
t_retro_yr | number (integer) | Year in which the turbine was partially retrofit. |
t_conf_atr | number (integer) | Level of confidence in the turbine attributes. 1—No confidence: no attribute data beyond total height and year, 2—Partial confidence: incomplete information or substantial conflict between, 3—Full confidence: complete information, consistent across multiple data sources. |
t_conf_loc | number (integer) | Level of confidence in turbine location. 1— No turbine shown in image; image has clouds; imagery older than turbine built date, 2— Partial confidence: image shows a developed pad with concrete base and/or turbine parts on the ground, 3— Full confidence: image shows an installed turbine. |
t_img_date | number (integer) | Date of image used to visually verify turbine location. Note if source of image is NAIP, the month and day were set to 01/01. |
t_img_src | string | Source of image used to visually verify turbine location. |
xlong | number (float) | Longitude of the turbine point, in decimal degrees. |
ylat | number (float) | Latitude of the turbine point, in decimal degrees. |
Status Codes
The USWTDB API returns appropriate HTTP status codes for every request. Response status codes indicate whether a specific request has been successfully completed. USWTDB API responses are grouped into four classes: successful responses (2XX), redirects (3XX), client errors (4XX), and server errors (5XX). An exhaustive list of status codes are defined in the RFC 2616. The most common USWTDB API status codes are listed in the table below.
Code | Description |
---|---|
200 | OK - The request has succeeded. Clients can read the result of the request in the body and the headers of the response. The response is sent after a successful GET request. |
201 | Created - The request has succeeded, and a new resource has been created as a result of it. The response is sent after a successful POST request. |
206 | Partial Content - The request has succeeded and contains the requested range of data, as described in the Range header of the request. |
400 | Bad Request - The request could not be understood by the server due to malformed syntax. The message body will contain more information. |
401 | Unauthorized - The server understood the request but is refusing to fulfill it. This error is likely due to authentication not being provided or invalid token. The message body will contain more information. |
404 | Not Found - The requested resource could not be found. This error can be due to a temporary or permanent condition. |
409 | Conflict - A request conflicts with the current state of the server. Most likely due to duplicate key value when attempting a POST. The message body will contain more information. |
500 | Internal Server Error - Indicates that the server encountered an unexpected condition that prevented it from fulfilling the request. |
502 | Bad Gateway - The USWTDB API is down or being upgraded. |
503 | Service Unavailable - The server is currently unable to handle the request, commonly due to the server being overloaded. |
Pagination
When making requests to the USWTDB API, it's possible to receive a large amount of data in the response. The API has controls in place that let you paginate the results, to make returns more manageable and avoid extraneous network traffic. These controls let you set limit and offset via either request headers, or query parameters. Every API response contains Content-Range headers which describe the size of results. By default, the response includes the current range, and, if sent with Prefer: count=exact in the request, the total number of results. When using request headers to limit results, you simply specify the range of rows desired. For example, the request below returns the first 250 turbines (note that the offset numbering is zero-based).
GET /turbines HTTP/1.1
Range: 0-249
Prefer: count=exact
Since we sent our preference Prefer: count=exact in the request header, we get a Content-Range response (below) that includes the total size of the table (58,188 records). This is particularly useful when rendering a 'last' link in a pagination control.
HTTP/1.1 206 Partial Content
Content-Range: 0-249/58188
Paging the dataset can also be achieved by taking an offset and limit as query parameters. In the example below, the limit and offset were added to the query so that 50 (limit) turbine records are returned starting from the 300th (offset) record. Note that the API always returns range headers in the response, even if you use query parameters to paginate the query.
$ curl -i -X GET "https://eersc.usgs.gov/api/uswtdb/v1/turbines?&offset=300&limit=50"
Sorting
You can reorder the records in the response by using order in the query string. The parameter uses a comma separated list of turbine columns and can contain directions asc (ascending) or desc (descending) if desired. As an example (below), let's say we wanted to return turbine records sorted by the number of turbines per project (p_tnum) in ascending order, and then sorted by the year the project went online (p_year) in descending order.
$ curl -i -X GET "https://eersc.usgs.gov/api/uswtdb/v1/turbines?&order=p_tnum.desc,p_year.asc"
The USWTDB contains null values where data attributes are unknown or missing. Null values for any desired key can be sorted in either direction by appending nullsfirst or nullslast to the order query. In the example below, 100 turbine records are queried, ordered by turbine model, where null values are sent to the end of the return:
$ curl -i -X GET "https://eersc.usgs.gov/api/uswtdb/v1/turbines?&order=t_model.nullslast&limit=100"
Row Filtering
The USWTDB API supports filtering table rows by appending the property (or multiple properties), the filter operator, and the filter value to the request. Filters can keep or exclude table rows using simple operators that compare against specified key values. Applying filters to the request allows for more efficient, faster API responses because unneeded data is withheld by the server prior to API return. This is particularly useful when users are only interested in a subset of data from the USWTDB.
To apply row filtering, simply append the ? query string parameter and a valid filter expression (see Filter Operators section) to your request. In the example below, we'll filter our return to show only turbines that were installed in 1995:
$ curl -i -X GET "https://eersc.usgs.gov/api/uswtdb/v1/turbines?&p_year=eq.1995"
Multiple parameters can be logically conjoined using the & parameter, allowing for filtering on as many attributes as desired. In the request below, we'll further refine our query to only return turbines that were installed in 1995 and had a rated capacity greater than 2.5 MW:
$ curl -i -X GET "https://eersc.usgs.gov/api/uswtdb/v1/turbines?&p_year=eq.1995&t_cap=gt.200"
Filter Operators
The table below contains the available operators used to filter returns by USWTDB key values. For each available operator, a real-world example is included showing how the operator is used to filter API responses. Note that some of the examples combine the query operators with additional functions described previously in the documentation. As previously noted, query strings should be appended to the USWTDB API base path https://eersc.usgs.gov/api/uswtdb/v1/.
Operator | Meaning | Example of Operator in Request |
---|---|---|
eq | equals | turbines?&t_state=eq.AK Return turbines that are located in Alaska. |
gt | greater than | turbines?&t_cap=gt.3&t_state=eq.OH Return turbines that have a rated capacity greater than 3 MW that are located in Ohio. |
gte | greater than or equal | turbines?&t_hh=gte.100&p_year=eq.2012 Return turbines that have a hub height greater or equal to 100 meters that were constructed in 2012. |
lt | less than | turbines?&p_tnum=lt.45&t_manu=eq.Vestas Return turbines in projects containing less than 45 turbines that were manufactured by Vestas. |
lte | less than or equal | turbines?&t_conf_loc=lte.2&ylat=gt.42 Return turbines that have a location confidence less than or equal to 2 (see attribute definitions for t_conf_loc in table above) and are north of 42° latitude. |
neq | not equal | turbines?&t_manu=neq.Gamesa&select=count Count the number of turbines where the manufacturer is not Gamesa. Note that you can return a count on any query by simply appending &select=count to the query string. |
like | LIKE operator (use * as wildcard) | turbines?&t_img_date=like.*/20*&order=case_id Return turbines that have "/20" somewhere in the image date string and return them in alphabetical order by identification number. Note the like operator is case-sensitive (use ilike operator for case-insensitive queries). |
ilike | ILIKE operator (use * as wildcard) | turbines?&p_name=ilike.Wind*&order=t_cap.desc,t_ttlh.asc Return turbines that have project names that begin with "Wind", "wind", "WIND", etc., and return them sorted by descending rated capacity, and ascending total height. Note the ilike operator is case-insensitive. |
in | one of a list of values | turbines?&t_state=in.(VA,WV)&select=p_name,p_year Return turbines that are located in either Virginia or West Virginia, and only show the keys "project name" and "project year" in response. |
is | checking for exact equality (null,true,false) | turbines?&or=(t_cap.is.null,t_cap.gte.3500) Return turbines where rated capacity is either null or is greater than or equal to 3500 kW. Note that multiple parameters are logically disjoined by using or. |
not | negates another operator | turbines?&and=(t_manu.not.ilike.*China*,t_cap.gt.3500) Return turbines where the manufacturer name does not contain "China" and rated capacity is greater or equal to 3000 kW. Note that multiple parameters are logically conjoined by using and. |
Column Filtering
By default, the USWTDB API returns data with all columns (attribute fields) in the response. If you're only interested in a subset of these, you can specify which columns are returned using the select parameter in the query string. This effectively tells the API to withhold all unneeded data fields, resulting in a far more efficient response. In the example below, let's say you were only interested a response that included project name, turbine capacity, and the state where the turbine was located (we'll also sort by project name in descending order):
$ curl -i -X GET "https://eersc.usgs.gov/api/uswtdb/v1/turbines?&select=p_name,t_cap,t_state&order=p_name.desc"
Our response (below) only returns the columns passed in our select parameter:
{"p_name":"Zotos","t_cap":1650,"t_state":"NY"},
{"p_name":"Zotos","t_cap":1650,"t_state":"NY"},
{"p_name":"Zephyr Wind Project","t_cap":1500,"t_state":"OH"},
...
In some cases, you may want to rename (alias) a column name on API return. Aliases are often used to make column names more readable or easier to understand. This can be achieved by prefixing the column name with a column alias, followed by the : operator. Let's say you'd like to display API returns limited to project name, turbine capacity, and rotor diameter, but feel that the default column name for rotor diameter t_rd needs to be spelled out as "rotor_diameter". To do this, we'd simply append the normal select parameter to our query and add the column rename prefix rotor_diameter to t_rd:
$ curl -i -X GET "https://eersc.usgs.gov/api/uswtdb/v1/turbines?&select=p_name,t_cap,rotor_diameter:t_rd"
Our response (below) returns the columns passed in our select parameter, but with t_rd column renamed to rotor_diameter:
{"p_name":"Agassiz Beach","t_cap":660,"rotor_diameter":47.00},
{"p_name":"Air Force (Barnstable)","t_cap":1500,"rotor_diameter":77.00},
{"p_name":"Alite Wind Farm","t_cap":3000,"rotor_diameter":90.00},
...
The USWTDB API allows columns to be converted from one data type to another through casting. Examples of common casts are strings to date type, numeric type to text, or character strings to numeric values. Note that not every data type can be cast into every other data type, and invalid casting will result in an code 400 error from the API. To cast a column, suffix it with a :: plus the desired type. Let's say you'd like to cast the default string type t_img_date as a date type, and cast the default integer type t_cap as a string type. To do this we'll apply our casts to the appropriate columns:
$ curl -i -X GET "https://eersc.usgs.gov/api/uswtdb/v1/turbines?&select=t_img_date::date,t_cap::text"
Our response (below) returns the selected columns formatted with the desired casts:
{"t_img_date":"2017-04-21","t_cap":"1000"},
{"t_img_date":"2017-04-21","t_cap":"660"},
{"t_img_date":"2012-01-01","t_cap":"1500"},
...
Authorization
The creation of USWTDB was jointly funded by the U.S. Department of Energy via the Lawrence Berkeley National Laboratory, the U.S. Geological Survey, and the American Clean Power Association. The database is being continuously updated through collaboration among these partners and as such, requires authorized access to the API by selected collaborators. For public users, the USWTDB API acts as read-only resource and allows standard HTTP GET (read) requests to be received successfully without authentication. For any additional incoming HTTP methods, including POST (create records), PUT (replace/update records), PATCH (patial update records), and DELETE (deletes a record), authorization is required.
JSON Web Tokens
Authorized users can authenticate with the USWTDB API by sending requests with a JSON Web Token (JWT). A JWT is a JSON object used as a compact and self-contained way for securely transmitting information between an authorized user and the API server. JWT's consist of three components: a header, a payload, and a signature. JWT signatures are cryptographically signed using a password known to USWTDB administrators and the server. Since token holders don't have access to the password, they cannot modify the contents of the JWT without receiving a 401 (Unauthorized) response from the API. Once the user has made a successful connection to the API using the JWT, each subsequent request will include the token, allowing the user authorized access without having to set up the token again until its expiration. Tokens distributed to authorized users will have expiration explicitly set via the payload in the signing key. Authorized users can request a JWT by contacting a USWTDB API administrator.
Authorized Requests
Once the JWT is received by the authorized user, API authenticated requests can be sent with the token to the API server. This is done by adding the token via the Authorization header with the Bearer authentication scheme. In the example below, let's update the turbine manufacturer t_manu value for turbine ID 636 via a PATCH request method. We'll send the data as JSON but could alternatively send as CSV by setting Content-Type: text/csv. The request will include an HTTP header containing the authentication token:
curl -X PATCH "https://eersc.usgs.gov/api/uswtdb/v1/turbines?&case_id=eq.636" \
-H 'Authorization: Bearer {your token here}' \
-H 'Content-Type: application/json' \
-d '{ "t_manu": "GE Wind" }'
Bulk inserts work just like single row inserts except that you provide either a JSON array of objects having uniform keys, or multiple lines in CSV format. In many cases, users may wish to insert new rows to the database and update existing rows via a single operation (UPSERT). To do this, simply POST with the Prefer: resolution=merge-duplicates header.
curl -X POST "https://eersc.usgs.gov/api/uswtdb/v1/turbines?&case_id=eq.636" \
-H 'Authorization: Bearer {your token here}' \
-H 'Prefer: resolution=merge-duplicates' \
-H 'cache-control: no-cache' \
-d 'case_id,p_name,p_year,p_tnum,p_cap,t_manu,t_model \
3018370,Jiminy Peak Ski Resort,2007,1,1.5,GE Wind \
3045115,Judith Gap,2005,90,135,GE Wind'
Note that authorization claims via database roles will be included in the payload of the token. If authorization claims are changed during the lifetime of the token, the changes will not become effective until a new token is issued.