Carbon labels are showing up everywhere — booking flows, expense tools, ESG dashboards, offset checkouts. But "this flight emits 847 kg of CO₂ per passenger" is the output of a real calculation with real inputs, and if you're building one of those labels you need to understand what goes into it before you trust a number. This post walks through the formula for a flight's carbon emissions, the data sources each step depends on, and how to get an auditable estimate by API instead of maintaining your own emission-factor tables.

The formula, from the top

At its core, a flight's CO₂ estimate is a short chain of multiplications:

total_fuel_kg   = f(distance, aircraft_type)      # how much jet fuel the flight burns
total_CO2_kg    = total_fuel_kg × 3.16            # every kg of jet fuel → 3.16 kg CO2
per_pax_CO2_kg  = (total_CO2_kg × pax_share) / passengers

Three things drive the whole result:

  1. Distance — longer flight, more fuel. But fuel burn isn't linear with distance: takeoff and climb are disproportionately thirsty, so a 500 km hop burns more per kilometre than a 5,000 km haul.
  2. Aircraft type — a wide-body burns far more than a regional jet, but it also carries far more people. What matters for a per-passenger label is fuel burn divided by seats.
  3. Passenger share and load — freight in the hold offsets some fuel to cargo, and empty seats raise everyone's share. The estimate allocates a fraction of total fuel to passengers, then divides by how many are aboard.

The constant 3.16 is not an approximation to argue about — it's the stoichiometric amount of CO₂ produced by completely burning one kilogram of jet kerosene, and it's fixed by chemistry. Everything else in the chain is where the modelling — and the data — lives.

A close-up of an airliner's turbofan engine intake and nacelle

The data sources you actually need

Each input in that chain comes from somewhere, and the quality of your estimate is the quality of these sources:

  • A distance between two airports. The floor is the great-circle distance (the haversine formula over airport coordinates). Better is the actual flown distance, which is longer than great-circle because of routing, holds, and ATC vectors.
  • Fuel-burn factors per aircraft category. This is the hard part to maintain yourself: a table mapping aircraft types to fuel consumption at distance, grouped into categories like regional turboprop, narrow-body single-aisle, and long-haul wide-body. The recognized reference is the ICAO Carbon Emissions Calculator methodology (Doc 9988), the standard used for aviation CO₂ disclosure.
  • A passenger count and load assumption, to turn a whole-aircraft number into a per-person one.

CO₂ vs CO₂e: the radiative forcing question

Here's the part most naive calculators get wrong: CO₂ is not aviation's whole climate impact. Contrails and high-altitude ozone formation cause additional warming, and accounting for them roughly doubles the figure. This multiplier is the Radiative Forcing Index (RFI), commonly applied at 1.9×. When you include it, you're no longer reporting CO₂ — you're reporting CO₂e (CO₂ equivalent), the total climate impact.

Neither figure is "wrong," but they're different numbers and you must disclose which one you show. A pure-CO₂ label understates real climate impact; a CO₂e label is more complete but roughly double, which surprises users comparing you against a CO₂-only competitor. Pick a primary disclosure and label it.

Getting an estimate by API

Rather than maintain Doc 9988 fuel tables and category factors yourself, SkyLink API's carbon estimate endpoint takes a route and returns the full calculation with its inputs exposed for audit. The simplest call is airport-pair mode:

curl "https://skylink-api.p.rapidapi.com/carbon/estimate?departure_icao=EGLL&arrival_icao=KJFK&aircraft_type=B77W&passengers=280" \
  -H "X-RapidAPI-Key: $RAPIDAPI_KEY" \
  -H "X-RapidAPI-Host: skylink-api.p.rapidapi.com"
{
  "departure_icao": "EGLL",
  "arrival_icao": "KJFK",
  "aircraft_type": "B77W",
  "aircraft_category": "wide_body_large",
  "distance_km": 5539.8,
  "passengers": 280,
  "co2_kg_total": 271451.4,
  "co2_kg_per_passenger": 847.3,
  "rfi_applied": false,
  "rfi_factor": 1.9,
  "co2_equivalent_kg_total": null,
  "methodology": "ICAO-Doc9988",
  "confidence": "high",
  "distance_source": "haversine"
}

Notice the response is auditable: it shows the distance_km it used, the aircraft_category it mapped your type into, the passengers count, the methodology, and a confidence rating — so a label backed by this can explain itself rather than presenting a bare number.

To include radiative forcing, set include_rfi=true and read the co2_equivalent_kg_* fields (which are null otherwise):

curl "https://skylink-api.p.rapidapi.com/carbon/estimate?departure_icao=EGLL&arrival_icao=KJFK&include_rfi=true" \
  -H "X-RapidAPI-Key: $RAPIDAPI_KEY" \
  -H "X-RapidAPI-Host: skylink-api.p.rapidapi.com"

A Singapore Airlines Airbus A380 climbing after takeoff, a large wide-body burning fuel across a long-haul sector

Let a callsign resolve the route for you

If you don't have the airport pair but you do have a flight, pass a callsign and let the API resolve the route — it prefers the actual flown distance from a recent matching flight (last 7 days) and falls back to great-circle when no track is available:

curl "https://skylink-api.p.rapidapi.com/carbon/estimate?callsign=BAW117&include_rfi=true" \
  -H "X-RapidAPI-Key: $RAPIDAPI_KEY" \
  -H "X-RapidAPI-Host: skylink-api.p.rapidapi.com"

In callsign mode the response adds callsign_resolved and route_confidence, and distance_source reflects whether a real track was used instead of haversine — which is exactly the "great-circle vs actual flown" quality difference from earlier, surfaced as a field you can show or gate on.

Building a trustworthy label

Three rules keep a carbon feature honest and defensible:

  • Show your inputs. Store and, ideally, surface the distance, aircraft category, passenger count, and methodology alongside the number. confidence: "low" should visibly soften the claim.
  • Provide the aircraft type when you can. Omitting aircraft_type makes the API infer from the callsign or fall back to a category average — fine for a rough estimate, weaker for a per-flight one. If you know the type (from tail-number lookup or the schedule), pass it.
  • Be explicit about RFI. Decide whether your primary figure is CO₂ or CO₂e and label it consistently everywhere it appears.

This pairs naturally with the rest of a flight stack — resolve the aircraft from a tail number, price the route with flight status, and attach a carbon figure — all under the same carbon emissions feature set.

SkyLink API gives you a free tier of 1,000 requests/month to prototype carbon labels against, with paid plans starting at $18.59/mo once you're ready for production traffic. It's available through the free trial — sign up, grab a key, and return auditable per-flight CO₂ without maintaining a single emission-factor table.