- Home
- Python API guide
How to call a freight emissions API from Python
A Python integration tutorial for EcoFreight: authenticate, send UN/LOCODE or IATA inputs, handle rate limits, and store audit fields from the freight CO2 API response.
Use stable codes first
Prefer UN/LOCODE for ports and IATA for airports. Text queries work, but storing resolved codes makes repeat calculations deterministic.
Store the evidence
Persist calculation_id, factor source, methodology version, and data quality tier alongside the shipment record.
Retry only safe failures
Retry 429 and 5xx responses with backoff. Treat validation errors as data problems and surface them to the operator.
1. Create the request payload
The calculate endpoint accepts coordinates, UN/LOCODE, IATA airport codes, or text queries for each location. The example below uses the Shanghai to Rotterdam sea lane and refrigerated cargo so the payload mirrors a real reefer container workflow.
import os
import requests
payload = {
"origin": {"unlocode": "CNSHA"},
"destination": {"unlocode": "NLRTM"},
"cargo": {"weight": 21000, "type": "refrigerated"},
"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']}",
"Content-Type": "application/json",
},
json=payload,
timeout=10,
)
response.raise_for_status()
result = response.json()
print(result["emissions"]["wtw"])
print(result["calculation_id"])2. Persist the response fields an auditor will ask for
Do not store only the final kg CO2e number. Store the method fields too: calculation ID, WTW/TTW/WTT breakdown, distance, factor source, methodology version, and ISO 14083 data quality tier. Those fields are what make the same shipment defensible later.
3. Add retry handling
from time import sleep
for attempt in range(4):
response = requests.post(API_URL, headers=headers, json=payload, timeout=10)
if response.status_code != 429 and response.status_code < 500:
break
retry_after = int(response.headers.get("Retry-After", "2"))
sleep(retry_after * (attempt + 1))
response.raise_for_status()Production checklist
Keep the API key in environment secrets, not source code.
Send kilogram weights as numbers and normalize units before calling the API.
Log validation errors with the shipment ID and operator-visible field names.
Cache repeat lane defaults only when cargo, mode, vessel type, and weight match.
Store calculation_id for every shipment that appears in a customer report.
Pin methodology output by report period before filing CSRD or CDP disclosures.