Skip to main content

EcoFreight CO2 Emissions API

A REST API for calculating freight CO2 emissions across road, sea, rail, and air. It returns WTW, TTW, and WTT breakdowns using GLEC Framework v3.2 factors aligned with ISO 14083:2023.

Base URL
https://api.ecofreight.co/api/v1
Auth
Bearer token
Free tier
1,000 requests/month

Endpoints

  • POST /calculate - calculate emissions for a single shipment.
  • GET /autocomplete - location autocomplete for calculator-style search.
  • GET /location - location geocoding and code resolution.
  • GET /methodology - methodology metadata and supported factors.

Quick start

The calculate endpoint accepts coordinates, free-text places, IATA airport codes, and UN/LOCODE port codes. The location resolver uses coordinates first, then code, then query.

curl https://api.ecofreight.co/api/v1/calculate \
  -H "Authorization: Bearer $ECOFREIGHT_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "origin": { "unlocode": "CNSHA" },
    "destination": { "unlocode": "NLRTM" },
    "cargo": { "weight": 21000, "type": "refrigerated" },
    "transport_mode": "sea",
    "vessel_type": "container_ship_8000_teu_plus"
  }'

JavaScript - air freight with IATA codes

const response = await fetch("https://api.ecofreight.co/api/v1/calculate", {
  method: "POST",
  headers: {
    Authorization: `Bearer ${process.env.ECOFREIGHT_API_KEY}`,
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    origin: { iata: "PVG" },
    destination: { iata: "AMS" },
    cargo: { weight: 2000, type: "general" },
    transport_mode: "air",
    vessel_type: "dedicated_cargo",
  }),
});

const result = await response.json();

Python - free-text locations

import os
import requests

payload = {
    "origin": {"query": "Shanghai, China"},
    "destination": {"query": "Rotterdam, Netherlands"},
    "cargo": {"weight": 5000, "type": "general"},
    "transport_mode": "sea",
    "vessel_type": "container_ship_8000_teu_plus",
}

response = requests.post(
    "https://api.ecofreight.co/api/v1/calculate",
    headers={"Authorization": f"Bearer {os.environ['ECOFREIGHT_API_KEY']}"},
    json=payload,
    timeout=10,
)
response.raise_for_status()
print(response.json()["emissions"]["wtw"])

Location inputs

Airports

Use 3-letter IATA airport codes for air freight when you already know the origin and destination airports.

{ "origin": { "iata": "PVG" }, "destination": { "iata": "AMS" } }

Ports and terminals

Use 5-character UN/LOCODE values for sea freight and intermodal port legs.

{ "origin": { "unlocode": "CNSHA" }, "destination": { "unlocode": "NLRTM" } }

Coordinates

Coordinates are the most explicit input and bypass geocoding ambiguity.

{ "coordinates": { "lat": 31.2, "lng": 121.5 } }

Text queries

Use text queries for ad-hoc tools, then store the resolved code or coordinates for repeat calculations.

{ "query": "Rotterdam, Netherlands" }

Cargo and mode rules

Cargo type is sent inside the cargo object. Supported values are general, refrigerated, and hazardous. Refrigerated cargo is supported for sea freight, road, rail, and air, and adds the documented refrigeration load to the result instead of changing the vessel class.

Vehicle and vessel types remain mode-specific. For example, a container ship vessel type is valid with transport_mode: "sea", while dedicated_cargo is valid with air freight.

Authentication

Send an Authorization: Bearer ef_live_... header with every production request. You can generate and rotate API keys in the dashboard. Public calculator calls use reCAPTCHA and do not replace authenticated API access.

Rate limits

PlanMonthly limitBurst limitHeaders
Free1,000 requests60 requests/minuteX-RateLimit-*
Growth50,000 requests300 requests/minuteRetry-After
EnterpriseCustomContract-specificX-Request-Id

Errors and retries

HTTPCodeMeaning
400invalid_requestRequired field missing, unsupported cargo type, or impossible coordinates.
401unauthorizedBearer token missing, malformed, expired, or revoked.
404location_not_foundA query, IATA airport code, or UN/LOCODE could not be resolved.
422unsupported_modeThe selected vessel or vehicle type is not valid for the transport mode.
429rate_limitedPlan limit exceeded. Retry after the reset time in the rate-limit headers.
500internal_errorUnexpected server error. Safe to retry with exponential backoff.

Versioning and changelog

Breaking response-shape changes are versioned at the API path. Methodology and rate-limit changes are dated in the methodology changelog. First-party Python and Node SDKs, batch ingest, and webhooks are listed on the roadmap. Until those SDKs ship, the public OpenAPI specification is the supported contract.

Methodology evidence

Every calculation response includes WTW, TTW, WTT, distance, factor source, data quality tier, methodology version, timestamp, and stable calculation ID fields. Use the methodology page and source catalogue as audit references when storing API results.

Implementation templates

OpenAPI contract

The interactive reference loads in the browser. The same OpenAPI 3.1 specification is also available directly at /openapi.json.