Scope stacked pathways
bauScopeEmissions, extScopeEmissions,
intScopeEmissions (plus Min/Max for EXT/INT) — each
{ "1": number[], "2": number[], "3": number[] } aligned to
projectionyears.
Run emissions pathway projections from your own tools. This walkthrough covers authentication, a minimal request payload, standard vs extended responses, and scenario analysis — with copyable and downloadable examples.
API keys are issued to approved customers and partners. This site never embeds a key —
use placeholders like YOUR_API_KEY until yours is issued.
Protected endpoints expect an API key (or a Cognito JWT for app sessions). Prefer an environment variable — never commit keys to source control or notebooks shared publicly.
Header options
Authorization: ApiKey YOUR_API_KEYX-API-Key: YOUR_API_KEYAuthorization: Bearer <JWT> / JWT <token>
Base URL:
https://app.viablepathway.net
Send a complete organisation payload as JSON. The mini example below uses one org unit, three activities (v2 flat format), and two internal actions — enough to exercise BAU, EXT, and INT pathways without a full inventory dump.
Organisation settings sit at the top level. Inventory, geography, and actions live under
orgunits.
location (default) or market for Scope 2
1.5, WB2)
actionid
Each key is a unique instance id (often
catalogActivity@@region). Use
catalogactivityid for trend matching and
activityname for display. Set
activitydataversion: 2 at the top level.
The object key (e.g. useraction_efficiency_2027) becomes
actionid in outputs. actionname is a label only.
multiplier is a fractional change (e.g. -0.15 = −15%).
Optional balancingactivity shifts quantity to another activity (e.g. petrol → EV).
Set electricityapproach: "market" and add per-org-unit
recPurchase with a ramp schedule (entries +
pricePerKwh). Not required for the mini example below.
BAU grows inventory with desiredgrowth.
EXT applies external market trends (e.g. grid decarbonisation).
INT layers your internalactions on top of EXT.
{
"organisationid": "DEMO_CO",
"name": "Demo Company",
"desiredgrowth": 2,
"projectionstartyear": 2025,
"projectionendyear": 2050,
"currency": "aud",
"electricityapproach": "location",
"neartermsbtitarget": "1.5",
"neartermsbtitargetyear": 2030,
"activitydataversion": 2,
"orgunits": {
"orgunit_sydney": {
"name": "Sydney Office",
"orgunitid": "orgunit_sydney",
"country": "australia",
"region": "au-nsw",
"currency": "aud",
"employees": 120,
"activitydata": {
"utilities_electricity_grid@@au-nsw": {
"activityname": "Grid electricity — NSW",
"catalogactivityid": "utilities_electricity_grid",
"region": "au-nsw",
"activitydatavalue": 500000,
"activityuom": "kWh",
"ghgpscope": 2,
"ghgpscopecategory": "2",
"emissionfactortrendid": "utilities_electricity_grid",
"emissionfactorvalue": 0.68,
"emissionfactorunit": "kgCO2e"
},
"companyvehicle_car_petrol@@au-nsw": {
"activityname": "Fleet — petrol cars",
"catalogactivityid": "companyvehicle_car_petrol",
"region": "au-nsw",
"activitydatavalue": 250000,
"activityuom": "km",
"ghgpscope": 1,
"ghgpscopecategory": "1-2",
"emissionfactortrendid": "companyvehicle_car_petrol",
"emissionfactorvalue": 0.192,
"emissionfactorunit": "kgCO2e"
},
"companyvehicle_car_bev@@au-nsw": {
"activityname": "Fleet — battery electric cars",
"catalogactivityid": "companyvehicle_car_bev",
"region": "au-nsw",
"activitydatavalue": 10000,
"activityuom": "km",
"ghgpscope": 2,
"ghgpscopecategory": "2",
"emissionfactortrendid": "companyvehicle_car_bev",
"emissionfactorvalue": 0.05,
"emissionfactorunit": "kgCO2e"
}
},
"internalactions": {
"useraction_efficiency_2027": {
"actionname": "Office energy efficiency",
"actiontype": "Energy Efficiency",
"activity": "utilities_electricity_grid@@au-nsw",
"startyear": 2027,
"multiplier": -0.15,
"absolutechange": 0,
"balancingactivity": "",
"balancingmultiplier": 0,
"capitalcost": 80000,
"capitalcostcalculationmethod": "absolute",
"description": "Lighting and HVAC upgrades reducing grid electricity use by 15% from 2027."
},
"useraction_fleet_ev_2028": {
"actionname": "Switch petrol fleet to EV",
"actiontype": "Company Vehicles",
"activity": "companyvehicle_car_petrol@@au-nsw",
"startyear": 2028,
"multiplier": -0.5,
"absolutechange": 0,
"balancingactivity": "companyvehicle_car_bev@@au-nsw",
"balancingmultiplier": 1,
"capitalcost": 150000,
"capitalcostcalculationmethod": "absolute",
"description": "Replace half of petrol car kilometres with battery electric from 2028."
}
},
"historicemissionsyears": [
2023,
2024
],
"historicemissions": {
"1": [
48.2,
46.1
],
"2": [
340,
325.5
],
"3": [
12,
11.5
]
}
}
}
}
POST /api/calculate runs the calculation engine.
Use savePayload=false while experimenting so calls
stay compute-only and do not persist organisation input.
Endpoint:
https://app.viablepathway.net/api/calculate?savePayload=false
#!/usr/bin/env bash
# Replace YOUR_API_KEY with the key issued after approval.
# savePayload=false keeps experimental calls from persisting input.
curl -sS -X POST \
"https://app.viablepathway.net/api/calculate?savePayload=false" \
-H "Content-Type: application/json" \
-H "Authorization: ApiKey YOUR_API_KEY" \
-d @minimal-payload.json
"""Minimal Viable Pathway calculate example.
Set VIABLE_API_KEY in your environment — never commit the key.
"""
import json
import os
import urllib.request
API_KEY = os.environ["VIABLE_API_KEY"]
BASE = "https://app.viablepathway.net"
URL = f"{BASE}/api/calculate?savePayload=false"
with open("minimal-payload.json", encoding="utf-8") as f:
payload = json.load(f)
req = urllib.request.Request(
URL,
data=json.dumps(payload).encode("utf-8"),
headers={
"Content-Type": "application/json",
"Authorization": f"ApiKey {API_KEY}",
},
method="POST",
)
with urllib.request.urlopen(req) as resp:
result = json.load(resp)
print("projectionyears:", result.get("projectionyears"))
print("BAU pathway (tCO2e):", result.get("ghgBAUsumperyear"))
print("EXT pathway (tCO2e):", result.get("ghgEXTsumperyear"))
print("INT pathway (tCO2e):", result.get("ghgINTsumperyear"))
The standard response is the shape most integrators need first: organisation-level
pathway totals, target pathways, waterfall, contributions, and trimmed
orgunitResults.
Default POST /api/calculate returns a compact
calculatedData-style object: pathway totals, targets,
waterfall, and trimmed per-unit results (no full activity arrays).
projectionyears
X-axis for pathway charts
ghgBAUsumperyear
BAU total tCO₂e per year
ghgEXTsumperyear (+ Min/Max)
External-trend pathway (± band)
ghgINTsumperyear (+ Min/Max)
Internal-actions pathway (± band)
sbtiPathwayValues / targetyears
Science-based target line
waterfallMultiYear
Bridge from BAU → EXT → INT
internalActionsContributions
Abatement by actionid
orgunitResults[]
Per-unit GHG sums (trimmed)
transitionPlan / methodology
Narrative / methodology blocks
All GHG sum arrays are aligned to projectionyears.
SBTi / custom target arrays align to targetyears.
Illustrative values only — not a live calculation.
{
"organisationid": "DEMO_CO",
"name": "Demo Company",
"neartermsbtitarget": "1.5",
"neartermsbtitargetyear": 2030,
"historicemissionsyears": [
2023,
2024
],
"historicemissions": {
"1": [
48.2,
46.1
],
"2": [
340,
325.5
],
"3": [
12,
11.5
]
},
"projectionyears": [
2025,
2026,
2027,
2028,
2029,
2030
],
"targetyears": [
2025,
2026,
2027,
2028,
2029,
2030
],
"orgUnits": [
{
"id": "orgunit_sydney",
"name": "Sydney Office"
}
],
"ghgBAUsumperyear": [
390,
397.8,
405.8,
413.9,
422.2,
430.6
],
"ghgEXTsumperyear": [
390,
385,
372,
358,
345,
332
],
"ghgEXTsumperyearMin": [
390,
380,
365,
348,
332,
318
],
"ghgEXTsumperyearMax": [
390,
390,
380,
368,
358,
346
],
"ghgINTsumperyear": [
390,
385,
340,
280,
265,
250
],
"ghgINTsumperyearMin": [
390,
380,
330,
268,
250,
235
],
"ghgINTsumperyearMax": [
390,
390,
350,
292,
280,
265
],
"sbtiPathwayValues": [
390,
365,
340,
315,
290,
265
],
"userDefinedPathwayValues": null,
"waterfallMultiYear": {
"note": "Illustrative stub — real responses include yearly waterfall breakdowns"
},
"internalActionsContributions": [
{
"actionid": "useraction_efficiency_2027",
"actionname": "Office energy efficiency",
"abatementByYear": {
"2027": 18.5,
"2030": 22
}
},
{
"actionid": "useraction_fleet_ev_2028",
"actionname": "Switch petrol fleet to EV",
"abatementByYear": {
"2028": 22,
"2030": 28
}
}
],
"methodology": {
"note": "Illustrative stub — real responses include methodology statement text"
},
"transitionPlan": {
"note": "Illustrative stub — real responses include structured transition-plan sections"
},
"orgunitResults": [
{
"id": "orgunit_sydney",
"orgunitid": "orgunit_sydney",
"ghgBAUsumperyear": [
390,
397.8,
405.8,
413.9,
422.2,
430.6
],
"ghgEXTsumperyear": [
390,
385,
372,
358,
345,
332
],
"ghgINTsumperyear": [
390,
385,
340,
280,
265,
250
],
"internalActionsContributions": []
}
]
}
Numbers above are shortened for documentation. Real responses use full
projectionyears ranges (often through 2050).
Add extended=true for per-activity time series,
scope breakdowns, and MAC curve points used by pathway and activity charts.
#!/usr/bin/env bash
# Extended response includes per-activity AD/GHG arrays, scope emissions, and MAC curve points.
curl -sS -X POST \
"https://app.viablepathway.net/api/calculate?extended=true&savePayload=false" \
-H "Content-Type: application/json" \
-H "Authorization: ApiKey YOUR_API_KEY" \
-d @minimal-payload.json
?extended=true adds
The web client uses the extended payload. API integrators often start with the standard response, then request extended when they need activity detail, scope stacks, or MAC curves.
bauScopeEmissions, extScopeEmissions,
intScopeEmissions (plus Min/Max for EXT/INT) — each
{ "1": number[], "2": number[], "3": number[] } aligned to
projectionyears.
projectedEXTAD2 and projectedINTAD2 — arrays of
{ activity, values[] } for activity-detail charts. Join on
activity (instance id).
projectedBAUGHG, projectedEXTGHG,
projectedINTGHG — same shape as AD arrays, in tCO₂e per activity.
sbtiPathwayByScope / userDefinedPathwayByScope for scope charts;
maccByEndpoint (2030 / 2040 / 2050)
for marginal abatement cost curves.
{
"_comment": "Excerpt of fields added (or expanded) when calling POST /api/calculate?extended=true&savePayload=false. Arrays are shortened for readability.",
"projectionyears": [
2025,
2026,
2027,
2028,
2029,
2030
],
"bauScopeEmissions": {
"1": [
48,
49,
50,
51,
52,
53
],
"2": [
330,
336,
342,
348,
355,
362
],
"3": [
12,
12.8,
13.8,
14.9,
15.2,
15.6
]
},
"extScopeEmissions": {
"1": [
48,
47,
45,
43,
41,
39
],
"2": [
330,
326,
315,
303,
292,
281
],
"3": [
12,
12,
12,
12,
12,
12
]
},
"intScopeEmissions": {
"1": [
48,
47,
45,
28,
26,
24
],
"2": [
330,
326,
283,
240,
227,
214
],
"3": [
12,
12,
12,
12,
12,
12
]
},
"extScopeEmissionsMin": {
"1": [],
"2": [],
"3": []
},
"extScopeEmissionsMax": {
"1": [],
"2": [],
"3": []
},
"intScopeEmissionsMin": {
"1": [],
"2": [],
"3": []
},
"intScopeEmissionsMax": {
"1": [],
"2": [],
"3": []
},
"sbtiPathwayByScope": {
"1": [
48,
45,
42,
39,
36,
33
],
"2": [
330,
308,
286,
264,
242,
220
],
"3": [
12,
12,
12,
12,
12,
12
]
},
"userDefinedPathwayByScope": null,
"projectedEXTAD2": [
{
"activity": "utilities_electricity_grid@@au-nsw",
"values": [
500000,
510000,
520200,
530604,
541216,
552040
]
},
{
"activity": "companyvehicle_car_petrol@@au-nsw",
"values": [
250000,
255000,
260100,
265302,
270608,
276020
]
}
],
"projectedINTAD2": [
{
"activity": "utilities_electricity_grid@@au-nsw",
"values": [
500000,
510000,
442170,
451013,
460034,
469234
]
},
{
"activity": "companyvehicle_car_petrol@@au-nsw",
"values": [
250000,
255000,
260100,
132651,
135304,
138010
]
},
{
"activity": "companyvehicle_car_bev@@au-nsw",
"values": [
10000,
10200,
10404,
143055,
145866,
148732
]
}
],
"projectedBAUGHG": [
{
"activity": "utilities_electricity_grid@@au-nsw",
"values": [
340,
346.8,
353.7,
360.8,
368,
375.4
]
}
],
"projectedEXTGHG": [
{
"activity": "utilities_electricity_grid@@au-nsw",
"values": [
340,
336,
325,
313,
302,
291
]
}
],
"projectedINTGHG": [
{
"activity": "utilities_electricity_grid@@au-nsw",
"values": [
340,
336,
276,
245,
232,
219
]
}
],
"maccByEndpoint": {
"2030": [
{
"actionid": "useraction_efficiency_2027",
"actionname": "Office energy efficiency",
"abatement": 22,
"marginalCost": 45
},
{
"actionid": "useraction_fleet_ev_2028",
"actionname": "Switch petrol fleet to EV",
"abatement": 28,
"marginalCost": 120
}
],
"2040": [],
"2050": []
}
}
POST /api/scenarioanalysis reuses the organisation
payload and overlays climate-scenario emission-factor narratives (for example NGFS,
AASB, Arup, TCFD-inspired sets).
scenarioSet
Narrative source slug (e.g. ngfs_climate_scenarios)
selectedOrgUnit
Required when the org spans multiple countries
baselineEmissions
Baseline pathway context in the response
narrativeSummaries[]
Per-narrative GHG pathway sums + years
sections
Narrative report text blocks
{
"organisationid": "DEMO_CO",
"name": "Demo Company",
"desiredgrowth": 2,
"projectionstartyear": 2025,
"projectionendyear": 2050,
"currency": "aud",
"electricityapproach": "location",
"scenarioSet": "ngfs_climate_scenarios",
"selectedOrgUnit": "orgunit_sydney",
"activitydataversion": 2,
"orgunits": {
"orgunit_sydney": {
"name": "Sydney Office",
"orgunitid": "orgunit_sydney",
"country": "australia",
"region": "au-nsw",
"currency": "aud",
"employees": 120,
"activitydata": {
"utilities_electricity_grid@@au-nsw": {
"activityname": "Grid electricity — NSW",
"catalogactivityid": "utilities_electricity_grid",
"region": "au-nsw",
"activitydatavalue": 500000,
"activityuom": "kWh",
"ghgpscope": 2,
"ghgpscopecategory": "2",
"emissionfactortrendid": "utilities_electricity_grid",
"emissionfactorvalue": 0.68,
"emissionfactorunit": "kgCO2e"
},
"companyvehicle_car_petrol@@au-nsw": {
"activityname": "Fleet — petrol cars",
"catalogactivityid": "companyvehicle_car_petrol",
"region": "au-nsw",
"activitydatavalue": 250000,
"activityuom": "km",
"ghgpscope": 1,
"ghgpscopecategory": "1-2",
"emissionfactortrendid": "companyvehicle_car_petrol",
"emissionfactorvalue": 0.192,
"emissionfactorunit": "kgCO2e"
}
},
"internalactions": {},
"historicemissionsyears": [
2023,
2024
],
"historicemissions": {
"1": [
48.2,
46.1
],
"2": [
340,
325.5
],
"3": [
12,
11.5
]
}
}
}
}
#!/usr/bin/env bash
# Scenario analysis reuses the organisation payload and adds scenarioSet.
# Multi-country orgs should also set selectedOrgUnit to an org-unit key.
curl -sS -X POST \
"https://app.viablepathway.net/api/scenarioanalysis" \
-H "Content-Type: application/json" \
-H "Authorization: ApiKey YOUR_API_KEY" \
-d @scenario-request.json
Download the samples, set your key in the environment, and call the API from your machine or notebook. We share a Jupyter (Colab-ready) notebook after your key is issued — it is not published here so keys never appear on this site.