API examples¶
Worked curl calls for every endpoint, with the reasoning behind each result's shape. The
machine-readable contract — every field, type and a response example cut from the live
calculation — is on the Endpoints page, rendered from the committed
openapi.json. Where the two disagree, the spec wins: it is regenerated
from the running app and checked in CI.
All examples assume the API is running locally:
The interactive Swagger UI (/docs) and ReDoc (/redoc) are served by the running app.
GET /health¶
Liveness probe.
GET /quantities/keur-songho¶
Returns corrected material quantities for the Keur Songho School Complex reference project.
CORRECTED formulas (C1–C4) are applied. BLOCKED parameters appear in blocked_parameters.
The full response, with an example excerpted from the live calculation, is in the rendered spec.
POST /quantities/explode¶
Explode a user-supplied BoQ into material quantities.
Phase 1 supports only "Keur Songho School Complex". Returns 501 for other projects.
curl -X POST http://localhost:8000/quantities/explode \
-H "Content-Type: application/json" \
-d '{
"project_name": "Keur Songho School Complex",
"line_items": [
{"code": "A.III.4", "unit": "m3", "quantity": 4.608}
]
}'
Phase 1 limitation
Generic BoQ explosion (arbitrary line items mapped to domain formulas) is planned for Phase 2 once the Assembly recipe model is defined. The POST /quantities/explode endpoint currently delegates to the same Keur Songho dispatcher as the GET endpoint.
GET /lca/a1-a3/keur-songho¶
Returns the A1-A3 (product stage) GWP for the Keur Songho School Complex reference project.
Applies E = weight × factor per material (VALIDATED formula, decision #23). Each per-material result carries its factor, source citation, verdict, geographic-provenance tag (decision #26), pending_african_data flag, and Weidema axis-4 note.
The aggregate total is null: five materials block a defensible total — Earth (decision #26 hard block, no EU substitute), Crude oil, Floor Tiles and Anti-termite (anomalous or uncited factors), and Antirust paint (CORRECTED provisional 4.87 kg CO₂/kg). Those five are listed in incomplete_reason. The other 13 materials still carry their individual A1-A3 GWP.
Four materials — Cement, Steel Rebars, Rock and Sand — resolve their factor from a
provenance-gated seed EPD rather than from the reference workbook (AR-63), and surface
source_epd_id, provenance_cascade_step and the full five-axis Weidema pedigree alongside the
value. The other fourteen are still inline literals and report all three as null; that asymmetry
is tracked debt, not a finished state.
Every CORRECTED row — those four plus Antirust paint — also carries reference_value, the
reference workbook's factor it supersedes (2_lca_vn.xlsx LCI Final column I, unit
kg_CO2_eq_kg), and divergence_pct = (factor − reference) / reference × 100: Rock +190.1 %,
Sand −4.0 %, Cement −14.6 %, Steel Rebars −78.2 %, Antirust paint −95.4 %. Both are null on
VALIDATED and BLOCKED rows (AR-71).
The full response, with an example excerpted from the live calculation, is in the rendered spec.
The A1-A3 total is intentionally null
The tool never emits a partial total as if complete (result policy, decision #23). Because Earth, Crude oil, Floor Tiles and Anti-termite are BLOCKED and Antirust paint is PROVISIONAL, the aggregate is withheld and the blockers are surfaced in incomplete_reason. Per-material impacts remain available for the 13 computable materials.
GET /lca/a4/keur-songho¶
Returns the A4 (transport to site) GWP for the Keur Songho School Complex reference project.
Applies A4_i = Σ_legs (mass_i [t] × distance [km] × factor [kg CO₂-eq/t·km]) (VALIDATED formula, decision #23). Mass comes from the LCI mass path — A4 never re-derives quantities. Each material carries one result per transport leg, with distance, transport work (t·km), route note, distance source, provenance verdict and Weidema axis-4 score.
The aggregate total is null: both transport emission factors are BLOCKED (decision #23 Axis 2).
- Road truck — the workbook's
0.26 kg CO₂-eq/kWh(A4!I5:I22) has no cited dataset; the Pedrazzi thesis describes the same model with different numbers (0.27 kg CO₂-eq/kWh,386 kW) and names no programme operator either. - Sea freight —
A4!L11 = 182.4/(F11*N11)back-solves a rate from an unexplained182.4 kg CO₂-eqconstant, then broadcasts it to every sea-freighted material via$L$11.
Decision #26 admits only an IPCC EFDB or ÖKOBAUDAT transport-EPD factor per t·km for A4. Fifteen materials are therefore BLOCKED and listed in incomplete_reason. Water, Crude oil and Waste Oil are on-site (zero distance per A4!B25) and compute to exactly 0 — a zero-length leg contributes nothing whatever the factor turns out to be.
The full response, with an example excerpted from the live calculation, is in the rendered spec.
The A4 total is intentionally null
Unlike A1-A3, where 13 of 18 materials remain computable, A4 has no usable emission factor at all. Sourcing a road-freight and a sea-freight factor per t·km from IPCC EFDB or an ÖKOBAUDAT transport EPD (sourcing tasks A4-1 and A4-2) is the gate for reporting any A4 result. See docs/methodology/lca-a4-transport-spec.md §8.
GET /lca/a5/keur-songho¶
Returns the A5 (on-site construction and installation) GWP for the Keur Songho School Complex reference project.
Applies A5_e = rated_power [kW] × usage [h] × factor [kg CO₂-eq/kWh] and share_e = A5_e / Σ A5 (both VALIDATED formulas, decision #23). The A5 sheet is already written in the EN 15804+A2 energy-carrier form, so — unlike A4 — no algebraic reduction was needed to reach it.
A5 is the first stage that is not material-keyed. A1-A3, A4, B4, C2, C3, C4 and D all carry one row per material and join on the 18-row LCI inventory. A5 carries one row per item of site plant, and the workbook's own INTERPRETATION sheet places its three A5 rows below the 18 material rows with every material-stage cell empty. Results are therefore keyed on SiteEquipment (generator, cutting_machine, welding_machine), not MaterialCategory.
The aggregate total is null: the single site-energy emission factor is BLOCKED (decision #23 Axis 2). Four independent reasons, any one sufficient —
- No citation.
A5!F5:F7 = 0.26 kg CO₂-eq/kWhis a bare literal in three cells. The sheet has no source column, no cell comments and no legend. - Decision #26 governs it. A5 construction energy is named explicitly as an energy-linked stage on which EU grid factors are BLOCKED outright; an African national grid factor from IEA World Energy Statistics or IPCC EFDB is required, and
0.26sits in the EU-average band. - The workbook contradicts itself. The same file carries a Senegal grid factor at
B1!D5 = 1.1 kg CO₂/kWh— 4.2× larger, unreconciled, and itself unverified (AR-09). - It is applied to a diesel genset. A generator consumes no grid electricity; its per-kWh factor is a fuel-combustion quantity (published gensets run ≈ 0.7–0.8 kg CO₂-eq/kWh), so a grid-shaped number is a category error here whatever grid it came from.
total_energy_demand is reported — 1 080 kWh — because energy demand is power × hours and needs no emission factor. This is the shape every blocked module should aim for: report the half that is defensible, withhold the half that is not.
The full response, with an example excerpted from the live calculation, is in the rendered spec.
This is a deliberately partial A5, and every response says so
EN 15804+A2 §6.3.4.4 places six further sub-scopes in A5 — material installation losses, on-site water, packaging waste treatment, temporary works, transport of plant and workers, and site earthworks. None of them exists in 2_lca_vn.xlsx, and none is invented here: filling them would put numbers into an ISO 14071 review that trace to nothing. scope_note carries that statement on every response so the figure can never read as a complete A5. Choosing which sub-scopes v1 declares, and documenting a cut-off justification for the rest, is register row AR-58.
The A5 GWP total is intentionally null
Sourcing a Senegalese grid factor from IEA World Energy Statistics or IPCC EFDB (register row AR-54, which turns on AR-09) is the gate. It cannot be sourced blind: whether A5 needs a grid factor at all depends on resolving whether the cutting and welding machines ran off the generator, in which case the sheet double-counts their energy and needs a fuel-combustion factor instead (AR-56). See docs/methodology/lca-a5-construction-spec.md §4.