Introduction
Welcome to the Data Dashboard API (DDAPI) Usage Documentation page. A RESTful API web service has been implemented for programmatic access to the same underlying datasets used on the dashboard pages. This documentation explains how to use the API endpoints to retrieve records from each currently supported dataset.
The general usage, including data sorting and pagination, as well as the structure of requests and responses is described below. Specific details for each endpoint are also included. In addition, this documentation page allows authorized users to interactively invoke the API by submitting requests and receiving responses by simply pasting and submitting text in the available forms.
Aside from the Try it out functions on this page, the API cannot be used with a typical web browser. You cannot paste a request and body into the URL bar of the browser. For requests for assistance regarding the Data Dashboard API or to report data related issues, please e-mail FDADataDashboard@fda.hhs.gov.
Authentication
To obtain the credentials necessary to use the API, please submit authorization key requests using the online ORA Unified Logon application. Upon arriving at the site, existing users will be prompted to enter their email and password. New users will be prompted to create an account. The request for API credentials must include:
- Valid email address
- First Name
- Last Name
- Organization
If Organization is not applicable, specify “Self” or “Consumer” in the credentials request email.
The provided email address will be set as the Authorization-User value for authentication and will also be used for communication regarding the credentials, including sending the FDA-generated Authorization-Key value. Once established, the API credentials must be passed in the header of each API request as shown below in Request Headers.
To try using the API once you have credentials, first click the AUTHORIZATION button located on the page to enter and submit the Authorization-User and Authorization-Key. The result of that authentication request must be successful for any subsequent trial requests to function properly.
API Usage
SSL Requirements
API requests must be sent from a client using TLS 1.2.
Request Headers
Valid API requests must include certain headers in addition to the formatted request body. The general format for the request is:
POST <endpoint URL> Content-Type: application/json Authorization-User: <email address> Authorization-Key: <FDA-generated key> { <request body> }
Required headers include:
Header Name | Value |
---|---|
Content-Type | application/json |
Authorization-User | The approved email address |
Authorization-Key | The FDA-generated key |
Request Body Structure and Parameters
Currently, all endpoints use the HTTP POST method. Requests require a body in valid JSON format that may include the following key/value pairs (parameters). Some keys are required in the request and others are optional. All required keys included in the request must have corresponding values, although the values can be empty. Defaults will be used if empty values are provided for required keys. Optional keys cannot have empty values. Instead, omit optional keys from the request to use the default value. Only the valid key names listed will be accepted in a request. Any other key included in a request will cause an error response.
Key Name (Parameter) | Request Usage | Value Type | Parameter Meaning | Default Value |
---|---|---|---|---|
columns | Required | Array delimited with [ ] containing strings separated by commas. | Indicates which fieldnames (columns) to return in the result set. | All columns are returned. |
filters | Required | JSON object delimited by { } containing key/value pairs separated by commas. | Defines fieldnames and values to narrow result set returned. | Return all rows in the data. |
returntotalcount | Optional | Boolean (true or false) | Determines whether the total count of records matching the request is returned in the response key totalrecordcount. | false, totalrecordcount is not returned in the response. |
rows | Optional | Single numeric value | The maximum number of rows to return in the result set. | 5000, the maximum number of rows supported. |
sort | Required | Single string value in " | The fieldname (column) to use for sorting the result set. | The unique primary key of the table. |
sortorder | Required | Single string value in " | The order of sorting applied (asc or desc). | asc (ascending) |
start | Optional | Single numeric value | The first row to be returned within the matching result set. | Rows are returned starting with row 1. |
If the columns key is included in the request body, the value must be set to a [ ] delimited array of fieldname strings, separated by commas. To indicate a single field, use an array of one value (e.g. [“FEINumber”]).
If the filters key is included in the request body, the value must be a { } delimited JSON object which itself is a set of key/value pairs. Within the filters value object, each included key is a valid dataset-specific fieldname, while the value(s) associated with each fieldname key represent what should be searched/matched in the dataset to determine the result set. See Field Names and Filters Format below, for more details on finding valid names plus an explanation and examples of how to specify values for them.
Valid values for the returntotalcount key are the Booleans true and false. Typically, you should only include this key if you want the value in one response. See Paging Results, below for more usage information.
The only valid values for the sortorder key are asc or desc (case insensitive).
A maximum of 5000 result rows will be returned per response. Each response will also include the actual number of rows returned. Together with the value of start, these may be used to page through results larger than the maximum page size. See Paging Results, below for more information.
Some example request bodies are shown below:
Minimal Request Body (all defaults will be used)
{ "sort" : "", "sortorder" : "", "filters" : {}, "columns" : [] }
Request Body with Search and Result Parameters
{ "start" : 1, "rows" : 5, "sort" : "ShipmentID", "sortorder" : "ASC", "filters" : { "FEINumber":[3004249948,3002875226] }, "columns" : [ "FEINumber", "FirmName", "CountryName" ] }
Field Names
Each individual endpoint section below contains a link to a table defining the fieldnames that may be used in requests with the filters, columns and sort key/value parameters for that dataset endpoint. Note that some fieldnames can be returned in the response results but cannot be used to filter the result set. In the field definition tables:
- Field Name lists the supported names for the dataset endpoint. Fieldnames differ by dataset and are case sensitive.
- Check marks will indicate whether each fieldname can be included in filters, columns or sort parameters.
- The Match Type value specifies how search term values in the request body will be compared to dataset values when selecting rows to return in the response result set.
The Match Type values include:
Match Type | Description |
---|---|
Exact | Dataset value must be identical to the supplied request filter search term value. |
Partial | Dataset value must contain the supplied request filter search term value. Dataset value will be compared using LIKE %<filter search term>%. |
Range | Dataset values compared as >= From value and/or <= To value depending on which are provided. See Date Fields and Date Ranges. |
Filters Format
The filters key in the request must have a matching JSON value. That corresponding value is a JSON object enclosed in { } that is nested within the JSON of the request. Since JSON is made up of key/value pairs, each key in the nested filters value is a fieldname and the corresponding value is the search terms for that fieldname within the dataset.
Key Value | +-------------------------------+-------------------------------+ | | Key Value Key Value | | | | | | | | "filters" : {FieldName : [Searchterm, Searchterm], FieldName : [Searchterm]}
In general, one or more search terms may be included and most must be entered as quoted strings, separated by commas within a [ ] delimited array. A few special format exceptions are described below. Although the value array may contain multiple search terms, a single term in an array with a size of one is still a valid entry. For example, to search for the field FEINumber with a value of 3004249948, the filter expression would be:
"filters": { "FEINumber":[3004249948] }
To add a second search term for the same field, simply add another value to the array:
"filters": { "FEINumber":[3004249948,3002875226] }
Include other fields in the filter by inserting additional fieldname key/value pairs. Separate each pair with a comma as shown below:
"filters": { "FEINumber":[3004249948,3002875226], "LegalName":["Delicato"] }
Field datatypes are significant in the filters parameter and affect how values must be supplied as search terms. FEINumber, InspectionID and CitationID are defined as numeric. Any fields with containing date information are defined as date and all others are defined as string.
- Fields defined as string must be provided with string values enclosed in "".
- Fields defined as numeric must be provided with numeric values, meaning they should not be in "".
- Fields defined as date must be provided with valid dates enclosed in "".
Filters Format Exceptions
- For date fields, both the fieldname (key) and the search term (value) are handled differently. This is explained below in Date Fields and Date Ranges and Date Field Format.
- The API request will handle NULLs and distinguishes between NULL values and empty strings. The JSON object null is a valid search term for string and numeric fields. It is never enclosed in "" because that is not valid JSON.
- The empty string "" is a valid search term for only for string fields. It cannot be used as a filter with numerics like FEINumber or with date fields.
Note that the array value may be used to search for either null or empty string at the same time. To request any rows with either condition, enter a filter similar to:
"filters": { "AddressLine2":[null,""], }
Date Fields and Date Ranges
Date fields may be included in request filters in three ways, supporting a single value as well as ranges.
- Including a key that is the fieldname with the suffix From appended (E.g. InspectionEndDateFrom) will match values >= (greater than or equal) to the provided date value.
- Including a key that is the fieldname with the suffix To appended (E.g. InspectionEndDateTo) will match values <= (less than or equal) the provided date value.
- The From and To range parameters may be supplied separately or together to form expressions >= a From date, <= a To date or a range of values between From and To dates. Setting the From and To dates to the same value will match values = (equal) to the provided date value.
Date Field Format
Filters for date fields must be specified differently from other fields in a request.
- Filters for date fields must use the From and To forms (described above) as the key rather than the fieldname.
- Unlike other fields, the corresponding value array to be used as the search term may only contain a single value. If the value array for a From or To date contains more than one search term, the first one will be used and all others will be ignored.
- Date values for request filters may be supplied in common date formats. Time components are
not included in the date values. Recommended formats include:
- MM-DD-YYYY
- MM/DD/YYYY
- YYYY-MM-DD
- Note: Date values in API responses will be returned in ISO format YYYY-MM-DD.
The example below demonstrates how to enter a range search for RefusalDate between 11/27/2001
and 11/27/2020:
"filters" : { "RefusalDateFrom":["2001-11-27"], "RefusalDateTo":["2020-11-27"] }
Response Format
The API returns a response in JSON format, based on information supplied in the body of the request:
- The JSON response will consist of key/value pairs.
- Keys and values are separated by a colon.
- Each key/value pair is separated by a comma.
- Keys will be quoted strings, and values will be a valid JSON data type (string, number, object, array, boolean or null).
- JSON objects are surrounded by curly braces {}.
The general format of the result response is shown below:
{ "statuscode":number, "message":"string", "resultcount":number, "result":[] }
The response fields include:
Field Name | Description |
---|---|
message | A text message about the status of the request. |
resultcount | A number indicating the total count of rows returned. |
totalrecordcount | A number indicating the total count of records matching the criteria in the request. Only returned if the request contains returntotalcount set to true. |
statuscode | A numeric code indicating the success or failure of the request. |
result | An array of objects containing key/value pairs. |
Error responses may also include these additional fields describing validation errors found in the request:
Field Name | Description |
---|---|
invalid_columns | An array of invalid column names if the columns value in the request contains errors. Returned with statuscode 406. |
invalid_filters | An array of invalid column names if the filters value in the request contains errors. Returned with statuscode 413. |
invalid_filters_type | An array of column names, used in the filters parameter of the request, whose value is an incorrect type. May be returned with statuscode 403. (Typically this results when a filters value is not supplied as an array within [ ]. See Filters Format for more details.) |
invalid_parameters | An array of invalid key names (parameters) in the request body. May be returned with statuscode 403. |
fieldnames_with_invalid_values | An array of column names, used in the filters parameter of the request, whose value does not match the datatype of the fieldname. Returned with statuscode 414. |
missing_parameters | An array of missing required key names (parameters) in the request body. Returned with statuscode 410. |
duplicate_parameters | An array of duplicate key names (parameters) in the request body. Returned with statuscode 416. |
duplicate_filters | An array of duplicate fieldnames in the filters parameter. Returned with statuscode 418. |
duplicate_columns | An array of duplicate fieldnames in the columns parameter. Returned with statuscode 419. |
Response message and statuscode values
Possible values returned in the statuscode and message fields include:
statuscode | message |
---|---|
400 | Success. |
401 | Not Authorized. |
402 | Invalid JSON in request. |
403 | Invalid request body format. |
404 | Invalid request endpoint. |
405 | HTTP method not allowed. |
406 | Invalid fieldname in request body columns parameter value. |
407 | Invalid fieldname in request body sort parameter value. |
408 | Request body start parameter must be numeric and greater than 0. |
409 | Request body rows parameter must be numeric and greater than 0. |
410 | Required parameter(s) missing from request body. |
411 | Invalid value in request body sortorder parameter. Valid values are asc and desc. |
412 | No results found. |
413 | Invalid fieldname in request body filters parameter item key. |
414 | Invalid values in request body filters parameter for the following item(s). |
415 | Request body rows parameter must be <= 5000. |
416 | Duplicate request body parameters are not allowed. |
417 | Invalid input value in request body parameter. |
418 | Duplicate fieldnames are not allowed in filters. |
419 | Duplicate fieldnames are not allowed in columns. |
Response Result Rows
Each object in the result array represents one row and contains a key/value pair for every fieldname provided in the columns parameter of the request body. If the columns parameter is not provided in the request body, then all available columns will be returned in each row.
The value of the rows key in the request body may be used to control the size of the response. The number of rows returned will be one of:
- The value provided in the rows parameter of the request body.
- A maximum of 5000 if the rows parameter is not provided in the request body.
- The number of remaining rows matching the request body criteria if less than any of the above.
The resultcount in the response will contain the actual number of rows returned in the result array. If no results match the request, then:
- resultcount will be returned set to the value 0.
- result will be returned as an empty array.
Paging Results
Paging forward may be achieved using several API features. One method is to start with the total number of records matching a request and then continue incrementing start by the page size until that total number of rows has been returned. Including the returntotalcount key set to true in a valid request body, will cause the response to include the corresponding key totalrecordcount with the count of all matching records. That value may be divided by the requested page size to compute the number of request cycles needed to return the entire result matching the search criteria. When doing this, however, it is recommended to only include returntotalcount in the request for the first page in order to avoid the overhead of recomputing and returning the same, unchanging value back for every other subsequent request.
A second way to page forward is by continuously summing the returned value of resultcount with the previous value of start in the request body, and then iteratively making new requests with start updated to that new value until resultcount is less than the expected maximum page size as determined by either the rows parameter of the request body or the default. For example, to page through a desired result page size of 50 rows, the first request would set start to 1 and rows to 50. Assuming more than 50 records match any other request body settings, the first valid response would return 50 in resultcount. The next request should then set start to 51 (i.e. previous start + resultcount = 1 + 50). The process could continue until the value of resultcount is less than 50, indicating the response contains the last page of results. The returntotalcount key can be used together with this method also. Note that regardless of whether the total record count value is returned, if the actual number of matches happens to be an exact multiple of the page size used, then the response for the last page with data will have rows set to that page size and any subsequent page request would then be returned with a rows value of zero. In other words, given a request with rows set to 10 and data with 20 actual matches, two paged requests would each return resultcount set to 10. You can stop at that point if you know in advance there are exactly 20 or you could wait for the next request to return resultcount set to 0.
Sorting Results
The result array will be sorted by the fieldname provided in the sort parameter of the request body. If the sort parameter is not provided in the request body, the API will determine the order from a unique primary key.
Date Value Format
Date values in API responses will be returned in ISO format YYYY-MM-DD. Time components are not included in the date values.
Null Values
The API responses will handle NULLs and distinguish between NULL values and empty strings. A NULL value in the response indicates that data is not present for a fieldname (column) in a row. The JSON value for that condition will appear as null. Columns in the response with a string datatype may also have a non-NULL value that is empty (e.g. no actual text for AddressLine2). The JSON value for that condition will appear as "".
A response containing both types of null values is shown below:
{ "statuscode": 400, "message": "Success", "resultcount": 1, "result": [ { "FEINumber": "9999999999", "FirmName": "Company Name, Inc.", "AddressLine1": "1120 Somewhere Road", "AddressLine2": "", "City": "Locationville", "State": "ON", "ZipCode": "", "CountryCode": "CA", "CountryName": "", "DistrictCode": "NYK-DO", "DistrictDescription": null, "IndustryCode": null, "IndustryCodeDescription": null, "ProductCategory": "Devices", "ProductCode": "88LDT", "ProductCodeDescription": "REAGENT, GENERAL PURPOSE", "RefusalDate": "2021-01-01", "ShipmentID": 1, "FDASampleAnalysis": "No ", "PrivateLabAnalysis": "No ", "RefusalCharges": "118,508", "FirmProfile": null } ] }
Example Request and Response
A complete HTTP example request and corresponding response are shown below:
Example Data Dashboard API request
{ "start" : 1, "rows" : 10, "sort" : "ProductCode", "sortorder" : "ASC", "filters" : { "FEINumber":[3003378587,1000117386,3008091479] }, "columns" : [ "FEINumber", "FirmName", "CountryCode", "ProductCode", "RefusalDate" ] }
Example Data Dashboard API response
{ "statuscode": 400, "message": "Success.", "resultcount": 3, "result": [ { "FEINumber": "3003378587", "FirmName": "Company 1", "CountryCode": "VN", "ProductCode": "16AGT64", "RefusalDate": "2010-09-05" }, { "FEINumber": "1000117386", "FirmName": " Company 2, Inc", "CountryCode": "US", "ProductCode": "77EWO", "RefusalDate": "2015-10-01" }, { "FEINumber": "3008091479", "FirmName": " Company 3", "CountryCode": "MX", "ProductCode": "94V07", "RefusalDate": "2018-10-04" } ] }
API Endpoints
The available Data Dashboard API endpoints are listed below. Click an endpoint link below to expand the accordion and display details specific to its use as well as the option to try using it on the page.
The API endpoint definitions are also available for download in OpenAPI 3.0 JSON format. The file ddapi.json may be imported into a variety of REST client tools to aid development.
Endpoint URL Format
Endpoint URLs are constructed from the following components:
Protocol Name | Protocol Scheme | Fully Qualified Domain Name (FQDN) | Base URL | Endpoint |
---|---|---|---|---|
SSL | https:// | api-datadashboard.fda.gov | /v1 | Varies by dataset |
Complete URLs take the form of: https://api-datadashboard.fda.gov/v1/<endpoint>. The actual URLs for submitting requests are shown in the Try It Out section of each endpoint.
Try It Out!
Inspections Classifications Field Definitions
Examples of Request body to retrieve Inspections Classifications
Request body to retrieve data using all default parameters values, returning all fields and the maximum number of rows:
{ "returntotalcount" : true, "sort" : "", "sortorder" : "", "filters" : {}, "columns" : [] }
Request body with filters combining Classification containing the words "Voluntary Action" and InspectionEndDate range starting from "2018-11-27" until now, sorted ascending by InspectionEndDate, limited to 100 rows, and returning the 5 selected columns:
{ "start" : 1, "rows":100, "returntotalcount" : true, "sort" : "InspectionEndDate", "sortorder" : "ASC", "filters" : { "Classification":["Voluntary Action"], "InspectionEndDateFrom":["2018-11-27"] }, "columns" : [ "FEINumber", "LegalName", "InspectionID", "Classification", "InspectionEndDate" ] }
Request body with filter InspectionEndDate range, sorted ascending by InspectionEndDate, limited to 10 rows, and returning the 5 selected columns:
{ "start" : 1, "rows" : 10, "sort" : "InspectionEndDate", "sortorder" : "ASC", "filters" : { "InspectionEndDateFrom":["2001-11-27"], "InspectionEndDateTo":["2020-11-27"] }, "columns" : [ "FEINumber", "LegalName", "InspectionID", "Classification", "InspectionEndDate" ] }
Request URL
Response Body
Response Content-Type: application/json; charset=utf-8
Inspections Citations Field Definitions
Examples of Request body to retrieve Inspections Citations
Request body to retrieve data using all default parameters values, returning all fields and the maximum number of rows:
{ "returntotalcount" : true, "sort" : "", "sortorder" : "", "filters" : {}, "columns" : [] }
Request body filtering InspectionEndDate range starting from the earliest date until "2020-11-27", sorted descending by InspectionEndDate, limited to 100 rows, and returning the 5 selected columns:
{ "start" : 1, "rows" : 100, "sort" : "InspectionEndDate", "sortorder" : "DESC", "returntotalcount" : true, "filters" : { "InspectionEndDateTo":["2020-11-27"] }, "columns" : [ "InspectionEndDate", "FEINumber", "LegalName", "CitationID", "InspectionID" ] }
Request body filtering multiple FEINumber values, sorted ascending by LegalName, limited to 1000 rows, and returning the 4 selected columns:
{ "start" : 1, "rows" : 1000, "sort" : "LegalName", "sortorder" : "ASC", "returntotalcount" : true, "filters" : { "FEINumber":[3003570895,3007755021,3006647331,3001452914,1121950] }, "columns" : [ "FEINumber", "LegalName", "CitationID", "InspectionID" ] }
Request URL
Response Body
Response Content-Type: application/json; charset=utf-8
Compliance Actions Field Definitions
Examples of Request body to retrieve Compliance Actions
Request body to retrieve data using all default parameters values, returning all fields and the maximum number of rows:
{ "returntotalcount" : true, "sort" : "", "sortorder" : "", "filters" : {}, "columns" : [] }
Request body with filters combining ProductType values "Biologics" or "Drugs", ActionType value “Injunction” and ActionTakenDate range starting from "2022-01-01" until now, sorted descending by ActionTakenDate, limited to 50 rows, and returning the 5 selected columns:
{ "start" : 1, "rows": 50, "returntotalcount" : true, "sort" : "ActionTakenDate", "sortorder" : "DESC", "filters" : { "ProductType":["Biologics", "Drugs"], "ActionType" :["Injunction"], "ActionTakenDateFrom":["2022-01-01"] }, "columns" : [ "FEINumber", "LegalName", "CaseInjunctionID", "ActionType", "ActionTakenDate" ] }
Request body with filter ActionTakenDate range, sorted ascending by ActionTakenDate, limited to 10 rows, and returning the 5 selected columns:
{ "start" : 1, "rows" : 10, "sort" : "ActionTakenDate", "sortorder" : "ASC", "filters" : { "ActionTakenDateFrom":["2022-09-07"], "ActionTakenDateTo":["2022-09-07"] }, "columns" : [ "FEINumber", "LegalName", "ProductType", "ActionType", "ActionTakenDate" ] }
Request URL
Response Body
Response Content-Type: application/json; charset=utf-8
Import Refusals Field Definitions
Examples of Request body to retrieve Import Refusals
Request body to retrieve data using all default parameters values, returning all fields and the maximum number of rows:
{ "returntotalcount" : true, "sort" : "", "sortorder" : "", "filters" : {}, "columns" : [] }
Request body with filters combining two fields, and returning the 5 selected columns:
{ "start" : 1, "rows" : 3, "sort" : "ProductCode", "sortorder" : "ASC", "returntotalcount" : true, "filters" : { "CountryCode" : ["JP","MX"], "ProductCodeDescription":["RECEIVER"] }, "columns" : [ "FEINumber", "FirmName", "CountryCode", "ProductCode", "RefusalDate" ] }
Request body with filters combining FEINumber and RefusalDate range, sorted descending by RefusalDate, limited to 10 rows, and returning the 5 selected columns:
{ "start" : 1, "rows" : 10, "returntotalcount" : true, "sort" : "RefusalDate", "sortorder" : "DESC", "filters" : { "FEINumber":[3003378587,1000117386,3008091479], "RefusalDateFrom":["2001-11-27"], "RefusalDateTo":["2020-11-27"] }, "columns" : [ "FEINumber", "FirmName", "CountryCode", "ProductCode", "RefusalDate" ] }
Request URL
Response Body
Response Content-Type: application/json; charset=utf-8