Sourced greenhouse-gas emission factors and audit-traced carbon calculations. Every value returns with its exact source cell and data version - reproducible and citable. REST API with bearer-token auth; endpoints for factor lookup, resolution, and GHG activity, embodied, PCAF, electricity, freight, spend-based and business-travel calculations.
Full LLM thinking from the 4-phase benchmark pipeline.
```json
{
"service_type": "rest_api",
"base_url": "https://api.greencalculus.com/v1",
"auth_method": "bearer_token",
"auth_config": {
"header": "Authorization",
"prefix": "Bearer"
},
"endpoints": [
{
"path": "/health",
"method": "GET",
"purpose": "Liveness probe; open, no auth.",
"params": {},
"response_format": "json",
"is_primary": false
},
{
"path": "/factors",
"method": "GET",
"purpose": "Browse/search the emission-factor corpus by section, key prefix, or region. Open, no auth; values redacted without a key.",
"params": {
"search": {"type": "string", "required": false},
"section": {"type": "string", "required": false},
"key_prefix": {"type": "string", "required": false},
"region": {"type": "string", "required": false},
"limit": {"type": "integer", "required": false}
},
"response_format": "json",
"is_primary": true
},
{
"path": "/factors/{key}",
"method": "GET",
"purpose": "Resolve one emission factor by canonical key; returns value plus full provenance (source id, source reference, data version).",
"params": {
"key": {"type": "string", "required": true},
"as_of": {"type": "string", "required": false}
},
"response_format": "json",
"is_primary": true
},
{
"path": "/factors/{key}/history",
"method": "GET",
"purpose": "Every data version the archive holds for one factor key, with the value each served.",
"params": {
"key": {"type": "string", "required": true}
},
"response_format": "json",
"is_primary": false
},
{
"path": "/calculate/resolve",
"method": "POST",
"purpose": "Turn a plain-text description into ranked canonical factor keys with confidence scores.",
"params": {
"description": {"type": "string", "required": true}
},
"response_format": "json",
"is_primary": true
},
{
"path": "/calculate/ghg-activity",
"method": "POST",
"purpose": "Activity × factor emissions with unit conversion, arithmetic working, and GHG Protocol scope tagged.",
"params": {
"activity": {"type": "object", "required": true},
"factor_key": {"type": "string", "required": true}
},
"response_format": "json",
"is_primary": true
},
{
"path": "/calculate/electricity",
"method": "POST",
"purpose": "Scope 2 purchased electricity, location-based + market-based dual reporting.",
"params": {
"consumption": {"type": "object", "required": true},
"market_factor_key": {"type": "string", "required": false},
"location_factor_key": {"type": "string", "required": false}
},
"response_format": "json",
"is_primary": false
},
{
"path": "/calculate/embodied",
"method": "POST",
"purpose": "Whole-life embodied carbon per EN 15978 (modular A1–A3/A4/A5/B/C/D, boundary-aware).",
"params": {},
"response_format": "json",
"is_primary": false
},
{
"path": "/calculate/pcaf",
"method": "POST",
"purpose": "PCAF Part A financed emissions with full audit trail.",
"params": {},
"response_format": "json",
"is_primary": false
},
{
"path": "/calculate/freight",
"method": "POST",
"purpose": "Freight tonne-km emissions (GLEC), Scope 3 Cat 4/9.",
"params": {},
"response_format": "json",
"is_primary": false
},
{
"path": "/calculate/spend-based",
"method": "POST",
"purpose": "Spend-based EEIO Scope 3 screening estimate.",
"params": {},
"response_format": "json",
"is_primary": false
},
{
"path": "/calculate/business-travel",
"method": "POST",
"purpose": "Business travel passenger-km emissions, Scope 3 Cat 6.",
"params": {},
"response_format": "json",
"is_primary": false
},
{
"path": "/calculate/batch",
"method": "POST",
"purpose": "Run up to 100 calculation line-items in one request.",
"params": {},
"response_format": "json",
"is_primary": false
},
{
"path": "/changes",
"method": "GET",
"purpose": "What each data release added, changed and withdrew (open, no key).",
"params": {},
"response_format": "json",
"is_primary": false
},
{
"path": "/changes/{version}",
"method": "GET",
"purpose": "Per-release detail for a specific data version.",
"params": {
"version": {"type": "string", "required": true}
},
"response_format": "json",
"is_primary": false
},
{
"path": "/roadmap",
"method": "GET",
"purpose": "The API's own published coverage gaps (open, no key).",
"params": {},
"response_format": "json",
"is_primary": false
```json
{
"tests": [
{
"name": "health_liveness",
"endpoint": "/health",
"method": "GET",
"headers": {},
"payload": null,
"expected_status": 200,
"intent": "happy_path",
"expected_behavior": "Liveness probe returns JSON confirming the service is up",
"metrics": ["latency", "status_code"],
"validation": {"field": null, "type": "object", "min_length": null}
},
{
"name": "list_factors_anonymous",
"endpoint": "/factors",
"method": "GET",
"headers": {},
"payload": null,
"expected_status": 200,
"intent": "happy_path",
"expected_behavior": "Keyless browse of the corpus returns a list of factor metadata (values redacted without a key)",
"metrics": ["latency", "status_code", "accuracy"],
"validation": {"field": "factors", "type": "array", "min_length": 1}
},
{
"name": "search_factors_query",
"endpoint": "/factors?search=electricity&limit=10",
"method": "GET",
"headers": {},
"payload": null,
"expected_status": 200,
"intent": "happy_path",
"expected_behavior": "Search by keyword returns matching factor rows respecting the limit",
"metrics": ["latency", "status_code", "accuracy"],
"validation": {"field": "factors", "type": "array", "min_length": 1}
},
{
"name": "get_factor_by_key",
"endpoint": "/factors/grid.gbr.electricity.location_based",
"method": "GET",
"headers": {"Authorization": "Bearer ${API_KEY}"},
"payload": null,
"expected_status": 200,
"intent": "happy_path",
"expected_behavior": "Returns the factor value plus full provenance: source id, source reference, data version",
"metrics": ["latency", "status_code", "accuracy"],
"validation": {"field": "value", "type": "number", "min_length": null}
},
{
"name": "factor_history",
"endpoint": "/factors/grid.gbr.electricity.location_based/history",
"method": "GET",
"headers": {"Authorization": "Bearer ${API_KEY}"},
"payload": null,
"expected_status": 200,
"intent": "happy_path",
"expected_behavior": "Returns every data version the archive holds for the key with the value each served",
"metrics": ["latency", "status_code"],
"validation": {"field": "history", "type": "array", "min_length": 1}
},
{
"name": "resolve_description",
"endpoint": "/calculate/resolve",
"method": "POST",
"headers": {"Authorization": "Bearer ${API_KEY}", "Content-Type": "application/json"},
"payload": {"description": "UK grid electricity, location based, one kilowatt hour"},
"expected_status": 200,
"intent": "happy_path",
"expected_behavior": "Returns ranked canonical factor keys with confidence scores",
"metrics": ["latency", "status_code", "accuracy"],
"validation": {"field": "candidates", "type": "array", "min_length": 1}
},
{
"name": "ghg_activity_calculation",
"endpoint": "/calculate/ghg-activity",
"method": "POST",
"headers": {"Authorization": "Bearer ${API_KEY}", "Content-Type": "application/json"},
"payload": {"activity": {"amount": 1000, "unit": "kWh"}, "factor_key": "grid.gbr.electricity.location_based"},
"expected_status": 200,
"intent": "happy_path",
"expected_behavior": "Returns emissions with unit conversion, arithmetic working shown, and GHG Protocol scope tagged",
"metrics": ["latency", "status_code", "accuracy"],
"validation": {"field": "emissions", "type": "object", "min_length": null}
},
{
"name": "electricity_dual_reporting",
"endpoint": "/calculate/electricity",
"method": "POST",
"headers": {"Authorization": "Bearer ${API_KEY}", "Content-Type": "application/json"},
"payload": {"consumption": {"amount": 5000, "unit": "kWh", "region": "GBR"}},
"expected_status": 200,
"intent": "happy_path",
"expected_behavior": "Returns Scope 2 location-based and market-based figures",
"metrics": ["latency", "status_code", "accuracy"],
"validation": {"field": "location_based", "type": "object", "min_length": null}
},
{
"name": "calculate_missing_required_field",
"endpoint": "/calculate/ghg-activity",
"method": "POST",
"headers": {"Authorization": "Bearer ${API_KEY}", "Content-Type": "application/json"},
"payload": {"activity": {"amount": 1000, "unit": "kWh"}},
"expected_status": 400,
"intent": "validation",
"expected_behavior": "Rejects request missing the required factor_key with a structured error",
"metrics": ["status_code"],
"validation": {"field": "error", "type": "object", "min_length": null}
},
{
"name": "get_factor_missing_auth_boundary",
"endpoint": "/account/watch/diff?from=2026-01-01&to=2026-02-01",
"method": "GET",
"headers": {},
"payload": null,
3/12 tests passed
| Test | Endpoint | Status | Latency |
|---|---|---|---|
| health_liveness | GET /health | 200 | 220ms |
| list_factors_anonymous | GET /factors | 200 | 606ms |
| search_factors_query | GET /factors?search=electricity&limit=10 | 200 | 178ms |
| get_factor_by_key | GET /factors/grid.gbr.electricity.location_based | 401 | 235ms |
| factor_history | GET /factors/grid.gbr.electricity.location_based/history | 401 | 49ms |
| resolve_description | POST /calculate/resolve | 401 | 52ms |
| ghg_activity_calculation | POST /calculate/ghg-activity | 401 | 133ms |
| electricity_dual_reporting | POST /calculate/electricity | 401 | 47ms |
| calculate_missing_required_field | POST /calculate/ghg-activity | 401 | 45ms |
| get_factor_missing_auth_boundary | GET /account/watch/diff?from=2026-01-01&to=2026-02-01 | 401 | 182ms |
{"model": "deepseek", "data": {"overall": 58, "dimensions": {"token_efficiency": 7.0, "first_try_success": 6.0, "response_parseability": 9.0, "error_clarity": 9.0, "doc_quality": 6.0, "auth_simplicity": 3.0, "latency": 9.0, "consistency": 9.0}, "pricing_normalized": {"cost_per_1k_requests": null, "cost_per_1m_input_tokens": null, "cost_per_1m_output_tokens": null, "free_tier_requests": 1000, "estimated_monthly_cost_light": 0, "estimated_monthly_cost_heavy": null}, "issues": [{"severity": "high", "detail": "Most primary endpoints (/factors/{key}, /calculate/*, /account/watch/diff) return 401 without an API key. The benchmark had no API key, so nearly all functional tests failed. Open endpoints (/health, /factors search) work fine. If a key were supplied, most tests would likely pass \u2014 but the agent could not autonomously obtain one: no self-service registration endpoint is exposed.", "endpoint": "/factors/{key}, /calculate/resolve, /calculate/ghg-activity, /calculate/electricity, /calculate/batch"}, {"severity": "high", "detail": "No documented self-service registration/signup endpoint for agents to obtain an API key. Auth requires a key (401 'Missing or invalid API key'), but onboarding path is opaque (credit-card-free free tier exists per pricing, but no programmatic endpoint found). This blocks first-try autonomous agent onboarding.", "endpoint": "/account (auth)"}, {"severity": "medium", "detail": "Validation tests could not be exercised \u2014 requests without auth short-circuit to 401 before reaching validation logic. A malformed /calculate/ghg-activity body returned 401 rather than 400, so an agent cannot discover required-field behavior until authenticated. Auth check should ideally run after routing but validation behavior is untestable anonymously.", "endpoint": "/calculate/ghg-activity"}, {"severity": "low", "detail": "The /factors list response is large (limit defaulting to 100 despite limit=10 in the query string; returned=100, filters echoed as all None). The search_factors_query test with search=electricity&limit=10 still returned 100 items with filters.search=None \u2014 the query parameters appear not to have been applied as intended.", "endpoint": "/factors"}, {"severity": "low", "detail": "Invalid factor key returns 401 rather than 404, because auth is enforced before resource existence. This makes it harder for an authenticated agent to distinguish 'bad key' from 'missing resource', though 401 is a defensible security choice.", "endpoint": "/factors/{key}"}], "recommendations": ["Provide a documented, programmatic API-key self-registration endpoint (email-based, no CAPTCHA/human) so an autonomous agent can onboard in seconds without human-in-the-loop.", "Keep the free tier truly no-credit-card (already stated) and expose the signup URL prominently in /health and error docs payloads so agents can self-remediate 401s.", "For authenticated requests, run schema validation before (or independent of) auth where safe, so agents get 400/422 with field-level detail rather than a 401 that hides validation behavior.", "Fix the /factors query-string handling: search=electricity&limit=10 returned 100 unfiltered rows with filters.search=None \u2014 ensure search/limit/section params are actually applied.", "Return 404 (not 401) for unknown factor keys when a valid key is supplied, and keep 401 only for missing/invalid credentials.", "Add a brief machine-readable error hint in the 401 body pointing to the exact signup/obtain-key URL.", "Confirm whether /calculate/batch exists as an endpoint \u2014 it 401'd like the others but was not in the published endpoint list.", "Publish a complete OpenAPI spec with request/response examples for the /calculate/* family to raise doc_quality and lower token cost for agents."]}}Sourced greenhouse-gas emission factors and audit-traced carbon calculations over a REST API. Every value returns with its exact source cell and data version, so a number an agent produces can be traced back to the published row it came from and cited. The corpus carries roughly 17,000 canonical factor keys across fuels, grid electricity, freight, refrigerants, embodied materials, spend-based EEIO and business travel. Where a factor does not exist, the API returns a structured absence record explaining why rather than an empty result or a silent zero - an agent can tell 'we do not publish this' apart from 'your request was ignored'. Base URL is https://api.greencalculus.com/v1; the OpenAPI 3.1 spec is at https://api.greencalculus.com/openapi.json and an MCP surface at https://mcp.greencalculus.com.
Show your live agent-readiness score on your own site. Free, no auth — it updates as your score changes.
<a href="https://prowl.world/service/greencalculus">
<img src="https://prowl.world/badge/greencalculus.svg" height="56" alt="Agent-readiness on Prowl">
</a>
See operational metrics, LLM evaluations, agent readiness, and more.
Open in Dashboard