Documentation
Methodology Graph is a live, typed graph of every standard, calculator, factor table, framework, and registry that climate accounting runs on. Each methodology is exposed as a callable endpoint with full provenance. This page covers the mental model, quickstart, full REST reference, and the MCP server for AI agents.
What this API gives you#
One HTTPS endpoint to call any climate calculation, query any factor table, walk any framework's dependency graph, or audit any registry. The graph is parsed from primary sources (PDFs, HTML, XML, JSON, RSS feeds), version tracked, dependency mapped, and kept current by an autonomous review loop. Free for individual use with a one-minute email signup.
Three surfaces, same data:
- REST API, at
https://api.methodology.energyweb.org/v1/. Standard HTTPS, JSON in and out. Documented in full below. - MCP server, at
https://mcp.methodology.energyweb.org. For Claude (web, desktop, mobile), Cursor, or any agent runtime that speaks the protocol. One-click OAuth in Claude. - Interactive viewer, at
https://methodology.energyweb.org/viewer. For humans browsing the graph visually.
Get a free API key
Every call needs an API key. Free tier gives you 600 requests/minute, takes 60 seconds to set up via email magic link. Sign up here. A public demo key exists (300 requests/minute, suitable for browsing and exploration).
Quickstart#
Five minutes from zero to a working calculation. The example below calculates the lifecycle CO2e abatement of a sustainable aviation fuel shipment, using only the inputs a shipper would actually have. The API resolves the carbon intensity factor from the ICAO default LCA table automatically.
1. List the methodologies in the graph
curl https://api.methodology.energyweb.org/v1/methodologies?limit=5
{
"data": [
{ "id": "icao-corsia-lca", "name": "ICAO CORSIA LCA", "layer": 3, ... },
{ "id": "ipcc-gwp", "name": "IPCC GWP", "layer": 1, ... },
...
],
"count": 5
}
2. Inspect a specific methodology's calculation schema
curl https://api.methodology.energyweb.org/v1/methodologies/icao-corsia-lca/schema
{
"methodology_id": "icao-corsia-lca",
"methodology_version": "Eighth Edition, November 2025",
"input_schema": {
"type": "object",
"required": ["baseline_ci", "saf_ci", "lhv", "units"],
"properties": {
"baseline_ci": { "type": "number", "description": "Baseline jet fuel CI, gCO2e/MJ" },
"saf_ci": { "type": "number", "description": "SAF carbon intensity, gCO2e/MJ" },
"lhv": { "type": "number", "description": "Lower heating value, MJ/kg" },
"units": { "type": "number", "description": "Quantity in tonnes" },
"pathway": { "type": "string", "description": "SAF pathway, auto-resolves saf_ci if provided" }
}
},
"output_schema": { "properties": { "co2e_abated_tonnes": { "type": "number" } } },
"formula_spec": {
"type": "arithmetic",
"outputs": [{
"key": "co2e_abated_tonnes",
"formula": "((baseline_ci - saf_ci) / 1000000) * (lhv * 1000) * units",
"unit": "tCO2e"
}]
}
}
3. Call the calculation
Notice that saf_ci is not passed explicitly. The engine pulls it from the ICAO default LCA dataset using pathway as the lookup key.
curl -X POST https://api.methodology.energyweb.org/v1/calculate/icao-corsia-lca \
-H "content-type: application/json" \
-d '{
"inputs": {
"pathway": "HEFA-UCO",
"lhv": 44,
"units": 234.765,
"baseline_ci": 89
}
}'
{
"methodology_id": "icao-corsia-lca",
"version": "Eighth Edition, November 2025",
"result": {
"co2e_abated_tonnes": 775.757,
"co2e_abated_tonnes_unit": "tCO2e"
},
"provenance": {
"formula": "((baseline_ci - saf_ci) / 1000000) * (lhv * 1000) * units",
"inputs_used": { "pathway": "HEFA-UCO", "saf_ci": 13.9, "lhv": 44, ... },
"standard_reference": "ICAO Annex 16 Vol IV",
"resolved_from_datasets": {
"saf_ci": {
"dataset": "icao-corsia-lca",
"key": "HEFA-UCO",
"field": "core_lsf_value",
"value": 13.9,
"impl_id": "icao-corsia-saf-default-lca-v1"
}
}
},
"computed_at": "2026-05-14T10:30:00.000Z"
}
That's the entire integration loop. You passed four inputs, got back the answer (775.757 tCO2e abated), the formula text, the version, and the exact factor value the engine substituted for you with its citation.
What just happened
The engine looked up your pathway = "HEFA-UCO" in the ICAO Annex 16 Appendix 3 default LCA table, found core_lsf_value = 13.9, plugged it in as saf_ci, then evaluated the formula. Without this auto-resolution, you would have to fetch and maintain the ICAO default LCA table yourself.
4. Call a composition (umbrella with parts)
Some standards (EU RED III, ISO 14067, GHG Protocol Product) define a calculation as an umbrella plus a list of named components. Inspect the umbrella's structure with GET /v1/compositions/:id, then POST to /v1/calculate/:id to run it. Pass the components you have; the engine resolves the rest from their sub-methodologies, defaulting missing optional components to 0.
curl -X POST https://api.methodology.energyweb.org/v1/calculate/eu-red3 \
-H "content-type: application/json" \
-d '{
"inputs": {
"e_ec": 12.5,
"e_l": 0.0,
"e_p": 8.4,
"e_td": 1.2,
"e_u": 0.0
}
}'
{
"methodology_id": "eu-red3",
"result": { "composition_value": 22.1 },
"provenance": {
"composition": {
"final_formula": "e_ec + e_l + e_p + e_td + e_u - e_sca - e_ccs - e_ccr",
"resolved_components": {
"e_ec": { "value": 12.5, "from": "input" },
"e_l": { "value": 0, "from": "input" },
"e_p": { "value": 8.4, "from": "input" },
"e_td": { "value": 1.2, "from": "input" },
"e_u": { "value": 0, "from": "input" },
"e_sca": { "value": 0, "from": "default_optional" },
"e_ccs": { "value": 0, "from": "default_optional" },
"e_ccr": { "value": 0, "from": "default_optional" }
}
},
"standard_reference": "Directive (EU) 2023/2413, Annex V Part C"
}
}
You passed five of the eight components; the engine defaulted the three optional subtractors to 0 and surfaced that in the trace. Each component (eu-red3-cultivation, eu-red3-processing, and the others) is also a methodology on its own, callable at /v1/calculate/eu-red3-cultivation etc., with its own input schema.
The graph model#
Every methodology is a node. Every dependency between methodologies is a typed edge. Layers reflect where each methodology sits in the global standards stack, from layer 1 (constitutional standards like IPCC, ISO 14064) up to layer 7 (compliance regimes like EU CBAM).
- Layer 1, accounting fundamentals (IPCC GWP, ISO 14064, GHG Protocol)
- Layer 2, disclosure frameworks (TCFD, ISSB, CSRD ESRS, CDP)
- Layer 3, sector methodologies (ICAO CORSIA, PCAF, GLEC, RSB)
- Layer 4, registries (Verra, Gold Standard, ACR, I-REC, EnergyTag)
- Layer 5, integrity meta-standards (ICVCM)
- Layer 6, demand-side buyer frameworks (RE100, CEBA)
- Layer 7, compliance regimes (EU CBAM, CSRD directive)
Edges between methodologies are typed: references, extends, requires, implements, supersedes. The full edge graph drives the cascade: when IPCC GWP updates, every downstream methodology that references GWP is flagged for re-evaluation automatically.
Five kinds of methodology#
The formula_type column on every methodology tells you what kind it is and which URL space it lives under:
| Kind | URL space | What it is |
|---|---|---|
| formula | /v1/calculate/:id |
An executable math expression or boolean rule. Pass inputs, get a result. |
| dataset | /v1/lookup/:id |
A factor lookup table. Pass a key, get a value (or a row). |
| composition | /v1/calculate/:id plus /v1/compositions/:id |
An umbrella methodology that decomposes into named components, each itself a methodology. POST the umbrella to run it; GET the compositions endpoint for the structural metadata. |
| framework | /v1/frameworks/:id |
Governance, guidance, or disclosure principles. Read-only, no calculation. |
| registry | /v1/registries/:id |
A credit or certificate issuance ledger. Detail endpoint lists consumers. |
Methodologies of every kind also appear under /v1/methodologies/:id, which returns the bare graph node. The kind-specific endpoints add the right contract on top (calculate inputs, lookup keys, composition structure, framework dependencies, registry consumers).
A note on sub-methodologies: a composition's components are real methodologies, with their own id, schema, and version. They carry is_component: 1 on the methodology row and are filtered out of headline lists like /v1/methodologies by default. Pass ?include_components=true to see them, or look up any component by id directly.
Dataset auto-resolution#
A formula can declare that one of its inputs is sourced from a dataset. When a caller invokes the formula without that input, the engine resolves it for them. The mechanism uses the dependencies array on the formula spec:
{
"type": "arithmetic",
"outputs": [...],
"dependencies": [{
"input": "saf_ci", // the variable to populate
"dataset": "icao-corsia-lca", // methodology_id of the source dataset
"package": "icao-corsia-saf-default-lca-v1", // optional pin
"key_from": "pathway", // which user input holds the lookup key
"value_field": "core_lsf_value", // which field on the row to use
"optional": true // if user passes saf_ci explicitly, skip lookup
}]
}
If the caller passes saf_ci explicitly, the lookup is skipped (because optional: true). If they don't, but they pass pathway, the engine looks up the matching row in the ICAO dataset, pulls core_lsf_value, and stores it. The response's provenance.resolved_from_datasets block discloses every substitution.
Composition and component resolution#
Some climate standards do not define a single calculation. They define an umbrella plus a list of named components, each of which is its own calculation. EU RED III's lifecycle GHG, ISO 14067's product carbon footprint, and the GHG Protocol Product Standard's life-cycle inventory are all shaped this way. These are compositions. The umbrella is a methodology of kind composition; each component is a methodology in its own right, with is_component: 1 set on its row and a typed imports edge pointing at it from the umbrella with predicate component:<symbol>.
A composition's formula_spec declares a final_formula (e.g. e_ec + e_l + e_p + e_td + e_u - e_sca - e_ccs - e_ccr) and a components array. Each component carries a symbol (the variable name in the final formula), a description, an expected_sub_kind, and a sub_methodology_id pointing at the child:
{
"type": "composition",
"final_formula": "e_ec + e_l + e_p + e_td + e_u - e_sca - e_ccs - e_ccr",
"components": [
{
"symbol": "e_ec",
"description": "Emissions from feedstock cultivation",
"expected_sub_kind": "formula",
"sub_methodology_id": "eu-red3-cultivation"
},
// e_l, e_p, e_td, e_u, e_sca, e_ccs, e_ccr...
]
}
When a caller POSTs to /v1/calculate/:umbrella_id, the composition runner resolves each symbol in order:
- If the caller provided a value directly under
inputs, that value is used. The trace marks itfrom: "input". - Otherwise, if the component has a
sub_methodology_idpointing at a methodology with a live executable implementation, the engine recursively calls that sub-methodology and uses its result. The trace marks itfrom: "sub_methodology"and records which sub-methodology supplied the value. - Otherwise, if the symbol is in
input_schema.propertiesbut NOT ininput_schema.required, the engine defaults the value to 0. The trace marks itfrom: "default_optional". - Otherwise (the symbol IS required and could not be resolved), the runner returns a 422 listing every unresolved symbol and refuses to compute a result.
The recursion has a depth cap (5 by default) so a malformed extraction cannot loop. Optional defaults are only applied when input_schema.required is declared as an array; if the schema does not declare a required list, the engine falls back to strict mode (every symbol must come from input or sub-methodology).
The metadata endpoint GET /v1/compositions/:id returns the components list with each one annotated by is_required (from the umbrella's input_schema) and sub_methodology_live (whether the referenced sub-methodology has a live executable implementation today). Useful for clients that want to render the umbrella's structure without making a calculate call.
Edge provenance: how dependencies are grounded#
Every dependency edge in the graph carries its own provenance, so a reader can always see why an edge exists and what it rests on. An edge is grounded in one of three ways. These are three different kinds of grounding, presented as equal. None is a ranking above the others, and none implies the others are unverified.
- Source-checked. A model re-read the published source document and confirmed the text states this dependency. This is the only basis that carries a
confidence_band(High, Medium, or Low), which reflects how well the source text supports the edge, not human sign-off. The confirmed passage is shown. - Extracted. Identified by the extraction pipeline from the source material when the methodology was processed. When the pipeline captured the exact sentence that states the dependency, that sentence is carried on the edge as
evidence_phraseand shown as a quote; otherwise the edge states its basis without a pinned passage. - Structural. A relationship the graph knows from how the standards are organized, for example a project methodology that builds on its program's framework, established or inferred from the program structure and direction-checked. It is not drawn from a single source passage, and that is the point: it is where the graph captures a real relationship that no individual document spells out.
Each edge also carries an origin (one of author_declared, parser_hardcoded, model_inferred, migration_audit, structural_inferred, composition, operator), a one-line rationale, a status_label naming the basis above with a one-sentence status_text, and a source pointer. The source pointer always includes the publisher_url (a link to the publisher's own page). It includes a cached_url to our stored snapshot only when the source's license permits redistribution, because serving the snapshot is redistributing the publisher's document.
These fields appear on every edge returned by the dependency endpoints, the dependency tree, and the MCP tools, and they drive the "why this edge exists" panel in the viewer.
Provenance#
Every successful calculate response carries:
- The formula text that produced the result, exactly as stored.
- The full inputs object used in evaluation, including any auto-resolved factor values.
- The methodology version that was active when the calculation ran.
- The standard reference, a citation pointing to the published source.
- Any dataset resolutions, including which dataset, which row, which field, and which implementation supplied each value.
- For composition calls, the per-component resolution trace under
provenance.composition.resolved_components. Each symbol carries avalueand afromfield:input(the caller passed it directly),sub_methodology(the engine recursively resolved it from a child methodology, withsub_methodology_idandoutput_fieldattached), ordefault_optional(the symbol is ininput_schema.propertiesbut not inrequired, and the engine defaulted it to 0). The final composed formula is repeated underprovenance.composition.final_formula. - A timestamp,
computed_at, in ISO 8601 UTC.
This is enough metadata to replay the same call years later and get bit-identical results, assuming the version is still available. Methodology versions are immutable; new versions get new identifiers.
Versions and cascades#
Each methodology has a current_version string. Calling /v1/calculate/:id uses the current live version. Calling /v1/calculate/:id/:version pins to a specific version (useful for audit replay).
When a methodology's version bumps, the cascade walks every edge in the dependency graph and flags every downstream methodology as requires re-evaluation. This is published as a revision event in /v1/revisions/recent, so consumers can subscribe to changes and decide when to migrate.
API base & auth#
Base URL for all REST endpoints:
https://api.methodology.energyweb.org/v1/Authentication
Every /v1/* request requires an API key. Send it as the X-API-Key header (or Authorization: Bearer if you prefer the OAuth convention):
curl https://api.methodology.energyweb.org/v1/methodologies \
-H "X-API-Key: vcc_mg_..."
Getting a key. Three tiers:
| Tier | Rate limit | How to get one |
|---|---|---|
demo | 300 requests / minute * | Shared public key demo-key-public-2026. Used by the viewer and API explorer by default, with no signup required. Suitable for browsing and exploration. Both surfaces switch to your personal key automatically once you sign up. |
free | 600 requests / minute | Sign up with email. One key per email. Magic-link confirmation, no password. Manage at /account. |
enterprise | Custom (admin-issued) | For partner integrations. Email methodology@energyweb.org. |
* The demo key's 300 req/min cap applies to programmatic callers (scripts, server-side code, external clients). Calls made from our own viewer and API explorer pages bypass the per-key cap because the browser's Origin header marks them as same-origin to the API host. The per-IP cap below still applies in both cases.
The single exception: GET /v1/health requires no key, so uptime probes work without authentication. GET /v1/stats is also unauthenticated for the marketing page.
Rate limits
Per-key, per-minute, sliding window. When you exceed your quota the API returns 429 rate_limited with a Retry-After header and a JSON body that includes retry_after_seconds:
HTTP/1.1 429 Too Many Requests
Retry-After: 23
Content-Type: application/json
{
"error": {
"code": "rate_limited",
"message": "You hit your per-minute limit (600). Retry in 23s.",
"retry_after_seconds": 23,
"details": {
"limit": 600,
"used": 600,
"window_seconds": 60,
"tier": "free"
}
}
}
A secondary per-IP limit (1200 req/min) sits in front of the key check to slow brute-force key-guessing. In practice you will not see it unless you share an IP with many other callers or you're making unauthenticated requests at high volume.
Response envelope
List responses always return { "data": [...], "count": N }. Single-resource responses return the resource object directly. Errors always return:
{
"error": {
"code": "validation_failed",
"message": "Provide an inputs object in the request body",
"details": { ... optional ... }
}
}
Error codes are documented in the Errors section below.
Versioning
The API itself is versioned under the URL path. Today's version is v1. Breaking changes will introduce v2; v1 remains supported for a deprecation window of at least 12 months.
Methodologies#
The core resource. Every node in the graph is a methodology. Use these endpoints to browse the registry, fetch detail, and walk dependencies.
List methodologies
/v1/methodologiesQuery parameters
| Name | Type | Description |
|---|---|---|
| layer | integer | Filter by layer (1 to 7). |
| jurisdiction | string | Filter by jurisdiction code (e.g. EU, US, GLOBAL). |
| limit | integer | Max results to return, default 200, max 1000. |
| offset | integer | Skip results, default 0. |
Get a methodology
/v1/methodologies/:idReturns the full graph node, including name, layer, modality, jurisdiction, current_version, formula_type, vcc_status, scope, and timestamps.
List versions
/v1/methodologies/:id/versionsReturns every version of a methodology, ordered newest to oldest. Each version has an immutable identifier, an effective date, and a source content reference.
Recent revisions
/v1/methodologies/:id/revisionsAudit log of every revision event for a methodology (version bumps, status changes, dependency updates). Useful for change tracking.
Dependencies
/v1/methodologies/:id/dependenciesUpstream and downstream edges in one response. upstream lists methodologies this one depends on; downstream lists methodologies that depend on this one.
Each edge carries its full provenance (see Edge provenance for what each basis means):
| Field | Type | Description |
|---|---|---|
| from_methodology_id / to_methodology_id | string | The two endpoints of the edge. |
| edge_type | string | The relationship, e.g. imports, uses_factor, references, supersedes. |
| predicate | string | The specific thing the dependency is for, e.g. "woody biomass carbon stock estimation". |
| rationale | string | One-line statement of why the edge exists. |
| status_label | string | How the edge is grounded: Source-checked, Extracted, or Structural. Three equally legitimate kinds of grounding, not a ranking. |
| status_text | string | One sentence expanding the label for a reader. |
| confidence_band | string or null | High, Medium, or Low. Present only for Source-checked edges; null otherwise. |
| evidence_phrase | string or null | The exact sentence from the source that states the dependency, when the pipeline captured one (Extracted edges). null when no single passage was pinned. |
| origin | string | One of author_declared, parser_hardcoded, model_inferred, migration_audit, structural_inferred, composition, operator. |
| source | object | source_id, publisher_url (always present), and cached_url (our stored snapshot, present only when the source license permits redistribution; null otherwise). |
The dependency tree at /v1/methodologies/:id/tree and the MCP tools return edges in the same shape.
Get a methodology's schema
/v1/methodologies/:id/schemaReturns the live implementation's input_schema, output_schema, formula_spec, and standard_reference. Use this to discover what inputs a calculator expects before calling it.
Calculate#
Execute a methodology's formula. Pass the inputs the schema requires, get the result with full provenance metadata.
List calculators
/v1/calculateReturns every methodology with a live, callable implementation. Each entry includes the implementation id, version, status, and schema summary.
List extraction candidates
/v1/calculate/candidatesMethodologies that have a formula in the published standard but no live implementation yet. Useful for tracking pipeline coverage.
Get calculator metadata
/v1/calculate/:methodology_idReturns every implementation for one methodology, with input and output schemas.
Run a calculation
/v1/calculate/:methodology_idRequest body
| Field | Type | Description |
|---|---|---|
| inputsrequired | object | Object containing all required inputs from the methodology's input_schema. Optional inputs may be omitted; declared dataset dependencies may also be omitted if the lookup key is provided. |
Response
| Field | Type | Description |
|---|---|---|
| methodology_id | string | Echo of the requested methodology. |
| version | string | Methodology version that ran. |
| impl_id | string | Implementation identifier. |
| result | object | Output values keyed per output_schema. Numbers rounded to 3 decimals. Each output may be accompanied by a _unit sibling. |
| provenance | object | Formula text, inputs used, standard reference, resolved dataset values. |
| vcc_receipt | object | Verified Compute receipt if available, null otherwise. |
| computed_at | string | ISO 8601 UTC timestamp. |
Run pinned to a specific version
/v1/calculate/:methodology_id/:versionIdentical to the unpinned variant, but executes against the named version instead of the current live version. Use this for audit replay and version-locked integrations.
Lookup#
Query dataset-type methodologies. Each dataset is a key-value lookup table, optionally with multiple value fields per row.
List datasets
/v1/lookupReturns every methodology with formula_type = dataset, including those without a populated lookup table yet.
Get dataset metadata
/v1/lookup/:methodology_idReturns implementation metadata: the key field, the available value fields, row count, and three sample rows. Does not return the full table.
List keys
/v1/lookup/:methodology_id/keysReturns the available key values for a dataset, plus one suggested_key. Useful for clients that want to prefill a lookup form with a key that will hit a real row.
Query parameters
| Name | Type | Description |
|---|---|---|
| limit | integer | Max keys to return, default 50, max 500. |
Get the full table
/v1/lookup/:methodology_id/tableReturns every row in the live lookup table for a dataset.
Query parameters
| Name | Type | Description |
|---|---|---|
| limit | integer | Max rows to return, default 500, max 5000. |
| offset | integer | Skip rows, default 0. |
Look up a key
/v1/lookup/:methodology_id/key?key=...&field=.../v1/lookup/:methodology_idPOST body shape:
| Field | Type | Description |
|---|---|---|
| keyrequired | string | The value to look up. Matched against the dataset's key_field. |
| field | string | Optional. Return only this field from the matching row. Omit to return the whole row. |
curl -X POST https://api.methodology.energyweb.org/v1/lookup/ipcc-gwp \
-H "content-type: application/json" \
-d '{"key": "CH4", "field": "gwp_100"}'
{
"methodology_id": "ipcc-gwp",
"version": "AR6 WG1 (2021)",
"result": { "gwp_100": 29.8 },
"provenance": {
"key_field": "gas",
"standard_reference": "IPCC AR6 WG1, Chapter 7, Table 7.15"
}
}
Frameworks#
Governance and disclosure frameworks with no calculation logic. Useful for understanding the regulatory context around calculators that implement them.
List frameworks
/v1/frameworksQuery parameters
| Name | Type | Description |
|---|---|---|
| layer | integer | Filter by layer. |
| jurisdiction | string | Filter by jurisdiction. |
| limit | integer | Max results, default 200. |
Get framework detail
/v1/frameworks/:methodology_idReturns four blocks. framework is the bare graph node. impl is the live framework method package, including its standard reference and critic confidence. content carries the extracted structure: purpose, scope, audience, sections (each with a title and a summary), key_definitions (each with a term and a definition), and references. upstream and downstream list every methodology connected by an edge.
Registries#
Credit and certificate issuance registries that other methodologies depend on.
List registries
/v1/registriesGet registry detail
/v1/registries/:methodology_idReturns four blocks. registry is the bare graph node. impl is the live registry method package. metadata carries the registry profile: issuer, jurisdiction, governance_body, accepted_credit_types, accepted_methodologies, public_portal_url, has_public_api, ledger_access, scope_summary. consumers lists every methodology that depends on this registry.
Compositions#
Umbrella methodologies that decompose into named components. The metadata endpoint described here returns the structural view. To actually run a composition, POST to /v1/calculate/:id with the umbrella's id.
List compositions
/v1/compositionsReturns every methodology with formula_type = composition.
Get composition detail
/v1/compositions/:methodology_idReturns the structural view of an umbrella. The response carries:
composition: the umbrella's bare graph node.impl: the live composition method package, including its standard reference and critic confidence.final_formula: the umbrella's final calculation as a string (e.g.e_ec + e_l + e_p + e_td + e_u - e_sca - e_ccs - e_ccr).components: every component, annotated withsymbol,description,source_section,sub_methodology_id,sub_methodology_name,expected_sub_kind,is_required(true when the symbol is in the umbrella'sinput_schema.required), andsub_methodology_live(true when the sub-methodology has a live executable implementation today).required_symbols: the umbrella'sinput_schema.requiredlist, repeated at the top level for convenience.component_edges: theimportsedges from the umbrella to its components, each with predicatecomponent:<symbol>.
curl https://api.methodology.energyweb.org/v1/compositions/eu-red3 \
-H "X-API-Key: vcc_mg_..."
{
"composition": { "id": "eu-red3", "name": "EU RED III", ... },
"impl": { "impl_id": "eu-red3-composition-...", "status": "live", ... },
"final_formula": "e_ec + e_l + e_p + e_td + e_u - e_sca - e_ccs - e_ccr",
"components": [
{ "symbol": "e_ec", "sub_methodology_id": "eu-red3-cultivation", "is_required": true, "sub_methodology_live": false },
// ...
],
"required_symbols": ["e_ec", "e_l", "e_p", "e_td", "e_u"],
"component_edges": [...]
}
Impacts & dependency trees#
Traverse the graph by edge relationships, not just by methodology.
Get impacts
/v1/impacts?upstream=X/v1/impacts?downstream=YWalk upstream or downstream from a given methodology. Useful for change-impact analysis (e.g. "what breaks if IPCC GWP updates"). Requires a personal API key. The shared demo key is not accepted from external callers on this endpoint; sign up for a free key (email only, no credit card) at /signup.
Layer matrix
/v1/impacts/layer-matrixReturns edge-count aggregates between each pair of layers (1 through 7). Up to 49 rows. Use for chord and sankey diagrams that show the topology shape without enumerating individual edges. Public, demo-key accessible.
Centrality leaderboard
/v1/impacts/centralityReturns the top methodologies ranked by total degree (inbound + outbound edges). Each row has the methodology id, name, layer, and the inbound and outbound counts. Default 50, max 500. Public, demo-key accessible. Useful for finding the most-depended-on methodologies (the gravity wells of the graph).
All edges (enterprise)
/v1/impacts/edges/allReturns every edge in the graph with both endpoints' layers pre-joined. Restricted to enterprise-tier keys. Responses include a watermark _meta.export_token for traceability. For most use cases, the layer matrix and centrality endpoints above provide the same insight without exposing individual edges. Contact methodology@energyweb.org for enterprise access.
Dependency tree
/v1/dependency-tree/:methodology_idReturns the full upstream-plus-downstream dependency tree for one methodology, up to depth 3 in each direction, capped at 500 nodes total. Public, demo-key accessible. Subject to per-IP scrape detection: fetching more than 100 distinct methodologies in a 5-minute window from one IP triggers a temporary 1-request-per-second throttle. Sign up for a free key to bypass the demo restrictions on related endpoints.
Sources#
The primary documents the pipeline crawls and parses. One source can produce many methodologies (e.g. a single ICAO Annex document defines multiple calculators and a default LCA table).
List sources
/v1/sourcesReturns every active source, with publisher, content type, last fetched time, and the methodologies it produced.
Get a source
/v1/sources/:idReturns full detail for one source: publisher, URL, jurisdiction, fetch cadence, last fetched at, current status, and the methodologies it produces.
Source snapshots
/v1/sources/:id/snapshotsEvery archived snapshot the pipeline has taken of a source, ordered newest to oldest. Each entry includes the content hash, fetch timestamp, and snapshot storage reference.
Revisions#
The audit log of every meaningful change in the graph: methodology version bumps, status transitions, dataset re-extractions, dependency edge updates. Useful for change-tracking integrations and webhook fan-out.
Recent revisions
/v1/revisions/recentThe 50 most recent revision events across the entire registry, ordered newest first. Each entry includes the methodology id, revision kind (version_bump, status_change, schema_change, dataset_update), the from and to values, and the timestamp.
List revisions
/v1/revisionsPaginated list of every revision event. Supports limit and offset for pagination. For methodology-scoped revisions use /v1/methodologies/:id/revisions instead.
Stats#
A public snapshot of headline counts across the registry. Useful for dashboards, status pages, and any integration that wants to show "how big is the graph today" without crawling every endpoint.
Get stats
/v1/statsThe only /v1/* endpoint that does not require an API key, since it returns only aggregate counts and no individual records. Cached server-side for 60 seconds.
{
"as_of": "2026-05-16T17:00:00Z",
"cached": true,
"methodologies": {
"total": 412,
"by_type": {
"formula": 198,
"dataset": 22,
"framework": 96,
"registry": 14
}
},
"calculators": { "live": 111, "beta": 5, "deprecated": 2 },
"sources": { "total": 312, "active": 296 },
"graph": { "edges": 568, "revisions": 1284 },
"factor_sets": { "loaded": 42, "rows_total": 8915 },
"discovery": { "seeds_active": 87, "parser_templates": 31 }
}
Errors#
All errors return a unified JSON envelope with an HTTP status that matches the code:
{
"error": {
"code": "rate_limited",
"message": "Human-readable summary.",
"details": { ... optional structured detail ... },
"retry_after_seconds": 60
}
}
The retry_after_seconds field is only set on rate_limited and service_unavailable, and is mirrored to the HTTP Retry-After header so off-the-shelf retry libraries pick it up automatically.
| Status | error code | Meaning |
|---|---|---|
| 400 | bad_request | Request body could not be parsed as JSON, or is malformed. |
| 400 | validation_failed | Required fields are missing or invalid. details often includes an example showing the expected shape. |
| 401 | unauthorized | Missing, unknown, or revoked API key. Visit /signup for a key, /account to manage an existing one. |
| 403 | forbidden | Authentication succeeded but the resource is not accessible to this key's tier or scopes. |
| 404 | not_found | Path, methodology, lookup key, or version does not exist. The message states which. |
| 405 | method_not_allowed | The endpoint exists but does not accept this HTTP verb. |
| 409 | conflict | The action conflicts with current state (for example, signing up with an email that already has a key). |
| 410 | gone | A token or link has expired or already been used. |
| 413 | payload_too_large | Request body exceeds 64 KB. |
| 429 | rate_limited | Per-key or per-IP rate limit exceeded. Honour Retry-After. |
| 500 | internal_error | Server-side bug or transient failure. Safe to retry with backoff. |
| 503 | service_unavailable | An upstream dependency (D1, Resend, etc.) is degraded. Retry with backoff. |
Some calculation-specific responses return additional fields inside details:
not_implemented(status 501) when a methodology exists in the graph but has no live calculator yet.detailsincludesmethodology_id,vcc_status, and asuggestionto call/v1/calculate/candidatesfor the list of methodologies awaiting implementation.wrong_typeon framework or registry endpoints includes asuggestionfield with the correct path to use.
MCP server overview#
An MCP server exposing the entire Methodology Graph as typed tools. Designed for LLM clients that speak the Model Context Protocol: Claude (web, desktop, mobile), Cursor, custom ChatGPT integrations, or any agent runtime with MCP support.
https://mcp.methodology.energyweb.orgOnce connected, the agent can ask questions like:
- "What is the SAFc CO2e abatement for 234 tonnes of HEFA-UCO at 89 gCO2e/MJ baseline?"
- "List all methodologies that depend on IPCC GWP."
- "What's the GWP100 for HFC-134a in AR6?"
The server replies with structured tool calls that return JSON the agent can reason about, including the same provenance metadata as the REST API.
Connecting an MCP client#
Two flows. Consumer clients (Claude on web, desktop, mobile) authenticate via OAuth, taking about a minute. Programmatic clients use a Bearer API key, the same one the REST API uses.
Claude (web, desktop, mobile)
One-click OAuth flow. No config files, no API keys to paste.
- Open Settings → Connectors (or visit claude.ai/customize/connectors).
- Click the + button next to Connectors. Pick a name (for example, Methodology Graph) and paste:
Leave the Advanced settings empty. Click Add.MCP server URL
https://mcp.methodology.energyweb.org - Click Connect. A new tab opens to a Methodology Graph consent page. Enter your email, click Send confirmation link.
- Open the email titled Confirm Claude connection to Methodology Graph and click Confirm connection. Your browser briefly lands on Methodology Graph then redirects back to Claude. You are connected.
The connection mints a new API key tied to your email under the hood. You can revoke it any time at /account (look for a key named MCP: ... (your-email)). Re-connecting from a new device or after revocation issues a new key. The same email can hold multiple MCP connections at once (one per client: Claude web, Claude desktop, Cursor, and so on).
If you are on a Claude Team or Enterprise plan, an admin can add the connector at the organization level so it appears in every member's connectors list automatically. Each member still completes their own OAuth flow; tokens are per-user by design.
Claude Desktop (manual config, legacy)
If you prefer the legacy config-file path, edit Claude Desktop's config and paste your existing REST API key as a Bearer token. The OAuth flow above is recommended instead because it manages token rotation and per-device revocation automatically.
{
"mcpServers": {
"methodology-graph": {
"url": "https://mcp.methodology.energyweb.org",
"headers": {
"Authorization": "Bearer vcc_mg_..."
}
}
}
}
Get a key at /signup (email magic link, 60 seconds, no credit card). Restart Claude Desktop after editing.
Programmatic clients (Cursor, agent frameworks, custom)
Any MCP-compatible client can connect by pointing at the server URL above with a Bearer token in the Authorization header:
Authorization: Bearer vcc_mg_...
Get a key the same way as the REST API: /signup. Free tier (600 req/min) is enough for typical agent workflows. For high-volume integrations, request an enterprise key at methodology@energyweb.org.
The server speaks the MCP 2025-06-18 Streamable HTTP transport. POST JSON-RPC 2.0 messages to the server root. The handshake is:
POST https://mcp.methodology.energyweb.org/
Authorization: Bearer vcc_mg_...
Content-Type: application/json
{"jsonrpc":"2.0","method":"initialize","id":1}
Followed by tools/list to discover available tools, and tools/call to invoke one. See the MCP specification at modelcontextprotocol.io for the full protocol.
Available MCP tools#
| Tool name | What it does |
|---|---|
| search_methodologies | Semantic search across the registry. Returns the top matches with similarity scores. |
| get_methodology | Fetch full detail for one methodology including version, schema, dependencies. |
| list_methodologies | Filter the registry by layer, jurisdiction, or formula type. |
| calculate | Run a calculator with inputs. Returns result plus full provenance. |
| lookup_dataset | Query a dataset lookup table by key. |
| get_framework | Read a framework's metadata plus dependency context. |
| get_registry | Read a registry's metadata plus consumer list. |
| dependency_tree | Walk upstream and downstream from a methodology. |
| which_rules_apply | Find which methodologies apply to a company given what it does. Provide an activity code (ISIC, NACE, or NAICS), optionally narrowed by jurisdiction and regime (V/R/B). Returns the grounded set of rules that govern that activity, each with its applicability and an importance signal, mandatory rules first. The primary tool for onboarding a claimant: it answers "which rules apply to me". |
| get_applicability | Get the applicability of one methodology: the activities it governs, the actor role it applies to, conditions, exclusions, and the basis (stated in source vs provisional), each grounded to a source. Use after get_methodology to explain who a rule applies to. |
| get_reporting | Get the reporting requirement for one methodology: the format, where it is submitted, whether third-party verification is required and of what, and the filing cadence, grounded to a source. Answers "how do I report this". |
| recent_revisions | List the most recent change events across the registry. |
| list_sources | List all source entities (regulators, standards bodies, registries, dataset publishers) with license disposition. Use to answer "who is behind X" or "which sources permit commercial reuse". |
| get_source | Fetch one source entity with optional full license chain including attribution template. Use to answer "can I use this dataset commercially". |
| plan | Compose a content-addressed Verification Plan from a natural-language company description. Picks the right methodologies, frameworks, and factor sources for the target regimes and jurisdictions. Useful when an agent does not yet know which calculator to call. |
| replay | Re-fetch a previously composed Plan by its content identifier. Returns the plan structure; re-executing a plan's results is a separate step. |
| attest | Produce a signed attestation over a plan execution. Returns a Verified Compute receipt that an auditor can verify offline against the published standard. Currently in beta and available to allowlisted enterprise keys. |
Every tool returns the same structured data shape as the REST API, with the same provenance metadata. The MCP server is a transport wrapper, not a separate data model.
Webhooks#
Subscribe to events emitted by the autonomous pipeline. Today's primary event is plan.published, fired when a Verification Plan is composed or republished. Future events include methodology.revised, calculator.promoted, and calculator.deprecated; subscribers receive these automatically when they ship.
Creating a webhook
Webhooks are managed in the admin Settings UI by users with admin access. For enterprise customers, Energy Web staff can create webhooks on your behalf. Contact methodology@energyweb.org for a webhook registration. You will receive back a webhook id and a one-time-displayed secret of the form whsec_... that you'll need to verify deliveries.
Delivery contract
The pipeline POSTs each event to your endpoint as JSON with three control headers:
| Header | Value |
|---|---|
content-type | application/json |
x-ew-mg-event | Event name, currently always plan.published. |
x-ew-mg-delivery-id | UUID. Use as your idempotency key. |
x-ew-mg-signature | sha256=<hex>, HMAC-SHA256 of the raw request body using your webhook secret. |
{
"event": "plan.published",
"plan_cid": "bafy2bzaceabc...xyz",
"reason": "revision-cascade",
"affected_methodology_ids": ["ipcc-gwp", "verra-vm0007"],
"emitted_at": "2026-05-19T15:08:42.117Z"
}
Verifying signatures
Every request is signed with HMAC-SHA256 using your webhook's secret. To verify, compute the HMAC over the raw request body (not the parsed object) and compare to the value in x-ew-mg-signature after the sha256= prefix. Use a constant-time comparison.
import crypto from 'node:crypto';
function verify(rawBody, signatureHeader, secret) {
const [scheme, hex] = signatureHeader.split('=');
if (scheme !== 'sha256') return false;
const expected = crypto
.createHmac('sha256', secret)
.update(rawBody)
.digest('hex');
return crypto.timingSafeEqual(
Buffer.from(hex, 'hex'),
Buffer.from(expected, 'hex')
);
}
Idempotency and retries
Each delivery carries a unique x-ew-mg-delivery-id. We dedup on the worker side too: a successful delivery of a given (webhook, plan_cid, reason) tuple is recorded for 30 days, and repeats are silently dropped at the source. You should still implement your own idempotency check using the delivery id, because edge cases (worker restart between dedup write and ack) can produce duplicates.
We treat any non-2xx response as a failure. The current implementation does not retry per-webhook (a single failure increments your failure_count; sustained failures result in your endpoint being disabled). A future revision will move per-webhook retry into a separate queue with exponential backoff for partners that require at-least-once with retry.
Best practices
- Respond fast. Return a 2xx within 5 seconds. Do the actual work asynchronously after acknowledging.
- Verify the signature before parsing. A signed payload from an unknown source should never reach your handler logic.
- Dedup on delivery id. Store delivery ids you've already processed for at least 7 days.
- Surface failures. Log non-2xx responses on your side; the admin Settings UI shows our view of your
last_statusandfailure_count, but you should have your own observability too.
Support#
For bug reports, feature requests, integration questions, or to discuss enterprise tier access, reach out at methodology@energyweb.org.
For partnership conversations (custom calculators, priority extraction, Verified Compute receipts, audit firm pilots), contact Energy Web directly.