Read emissions
GET /v3/company/{companyId}/emissions/summary returns a company’s emissions over a range of months: a total, and per period the emissions of each GHG Protocol scope and category.
It needs the emissions:read scope. For a group of companies, see Portfolios.
Request
All four query parameters are required. None has a default, because each one changes what the numbers mean.
| Parameter | Values | Meaning |
|---|---|---|
from | YYYY-MM | First month of the range, inclusive. |
to | YYYY-MM | Last month of the range, inclusive, and not before from. It may lie in the future: months without data come back null. |
granularity | MONTH, QUARTER, YEAR | The size of each period. |
emissionsUnit | kg, t | The unit of every value. The response states it as kgCO2e or tCO2e. |
The range must line up with the periods: with QUARTER, from is the first month of a quarter (01, 04, 07 or 10) and to the last (03, 06, 09 or 12); with YEAR, from is January and to December. A range that doesn’t line up, or a full date instead of a month, is rejected with a 400 rather than adjusted.
One request spans at most 36 months, 40 quarters or 20 years. For longer histories, make several requests.
curl
curl --max-time 60 -G "https://api.energi.ai/v3/company/1042/emissions/summary" \
-H "Authorization: Bearer $ENERGI_API_KEY" \
-d from=2025-01 -d to=2025-12 -d granularity=QUARTER -d emissionsUnit=tcurl
curl --max-time 60 -G "https://api.us.energi.ai/v3/company/1042/emissions/summary" \
-H "Authorization: Bearer $ENERGI_API_KEY" \
-d from=2025-01 -d to=2025-12 -d granularity=QUARTER -d emissionsUnit=tResponse
Shortened to one period, one scope and one category:
{
"data": {
"companyId": "1042",
"emissionsUnit": "tCO2e",
"granularity": "QUARTER",
"from": "2025-01",
"to": "2025-12",
"emissions": 4821.55,
"periods": [
{
"period": "2025-Q1",
"periodStart": "2025-01-01",
"periodEnd": "2025-03-31",
"emissions": 1284.51,
"scopes": [
{
"scope": "SCOPE_1",
"emissions": 210.4,
"categories": [
{
"code": "STATIONARY_COMBUSTION",
"label": "Stationary combustion",
"emissions": 180.2
}
]
}
]
}
]
},
"meta": { "status": "UP_TO_DATE", "asOf": "2026-09-16T09:12:04.000Z" }
}datarepeats the resolved request (emissionsUnit,granularity,from,to), so a stored result can always be read on its own. Keepdatawhole when you store it.emissionsat each level is the total of the level below: the range’s total, each period’s, each scope’s and each category’s.periodshas one entry per period fromfromtoto, oldest first, and is never empty.periodis labelled2025-03for a month,2025-Q1for a quarter and2025for a year;periodStartandperiodEndare its first and last days, inclusive. A period that hasn’t ended yet holds the data recorded so far.
Basis
Every figure is location-based.
A fixed grid
Every period has all three scopes, in the order SCOPE_1, SCOPE_2, SCOPE_3, and every scope lists all of its published categories, always in the same order. So the shape of the response depends only on the range and the granularity, never on the data.
- A category is
nullwhen it has no data points in that period, and0when its data adds up to zero. - A scope, period or total is the sum of the values below it that exist, and is
nullonly when nothing below it has data. - Non-emission measures, such as water, revenue or uncategorised data, are never returned.
Rounding
Every value is rounded to 2 decimals, from unrounded data. So a total can differ from the sum of its rounded parts by a few hundredths. Both are correct; don’t adjust either.
Categories
Each category has a stable code and a display label. Program against code: the label can change at any time. The codes published today:
STATIONARY_COMBUSTION, FUGITIVE, MOBILE_COMBUSTION, PHYSICAL_OR_CHEMICAL_PROCESSING, EMISSIONS_FROM_PURCHASED_ENERGY, PURCHASED_GOODS_AND_SERVICES, CAPITAL_GOODS, FUEL_AND_ENERGY_RELATED, UPSTREAM_TRANSPORT, WASTE_GENERATED_IN_OPERATIONS, BUSINESS_TRAVEL, EMPLOYEE_COMMUTING, UPSTREAM_LEASED_ASSETS, DOWNSTREAM_TRANSPORT, PROCESSING_OF_SOLD_PRODUCTS, USE_OF_SOLD_PRODUCTS, END_OF_LIFE_TREATMENT_OF_SOLD_PRODUCTS, DOWNSTREAM_LEASED_ASSETS, FRANCHISES, INVESTMENTS.
Each appears under its scope. New codes can be added, so accept codes you don’t know.
Freshness
Emissions are calculated in the background after data changes, for example after an upload. The summary is always served, also while a calculation runs, and meta says how current it is:
meta.statusisUP_TO_DATEwhen the figures are settled, andUPDATINGwhile a calculation is running. WhileUPDATING, the figures are an intermediate result: some months or categories may already include the latest changes and others not yet.meta.asOfis a timestamp: every change to the company’s data before it is reflected in the figures, and later changes may already be partly reflected. It describes the company’s data, so it doesn’t depend onfromandto. It isnullonly if nothing has ever been calculated for the company.
Use whichever fits:
- You need settled figures, for a report or an export: wait until
meta.statusisUP_TO_DATE. - You uploaded data and want to know it is in: wait until
meta.asOfis later than the moment your upload finished. This holds whileUPDATINGtoo.
When you poll, wait between requests, for example a minute, and keep within the rate limit. meta.status can gain new values; treat one you don’t know like UPDATING.