Feature: Expose per-flight CO2 emissions from API response
Summary
Google Flights returns estimated CO2 emissions for every flight in the API response, but fli currently discards this data during parsing. Adding emissions to FlightResult would make fli the only programmatic tool that surfaces Google's per-flight carbon estimates.
Where the data lives
The emissions data is in leg_block[22] of the raw API response, alongside the flight details already being parsed in _parse_flights_data. Specifically:
| Index |
Field |
Example (JFK-LAX nonstop) |
Unit |
[22][7] |
Flight CO2 emissions |
240000 |
grams CO2 |
[22][8] |
Route typical (median) emissions |
364000 |
grams CO2 |
[22][10] |
Route high emissions benchmark |
411000 |
grams CO2 |
[22][3] |
% difference from typical |
-34 |
percentage points |
Verified across multiple flights, routes, and cabin classes. The values match what Google Flights displays in its UI (e.g., "240 kg CO2, 34% less than typical").
Proposed changes
1. Add emissions fields to FlightResult
class FlightResult(BaseModel):
legs: list[FlightLeg]
price: NonNegativeFloat
currency: str | None = None
duration: PositiveInt
stops: NonNegativeInt
# New fields (optional to avoid breaking existing consumers)
emissions_grams: int | None = None # per-flight CO2 in grams
typical_emissions_grams: int | None = None # route median CO2 in grams
emissions_diff_pct: int | None = None # % vs typical (-34 = 34% less)
2. Parse emissions in SearchFlights._parse_flights_data
# In _parse_flights_data, after existing parsing:
emissions_grams = None
typical_emissions_grams = None
emissions_diff_pct = None
try:
emissions_block = data[0][22]
if emissions_block and len(emissions_block) > 10:
emissions_grams = emissions_block[7]
typical_emissions_grams = emissions_block[8]
emissions_diff_pct = emissions_block[3]
except (IndexError, TypeError):
pass
3. Surface in CLI and MCP output
Add an --emissions flag or include by default in --format json. For the MCP server, include in the tool response so AI assistants can factor emissions into recommendations.
Why this matters
- Google is the only major flight search that provides per-flight emissions estimates, and right now there's no programmatic way to access them
- The
EmissionsFilter and SortBy.EMISSIONS options already exist in fli, but users can't see the actual numbers they're filtering/sorting by
- Growing demand from developers building sustainability-aware travel tools
Testing notes
I verified the data across:
- Multiple routes (JFK-LAX, LAX-SYD, LAX-MEL)
- Nonstop and connecting flights
- Economy and business class
The [22] block is consistently present. When emissions data isn't available, the block is either None or the relevant indices are None, so the try/except fallback handles it cleanly.
Feature: Expose per-flight CO2 emissions from API response
Summary
Google Flights returns estimated CO2 emissions for every flight in the API response, but
flicurrently discards this data during parsing. Adding emissions toFlightResultwould makeflithe only programmatic tool that surfaces Google's per-flight carbon estimates.Where the data lives
The emissions data is in
leg_block[22]of the raw API response, alongside the flight details already being parsed in_parse_flights_data. Specifically:[22][7][22][8][22][10][22][3]Verified across multiple flights, routes, and cabin classes. The values match what Google Flights displays in its UI (e.g., "240 kg CO2, 34% less than typical").
Proposed changes
1. Add emissions fields to
FlightResult2. Parse emissions in
SearchFlights._parse_flights_data3. Surface in CLI and MCP output
Add an
--emissionsflag or include by default in--format json. For the MCP server, include in the tool response so AI assistants can factor emissions into recommendations.Why this matters
EmissionsFilterandSortBy.EMISSIONSoptions already exist infli, but users can't see the actual numbers they're filtering/sorting byTesting notes
I verified the data across:
The
[22]block is consistently present. When emissions data isn't available, the block is either None or the relevant indices are None, so the try/except fallback handles it cleanly.