JavaScript is disabled on your browser.

For full functionality of this page it is necessary to enable JavaScript. Here are the instructions how to enable JavaScript in your web browser.

USWTDB API

The USWTDB API allows for programmatic access to the U.S. Wind Turbine Database (USWTDB). The API is based on REST principles, where data are accessed via standard HTTPS requests to a dedicated API endpoint. Use the USWTDB API to programmatically query data through apps, stay in sync with USWTDB updates, and post new turbine data (authenticated users). Here we cover the basics of USWTDB API terminology and structure, and detail the various operations you can perform with the API.

Lawrence Berkeley National Laboratory American Wind Energy Association

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 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"

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,
	"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_conf_atr": 3,
	"t_conf_loc": 3,
	"t_img_date": "1/1/2013",
	"t_img_srce": "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.

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 Wind Energy Association (AWEA), 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 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.
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, AWEA, 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_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_srce 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.

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.

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"

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"

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"

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.

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"},
 ...

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 Wind Energy 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.

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.

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.