Compare Hotel Emissions

<span class="api-method api-method-get">GET</span> /v1/hotel/compare

Compare hotel emissions across multiple countries for the same stay duration. Results are sorted by total emissions (lowest first).


Request

Required Parameters

Parameter Type Description
countries string Comma-separated country codes (2-10 countries)

Optional Parameters

Parameter Type Default Description
nights integer 1 Number of nights (1-365)
rooms integer 1 Number of rooms (1-100)

Response

{
  "data": [
    {
      "country_code": "SE",
      "country_name": "Sweden",
      "total_kg": 25.5,
      "per_room_night_kg": 5.1,
      "region": "Northern Europe",
      "is_estimate": false,
      "savings_vs_highest_kg": 132,
      "savings_vs_highest_percent": 83.8
    },
    {
      "country_code": "FR",
      "country_name": "France",
      "total_kg": 41,
      "per_room_night_kg": 8.2,
      "region": "Western Europe",
      "is_estimate": false,
      "savings_vs_highest_kg": 116.5,
      "savings_vs_highest_percent": 74
    },
    {
      "country_code": "DE",
      "country_name": "Germany",
      "total_kg": 139,
      "per_room_night_kg": 27.8,
      "region": "Western Europe",
      "is_estimate": false,
      "savings_vs_highest_kg": 18.5,
      "savings_vs_highest_percent": 11.7
    },
    {
      "country_code": "GB",
      "country_name": "United Kingdom",
      "total_kg": 157.5,
      "per_room_night_kg": 31.5,
      "region": "Western Europe",
      "is_estimate": false,
      "savings_vs_highest_kg": 0,
      "savings_vs_highest_percent": 0
    }
  ],
  "meta": {
    "nights": 5,
    "rooms": 1,
    "total_room_nights": 5,
    "lowest_emissions": "SE",
    "highest_emissions": "GB",
    "calculated_at": "2026-02-07T14:30:00Z"
  }
}

Response Fields

data (array)

Field Type Description
country_code string ISO country code
country_name string Full country name
total_kg number Total emissions for the stay
per_room_night_kg number Emissions per room per night
region string Geographic region
is_estimate boolean Using regional average
savings_vs_highest_kg number CO2 saved vs highest option
savings_vs_highest_percent number Percentage savings

meta

Field Type Description
nights integer Number of nights
rooms integer Number of rooms
total_room_nights integer nights x rooms
lowest_emissions string Country code with lowest emissions
highest_emissions string Country code with highest emissions

Examples

Compare European Destinations

curl "https://api.emissions.dev/v1/hotel/compare?\
countries=GB,FR,DE,ES,IT&\
nights=5" \
  -H "Authorization: Bearer em_live_xxxx"

Conference Location Planning

curl "https://api.emissions.dev/v1/hotel/compare?\
countries=US,GB,SG,AE&\
nights=3&\
rooms=50" \
  -H "Authorization: Bearer em_live_xxxx"

Holiday Destination Comparison

curl "https://api.emissions.dev/v1/hotel/compare?\
countries=TH,MV,ID,MY,VN&\
nights=14" \
  -H "Authorization: Bearer em_live_xxxx"

Scandinavian Trip

curl "https://api.emissions.dev/v1/hotel/compare?\
countries=SE,NO,DK,FI&\
nights=7" \
  -H "Authorization: Bearer em_live_xxxx"

Code Examples

JavaScript

const response = await fetch(
  'https://api.emissions.dev/v1/hotel/compare?' + new URLSearchParams({
    countries: 'GB,FR,DE,ES',
    nights: 5
  }),
  {
    headers: {
      'Authorization': `Bearer ${process.env.EMISSIONS_API_KEY}`
    }
  }
);

const data = await response.json();

// Find the best option
const best = data.data[0];
const worst = data.data[data.data.length - 1];

console.log(`Best: ${best.country_name} (${best.total_kg} kg)`);
console.log(`Worst: ${worst.country_name} (${worst.total_kg} kg)`);
console.log(`Savings: ${best.savings_vs_highest_kg} kg (${best.savings_vs_highest_percent}%)`);

Python

import requests

response = requests.get(
    'https://api.emissions.dev/v1/hotel/compare',
    params={
        'countries': 'GB,FR,DE,ES',
        'nights': 5
    },
    headers={
        'Authorization': f'Bearer {api_key}'
    }
)

data = response.json()

# Find the best option
best = data['data'][0]
worst = data['data'][-1]

print(f"Best: {best['country_name']} ({best['total_kg']} kg)")
print(f"Worst: {worst['country_name']} ({worst['total_kg']} kg)")
print(f"Savings: {best['savings_vs_highest_kg']} kg ({best['savings_vs_highest_percent']}%)")

PHP

$response = Http::withToken($apiKey)
    ->get('https://api.emissions.dev/v1/hotel/compare', [
        'countries' => 'GB,FR,DE,ES',
        'nights' => 5,
    ]);

$data = $response->json();

// Find the best option
$best = $data['data'][0];
$worst = end($data['data']);

echo "Best: {$best['country_name']} ({$best['total_kg']} kg)\n";
echo "Worst: {$worst['country_name']} ({$worst['total_kg']} kg)\n";
echo "Savings: {$best['savings_vs_highest_kg']} kg ({$best['savings_vs_highest_percent']}%)\n";

Use Cases

Corporate Travel Policy

Help travel managers choose lower-carbon conference locations:

async function findBestConferenceLocation(countries, attendees, nights) {
  const response = await fetch(
    `https://api.emissions.dev/v1/hotel/compare?` + new URLSearchParams({
      countries: countries.join(','),
      nights,
      rooms: attendees
    }),
    { headers: { 'Authorization': `Bearer ${apiKey}` } }
  );
  
  const data = await response.json();
  
  const best = data.data[0];
  const worst = data.data[data.data.length - 1];
  
  return {
    recommendation: best.country_name,
    totalEmissions: best.total_kg,
    savings: {
      vs: worst.country_name,
      kg: best.savings_vs_highest_kg,
      percent: best.savings_vs_highest_percent
    }
  };
}

Display in Booking UI

function DestinationComparison({ countries, nights }) {
  const [data, setData] = useState(null);
  
  useEffect(() => {
    fetchComparison(countries, nights).then(setData);
  }, [countries, nights]);
  
  if (!data) return <Loading />;
  
  return (
    <div className="comparison-grid">
      {data.data.map(country => (
        <div key={country.country_code} className="country-card">
          <h3>{country.country_name}</h3>
          <div className="emissions">{country.total_kg} kg CO2e</div>
          {country.savings_vs_highest_percent > 0 && (
            <div className="savings">
              Save {country.savings_vs_highest_percent}% vs {data.meta.highest_emissions}
            </div>
          )}
        </div>
      ))}
    </div>
  );
}

Errors

Too Few Countries

{
  "error": {
    "code": "invalid_countries",
    "message": "Provide between 2 and 10 country codes separated by commas.",
    "status": 422
  }
}

Too Many Countries

{
  "error": {
    "code": "invalid_countries",
    "message": "Maximum 10 countries allowed per comparison.",
    "status": 422
  }
}

Invalid Country Code

{
  "error": {
    "code": "invalid_country",
    "message": "Country code 'XX' not recognised.",
    "status": 422
  }
}