Files
worldmonitor/docs/api/SupplyChainService.openapi.yaml
Elie Habib 7f83e1e0c3 chore: remove dormant proactive-intelligence agent (superseded by digest) (#3325)
* chore: remove dormant proactive-intelligence agent (superseded by digest)

PR #2889 merged a Phase 4 "Proactive Intelligence Agent" in 2026-04 with
588 lines of code and a PR body explicitly requiring a 6h Railway cron
service. That service was never provisioned — no Dockerfile, no Railway
entry, no health-registry key, all 7 test-plan checkboxes unchecked.

In the meantime the daily Intelligence Brief shipped via
scripts/seed-digest-notifications.mjs (PR #3321 and earlier), covering
the same "personalized editorial brief across all channels" use-case
at a different cadence (30m rather than 6h). The proactive agent's
landscape-diff trigger was speculative; the digest is the shipped
equivalent.

This PR retires the dormant code and scrubs the aspirational
"post-launch classifier" references that docs + comments have been
quietly carrying:

- Deleted scripts/proactive-intelligence.mjs (588 lines).
- scripts/_energy-disruption-registry.mjs, scripts/seed-fuel-shortages.mjs,
  scripts/_fuel-shortage-registry.mjs, src/shared/shortage-evidence.ts:
  dropped "proactive-intelligence.mjs will extend this registry /
  classifier output" comments. Registries are curated-only; no classifier
  exists.
- docs/methodology/disruptions.mdx: replaced "post-launch classifier"
  prose with the accurate "curated-only" description of how the event
  log is maintained.
- docs/api-notifications.mdx: envelope version is shared across **two**
  producers now (notification-relay, seed-digest-notifications), not three.
- scripts/notification-relay.cjs: one cross-producer comment updated.
- proto/worldmonitor/supply_chain/v1/list_energy_disruptions.proto +
  list_fuel_shortages.proto: same aspirational wording scrubbed.
- docs/api/SupplyChainService.openapi.{yaml,json} auto-regenerated via
  `make generate` — text-only description updates, no schema changes.

Net: -626 lines, +36 lines. No runtime behavior change. 6573/6573 unit
tests pass locally.

* fix(proto): scrub stale ListFuelShortages RPC comment (PR #3325 review)

Reviewer caught a stale "classifier-extended post-launch" comment on
the ListFuelShortages RPC method in service.proto that this PR's
initial pass missed — I fixed the message-definition comment in
list_fuel_shortages.proto but not the RPC-method comment in
service.proto, which propagates into the published OpenAPI
operation description.

- proto/worldmonitor/supply_chain/v1/service.proto: rewrite the
  ListFuelShortages RPC comment to match the curated-only framing
  used elsewhere in this PR.
- docs/api/SupplyChainService.openapi.{yaml,json}: auto-regenerated
  via `make generate`. Text-only operation-description update;
  no schema / contract changes.

No runtime impact. Other `classifier` references remaining in the
OpenAPI are legitimate schema field names (classifierVersion,
classifierConfidence) and an unrelated auto-revision-log trigger
enum value, both of which describe real on-row fields that existed
before this cleanup.
2026-04-23 09:15:57 +04:00

2335 lines
91 KiB
YAML
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
openapi: 3.1.0
info:
title: SupplyChainService API
version: 1.0.0
paths:
/api/supply-chain/v1/get-shipping-rates:
get:
tags:
- SupplyChainService
summary: GetShippingRates
operationId: GetShippingRates
responses:
"200":
description: Successful response
content:
application/json:
schema:
$ref: '#/components/schemas/GetShippingRatesResponse'
"400":
description: Validation error
content:
application/json:
schema:
$ref: '#/components/schemas/ValidationError'
default:
description: Error response
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
/api/supply-chain/v1/get-chokepoint-status:
get:
tags:
- SupplyChainService
summary: GetChokepointStatus
operationId: GetChokepointStatus
responses:
"200":
description: Successful response
content:
application/json:
schema:
$ref: '#/components/schemas/GetChokepointStatusResponse'
"400":
description: Validation error
content:
application/json:
schema:
$ref: '#/components/schemas/ValidationError'
default:
description: Error response
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
/api/supply-chain/v1/get-chokepoint-history:
get:
tags:
- SupplyChainService
summary: GetChokepointHistory
description: |-
GetChokepointHistory returns transit-count history for a single chokepoint,
loaded lazily on card expand. Keeps the status RPC compact (no 180-day
history per chokepoint on every call).
operationId: GetChokepointHistory
parameters:
- name: chokepointId
in: query
required: false
schema:
type: string
responses:
"200":
description: Successful response
content:
application/json:
schema:
$ref: '#/components/schemas/GetChokepointHistoryResponse'
"400":
description: Validation error
content:
application/json:
schema:
$ref: '#/components/schemas/ValidationError'
default:
description: Error response
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
/api/supply-chain/v1/get-critical-minerals:
get:
tags:
- SupplyChainService
summary: GetCriticalMinerals
operationId: GetCriticalMinerals
responses:
"200":
description: Successful response
content:
application/json:
schema:
$ref: '#/components/schemas/GetCriticalMineralsResponse'
"400":
description: Validation error
content:
application/json:
schema:
$ref: '#/components/schemas/ValidationError'
default:
description: Error response
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
/api/supply-chain/v1/get-shipping-stress:
get:
tags:
- SupplyChainService
summary: GetShippingStress
description: GetShippingStress returns carrier market data and a composite stress index.
operationId: GetShippingStress
responses:
"200":
description: Successful response
content:
application/json:
schema:
$ref: '#/components/schemas/GetShippingStressResponse'
"400":
description: Validation error
content:
application/json:
schema:
$ref: '#/components/schemas/ValidationError'
default:
description: Error response
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
/api/supply-chain/v1/get-country-chokepoint-index:
get:
tags:
- SupplyChainService
summary: GetCountryChokepointIndex
description: GetCountryChokepointIndex returns per-chokepoint exposure scores for a country. PRO-gated.
operationId: GetCountryChokepointIndex
parameters:
- name: iso2
in: query
description: ISO 3166-1 alpha-2 country code (uppercase).
required: false
schema:
type: string
- name: hs2
in: query
description: HS2 chapter (2-digit string). Defaults to "27" (energy/mineral fuels) when absent.
required: false
schema:
type: string
responses:
"200":
description: Successful response
content:
application/json:
schema:
$ref: '#/components/schemas/GetCountryChokepointIndexResponse'
"400":
description: Validation error
content:
application/json:
schema:
$ref: '#/components/schemas/ValidationError'
default:
description: Error response
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
/api/supply-chain/v1/get-bypass-options:
get:
tags:
- SupplyChainService
summary: GetBypassOptions
description: GetBypassOptions returns ranked bypass corridors for a chokepoint. PRO-gated.
operationId: GetBypassOptions
parameters:
- name: chokepointId
in: query
required: false
schema:
type: string
- name: cargoType
in: query
description: 'container | tanker | bulk | roro (default: "container")'
required: false
schema:
type: string
- name: closurePct
in: query
description: '0-100, percent of capacity blocked (default: 100)'
required: false
schema:
type: integer
format: int32
responses:
"200":
description: Successful response
content:
application/json:
schema:
$ref: '#/components/schemas/GetBypassOptionsResponse'
"400":
description: Validation error
content:
application/json:
schema:
$ref: '#/components/schemas/ValidationError'
default:
description: Error response
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
/api/supply-chain/v1/get-country-cost-shock:
get:
tags:
- SupplyChainService
summary: GetCountryCostShock
description: GetCountryCostShock returns cost shock and war risk data for a country+chokepoint. PRO-gated.
operationId: GetCountryCostShock
parameters:
- name: iso2
in: query
required: false
schema:
type: string
- name: chokepointId
in: query
required: false
schema:
type: string
- name: hs2
in: query
description: 'HS2 chapter (default: "27")'
required: false
schema:
type: string
responses:
"200":
description: Successful response
content:
application/json:
schema:
$ref: '#/components/schemas/GetCountryCostShockResponse'
"400":
description: Validation error
content:
application/json:
schema:
$ref: '#/components/schemas/ValidationError'
default:
description: Error response
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
/api/supply-chain/v1/get-country-products:
get:
tags:
- SupplyChainService
summary: GetCountryProducts
description: GetCountryProducts returns the seeded bilateral-HS4 import basket for a country. PRO-gated.
operationId: GetCountryProducts
parameters:
- name: iso2
in: query
required: false
schema:
type: string
responses:
"200":
description: Successful response
content:
application/json:
schema:
$ref: '#/components/schemas/GetCountryProductsResponse'
"400":
description: Validation error
content:
application/json:
schema:
$ref: '#/components/schemas/ValidationError'
default:
description: Error response
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
/api/supply-chain/v1/get-multi-sector-cost-shock:
get:
tags:
- SupplyChainService
summary: GetMultiSectorCostShock
description: |-
GetMultiSectorCostShock returns per-sector cost-shock estimates for a
country+chokepoint+closure-window. PRO-gated.
operationId: GetMultiSectorCostShock
parameters:
- name: iso2
in: query
required: false
schema:
type: string
- name: chokepointId
in: query
required: false
schema:
type: string
- name: closureDays
in: query
description: Closure-window duration in days. Server clamps to [1, 365]. Defaults to 30.
required: false
schema:
type: integer
format: int32
responses:
"200":
description: Successful response
content:
application/json:
schema:
$ref: '#/components/schemas/GetMultiSectorCostShockResponse'
"400":
description: Validation error
content:
application/json:
schema:
$ref: '#/components/schemas/ValidationError'
default:
description: Error response
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
/api/supply-chain/v1/get-sector-dependency:
get:
tags:
- SupplyChainService
summary: GetSectorDependency
description: GetSectorDependency returns dependency flags and risk profile for a country+HS2 sector. PRO-gated.
operationId: GetSectorDependency
parameters:
- name: iso2
in: query
required: false
schema:
type: string
- name: hs2
in: query
description: HS2 chapter code, e.g. "27" (mineral fuels), "85" (electronics)
required: false
schema:
type: string
responses:
"200":
description: Successful response
content:
application/json:
schema:
$ref: '#/components/schemas/GetSectorDependencyResponse'
"400":
description: Validation error
content:
application/json:
schema:
$ref: '#/components/schemas/ValidationError'
default:
description: Error response
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
/api/supply-chain/v1/get-route-explorer-lane:
get:
tags:
- SupplyChainService
summary: GetRouteExplorerLane
description: |-
GetRouteExplorerLane returns the primary maritime route, chokepoint exposures,
bypass options with geometry, war risk, and static transit/freight estimates for
a country pair + HS2 + cargo type. PRO-gated. Wraps the route-intelligence vendor
endpoint's compute with browser-callable auth and adds fields needed by the
Route Explorer UI.
operationId: GetRouteExplorerLane
parameters:
- name: fromIso2
in: query
required: false
schema:
type: string
- name: toIso2
in: query
required: false
schema:
type: string
- name: hs2
in: query
description: HS2 chapter code, e.g. "27", "85"
required: false
schema:
type: string
- name: cargoType
in: query
description: 'One of: container, tanker, bulk, roro'
required: false
schema:
type: string
responses:
"200":
description: Successful response
content:
application/json:
schema:
$ref: '#/components/schemas/GetRouteExplorerLaneResponse'
"400":
description: Validation error
content:
application/json:
schema:
$ref: '#/components/schemas/ValidationError'
default:
description: Error response
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
/api/supply-chain/v1/get-route-impact:
get:
tags:
- SupplyChainService
summary: GetRouteImpact
operationId: GetRouteImpact
parameters:
- name: fromIso2
in: query
required: false
schema:
type: string
- name: toIso2
in: query
required: false
schema:
type: string
- name: hs2
in: query
required: false
schema:
type: string
responses:
"200":
description: Successful response
content:
application/json:
schema:
$ref: '#/components/schemas/GetRouteImpactResponse'
"400":
description: Validation error
content:
application/json:
schema:
$ref: '#/components/schemas/ValidationError'
default:
description: Error response
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
/api/supply-chain/v1/list-pipelines:
get:
tags:
- SupplyChainService
summary: ListPipelines
description: |-
ListPipelines returns the curated oil & gas pipeline registry for the
Energy Atlas PathLayer. Public badges are DERIVED from evidence bundles
server-side and versioned (classifier_version). Free-tier; see
docs/methodology/pipelines.mdx for data + classifier spec.
operationId: ListPipelines
parameters:
- name: commodityType
in: query
description: Filter to one commodity. Omit (or pass empty) to receive both.
required: false
schema:
type: string
responses:
"200":
description: Successful response
content:
application/json:
schema:
$ref: '#/components/schemas/ListPipelinesResponse'
"400":
description: Validation error
content:
application/json:
schema:
$ref: '#/components/schemas/ValidationError'
default:
description: Error response
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
/api/supply-chain/v1/get-pipeline-detail:
get:
tags:
- SupplyChainService
summary: GetPipelineDetail
description: |-
GetPipelineDetail returns a single pipeline with full evidence bundle
+ auto-revision-log entries. Loaded lazily on drawer open.
operationId: GetPipelineDetail
parameters:
- name: pipelineId
in: query
required: false
schema:
type: string
responses:
"200":
description: Successful response
content:
application/json:
schema:
$ref: '#/components/schemas/GetPipelineDetailResponse'
"400":
description: Validation error
content:
application/json:
schema:
$ref: '#/components/schemas/ValidationError'
default:
description: Error response
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
/api/supply-chain/v1/list-storage-facilities:
get:
tags:
- SupplyChainService
summary: ListStorageFacilities
description: |-
ListStorageFacilities returns the curated strategic storage registry
(UGS + SPR + LNG + crude tank farms) for the Energy Atlas DeckGL
ScatterplotLayer. Public badges are DERIVED from evidence bundles
server-side and versioned (classifier_version). Free-tier; see
docs/methodology/storage.mdx.
operationId: ListStorageFacilities
parameters:
- name: facilityType
in: query
description: |-
Filter to one facility type. Accepts:
"ugs" | "spr" | "lng_export" | "lng_import" | "crude_tank_farm"
Omit (or pass empty) to receive all types.
required: false
schema:
type: string
responses:
"200":
description: Successful response
content:
application/json:
schema:
$ref: '#/components/schemas/ListStorageFacilitiesResponse'
"400":
description: Validation error
content:
application/json:
schema:
$ref: '#/components/schemas/ValidationError'
default:
description: Error response
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
/api/supply-chain/v1/get-storage-facility-detail:
get:
tags:
- SupplyChainService
summary: GetStorageFacilityDetail
description: |-
GetStorageFacilityDetail returns a single facility with full evidence
bundle + revision log. Loaded lazily on drawer open.
operationId: GetStorageFacilityDetail
parameters:
- name: facilityId
in: query
required: false
schema:
type: string
responses:
"200":
description: Successful response
content:
application/json:
schema:
$ref: '#/components/schemas/GetStorageFacilityDetailResponse'
"400":
description: Validation error
content:
application/json:
schema:
$ref: '#/components/schemas/ValidationError'
default:
description: Error response
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
/api/supply-chain/v1/list-fuel-shortages:
get:
tags:
- SupplyChainService
summary: ListFuelShortages
description: |-
ListFuelShortages returns the global fuel-shortage alert registry.
Curated-only: severity ("confirmed" | "watch") is a row field authored
at curation time, not a client-side derivation. Free tier.
operationId: ListFuelShortages
parameters:
- name: country
in: query
description: Filter to one ISO 3166-1 alpha-2 country. Omit for global.
required: false
schema:
type: string
- name: product
in: query
description: |-
Filter to one product. Accepts: "petrol" | "diesel" | "jet" | "heating_oil".
Omit for all products.
required: false
schema:
type: string
- name: severity
in: query
description: 'Filter to one severity. Accepts: "confirmed" | "watch". Omit for both.'
required: false
schema:
type: string
responses:
"200":
description: Successful response
content:
application/json:
schema:
$ref: '#/components/schemas/ListFuelShortagesResponse'
"400":
description: Validation error
content:
application/json:
schema:
$ref: '#/components/schemas/ValidationError'
default:
description: Error response
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
/api/supply-chain/v1/get-fuel-shortage-detail:
get:
tags:
- SupplyChainService
summary: GetFuelShortageDetail
description: |-
GetFuelShortageDetail returns a single shortage with full evidence
bundle and citation timeline. Loaded lazily on drawer open.
operationId: GetFuelShortageDetail
parameters:
- name: shortageId
in: query
required: false
schema:
type: string
responses:
"200":
description: Successful response
content:
application/json:
schema:
$ref: '#/components/schemas/GetFuelShortageDetailResponse'
"400":
description: Validation error
content:
application/json:
schema:
$ref: '#/components/schemas/ValidationError'
default:
description: Error response
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
/api/supply-chain/v1/list-energy-disruptions:
get:
tags:
- SupplyChainService
summary: ListEnergyDisruptions
description: |-
ListEnergyDisruptions returns the disruption event log for pipelines
and storage facilities. Supports per-asset or per-asset-type filtering
so panel drawers can fetch a scoped timeline without pulling the
full registry.
operationId: ListEnergyDisruptions
parameters:
- name: assetId
in: query
description: |-
Filter to one asset. Omit for all. When set, also narrows to the
matching asset_type if provided.
required: false
schema:
type: string
- name: assetType
in: query
description: 'Filter to one asset type. Accepts: "pipeline" | "storage".'
required: false
schema:
type: string
- name: ongoingOnly
in: query
description: If true, only return events with endAt empty (still ongoing).
required: false
schema:
type: boolean
responses:
"200":
description: Successful response
content:
application/json:
schema:
$ref: '#/components/schemas/ListEnergyDisruptionsResponse'
"400":
description: Validation error
content:
application/json:
schema:
$ref: '#/components/schemas/ValidationError'
default:
description: Error response
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
components:
schemas:
Error:
type: object
properties:
message:
type: string
description: Error message (e.g., 'user not found', 'database connection failed')
description: Error is returned when a handler encounters an error. It contains a simple error message that the developer can customize.
FieldViolation:
type: object
properties:
field:
type: string
description: The field path that failed validation (e.g., 'user.email' for nested fields). For header validation, this will be the header name (e.g., 'X-API-Key')
description:
type: string
description: Human-readable description of the validation violation (e.g., 'must be a valid email address', 'required field missing')
required:
- field
- description
description: FieldViolation describes a single validation error for a specific field.
ValidationError:
type: object
properties:
violations:
type: array
items:
$ref: '#/components/schemas/FieldViolation'
description: List of validation violations
required:
- violations
description: ValidationError is returned when request validation fails. It contains a list of field violations describing what went wrong.
GetShippingRatesRequest:
type: object
GetShippingRatesResponse:
type: object
properties:
indices:
type: array
items:
$ref: '#/components/schemas/ShippingIndex'
fetchedAt:
type: string
upstreamUnavailable:
type: boolean
ShippingIndex:
type: object
properties:
indexId:
type: string
name:
type: string
currentValue:
type: number
format: double
previousValue:
type: number
format: double
changePct:
type: number
format: double
unit:
type: string
history:
type: array
items:
$ref: '#/components/schemas/ShippingRatePoint'
spikeAlert:
type: boolean
ShippingRatePoint:
type: object
properties:
date:
type: string
value:
type: number
format: double
GetChokepointStatusRequest:
type: object
GetChokepointStatusResponse:
type: object
properties:
chokepoints:
type: array
items:
$ref: '#/components/schemas/ChokepointInfo'
fetchedAt:
type: string
upstreamUnavailable:
type: boolean
ChokepointInfo:
type: object
properties:
id:
type: string
name:
type: string
lat:
type: number
format: double
lon:
type: number
format: double
disruptionScore:
type: integer
format: int32
status:
type: string
activeWarnings:
type: integer
format: int32
congestionLevel:
type: string
affectedRoutes:
type: array
items:
type: string
description:
type: string
aisDisruptions:
type: integer
format: int32
directions:
type: array
items:
type: string
directionalDwt:
type: array
items:
$ref: '#/components/schemas/DirectionalDwt'
transitSummary:
$ref: '#/components/schemas/TransitSummary'
flowEstimate:
$ref: '#/components/schemas/FlowEstimate'
warRiskTier:
type: string
enum:
- WAR_RISK_TIER_UNSPECIFIED
- WAR_RISK_TIER_NORMAL
- WAR_RISK_TIER_ELEVATED
- WAR_RISK_TIER_HIGH
- WAR_RISK_TIER_CRITICAL
- WAR_RISK_TIER_WAR_ZONE
description: |-
*
War risk tier derived from Lloyd's JWC Listed Areas + OSINT threat classification.
This is a FREE field (no PRO gate) — it exposes the existing server-internal
threatLevel from ChokepointConfig, making it available to clients for badges
and bypass corridor scoring.
DirectionalDwt:
type: object
properties:
direction:
type: string
dwtThousandTonnes:
type: number
format: double
wowChangePct:
type: number
format: double
TransitSummary:
type: object
properties:
todayTotal:
type: integer
format: int32
todayTanker:
type: integer
format: int32
todayCargo:
type: integer
format: int32
todayOther:
type: integer
format: int32
wowChangePct:
type: number
format: double
history:
type: array
items:
$ref: '#/components/schemas/TransitDayCount'
riskLevel:
type: string
incidentCount7d:
type: integer
format: int32
disruptionPct:
type: number
format: double
riskSummary:
type: string
riskReportAction:
type: string
dataAvailable:
type: boolean
description: |-
False when the upstream portwatch/relay source did not return data for
this chokepoint in the current cycle — the summary fields are zero-state
fill, not a genuine "zero traffic" reading. Client should render a
"transit data unavailable" indicator and skip stat/chart rendering.
TransitDayCount:
type: object
properties:
date:
type: string
tanker:
type: integer
format: int32
cargo:
type: integer
format: int32
other:
type: integer
format: int32
total:
type: integer
format: int32
container:
type: integer
format: int32
dryBulk:
type: integer
format: int32
generalCargo:
type: integer
format: int32
roro:
type: integer
format: int32
capContainer:
type: number
format: double
capDryBulk:
type: number
format: double
capGeneralCargo:
type: number
format: double
capRoro:
type: number
format: double
capTanker:
type: number
format: double
FlowEstimate:
type: object
properties:
currentMbd:
type: number
format: double
baselineMbd:
type: number
format: double
flowRatio:
type: number
format: double
disrupted:
type: boolean
source:
type: string
hazardAlertLevel:
type: string
hazardAlertName:
type: string
GetChokepointHistoryRequest:
type: object
properties:
chokepointId:
type: string
required:
- chokepointId
description: |-
GetChokepointHistory returns the transit-count history for a single
chokepoint. Loaded lazily on card expand so the main chokepoint-status
response can stay compact (no 180-day history per chokepoint).
GetChokepointHistoryResponse:
type: object
properties:
chokepointId:
type: string
history:
type: array
items:
$ref: '#/components/schemas/TransitDayCount'
fetchedAt:
type: string
format: int64
GetCriticalMineralsRequest:
type: object
GetCriticalMineralsResponse:
type: object
properties:
minerals:
type: array
items:
$ref: '#/components/schemas/CriticalMineral'
fetchedAt:
type: string
upstreamUnavailable:
type: boolean
CriticalMineral:
type: object
properties:
mineral:
type: string
topProducers:
type: array
items:
$ref: '#/components/schemas/MineralProducer'
hhi:
type: number
format: double
riskRating:
type: string
globalProduction:
type: number
format: double
unit:
type: string
MineralProducer:
type: object
properties:
country:
type: string
countryCode:
type: string
productionTonnes:
type: number
format: double
sharePct:
type: number
format: double
GetShippingStressRequest:
type: object
GetShippingStressResponse:
type: object
properties:
carriers:
type: array
items:
$ref: '#/components/schemas/ShippingStressCarrier'
stressScore:
type: number
format: double
description: Composite stress score 0100 (higher = more disruption).
stressLevel:
type: string
description: '"low" | "moderate" | "elevated" | "critical".'
fetchedAt:
type: integer
format: int64
description: 'Warning: Values > 2^53 may lose precision in JavaScript'
upstreamUnavailable:
type: boolean
description: Set to true when upstream data source is unavailable and cached data is stale.
ShippingStressCarrier:
type: object
properties:
symbol:
type: string
description: Ticker or identifier (e.g., "BDRY", "ZIM").
name:
type: string
description: Human-readable name.
price:
type: number
format: double
description: Current price.
changePct:
type: number
format: double
description: Percentage change from previous close.
carrierType:
type: string
description: 'Carrier type: "etf" | "carrier" | "index".'
sparkline:
type: array
items:
type: number
format: double
description: 30-day price sparkline.
description: ShippingStressCarrier represents market stress data for a carrier or shipping index.
GetCountryChokepointIndexRequest:
type: object
properties:
iso2:
type: string
pattern: ^[A-Z]{2}$
description: ISO 3166-1 alpha-2 country code (uppercase).
hs2:
type: string
description: HS2 chapter (2-digit string). Defaults to "27" (energy/mineral fuels) when absent.
required:
- iso2
description: GetCountryChokepointIndexRequest specifies the country and optional HS2 chapter.
GetCountryChokepointIndexResponse:
type: object
properties:
iso2:
type: string
description: ISO 3166-1 alpha-2 country code echoed from the request.
hs2:
type: string
description: HS2 chapter used for the computation.
exposures:
type: array
items:
$ref: '#/components/schemas/ChokepointExposureEntry'
primaryChokepointId:
type: string
description: Canonical ID of the chokepoint with the highest exposure score.
vulnerabilityIndex:
type: number
format: double
description: Composite vulnerability index 0100 (weighted sum of top-3 exposures).
fetchedAt:
type: string
description: ISO timestamp of when this data was last seeded.
description: GetCountryChokepointIndexResponse returns exposure scores for all relevant chokepoints.
ChokepointExposureEntry:
type: object
properties:
chokepointId:
type: string
description: Canonical chokepoint ID from the chokepoint registry.
chokepointName:
type: string
description: Human-readable chokepoint name.
exposureScore:
type: number
format: double
description: Exposure score 0100; higher = more dependent on this chokepoint.
coastSide:
type: string
description: Which ocean/basin side the country's ports face (atlantic, pacific, indian, med, multi, landlocked).
shockSupported:
type: boolean
description: Whether the shock model is supported for this chokepoint + hs2 combination.
description: ChokepointExposureEntry holds per-chokepoint exposure data for a country.
GetBypassOptionsRequest:
type: object
properties:
chokepointId:
type: string
cargoType:
type: string
description: 'container | tanker | bulk | roro (default: "container")'
closurePct:
type: integer
format: int32
description: '0-100, percent of capacity blocked (default: 100)'
required:
- chokepointId
GetBypassOptionsResponse:
type: object
properties:
chokepointId:
type: string
cargoType:
type: string
closurePct:
type: integer
format: int32
options:
type: array
items:
$ref: '#/components/schemas/BypassOption'
fetchedAt:
type: string
primaryChokepointWarRiskTier:
type: string
enum:
- WAR_RISK_TIER_UNSPECIFIED
- WAR_RISK_TIER_NORMAL
- WAR_RISK_TIER_ELEVATED
- WAR_RISK_TIER_HIGH
- WAR_RISK_TIER_CRITICAL
- WAR_RISK_TIER_WAR_ZONE
description: |-
*
War risk tier derived from Lloyd's JWC Listed Areas + OSINT threat classification.
This is a FREE field (no PRO gate) — it exposes the existing server-internal
threatLevel from ChokepointConfig, making it available to clients for badges
and bypass corridor scoring.
BypassOption:
type: object
properties:
id:
type: string
name:
type: string
type:
type: string
addedTransitDays:
type: integer
format: int32
addedCostMultiplier:
type: number
format: double
capacityConstraintTonnage:
type: string
format: int64
suitableCargoTypes:
type: array
items:
type: string
activationThreshold:
type: string
waypointChokepointIds:
type: array
items:
type: string
liveScore:
type: number
format: double
bypassWarRiskTier:
type: string
enum:
- WAR_RISK_TIER_UNSPECIFIED
- WAR_RISK_TIER_NORMAL
- WAR_RISK_TIER_ELEVATED
- WAR_RISK_TIER_HIGH
- WAR_RISK_TIER_CRITICAL
- WAR_RISK_TIER_WAR_ZONE
description: |-
*
War risk tier derived from Lloyd's JWC Listed Areas + OSINT threat classification.
This is a FREE field (no PRO gate) — it exposes the existing server-internal
threatLevel from ChokepointConfig, making it available to clients for badges
and bypass corridor scoring.
notes:
type: string
GetCountryCostShockRequest:
type: object
properties:
iso2:
type: string
pattern: ^[A-Z]{2}$
chokepointId:
type: string
hs2:
type: string
description: 'HS2 chapter (default: "27")'
required:
- iso2
- chokepointId
GetCountryCostShockResponse:
type: object
properties:
iso2:
type: string
chokepointId:
type: string
hs2:
type: string
supplyDeficitPct:
type: number
format: double
description: Average refined-product supply deficit % under full closure (Gasoline/Diesel/Jet fuel/LPG average; HS 27 only)
coverageDays:
type: integer
format: int32
description: Energy stockpile coverage in days (IEA data, HS 27 only; 0 for non-energy sectors or net exporters)
warRiskPremiumBps:
type: integer
format: int32
description: War risk insurance premium in basis points for this chokepoint
warRiskTier:
type: string
enum:
- WAR_RISK_TIER_UNSPECIFIED
- WAR_RISK_TIER_NORMAL
- WAR_RISK_TIER_ELEVATED
- WAR_RISK_TIER_HIGH
- WAR_RISK_TIER_CRITICAL
- WAR_RISK_TIER_WAR_ZONE
description: |-
*
War risk tier derived from Lloyd's JWC Listed Areas + OSINT threat classification.
This is a FREE field (no PRO gate) — it exposes the existing server-internal
threatLevel from ChokepointConfig, making it available to clients for badges
and bypass corridor scoring.
hasEnergyModel:
type: boolean
description: Whether supply_deficit_pct and coverage_days are modelled (true) or unavailable (false)
unavailableReason:
type: string
description: Null/unavailable explanation for non-energy sectors
fetchedAt:
type: string
GetCountryProductsRequest:
type: object
properties:
iso2:
type: string
pattern: ^[A-Z]{2}$
required:
- iso2
GetCountryProductsResponse:
type: object
properties:
iso2:
type: string
products:
type: array
items:
$ref: '#/components/schemas/CountryProduct'
fetchedAt:
type: string
description: ISO timestamp from the seeded payload (empty when no data is cached).
CountryProduct:
type: object
properties:
hs4:
type: string
description:
type: string
totalValue:
type: number
format: double
topExporters:
type: array
items:
$ref: '#/components/schemas/ProductExporter'
year:
type: integer
format: int32
ProductExporter:
type: object
properties:
partnerCode:
type: integer
format: int32
partnerIso2:
type: string
value:
type: number
format: double
share:
type: number
format: double
GetMultiSectorCostShockRequest:
type: object
properties:
iso2:
type: string
pattern: ^[A-Z]{2}$
chokepointId:
type: string
closureDays:
type: integer
format: int32
description: Closure-window duration in days. Server clamps to [1, 365]. Defaults to 30.
required:
- iso2
- chokepointId
GetMultiSectorCostShockResponse:
type: object
properties:
iso2:
type: string
chokepointId:
type: string
closureDays:
type: integer
format: int32
description: Server-clamped closure-window duration in days (1-365).
warRiskTier:
type: string
enum:
- WAR_RISK_TIER_UNSPECIFIED
- WAR_RISK_TIER_NORMAL
- WAR_RISK_TIER_ELEVATED
- WAR_RISK_TIER_HIGH
- WAR_RISK_TIER_CRITICAL
- WAR_RISK_TIER_WAR_ZONE
description: |-
*
War risk tier derived from Lloyd's JWC Listed Areas + OSINT threat classification.
This is a FREE field (no PRO gate) — it exposes the existing server-internal
threatLevel from ChokepointConfig, making it available to clients for badges
and bypass corridor scoring.
sectors:
type: array
items:
$ref: '#/components/schemas/MultiSectorCostShock'
totalAddedCost:
type: number
format: double
description: Sum of total_cost_shock across all sectors.
fetchedAt:
type: string
unavailableReason:
type: string
description: Populated when no seeded import data is available for the country.
MultiSectorCostShock:
type: object
properties:
hs2:
type: string
description: HS2 chapter code (e.g. "27" mineral fuels, "85" electronics).
hs2Label:
type: string
description: Friendly chapter label (e.g. "Energy", "Electronics").
importValueAnnual:
type: number
format: double
description: Total annual import value (USD) for this sector.
freightAddedPctPerTon:
type: number
format: double
description: Bypass-corridor freight uplift fraction (0.10 == +10% per ton).
warRiskPremiumBps:
type: integer
format: int32
description: War-risk insurance premium (basis points) sourced from the chokepoint tier.
addedTransitDays:
type: integer
format: int32
description: Bypass-corridor transit penalty (informational).
totalCostShockPerDay:
type: number
format: double
totalCostShock30Days:
type: number
format: double
totalCostShock90Days:
type: number
format: double
totalCostShock:
type: number
format: double
description: Cost for the requested closure_days window.
closureDays:
type: integer
format: int32
description: Echoes the clamped closure duration used for total_cost_shock (1-365).
GetSectorDependencyRequest:
type: object
properties:
iso2:
type: string
pattern: ^[A-Z]{2}$
hs2:
type: string
description: HS2 chapter code, e.g. "27" (mineral fuels), "85" (electronics)
required:
- iso2
- hs2
GetSectorDependencyResponse:
type: object
properties:
iso2:
type: string
hs2:
type: string
hs2Label:
type: string
description: Human-readable HS2 chapter name.
flags:
type: array
items:
type: string
enum:
- DEPENDENCY_FLAG_UNSPECIFIED
- DEPENDENCY_FLAG_SINGLE_SOURCE_CRITICAL
- DEPENDENCY_FLAG_SINGLE_CORRIDOR_CRITICAL
- DEPENDENCY_FLAG_COMPOUND_RISK
- DEPENDENCY_FLAG_DIVERSIFIABLE
description: DependencyFlag classifies how a country+sector dependency can fail.
primaryExporterIso2:
type: string
description: ISO2 of the country supplying the largest share of this sector's imports.
primaryExporterShare:
type: number
format: double
description: Share of imports from the primary exporter (01). 0 = no Comtrade data available.
primaryChokepointId:
type: string
description: Chokepoint ID with the highest exposure score for this country+sector.
primaryChokepointExposure:
type: number
format: double
description: Exposure score for the primary chokepoint (0100).
hasViableBypass:
type: boolean
description: Whether at least one viable bypass corridor exists for the primary chokepoint.
fetchedAt:
type: string
GetRouteExplorerLaneRequest:
type: object
properties:
fromIso2:
type: string
pattern: ^[A-Z]{2}$
toIso2:
type: string
pattern: ^[A-Z]{2}$
hs2:
type: string
description: HS2 chapter code, e.g. "27", "85"
cargoType:
type: string
description: 'One of: container, tanker, bulk, roro'
required:
- fromIso2
- toIso2
- hs2
- cargoType
GetRouteExplorerLaneResponse:
type: object
properties:
fromIso2:
type: string
toIso2:
type: string
hs2:
type: string
cargoType:
type: string
primaryRouteId:
type: string
description: Primary trade route ID from TRADE_ROUTES config. Empty when no modeled lane.
primaryRouteGeometry:
type: array
items:
$ref: '#/components/schemas/GeoPoint'
chokepointExposures:
type: array
items:
$ref: '#/components/schemas/ChokepointExposureSummary'
bypassOptions:
type: array
items:
$ref: '#/components/schemas/BypassCorridorOption'
warRiskTier:
type: string
disruptionScore:
type: number
format: double
estTransitDaysRange:
$ref: '#/components/schemas/NumberRange'
estFreightUsdPerTeuRange:
$ref: '#/components/schemas/NumberRange'
noModeledLane:
type: boolean
description: |-
True when the wrapper fell back to the origin's first route (no shared route
between origin and destination clusters). Signals "no modeled lane" to the UI.
fetchedAt:
type: string
GeoPoint:
type: object
properties:
lon:
type: number
format: double
lat:
type: number
format: double
description: GeoPoint is a [longitude, latitude] pair.
ChokepointExposureSummary:
type: object
properties:
chokepointId:
type: string
chokepointName:
type: string
exposurePct:
type: integer
format: int32
BypassCorridorOption:
type: object
properties:
id:
type: string
name:
type: string
type:
type: string
addedTransitDays:
type: integer
format: int32
addedCostMultiplier:
type: number
format: double
warRiskTier:
type: string
status:
type: string
enum:
- CORRIDOR_STATUS_UNSPECIFIED
- CORRIDOR_STATUS_ACTIVE
- CORRIDOR_STATUS_PROPOSED
- CORRIDOR_STATUS_UNAVAILABLE
description: |-
Status of a bypass corridor for UI labeling. "active" means usable today;
"proposed" means documented but not yet built/operational; "unavailable"
means blockaded or otherwise blocked from use.
fromPort:
$ref: '#/components/schemas/GeoPoint'
toPort:
$ref: '#/components/schemas/GeoPoint'
description: |-
BypassCorridorOption is a single enriched bypass corridor for the Route Explorer UI.
Includes coordinate endpoints so the client can call MapContainer.setBypassRoutes
directly without any client-side geometry lookup.
NumberRange:
type: object
properties:
min:
type: integer
format: int32
max:
type: integer
format: int32
description: Inclusive integer range for transit days / freight USD estimates.
GetRouteImpactRequest:
type: object
properties:
fromIso2:
type: string
pattern: ^[A-Z]{2}$
toIso2:
type: string
pattern: ^[A-Z]{2}$
hs2:
type: string
required:
- fromIso2
- toIso2
- hs2
GetRouteImpactResponse:
type: object
properties:
laneValueUsd:
type: number
format: double
primaryExporterIso2:
type: string
primaryExporterShare:
type: number
format: double
topStrategicProducts:
type: array
items:
$ref: '#/components/schemas/StrategicProduct'
resilienceScore:
type: number
format: double
dependencyFlags:
type: array
items:
type: string
enum:
- DEPENDENCY_FLAG_UNSPECIFIED
- DEPENDENCY_FLAG_SINGLE_SOURCE_CRITICAL
- DEPENDENCY_FLAG_SINGLE_CORRIDOR_CRITICAL
- DEPENDENCY_FLAG_COMPOUND_RISK
- DEPENDENCY_FLAG_DIVERSIFIABLE
description: DependencyFlag classifies how a country+sector dependency can fail.
hs2InSeededUniverse:
type: boolean
comtradeSource:
type: string
fetchedAt:
type: string
StrategicProduct:
type: object
properties:
hs4:
type: string
label:
type: string
totalValueUsd:
type: number
format: double
topExporterIso2:
type: string
topExporterShare:
type: number
format: double
primaryChokepointId:
type: string
ListPipelinesRequest:
type: object
properties:
commodityType:
type: string
description: Filter to one commodity. Omit (or pass empty) to receive both.
description: |-
ListPipelines returns the full oil and/or gas pipeline registry with
evidence-based status per asset. Registry is curated (see
docs/methodology/pipelines.mdx) and refreshed weekly by
scripts/seed-pipelines-{gas,oil}.mjs. Typical consumer: PipelineStatusPanel
rendering the DeckGL PathLayer.
The public badge is DERIVED from the evidence bundle server-side at
read time — callers MUST use `public_badge` for display, not invent
their own derivation from `evidence` fields. This keeps the atlas and
MCP clients consistent and versioned together.
ListPipelinesResponse:
type: object
properties:
pipelines:
type: array
items:
$ref: '#/components/schemas/PipelineEntry'
fetchedAt:
type: string
classifierVersion:
type: string
upstreamUnavailable:
type: boolean
PipelineEntry:
type: object
properties:
id:
type: string
name:
type: string
operator:
type: string
commodityType:
type: string
description: Either "gas" or "oil".
fromCountry:
type: string
toCountry:
type: string
transitCountries:
type: array
items:
type: string
capacityBcmYr:
type: number
format: double
capacityMbd:
type: number
format: double
lengthKm:
type: integer
format: int32
inService:
type: integer
format: int32
startPoint:
$ref: '#/components/schemas/LatLon'
endPoint:
$ref: '#/components/schemas/LatLon'
waypoints:
type: array
items:
$ref: '#/components/schemas/LatLon'
evidence:
$ref: '#/components/schemas/PipelineEvidence'
publicBadge:
type: string
description: |-
Server-derived public badge. One of:
"flowing" | "reduced" | "offline" | "disputed"
LatLon:
type: object
properties:
lat:
type: number
format: double
lon:
type: number
format: double
PipelineEvidence:
type: object
properties:
physicalState:
type: string
description: 'One of: "flowing" | "reduced" | "offline" | "unknown"'
physicalStateSource:
type: string
description: 'One of: "operator" | "regulator" | "press" | "satellite" | "ais-relay"'
operatorStatement:
$ref: '#/components/schemas/OperatorStatement'
commercialState:
type: string
description: 'One of: "under_contract" | "expired" | "suspended" | "unknown"'
sanctionRefs:
type: array
items:
$ref: '#/components/schemas/SanctionRef'
lastEvidenceUpdate:
type: string
classifierVersion:
type: string
classifierConfidence:
type: number
format: double
OperatorStatement:
type: object
properties:
text:
type: string
url:
type: string
date:
type: string
SanctionRef:
type: object
properties:
authority:
type: string
listId:
type: string
date:
type: string
url:
type: string
GetPipelineDetailRequest:
type: object
properties:
pipelineId:
type: string
required:
- pipelineId
description: |-
GetPipelineDetail returns a single pipeline with its full evidence bundle.
Evidence surface here is richer than ListPipelinesResponse — the list view
is designed for the map layer's compact shape; detail is designed for the
click-through drawer.
GetPipelineDetailResponse:
type: object
properties:
pipeline:
$ref: '#/components/schemas/PipelineEntry'
revisions:
type: array
items:
$ref: '#/components/schemas/PipelineRevisionEntry'
fetchedAt:
type: string
unavailable:
type: boolean
PipelineRevisionEntry:
type: object
properties:
date:
type: string
fieldChanged:
type: string
previousValue:
type: string
newValue:
type: string
trigger:
type: string
description: 'One of: "classifier" | "source" | "decay" | "override"'
sourcesUsed:
type: array
items:
type: string
classifierVersion:
type: string
ListStorageFacilitiesRequest:
type: object
properties:
facilityType:
type: string
description: |-
Filter to one facility type. Accepts:
"ugs" | "spr" | "lng_export" | "lng_import" | "crude_tank_farm"
Omit (or pass empty) to receive all types.
description: |-
ListStorageFacilities returns the curated strategic storage registry
(underground gas storage, strategic petroleum reserves, LNG terminals,
crude tank farms) with evidence-based status per asset. Registry is
curated (see docs/methodology/storage.mdx) and refreshed weekly by
scripts/seed-storage-facilities.mjs. Typical consumer:
StorageFacilityMapPanel rendering the DeckGL ScatterplotLayer.
Like pipelines, the public badge is DERIVED from the evidence bundle
server-side at read time. Callers MUST use `public_badge` for display
rather than inventing their own derivation from `evidence` fields, so
the atlas and MCP clients stay consistent and versioned together.
ListStorageFacilitiesResponse:
type: object
properties:
facilities:
type: array
items:
$ref: '#/components/schemas/StorageFacilityEntry'
fetchedAt:
type: string
classifierVersion:
type: string
upstreamUnavailable:
type: boolean
StorageFacilityEntry:
type: object
properties:
id:
type: string
name:
type: string
operator:
type: string
facilityType:
type: string
description: 'One of: "ugs" | "spr" | "lng_export" | "lng_import" | "crude_tank_farm"'
country:
type: string
location:
$ref: '#/components/schemas/StorageLatLon'
capacityTwh:
type: number
format: double
description: |-
Working capacity in the facility's native unit (see working_capacity_unit).
Exactly ONE of these is populated per facility, chosen by facility_type:
ugs → capacity_twh
spr, crude_tank_farm → capacity_mb
lng_export, lng_import → capacity_mtpa
capacityMb:
type: number
format: double
capacityMtpa:
type: number
format: double
workingCapacityUnit:
type: string
description: 'One of: "TWh" | "Mb" | "Mtpa"'
inService:
type: integer
format: int32
evidence:
$ref: '#/components/schemas/StorageEvidence'
publicBadge:
type: string
description: |-
Server-derived public badge. One of:
"operational" | "reduced" | "offline" | "disputed"
StorageLatLon:
type: object
properties:
lat:
type: number
format: double
lon:
type: number
format: double
StorageEvidence:
type: object
properties:
physicalState:
type: string
description: 'One of: "operational" | "reduced" | "offline" | "under_construction" | "unknown"'
physicalStateSource:
type: string
description: 'One of: "operator" | "regulator" | "press" | "satellite" | "ais-relay"'
operatorStatement:
$ref: '#/components/schemas/StorageOperatorStatement'
commercialState:
type: string
description: 'One of: "under_contract" | "expired" | "suspended" | "unknown"'
sanctionRefs:
type: array
items:
$ref: '#/components/schemas/StorageSanctionRef'
fillDisclosed:
type: boolean
description: |-
Whether working-gas / stock-level fill is publicly disclosed for this
asset. LNG export terminals, for instance, tend NOT to disclose; UGS
sites in Europe are required to disclose via GIE AGSI+.
fillSource:
type: string
description: |-
Source of the disclosed fill series ("GIE AGSI+", "EIA SPR weekly
stock report", etc.). Empty when fill_disclosed=false.
lastEvidenceUpdate:
type: string
classifierVersion:
type: string
classifierConfidence:
type: number
format: double
StorageOperatorStatement:
type: object
properties:
text:
type: string
url:
type: string
date:
type: string
StorageSanctionRef:
type: object
properties:
authority:
type: string
listId:
type: string
date:
type: string
url:
type: string
GetStorageFacilityDetailRequest:
type: object
properties:
facilityId:
type: string
required:
- facilityId
description: |-
GetStorageFacilityDetail returns a single facility with its full evidence
bundle + revision log. Revisions land in Week 3 alongside the disruption
event log (Week 3 milestone — empty array in v1).
GetStorageFacilityDetailResponse:
type: object
properties:
facility:
$ref: '#/components/schemas/StorageFacilityEntry'
revisions:
type: array
items:
$ref: '#/components/schemas/StorageFacilityRevisionEntry'
fetchedAt:
type: string
unavailable:
type: boolean
StorageFacilityRevisionEntry:
type: object
properties:
date:
type: string
fieldChanged:
type: string
previousValue:
type: string
newValue:
type: string
trigger:
type: string
description: 'One of: "classifier" | "source" | "decay" | "override"'
sourcesUsed:
type: array
items:
type: string
classifierVersion:
type: string
ListFuelShortagesRequest:
type: object
properties:
country:
type: string
description: Filter to one ISO 3166-1 alpha-2 country. Omit for global.
product:
type: string
description: |-
Filter to one product. Accepts: "petrol" | "diesel" | "jet" | "heating_oil".
Omit for all products.
severity:
type: string
description: 'Filter to one severity. Accepts: "confirmed" | "watch". Omit for both.'
description: |-
ListFuelShortages returns the global fuel-shortage alert registry.
Seeded from a curated JSON file (scripts/data/fuel-shortages.json).
An LLM classifier extension was scoped but not shipped — the registry
is curated-only today. Severity ("confirmed" or "watch") is a row
field authored at curation time; the evidence is shipped alongside
so agents and humans can audit the grounds for a severity label.
See docs/methodology/shortages.mdx for the evidence-threshold spec.
ListFuelShortagesResponse:
type: object
properties:
shortages:
type: array
items:
$ref: '#/components/schemas/FuelShortageEntry'
fetchedAt:
type: string
classifierVersion:
type: string
upstreamUnavailable:
type: boolean
FuelShortageEntry:
type: object
properties:
id:
type: string
country:
type: string
product:
type: string
description: 'One of: "petrol" | "diesel" | "jet" | "heating_oil"'
severity:
type: string
description: 'One of: "confirmed" | "watch" (classifier output — not a client-side derivation)'
firstSeen:
type: string
lastConfirmed:
type: string
resolvedAt:
type: string
description: Empty string when not yet resolved.
impactTypes:
type: array
items:
type: string
description: |-
Observable consumer-facing impacts. Subset of:
"stations_closed" | "rationing" | "flights_cancelled" | "import_cut" | "price_spike"
causeChain:
type: array
items:
type: string
description: |-
Contributing root causes, ordered primary-first. Subset of:
"upstream_refinery" | "logistics" | "policy" | "chokepoint" |
"sanction" | "war" | "import_cut"
shortDescription:
type: string
evidence:
$ref: '#/components/schemas/FuelShortageEvidence'
FuelShortageEvidence:
type: object
properties:
evidenceSources:
type: array
items:
$ref: '#/components/schemas/FuelShortageEvidenceSource'
firstRegulatorConfirmation:
type: string
description: |-
ISO date of the first regulator confirmation, if any. Empty when
severity is "watch" on press-only signal.
classifierVersion:
type: string
classifierConfidence:
type: number
format: double
lastEvidenceUpdate:
type: string
FuelShortageEvidenceSource:
type: object
properties:
authority:
type: string
title:
type: string
url:
type: string
date:
type: string
sourceType:
type: string
description: 'One of: "regulator" | "operator" | "press" | "ais-relay" | "satellite"'
GetFuelShortageDetailRequest:
type: object
properties:
shortageId:
type: string
required:
- shortageId
description: |-
GetFuelShortageDetail returns a single shortage with full evidence
bundle + citation timeline. Loaded lazily on drawer open.
GetFuelShortageDetailResponse:
type: object
properties:
shortage:
$ref: '#/components/schemas/FuelShortageEntry'
fetchedAt:
type: string
unavailable:
type: boolean
ListEnergyDisruptionsRequest:
type: object
properties:
assetId:
type: string
description: |-
Filter to one asset. Omit for all. When set, also narrows to the
matching asset_type if provided.
assetType:
type: string
description: 'Filter to one asset type. Accepts: "pipeline" | "storage".'
ongoingOnly:
type: boolean
description: If true, only return events with endAt empty (still ongoing).
description: |-
ListEnergyDisruptions returns the energy disruption event log — state
transitions for pipelines and storage facilities (sabotage, sanction,
maintenance, mechanical, weather, commercial, war). Each event ties
back to an assetId seeded by the pipeline or storage registry, so the
panel drawer can render an asset-scoped timeline without a second RPC.
Seeded from a curated JSON file (scripts/data/energy-disruptions.json).
An automated state-transition classifier was scoped but not shipped —
the log is curated-only today.
See docs/methodology/disruptions.mdx.
ListEnergyDisruptionsResponse:
type: object
properties:
events:
type: array
items:
$ref: '#/components/schemas/EnergyDisruptionEntry'
fetchedAt:
type: string
classifierVersion:
type: string
upstreamUnavailable:
type: boolean
EnergyDisruptionEntry:
type: object
properties:
id:
type: string
assetId:
type: string
description: Maps to a pipeline or storage-facility id seeded elsewhere.
assetType:
type: string
description: 'One of: "pipeline" | "storage"'
eventType:
type: string
description: |-
One of: "sabotage" | "sanction" | "maintenance" | "mechanical" |
"weather" | "commercial" | "war" | "other"
startAt:
type: string
endAt:
type: string
description: Empty string when event is still ongoing.
capacityOfflineBcmYr:
type: number
format: double
description: Headline-offline capacity (contextual — 0 when not applicable).
capacityOfflineMbd:
type: number
format: double
causeChain:
type: array
items:
type: string
description: Contributing causes, primary-first.
shortDescription:
type: string
sources:
type: array
items:
$ref: '#/components/schemas/EnergyDisruptionSource'
classifierVersion:
type: string
classifierConfidence:
type: number
format: double
lastEvidenceUpdate:
type: string
EnergyDisruptionSource:
type: object
properties:
authority:
type: string
title:
type: string
url:
type: string
date:
type: string
sourceType:
type: string