The CavanReports API provides over 60 web services for querying data and computing metrics. Each web service is accessible as a REST API and documented using the OpenAPI standard.
These web services are consumed by the CavanReports web apps and can be accessed programmatically as described in the Integration section below.
Visit the Service Registry for links to the CavanReports OpenAPI documentation. The web services are grouped into categories. The "basic" and "flight" categories are shown below. Individual web service endpoints are listed under each category.
The CavanReports OpenAPI documentation is connected to the live server. This means that queries can be executed directly through the OpenAPI user interface (UI). To do so, enter your API key by clicking the Authorize button at the top of the page. The OpenAPI UI will automatically include your API Key when sending requests to the server.
To request an API key or to schedule a demo, please contact us at reports@cavansolutions.com.
After entering your API key, a good place to start running queries is with the set of "basic" web services. These do not require any inputs and simply return the latest arrival, latest departure, or latest TBFM configuration.
The response from the /latest-arrival web service is shown below, which returns information about the latest arrival at any airport. It can be accessed with a GET request and requires no parameters.
Most of the CavanReports API endpoints require input parameters. These inputs can define the time range for a query or inputs to a metrics calculation. The OpenAPI documentation defines the types of inputs required by each web service, also known as the request model.
To view the request model for a particular service, click on the "Model" link. For example, the request model for the /arrival-list service is shown below. This web service returns a list of arrivals at a particular airport during a time range. The time range and destination parameters are required, as indicated by the *. The origin parameter is optional.
The format of each CavanReports web service response is documented in OpenAPI. This serves as a data dictionary for response fields, which streamlines integration.
For example, the reponse model for the /arrival-list web service is shown below. Common to most CavanReports web services, the response includes a "meta" object providing user information, record count, and query time. The "data" array provides the query results.
OpenAPI documentation is useful for exploring each web service. Integration into an analytics pipeline, however, would likely be done programmatically such as in Python or Node.js. A Python setup is described below.
The following Python modules need to be installed:
pip install requests
pip install python-dotenv
pip install matplotlib
Most CavanReports API endpoints require an API key. Technically speaking, the API key needs to be set in the "api_key" request header. The Examples section shows how this is done in Python.
Regardless of programming language, it is a best practice to avoid storing your API key in source code. Rather, load the API key from an environment variable (.env) file. A .env file contains key value pairs and is a widely used configuration file format across programming languages.
In your working directory on your local machine, create a new file called .env
Define a variable called API_KEY and set it to the value of your API key as shown below
API_KEY=YourApiKeyGoesHere
Note: If using git, it is also recommended to add the .env extension in your .gitignore file.
After completing the Integration steps, the following examples show how to connect to the CavanReports API in Python.
Note: Date ranges may need to be adjusted throughout the examples based on data retention and user-role limits.
import requests
from dotenv import load_dotenv
import os
import json
# load environment variables to get API key from .env file
load_dotenv()
api_key = os.getenv("API_KEY")
# define URL of API endpoint
url_api = "https://cavanreports.com/api/arrival-list"
# define payload. This is where the request parameters are set
payload = {
"destination": "KDEN",
"arrival_timestamp_minimum": "2022-01-02T00:00:00Z",
"arrival_timestamp_maximum": "2022-01-02T01:00:00Z"
}
# send request and extract json content from response
res_json = requests.post(url_api, json=payload, headers={"api_key": api_key}).json()
# process response json... or simply print it
print(json.dumps(res_json, indent=2))
The /arrival-list web service response is shown below. The "meta" object provides user data, role limits, and query statistics. The "data" object contains an array of query records. The flight_id field is a unique flight identifier used throughout CavanReports.
{
"meta": {
"userdata": {
"username": "tmyers_trial",
"role": "trial",
"limits": {
"timestamp_minimum": "2022-01-01T00:00:00.000Z",
"timestamp_maximum": "2022-01-07T00:00:00.000Z",
"adaptation": [
"NFDC_200716",
"NFDC_211230",
"ZMP_T4.8.4_24.0",
"ZLA_T4.8.4_24.0",
"ZBW_T4.8.4_25.0",
"ZMA_T4.8.4_24.0",
"ZOB_T4.8.4_32.0",
"ZTL_T4.8.4_27.0",
"ZFW_T4.8.4_24.0",
"ZHU_T4.8.4_23.0",
"ZNY_T4.8.4_29.0",
"ZDV_T4.8.4_28.0",
"ZOA_T4.8.4_23.0",
"ZAU_T4.8.4_25.0",
"ZJX_T4.8.4_25.0",
"ZDC_T4.8.4_23.0",
"ZID_T4.8.4_26.0",
"ZKC_T4.8.4_25.0",
"ZLC_T4.8.4_25.0",
"ZME_T4.8.4_23.0",
"ZAB_T4.10.1_7.0",
"ZSE_T4.8.4_24.0"
]
}
},
"recordCount": 55,
"queryTime": 1.075
},
"data": [
{
"flight_id": "UAL1422_KIND_KDEN_1641068820",
"callsign": "UAL1422",
"origin": "KIND",
"destination": "KDEN",
"arrival_timestamp": "2022-01-02T00:02:00.000Z"
},
{
"flight_id": "UAL2267_KSLC_KDEN_1641074880",
"callsign": "UAL2267",
"origin": "KSLC",
"destination": "KDEN",
"arrival_timestamp": "2022-01-02T00:03:00.000Z"
},...
The same request can be sent via OpenAPI, Node.js, CURL or other programmatic methods. The identical request and response executed in the CavanReports OpenAPI UI is shown below.
The /flight-summary web service provides additional information for each flight. The request schema for this web service includes a broad range of optional parameters including origin, destination, time range or simply a flight_id or flight_id_list.
Here we take a flight_id from the prior example and use it to request additional information from the /flight-summary web service.
The flight_id values will differ by date range and airport.
import requests
from dotenv import load_dotenv
import os
import json
# load environment variables to get API key from .env file
load_dotenv()
api_key = os.getenv("API_KEY")
# define URL of API endpoint
url_api = "https://cavanreports.com/api/flight-summary"
# define payload. This is where the request parameters are set
payload = {
"flight_id_list":["UAL448_KBOS_KDEN_1641067500"]
}
# send request and extract json content from response
res_json = requests.post(url_api, json=payload, headers={"api_key": api_key}).json()
# process response json... this time print only the "data" object from the response
print(json.dumps(res_json["data"], indent=2))
The "data" object from the /flight-summary web service response is shown below. The response fields are defined in the OpenAPI documentation.
[
{
"flight_id": "UAL448_KBOS_KDEN_1641067500",
"callsign": "UAL448",
"origin": "KBOS",
"destination": "KDEN",
"departure_timestamp": "2022-01-01T20:21:00.000Z",
"arrival_timestamp": "2022-01-02T00:40:00.000Z",
"config": "N_VFR3",
"airline": "UAL",
"aircraft_type": "B739",
"engine_class": "J",
"weight_class": "L",
"etd": "2022-01-01T20:21:00.000Z",
"etd_type": "ACTUAL",
"eta": "2022-01-02T00:40:00.000Z",
"eta_type": "ACTUAL",
"tbfm_rwy": "35R",
"stream_class": "DEN_LAWGR_JET",
"tbfm_fix": "PPINT",
"sta_set": 1,
"frozen": 1,
"frozen_arrival": 1,
"frozen_timestamp": "2022-01-02T00:05:30.000Z",
"frozen_sta": "2022-01-02T00:23:25.000Z",
"frozen_eta": "2022-01-02T00:22:59.000Z",
"frozen_sta_delay": 26,
"route": 1,
"arrival_adaptation": "ZDV_T4.8.4_28.0",
"arrival_artcc": "ZDV",
"departure_adaptation": "ZBW_T4.8.4_25.0",
"departure_artcc": "ZBW"
}
]
Air Route Traffic Control Center (ARTCC) "center" boundaries are available through the /nas-center-boundaries web service. Center boundaries are retrieved and plotted.
import requests
from dotenv import load_dotenv
import os
import json
import matplotlib.pyplot as plt
# load environment variables to get API key from .env file
load_dotenv()
api_key = os.getenv("API_KEY")
# define URL of API endpoint
url_api = "https://cavanreports.com/api/nas-center-boundaries"
# send request and extract json content from response
res_json = requests.get(url_api, headers={"api_key": api_key}).json()
# initialize figure
fig = plt.figure(figsize=[12, 8])
ax = plt.subplot(111)
ax.set_xlim(-130, -65)
ax.set_ylim(20, 52)
# parse and plot coordinates for each center
for ctr in res_json['data']:
print('plotting center', ctr['name'])
coordinates = ctr['coordinates'][0]
lon = [item[0] for item in coordinates]
lat = [item[1] for item in coordinates]
ax.plot(lon, lat, linewidth=1, color=(1, 0, 0.6))
plt.show()
The /route-conformance web service is demonstrated for computing the distance and direction between a sample flown track and route. This metric is computed automatically as part of the /flight-object webservice and displayed in the Dashboard web app.
import requests
from dotenv import load_dotenv
import os
import json
import matplotlib.pyplot as plt
# load environment variables to get API key from .env file
load_dotenv()
api_key = os.getenv("API_KEY")
# define URL of API endpoint for center boundaries
url_ctr = "https://cavanreports.com/api/nas-center-boundaries"
# send request for center boundaries and extract json content from response
ctr_json = requests.get(url_ctr, headers={"api_key": api_key}).json()
# initialize figure
fig = plt.figure(figsize=[12, 8])
ax = plt.subplot(111)
ax.set_xlim(-130, -105)
ax.set_ylim(30, 45)
# parse and plot coordinates for each center
for ctr in ctr_json['data']:
print('plotting center', ctr['name'])
coordinates = ctr['coordinates'][0]
lon = [item[0] for item in coordinates]
lat = [item[1] for item in coordinates]
ax.plot(lon, lat, linewidth=1, color=(1, 0, 0.6))
# Compute route conformance (distance between flown track and joined route)
# joined route = combination of flight plan and nominal interior route computed (see /route-join)
flown_track = [[-122, 37], [-123, 37], [-123, 37], [-122, 38], [-120, 39], [-113, 38], [-111, 40]]
flight_plan = [[-122, 37], [-119, 39], [-111, 40]]
# API endpoint for computing route comformance
# Automatically computed as part of the /flight-object web service
url_rte_conf = "https://cavanreports.com/api/route-conformance"
# define payload. lineA = flown track. lineB = flight plan.
payload = {
"lineA": flown_track,
"lineB": flight_plan
}
# send request to compute route conformance and extract json content from response
rte_conf_json = requests.post(url_rte_conf, json=payload, headers={"api_key": api_key}).json()
# plot flight plan
lon_fp = [item[0] for item in flight_plan]
lat_fp = [item[1] for item in flight_plan]
ax.plot(lon_fp, lat_fp, linewidth=2, color=(0, 1, 0))
# plot flown track
lon_track = [item[0] for item in flown_track]
lat_track = [item[1] for item in flown_track]
ax.plot(lon_track, lat_track, linewidth=1, color=(0.5, 0.5, 1))
# label route conformance each point in the flown track
for i, conf in enumerate(rte_conf_json):
print(i)
print(conf)
plt.text(lon_track[i],lat_track[i], round(conf['pointLineDistancePositiveRight']))
plt.show()
For additional information or to schedule a demo, please contact us at reports@cavansolutions.com