Data Model
Carbon Activity Model
An activity goes in as a quantity and a unit. What comes back is either a priced result or a refusal with a reason.
Activity in
Each endpoint takes one kind of activity. The quantity is what you measured, in the unit you measured it in:
| Activity | Endpoint | Quantity | Scope |
|---|---|---|---|
| Grid electricity | /calculate/electricity | kwh | 2 |
| Fuel burned | /calculate/fuel | amount + unit (L, kg or m3) | 1 |
| Air travel | /calculate/flight | distance_km x passengers | 3 |
| Purchases | /calculate/spend | amount in INR + category | 3 |
The country selects the factor: country_code for electricity, country for the others, defaulting to IN. Full field lists are in the API Reference.
POST /api/v1/calculate/fueljson
{
"fuel_type": "diesel",
"amount": 100,
"unit": "L",
"country": "IN"
}Result out
A priced activity always carries the factor, its source and the arithmetic:
result.tstypescript
interface CalculateResponse {
success: true;
data: {
emissions_kg_co2e: number; // the result, kg CO2e
emission_factor: number; // factor applied per unit of activity
emission_factor_label: string; // factor + unit + dataset + methodology + GWP basis
emission_factor_source: string; // dataset, e.g. "IndiaGHGProgram_IPCC2006"
scope: 'scope_1' | 'scope_2' | 'scope_3';
activity: { value: number; unit: string };
formula: string | null; // e.g. "100 liter × 2.687954 kgCO2e/liter = 268.7950 kgCO2e"
details: Record<string, unknown>; // inputs echoed back, plus the method
};
}Or a refusal
If the library has no published factor for the input, nothing is estimated. You get a 422 that says why and what to send instead:
422 (coal without a variant)json
{
"success": false,
"error": "\"Coal\" requires a variant to be chosen; none was supplied.",
"code": "subtype_required",
"guidance": "Send one of: bituminous, lignite. ..."
}The guidance above is shortened. The list of codes is in the API Reference.