Inventory Endpoints¶
The Contrails.org API enables users with API keys to access a large historical dataset of flight contrail impact data from 2019 to nearly present-day. This dataset was generated by running sanitized ADS-B flight trajectories through CoCIP - effectively using the v1/trajectory API method for millions of flights.
There are two endpoints: one with flight-level information (summary), and one with minute-level detail (segments). Examples of both are below.
E-mail api@contrails.org to request an API key for yourself or your organization, or with any questions about this API endpoint or the backing dataset.
Inventory Summary Endpoint¶
First, we import needed dependencies, and get our environment set up with an API key and set up some constants.
[1]:
import os
import requests # pip install requests
import pandas as pd # pip install pandas
[ ]:
# Load API key
# (contact api@contrails.org if you need an API key)
URL = "https://api.contrails.org"
API_KEY = os.environ["CONTRAILS_API_KEY"]
HEADERS = {"x-api-key": API_KEY}
SUMMARY_ENDPOINT = "/v1/inventory/summary"
SEGMENTS_ENDPOINT = "/v1/inventory/segments"
Get summary data for a day¶
The v1/inventory/summary endpoint provides data for a single day at a time in Parquet file format. Each line of the file returned represents a summary of one flight and its contrail impact for each global commercial flight that started on that day.
We use Pandas to load the Parquet file into a Dataframe.
[3]:
params = {
"date": "2025-09-26" # ISO 8601 date string (YYYY-MM-DD) for the day of interest
}
r = requests.get(f"{URL}{SUMMARY_ENDPOINT}", params=params, headers=HEADERS)
print(f"HTTP Response Code: {r.status_code} {r.reason}\n")
filename = f"inventory_summary_{params['date']}.pq"
# write out response content as parquet file
with open(filename, "wb") as f:
f.write(r.content)
print(f"Wrote response content to {filename}\n")
HTTP Response Code: 200 OK
Wrote response content to inventory_summary_2025-09-26.pq
[4]:
# read parquet file with pandas
df = pd.read_parquet(filename)
print("Number of flights:", len(df))
print("Median flight length: ", df["flight_length_km"].median(), " km")
print(
"Median flight impact of warming contrail-producing flights (kg CO2e, GWP100):",
df[df["co2e_kg_gwp100"] > 0]["co2e_kg_gwp100"].median(),
)
df.head()
Number of flights: 91334
Median flight length: 1322.4753407517574 km
Median flight impact of warming contrail-producing flights (kg CO2e, GWP100): 5112.035
[4]:
| flight_id | flight_number | airline_iata | callsign | tail_number | aircraft_type_icao | engine_uid | departure_airport_icao | departure_airport_iata | arrival_airport_icao | ... | is_eu_mrv | time_start | time_end | flight_length_km | co2e_kg_gwp20 | co2e_kg_gwp50 | co2e_kg_gwp100 | aircraft_performance_model | pycontrails_version | nvpm_data_source | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 80619 | 30c204ea-2d15-48dc-ba54-b52e0495caf3 | DL86 | DL | DAL86 | N851NW | A332 | 7PW082 | KDTW | DTW | EDDF | ... | False | 2025-09-26 | 2025-09-26 07:34:00 | 6836.323468 | 1225554.48 | 582716.47 | 350954.24 | PSFlight | 0.60.3 | ICAO EDB (SCOPE11 with T4/T2) |
| 79583 | 488c86f9-19e1-48eb-905b-a1b1e4487148 | UA710 | UA | UAL710 | N19141 | B752 | 5RR039 | KIAD | IAD | EIDW | ... | False | 2025-09-26 | 2025-09-26 06:16:00 | 5606.502400 | 615589.37 | 292695.32 | 176282.41 | PSFlight | 0.60.3 | ICAO EDB (SCOPE11 with T4/T2) |
| 40705 | e710d9cd-0c0f-42ae-bc37-0120a39ccb35 | AC890 | AC | ACA890 | C-FIVM | B77W | 01P21GE217 | CYYZ | YYZ | LIRF | ... | False | 2025-09-26 | 2025-09-26 07:46:00 | 7199.946338 | 194567.90 | 92511.53 | 55717.17 | PSFlight | 0.60.3 | ICAO EDB (T4/T2) |
| 41313 | 29aad324-6d94-4a13-ba5b-2d2b26cae845 | QR714 | QR | QTR31J | A7-ANF | A35K | 01P21RR125 | KIAH | IAH | OTHH | ... | False | 2025-09-26 | 2025-09-26 13:57:00 | 13855.419299 | 185233.09 | 88073.09 | 53044.02 | PSFlight | 0.60.3 | ICAO EDB (T4/T2) |
| 82924 | 0b7f918b-69c6-4302-9fb7-f31c9e3fa865 | CM470 | CM | CMP470 | HP-1847CMP | B738 | 8CM051 | MPTO | PTY | CYYZ | ... | False | 2025-09-26 | 2025-09-26 04:43:00 | 3918.736636 | 142796.94 | 67895.90 | 40891.85 | PSFlight | 0.60.3 | ICAO EDB (SCOPE11 with T4/T2) |
5 rows × 21 columns
Inventory Segments Endpoint¶
The v1/inventory/segments endpoint provides minute level segment information for all global flights, returned in hourly chunks in Parquet file format. Each line of the file returned represents a single minute of one flight providing information on the flight and its contrail impacts.
The segments endpoint provides minute level segment information for all global flights, returned in hourly chunks. Access requires a spire-level API token, which are restricted to select partners.
E-mail api@contrails.org with subject Common ADS-B Access to learn more about how your organization can participate in this program.
Get segment data for a day¶
[7]:
segments_params = {
"date": "2025-09-26T13" # ISO 8601 date string with hour (YYYY-MM-DDThh) for the day and hour of interest
}
r = requests.get(f"{URL}{SEGMENTS_ENDPOINT}", params=segments_params, headers=HEADERS)
print(f"HTTP Response Code: {r.status_code} {r.reason}\n")
filename = f"inventory_segments_{segments_params['date']}.pq"
# write out response content as parquet file
with open(filename, "wb") as f:
f.write(r.content)
print(f"Wrote response content to {filename}\n")
HTTP Response Code: 200 OK
Wrote response content to inventory_segments_2025-09-26T13.pq
[8]:
# read parquet file with pandas
segments = pd.read_parquet(filename)
print("Number of flights:", segments["flight_id"].nunique())
print(
"Total flight length above 20000 ft:",
segments[segments["median_altitude_ft"] > 20000]["chunk_len_km"].sum(),
)
print(
"Total persistent contrail length: ",
segments["total_persistent_contrail_length_km"].sum(),
" km",
)
print(
"Median flight impact of warming contrail-producing flights (kg CO2e, GWP100):",
segments[segments["co2e_kg_gwp100"] > 0]["co2e_kg_gwp100"].median(),
)
segments.head()
Number of flights: 14805
Total flight length above 20000 ft: 7061773.071769587
Total persistent contrail length: 406700.2025778936 km
Median flight impact of warming contrail-producing flights (kg CO2e, GWP100): 797.3
[8]:
| flight_id | flight_number | airline_iata | callsign | tail_number | aircraft_type_icao | engine_uid | departure_airport_icao | departure_airport_iata | departure_scheduled_time | ... | nvpm_data_source | lat_start | lon_start | lat_end | lon_end | chunk_len_km | median_altitude_ft | icao_address | total_persistent_contrail_length_km | max_contrail_lifetime_h | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 80726 | 00014219-fc26-4684-8547-a91a21ab96ff | P47338 | P4 | APK7338 | 5N-BYH | E295 | 04P20PW201 | None | None | NaT | ... | ICAO EDB (T4/T2) | 9.045813 | 7.289462 | 9.029164 | 7.333164 | 5.185974 | 3698.0 | 06425E | 5.185974 | NaN |
| 584152 | 00014219-fc26-4684-8547-a91a21ab96ff | P47338 | P4 | APK7338 | 5N-BYH | E295 | 04P20PW201 | None | None | NaT | ... | ICAO EDB (T4/T2) | 9.029164 | 7.333164 | 8.942500 | 7.324470 | 9.704090 | 5798.0 | 06425E | 9.704090 | NaN |
| 136319 | 000542c5-ccaa-47e2-911c-959e525adb8b | AA770 | AA | AAL770 | N424AN | A21N | 01P20CM132 | KCLT | CLT | 2025-09-26 11:05:00 | ... | ICAO EDB (T4/T2) | 29.877245 | -80.813834 | 29.755771 | -80.803743 | 13.542867 | 34003.0 | A50A88 | NaN | NaN |
| 199120 | 000542c5-ccaa-47e2-911c-959e525adb8b | AA770 | AA | AAL770 | N424AN | A21N | 01P20CM132 | KCLT | CLT | 2025-09-26 11:05:00 | ... | ICAO EDB (T4/T2) | 29.755771 | -80.803743 | 29.638979 | -80.793728 | 13.023170 | 33966.0 | A50A88 | NaN | NaN |
| 261957 | 000542c5-ccaa-47e2-911c-959e525adb8b | AA770 | AA | AAL770 | N424AN | A21N | 01P20CM132 | KCLT | CLT | 2025-09-26 11:05:00 | ... | ICAO EDB (T4/T2) | 29.638979 | -80.793728 | 29.516619 | -80.783014 | 13.645594 | 33966.0 | A50A88 | NaN | NaN |
5 rows × 31 columns