openapi: 3.1.0 info: title: SupplyChainService API version: 1.0.0 security: - WorldMonitorKey: [] - ApiKeyHeader: [] servers: - url: https://api.worldmonitor.app paths: /api/supply-chain/v1/get-shipping-rates: get: tags: - SupplyChainService summary: GetShippingRates description: GetShippingRates returns current container shipping-rate indices; upstream_unavailable is set when the source could not be reached. operationId: GetShippingRates parameters: - name: jmespath in: query description: |- Optional JMESPath expression applied server-side to project or reduce the JSON response before it is returned (mirrors the MCP jmespath argument). Invalid expressions, expressions larger than 1024 UTF-8 bytes, or projections that exceed the 256 KB output cap return HTTP 400 with a {_jmespath_error, original_keys} envelope. Grammar and worked examples: https://www.worldmonitor.app/docs/mcp-jmespath. required: false example: "keys(@)" schema: type: string responses: "200": description: Successful response content: application/json: example: "fetchedAt": "2026-01-15T12:00:00Z" "indices": - "changePct": 1.69 "currentValue": 1072.16 "history": - "date": "2026-01-15" "value": 1072.16 "indexId": "CCFI" "name": "CCFI - China Container Freight" "periodChangeBasis": "publisher_reported" "periodChangePct": 1.69 "previousValue": 1054.38 "priorPeriodDate": "2026-01-08" "priorPeriodValue": 1054.38 "spikeAlert": false "unit": "index" - "changePct": 0 "currentValue": 1972 "history": - "date": "2026-01-15" "value": 1972 "indexId": "BDI" "name": "BDI - Baltic Dry Index" "previousValue": 1972 "spikeAlert": false "unit": "index" "upstreamUnavailable": false schema: $ref: '#/components/schemas/GetShippingRatesResponse' "400": description: Validation error content: application/json: schema: oneOf: - $ref: '#/components/schemas/ValidationError' - $ref: '#/components/schemas/JmespathProjectionError' "401": description: Missing or invalid API key. content: application/json: schema: $ref: '#/components/schemas/UnauthorizedError' "403": description: API access requires an active subscription (the API key's subscription is inactive or expired). headers: X-Billing-Verification: description: Present when the 403 is a billing-provider-confirmed subscription lapse (value subscription_lapsed, matching the body `code`). schema: type: string content: application/json: schema: $ref: '#/components/schemas/ForbiddenError' "429": description: Rate limit exceeded. headers: X-RateLimit-Limit: description: Maximum requests allowed in the active rate-limit window. schema: type: string X-RateLimit-Remaining: description: Requests remaining in the active rate-limit window. schema: type: string X-RateLimit-Reset: description: Unix epoch milliseconds when the active rate-limit window resets. schema: type: string Retry-After: description: Seconds to wait before retrying the request. schema: type: string content: application/json: schema: oneOf: - $ref: '#/components/schemas/Error' - $ref: '#/components/schemas/RateLimitError' "503": description: Service unavailable. Billing-verification responses include code and X-Billing-Verification; other gateway infrastructure failures use the generic GatewayError shape. headers: Retry-After: description: Seconds to wait before retrying (1-60). schema: type: string X-Billing-Verification: description: Billing-verification state that produced this response (matches the body `code`). schema: type: string X-Validation-Mode: description: Present with value degraded when user API-key validation is temporarily unavailable. schema: type: string X-RateLimit-Mode: description: Present with value degraded when a fail-closed rate-limit dependency is unavailable. schema: type: string content: application/json: schema: oneOf: - $ref: '#/components/schemas/BillingVerificationError' - $ref: '#/components/schemas/GatewayError' default: description: Gateway or handler error response. content: application/json: schema: oneOf: - $ref: '#/components/schemas/Error' - $ref: '#/components/schemas/GatewayError' /api/supply-chain/v1/get-chokepoint-status: get: tags: - SupplyChainService summary: GetChokepointStatus description: |- GetChokepointStatus retrieves seeded chokepoint status. Empty chokepoints with upstream_unavailable=true means the seed snapshot is unavailable/ degraded, not that there are confirmed zero chokepoints. operationId: GetChokepointStatus parameters: - name: jmespath in: query description: |- Optional JMESPath expression applied server-side to project or reduce the JSON response before it is returned (mirrors the MCP jmespath argument). Invalid expressions, expressions larger than 1024 UTF-8 bytes, or projections that exceed the 256 KB output cap return HTTP 400 with a {_jmespath_error, original_keys} envelope. Grammar and worked examples: https://www.worldmonitor.app/docs/mcp-jmespath. required: false example: "keys(@)" schema: type: string responses: "200": description: Successful response content: application/json: example: "chokepoints": - "activeWarnings": 1 "affectedRoutes": - "example" "aisDisruptions": 1 "aisSnapshotAvailable": true "congestionLevel": "example" "fetchedAt": "2026-01-15T12:00:00Z" "upstreamUnavailable": false schema: $ref: '#/components/schemas/GetChokepointStatusResponse' "400": description: Validation error content: application/json: schema: oneOf: - $ref: '#/components/schemas/ValidationError' - $ref: '#/components/schemas/JmespathProjectionError' "401": description: Missing or invalid API key. content: application/json: schema: $ref: '#/components/schemas/UnauthorizedError' "403": description: API access requires an active subscription (the API key's subscription is inactive or expired). headers: X-Billing-Verification: description: Present when the 403 is a billing-provider-confirmed subscription lapse (value subscription_lapsed, matching the body `code`). schema: type: string content: application/json: schema: $ref: '#/components/schemas/ForbiddenError' "429": description: Rate limit exceeded. headers: X-RateLimit-Limit: description: Maximum requests allowed in the active rate-limit window. schema: type: string X-RateLimit-Remaining: description: Requests remaining in the active rate-limit window. schema: type: string X-RateLimit-Reset: description: Unix epoch milliseconds when the active rate-limit window resets. schema: type: string Retry-After: description: Seconds to wait before retrying the request. schema: type: string content: application/json: schema: oneOf: - $ref: '#/components/schemas/Error' - $ref: '#/components/schemas/RateLimitError' "503": description: Service unavailable. Billing-verification responses include code and X-Billing-Verification; other gateway infrastructure failures use the generic GatewayError shape. headers: Retry-After: description: Seconds to wait before retrying (1-60). schema: type: string X-Billing-Verification: description: Billing-verification state that produced this response (matches the body `code`). schema: type: string X-Validation-Mode: description: Present with value degraded when user API-key validation is temporarily unavailable. schema: type: string X-RateLimit-Mode: description: Present with value degraded when a fail-closed rate-limit dependency is unavailable. schema: type: string content: application/json: schema: oneOf: - $ref: '#/components/schemas/BillingVerificationError' - $ref: '#/components/schemas/GatewayError' default: description: Gateway or handler error response. content: application/json: schema: oneOf: - $ref: '#/components/schemas/Error' - $ref: '#/components/schemas/GatewayError' /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 description: Chokepoint identifier whose transit history should be returned. required: true example: "suez" schema: type: string - name: jmespath in: query description: |- Optional JMESPath expression applied server-side to project or reduce the JSON response before it is returned (mirrors the MCP jmespath argument). Invalid expressions, expressions larger than 1024 UTF-8 bytes, or projections that exceed the 256 KB output cap return HTTP 400 with a {_jmespath_error, original_keys} envelope. Grammar and worked examples: https://www.worldmonitor.app/docs/mcp-jmespath. required: false example: "keys(@)" schema: type: string responses: "200": description: Successful response content: application/json: example: "chokepointId": "suez" "fetchedAt": "1717200000000" "history": - "capContainer": 1.5 "capDryBulk": 1.5 "capGeneralCargo": 1.5 "capRoro": 1.5 "capTanker": 1.5 schema: $ref: '#/components/schemas/GetChokepointHistoryResponse' "400": description: Validation error content: application/json: schema: oneOf: - $ref: '#/components/schemas/ValidationError' - $ref: '#/components/schemas/JmespathProjectionError' "401": description: Missing or invalid API key. content: application/json: schema: $ref: '#/components/schemas/UnauthorizedError' "403": description: API access requires an active subscription (the API key's subscription is inactive or expired). headers: X-Billing-Verification: description: Present when the 403 is a billing-provider-confirmed subscription lapse (value subscription_lapsed, matching the body `code`). schema: type: string content: application/json: schema: $ref: '#/components/schemas/ForbiddenError' "429": description: Rate limit exceeded. headers: X-RateLimit-Limit: description: Maximum requests allowed in the active rate-limit window. schema: type: string X-RateLimit-Remaining: description: Requests remaining in the active rate-limit window. schema: type: string X-RateLimit-Reset: description: Unix epoch milliseconds when the active rate-limit window resets. schema: type: string Retry-After: description: Seconds to wait before retrying the request. schema: type: string content: application/json: schema: oneOf: - $ref: '#/components/schemas/Error' - $ref: '#/components/schemas/RateLimitError' "503": description: Service unavailable. Billing-verification responses include code and X-Billing-Verification; other gateway infrastructure failures use the generic GatewayError shape. headers: Retry-After: description: Seconds to wait before retrying (1-60). schema: type: string X-Billing-Verification: description: Billing-verification state that produced this response (matches the body `code`). schema: type: string X-Validation-Mode: description: Present with value degraded when user API-key validation is temporarily unavailable. schema: type: string X-RateLimit-Mode: description: Present with value degraded when a fail-closed rate-limit dependency is unavailable. schema: type: string content: application/json: schema: oneOf: - $ref: '#/components/schemas/BillingVerificationError' - $ref: '#/components/schemas/GatewayError' default: description: Gateway or handler error response. content: application/json: schema: oneOf: - $ref: '#/components/schemas/Error' - $ref: '#/components/schemas/GatewayError' /api/supply-chain/v1/get-critical-minerals: get: tags: - SupplyChainService summary: GetCriticalMinerals description: GetCriticalMinerals returns critical-minerals supply indicators; upstream_unavailable is set when the source could not be reached. operationId: GetCriticalMinerals parameters: - name: jmespath in: query description: |- Optional JMESPath expression applied server-side to project or reduce the JSON response before it is returned (mirrors the MCP jmespath argument). Invalid expressions, expressions larger than 1024 UTF-8 bytes, or projections that exceed the 256 KB output cap return HTTP 400 with a {_jmespath_error, original_keys} envelope. Grammar and worked examples: https://www.worldmonitor.app/docs/mcp-jmespath. required: false example: "keys(@)" schema: type: string responses: "200": description: Successful response content: application/json: example: "fetchedAt": "2026-01-15T12:00:00Z" "minerals": - "globalProduction": 1.5 "hhi": 1.5 "mineral": "example" "riskRating": "example" "topProducers": - "country": "US" "countryCode": "US" "productionTonnes": 1.5 "sharePct": 1.5 "upstreamUnavailable": false schema: $ref: '#/components/schemas/GetCriticalMineralsResponse' "400": description: Validation error content: application/json: schema: oneOf: - $ref: '#/components/schemas/ValidationError' - $ref: '#/components/schemas/JmespathProjectionError' "401": description: Missing or invalid API key. content: application/json: schema: $ref: '#/components/schemas/UnauthorizedError' "403": description: API access requires an active subscription (the API key's subscription is inactive or expired). headers: X-Billing-Verification: description: Present when the 403 is a billing-provider-confirmed subscription lapse (value subscription_lapsed, matching the body `code`). schema: type: string content: application/json: schema: $ref: '#/components/schemas/ForbiddenError' "429": description: Rate limit exceeded. headers: X-RateLimit-Limit: description: Maximum requests allowed in the active rate-limit window. schema: type: string X-RateLimit-Remaining: description: Requests remaining in the active rate-limit window. schema: type: string X-RateLimit-Reset: description: Unix epoch milliseconds when the active rate-limit window resets. schema: type: string Retry-After: description: Seconds to wait before retrying the request. schema: type: string content: application/json: schema: oneOf: - $ref: '#/components/schemas/Error' - $ref: '#/components/schemas/RateLimitError' "503": description: Service unavailable. Billing-verification responses include code and X-Billing-Verification; other gateway infrastructure failures use the generic GatewayError shape. headers: Retry-After: description: Seconds to wait before retrying (1-60). schema: type: string X-Billing-Verification: description: Billing-verification state that produced this response (matches the body `code`). schema: type: string X-Validation-Mode: description: Present with value degraded when user API-key validation is temporarily unavailable. schema: type: string X-RateLimit-Mode: description: Present with value degraded when a fail-closed rate-limit dependency is unavailable. schema: type: string content: application/json: schema: oneOf: - $ref: '#/components/schemas/BillingVerificationError' - $ref: '#/components/schemas/GatewayError' default: description: Gateway or handler error response. content: application/json: schema: oneOf: - $ref: '#/components/schemas/Error' - $ref: '#/components/schemas/GatewayError' /api/supply-chain/v1/get-mineral-production: get: tags: - SupplyChainService summary: GetMineralProduction description: |- GetMineralProduction returns per-commodity mine and refinery country shares and HHI from the annual USGS MCS / BGS seed. PRO-gated. Requires entitlement tier >= 1. operationId: GetMineralProduction security: - WorldMonitorKey: [] - ApiKeyHeader: [] - BearerAuth: [] parameters: - name: commodity in: query description: USGS commodity id or label (e.g. "cobalt"). Empty returns every commodity. required: false example: "example" schema: type: string - name: iso2 in: query description: |- ISO 3166-1 alpha-2. When set, countries[] is scoped to this producer and the countries portfolio is populated. required: false example: "US" schema: type: string - name: stage in: query description: '"mine" or "refinery". Empty returns both stages when present.' required: false example: "example" schema: type: string - name: jmespath in: query description: |- Optional JMESPath expression applied server-side to project or reduce the JSON response before it is returned (mirrors the MCP jmespath argument). Invalid expressions, expressions larger than 1024 UTF-8 bytes, or projections that exceed the 256 KB output cap return HTTP 400 with a {_jmespath_error, original_keys} envelope. Grammar and worked examples: https://www.worldmonitor.app/docs/mcp-jmespath. required: false example: "keys(@)" schema: type: string responses: "200": description: Successful response content: application/json: example: "commodities": - "commodity": "example" "commodityId": "example-id" "mine": "countries": - "country": "US" "estimated": true "iso2": "US" "output": 1.5 "residual": true "hhi": 1.5 "unit": "example" "withheldCount": 1 "worldTotal": 1 "refinery": "countries": - "country": "US" "estimated": true "iso2": "US" "output": 1.5 "residual": true "hhi": 1.5 "unit": "example" "withheldCount": 1 "worldTotal": 1 "sources": - "example" "countries": - "holdings": - "commodity": "example" "commodityId": "example-id" "output": 1.5 "share": 1.5 "stage": "example" "iso2": "US" "dataYear": 1 "fetchedAt": "2026-01-15T12:00:00Z" "upstreamUnavailable": false schema: $ref: '#/components/schemas/GetMineralProductionResponse' "400": description: Validation error content: application/json: schema: oneOf: - $ref: '#/components/schemas/ValidationError' - $ref: '#/components/schemas/JmespathProjectionError' "401": description: Missing or invalid API key. content: application/json: schema: $ref: '#/components/schemas/UnauthorizedError' "403": description: PRO entitlement access denied. headers: X-Billing-Verification: description: Present when the 403 is a billing-provider-confirmed subscription lapse (value subscription_lapsed, matching the body `code`). schema: type: string content: application/json: schema: $ref: '#/components/schemas/ForbiddenError' "429": description: Rate limit exceeded. headers: X-RateLimit-Limit: description: Maximum requests allowed in the active rate-limit window. schema: type: string X-RateLimit-Remaining: description: Requests remaining in the active rate-limit window. schema: type: string X-RateLimit-Reset: description: Unix epoch milliseconds when the active rate-limit window resets. schema: type: string Retry-After: description: Seconds to wait before retrying the request. schema: type: string content: application/json: schema: oneOf: - $ref: '#/components/schemas/Error' - $ref: '#/components/schemas/RateLimitError' "503": description: Service unavailable. Billing-verification responses include code and X-Billing-Verification; other gateway infrastructure failures use the generic GatewayError shape. headers: Retry-After: description: Seconds to wait before retrying (1-60). schema: type: string X-Billing-Verification: description: Billing-verification state that produced this response (matches the body `code`). schema: type: string X-Validation-Mode: description: Present with value degraded when user API-key validation is temporarily unavailable. schema: type: string X-RateLimit-Mode: description: Present with value degraded when a fail-closed rate-limit dependency is unavailable. schema: type: string content: application/json: schema: oneOf: - $ref: '#/components/schemas/BillingVerificationError' - $ref: '#/components/schemas/GatewayError' default: description: Gateway or handler error response. content: application/json: schema: oneOf: - $ref: '#/components/schemas/Error' - $ref: '#/components/schemas/GatewayError' /api/supply-chain/v1/get-shipping-stress: get: tags: - SupplyChainService summary: GetShippingStress description: GetShippingStress returns Yahoo Finance quotes for the BDRY dry bulk ETF and four shipping carriers, plus a 0-100 stress score from their average daily move. operationId: GetShippingStress parameters: - name: jmespath in: query description: |- Optional JMESPath expression applied server-side to project or reduce the JSON response before it is returned (mirrors the MCP jmespath argument). Invalid expressions, expressions larger than 1024 UTF-8 bytes, or projections that exceed the 256 KB output cap return HTTP 400 with a {_jmespath_error, original_keys} envelope. Grammar and worked examples: https://www.worldmonitor.app/docs/mcp-jmespath. required: false example: "keys(@)" schema: type: string responses: "200": description: Successful response content: application/json: example: "carriers": - "carrierType": "all" "changePct": 1.5 "name": "WorldMonitor Analyst" "price": 75.25 "sparkline": - 1.5 "fetchedAt": 1717200000000 "stressLevel": "example" "stressScore": 42.5 "upstreamUnavailable": false schema: $ref: '#/components/schemas/GetShippingStressResponse' "400": description: Validation error content: application/json: schema: oneOf: - $ref: '#/components/schemas/ValidationError' - $ref: '#/components/schemas/JmespathProjectionError' "401": description: Missing or invalid API key. content: application/json: schema: $ref: '#/components/schemas/UnauthorizedError' "403": description: API access requires an active subscription (the API key's subscription is inactive or expired). headers: X-Billing-Verification: description: Present when the 403 is a billing-provider-confirmed subscription lapse (value subscription_lapsed, matching the body `code`). schema: type: string content: application/json: schema: $ref: '#/components/schemas/ForbiddenError' "429": description: Rate limit exceeded. headers: X-RateLimit-Limit: description: Maximum requests allowed in the active rate-limit window. schema: type: string X-RateLimit-Remaining: description: Requests remaining in the active rate-limit window. schema: type: string X-RateLimit-Reset: description: Unix epoch milliseconds when the active rate-limit window resets. schema: type: string Retry-After: description: Seconds to wait before retrying the request. schema: type: string content: application/json: schema: oneOf: - $ref: '#/components/schemas/Error' - $ref: '#/components/schemas/RateLimitError' "503": description: Service unavailable. Billing-verification responses include code and X-Billing-Verification; other gateway infrastructure failures use the generic GatewayError shape. headers: Retry-After: description: Seconds to wait before retrying (1-60). schema: type: string X-Billing-Verification: description: Billing-verification state that produced this response (matches the body `code`). schema: type: string X-Validation-Mode: description: Present with value degraded when user API-key validation is temporarily unavailable. schema: type: string X-RateLimit-Mode: description: Present with value degraded when a fail-closed rate-limit dependency is unavailable. schema: type: string content: application/json: schema: oneOf: - $ref: '#/components/schemas/BillingVerificationError' - $ref: '#/components/schemas/GatewayError' default: description: Gateway or handler error response. content: application/json: schema: oneOf: - $ref: '#/components/schemas/Error' - $ref: '#/components/schemas/GatewayError' /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. Requires entitlement tier >= 1. operationId: GetCountryChokepointIndex security: - WorldMonitorKey: [] - ApiKeyHeader: [] - BearerAuth: [] parameters: - name: iso2 in: query description: ISO 3166-1 alpha-2 country code (uppercase). required: true example: "US" schema: type: string pattern: '^[A-Z]{2}$' - name: hs2 in: query description: HS2 chapter (2-digit string). Defaults to "27" (energy/mineral fuels) when absent. required: false example: "27" schema: type: string - name: jmespath in: query description: |- Optional JMESPath expression applied server-side to project or reduce the JSON response before it is returned (mirrors the MCP jmespath argument). Invalid expressions, expressions larger than 1024 UTF-8 bytes, or projections that exceed the 256 KB output cap return HTTP 400 with a {_jmespath_error, original_keys} envelope. Grammar and worked examples: https://www.worldmonitor.app/docs/mcp-jmespath. required: false example: "keys(@)" schema: type: string responses: "200": description: Successful response content: application/json: example: "exposures": - "chokepointId": "suez" "chokepointName": "WorldMonitor Analyst" "coastSide": "example" "exposureScore": 42.5 "shockSupported": true "fetchedAt": "2026-01-15T12:00:00Z" "hs2": "27" "iso2": "US" "primaryChokepointId": "suez" schema: $ref: '#/components/schemas/GetCountryChokepointIndexResponse' "400": description: Validation error content: application/json: schema: oneOf: - $ref: '#/components/schemas/ValidationError' - $ref: '#/components/schemas/JmespathProjectionError' "401": description: Missing or invalid API key. content: application/json: schema: $ref: '#/components/schemas/UnauthorizedError' "403": description: PRO entitlement access denied. headers: X-Billing-Verification: description: Present when the 403 is a billing-provider-confirmed subscription lapse (value subscription_lapsed, matching the body `code`). schema: type: string content: application/json: schema: $ref: '#/components/schemas/ForbiddenError' "429": description: Rate limit exceeded. headers: X-RateLimit-Limit: description: Maximum requests allowed in the active rate-limit window. schema: type: string X-RateLimit-Remaining: description: Requests remaining in the active rate-limit window. schema: type: string X-RateLimit-Reset: description: Unix epoch milliseconds when the active rate-limit window resets. schema: type: string Retry-After: description: Seconds to wait before retrying the request. schema: type: string content: application/json: schema: oneOf: - $ref: '#/components/schemas/Error' - $ref: '#/components/schemas/RateLimitError' "503": description: Service unavailable. Billing-verification responses include code and X-Billing-Verification; other gateway infrastructure failures use the generic GatewayError shape. headers: Retry-After: description: Seconds to wait before retrying (1-60). schema: type: string X-Billing-Verification: description: Billing-verification state that produced this response (matches the body `code`). schema: type: string X-Validation-Mode: description: Present with value degraded when user API-key validation is temporarily unavailable. schema: type: string X-RateLimit-Mode: description: Present with value degraded when a fail-closed rate-limit dependency is unavailable. schema: type: string content: application/json: schema: oneOf: - $ref: '#/components/schemas/BillingVerificationError' - $ref: '#/components/schemas/GatewayError' default: description: Gateway or handler error response. content: application/json: schema: oneOf: - $ref: '#/components/schemas/Error' - $ref: '#/components/schemas/GatewayError' /api/supply-chain/v1/get-bypass-options: get: tags: - SupplyChainService summary: GetBypassOptions description: GetBypassOptions ranks a chokepoint's bypass corridors for a cargo type and closure share by cost and waypoint risk. PRO-gated. Requires entitlement tier >= 1. operationId: GetBypassOptions security: - WorldMonitorKey: [] - ApiKeyHeader: [] - BearerAuth: [] parameters: - name: chokepointId in: query description: Chokepoint identifier to evaluate for bypass options. required: true example: "suez" schema: type: string - name: cargoType in: query description: 'container | tanker | bulk | roro (default: "container")' required: false example: "container" schema: type: string - name: closurePct in: query description: '0-100, percent of capacity blocked (default: 100)' required: false example: 1 schema: type: integer format: int32 - name: jmespath in: query description: |- Optional JMESPath expression applied server-side to project or reduce the JSON response before it is returned (mirrors the MCP jmespath argument). Invalid expressions, expressions larger than 1024 UTF-8 bytes, or projections that exceed the 256 KB output cap return HTTP 400 with a {_jmespath_error, original_keys} envelope. Grammar and worked examples: https://www.worldmonitor.app/docs/mcp-jmespath. required: false example: "keys(@)" schema: type: string responses: "200": description: Successful response content: application/json: example: "cargoType": "container" "chokepointId": "suez" "closurePct": 1 "fetchedAt": "2026-01-15T12:00:00Z" "options": - "activationThreshold": "example" "addedCostMultiplier": 75.25 "addedTransitDays": 7 "bypassWarRiskTier": "WAR_RISK_TIER_NORMAL" "capacityConstraintTonnage": "1717200000000" schema: $ref: '#/components/schemas/GetBypassOptionsResponse' "400": description: Validation error content: application/json: schema: oneOf: - $ref: '#/components/schemas/ValidationError' - $ref: '#/components/schemas/JmespathProjectionError' "401": description: Missing or invalid API key. content: application/json: schema: $ref: '#/components/schemas/UnauthorizedError' "403": description: PRO entitlement access denied. headers: X-Billing-Verification: description: Present when the 403 is a billing-provider-confirmed subscription lapse (value subscription_lapsed, matching the body `code`). schema: type: string content: application/json: schema: $ref: '#/components/schemas/ForbiddenError' "429": description: Rate limit exceeded. headers: X-RateLimit-Limit: description: Maximum requests allowed in the active rate-limit window. schema: type: string X-RateLimit-Remaining: description: Requests remaining in the active rate-limit window. schema: type: string X-RateLimit-Reset: description: Unix epoch milliseconds when the active rate-limit window resets. schema: type: string Retry-After: description: Seconds to wait before retrying the request. schema: type: string content: application/json: schema: oneOf: - $ref: '#/components/schemas/Error' - $ref: '#/components/schemas/RateLimitError' "503": description: Service unavailable. Billing-verification responses include code and X-Billing-Verification; other gateway infrastructure failures use the generic GatewayError shape. headers: Retry-After: description: Seconds to wait before retrying (1-60). schema: type: string X-Billing-Verification: description: Billing-verification state that produced this response (matches the body `code`). schema: type: string X-Validation-Mode: description: Present with value degraded when user API-key validation is temporarily unavailable. schema: type: string X-RateLimit-Mode: description: Present with value degraded when a fail-closed rate-limit dependency is unavailable. schema: type: string content: application/json: schema: oneOf: - $ref: '#/components/schemas/BillingVerificationError' - $ref: '#/components/schemas/GatewayError' default: description: Gateway or handler error response. content: application/json: schema: oneOf: - $ref: '#/components/schemas/Error' - $ref: '#/components/schemas/GatewayError' /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. Requires entitlement tier >= 1. operationId: GetCountryCostShock security: - WorldMonitorKey: [] - ApiKeyHeader: [] - BearerAuth: [] parameters: - name: iso2 in: query description: ISO 3166-1 alpha-2 country code for the importing country. required: true example: "US" schema: type: string pattern: '^[A-Z]{2}$' - name: chokepointId in: query description: Chokepoint identifier to model as disrupted. required: true example: "suez" schema: type: string - name: hs2 in: query description: 'HS2 chapter (default: "27")' required: false example: "27" schema: type: string - name: jmespath in: query description: |- Optional JMESPath expression applied server-side to project or reduce the JSON response before it is returned (mirrors the MCP jmespath argument). Invalid expressions, expressions larger than 1024 UTF-8 bytes, or projections that exceed the 256 KB output cap return HTTP 400 with a {_jmespath_error, original_keys} envelope. Grammar and worked examples: https://www.worldmonitor.app/docs/mcp-jmespath. required: false example: "keys(@)" schema: type: string responses: "200": description: Successful response content: application/json: example: "chokepointId": "suez" "coverageDays": 7 "fetchedAt": "2026-01-15T12:00:00Z" "hasEnergyModel": true "hs2": "27" schema: $ref: '#/components/schemas/GetCountryCostShockResponse' "400": description: Validation error content: application/json: schema: oneOf: - $ref: '#/components/schemas/ValidationError' - $ref: '#/components/schemas/JmespathProjectionError' "401": description: Missing or invalid API key. content: application/json: schema: $ref: '#/components/schemas/UnauthorizedError' "403": description: PRO entitlement access denied. headers: X-Billing-Verification: description: Present when the 403 is a billing-provider-confirmed subscription lapse (value subscription_lapsed, matching the body `code`). schema: type: string content: application/json: schema: $ref: '#/components/schemas/ForbiddenError' "429": description: Rate limit exceeded. headers: X-RateLimit-Limit: description: Maximum requests allowed in the active rate-limit window. schema: type: string X-RateLimit-Remaining: description: Requests remaining in the active rate-limit window. schema: type: string X-RateLimit-Reset: description: Unix epoch milliseconds when the active rate-limit window resets. schema: type: string Retry-After: description: Seconds to wait before retrying the request. schema: type: string content: application/json: schema: oneOf: - $ref: '#/components/schemas/Error' - $ref: '#/components/schemas/RateLimitError' "503": description: Service unavailable. Billing-verification responses include code and X-Billing-Verification; other gateway infrastructure failures use the generic GatewayError shape. headers: Retry-After: description: Seconds to wait before retrying (1-60). schema: type: string X-Billing-Verification: description: Billing-verification state that produced this response (matches the body `code`). schema: type: string X-Validation-Mode: description: Present with value degraded when user API-key validation is temporarily unavailable. schema: type: string X-RateLimit-Mode: description: Present with value degraded when a fail-closed rate-limit dependency is unavailable. schema: type: string content: application/json: schema: oneOf: - $ref: '#/components/schemas/BillingVerificationError' - $ref: '#/components/schemas/GatewayError' default: description: Gateway or handler error response. content: application/json: schema: oneOf: - $ref: '#/components/schemas/Error' - $ref: '#/components/schemas/GatewayError' /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. Requires entitlement tier >= 1. operationId: GetCountryProducts security: - WorldMonitorKey: [] - ApiKeyHeader: [] - BearerAuth: [] parameters: - name: iso2 in: query description: ISO 3166-1 alpha-2 country code whose strategic products should be returned. required: true example: "US" schema: type: string pattern: '^[A-Z]{2}$' - name: hs4 in: query description: Optional requested heading; permits bounded recovery of a missing product. required: false example: "example" schema: type: string - name: jmespath in: query description: |- Optional JMESPath expression applied server-side to project or reduce the JSON response before it is returned (mirrors the MCP jmespath argument). Invalid expressions, expressions larger than 1024 UTF-8 bytes, or projections that exceed the 256 KB output cap return HTTP 400 with a {_jmespath_error, original_keys} envelope. Grammar and worked examples: https://www.worldmonitor.app/docs/mcp-jmespath. required: false example: "keys(@)" schema: type: string responses: "200": description: Successful response content: application/json: example: "evidence": "lastAttemptAt": "2026-01-15T12:00:00Z" "lastAttemptState": "example" "missingHs4s": - "example" "requestedHs4s": - "example" "source": "example" "fetchedAt": "2026-01-15T12:00:00Z" "iso2": "US" "products": - "denominatorBasis": "example" "description": "Example WorldMonitor observation." "hs4": "example" "topExporters": - "netWeightKg": 1.5 "partnerCode": 1 "partnerIso2": "US" "share": 1.5 "value": 1.5 "totalValue": 1 schema: $ref: '#/components/schemas/GetCountryProductsResponse' "400": description: Validation error content: application/json: schema: oneOf: - $ref: '#/components/schemas/ValidationError' - $ref: '#/components/schemas/JmespathProjectionError' "401": description: Missing or invalid API key. content: application/json: schema: $ref: '#/components/schemas/UnauthorizedError' "403": description: PRO entitlement access denied. headers: X-Billing-Verification: description: Present when the 403 is a billing-provider-confirmed subscription lapse (value subscription_lapsed, matching the body `code`). schema: type: string content: application/json: schema: $ref: '#/components/schemas/ForbiddenError' "429": description: Rate limit exceeded. headers: X-RateLimit-Limit: description: Maximum requests allowed in the active rate-limit window. schema: type: string X-RateLimit-Remaining: description: Requests remaining in the active rate-limit window. schema: type: string X-RateLimit-Reset: description: Unix epoch milliseconds when the active rate-limit window resets. schema: type: string Retry-After: description: Seconds to wait before retrying the request. schema: type: string content: application/json: schema: oneOf: - $ref: '#/components/schemas/Error' - $ref: '#/components/schemas/RateLimitError' "503": description: Service unavailable. Billing-verification responses include code and X-Billing-Verification; other gateway infrastructure failures use the generic GatewayError shape. headers: Retry-After: description: Seconds to wait before retrying (1-60). schema: type: string X-Billing-Verification: description: Billing-verification state that produced this response (matches the body `code`). schema: type: string X-Validation-Mode: description: Present with value degraded when user API-key validation is temporarily unavailable. schema: type: string X-RateLimit-Mode: description: Present with value degraded when a fail-closed rate-limit dependency is unavailable. schema: type: string content: application/json: schema: oneOf: - $ref: '#/components/schemas/BillingVerificationError' - $ref: '#/components/schemas/GatewayError' default: description: Gateway or handler error response. content: application/json: schema: oneOf: - $ref: '#/components/schemas/Error' - $ref: '#/components/schemas/GatewayError' /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. Requires entitlement tier >= 1. operationId: GetMultiSectorCostShock security: - WorldMonitorKey: [] - ApiKeyHeader: [] - BearerAuth: [] parameters: - name: iso2 in: query description: ISO 3166-1 alpha-2 country code for the importing country. required: true example: "US" schema: type: string pattern: '^[A-Z]{2}$' - name: chokepointId in: query description: Chokepoint identifier to model as disrupted. required: true example: "suez" schema: type: string - name: closureDays in: query description: Closure-window duration in days. Server clamps to [1, 365]. Defaults to 30. required: false example: 7 schema: type: integer format: int32 - name: jmespath in: query description: |- Optional JMESPath expression applied server-side to project or reduce the JSON response before it is returned (mirrors the MCP jmespath argument). Invalid expressions, expressions larger than 1024 UTF-8 bytes, or projections that exceed the 256 KB output cap return HTTP 400 with a {_jmespath_error, original_keys} envelope. Grammar and worked examples: https://www.worldmonitor.app/docs/mcp-jmespath. required: false example: "keys(@)" schema: type: string responses: "200": description: Successful response content: application/json: example: "chokepointId": "suez" "closureDays": 7 "fetchedAt": "2026-01-15T12:00:00Z" "iso2": "US" "sectors": - "addedTransitDays": 7 "closureDays": 7 "freightAddedPctPerTon": 1.5 "hs2": "27" "hs2Label": "27" schema: $ref: '#/components/schemas/GetMultiSectorCostShockResponse' "400": description: Validation error content: application/json: schema: oneOf: - $ref: '#/components/schemas/ValidationError' - $ref: '#/components/schemas/JmespathProjectionError' "401": description: Missing or invalid API key. content: application/json: schema: $ref: '#/components/schemas/UnauthorizedError' "403": description: PRO entitlement access denied. headers: X-Billing-Verification: description: Present when the 403 is a billing-provider-confirmed subscription lapse (value subscription_lapsed, matching the body `code`). schema: type: string content: application/json: schema: $ref: '#/components/schemas/ForbiddenError' "429": description: Rate limit exceeded. headers: X-RateLimit-Limit: description: Maximum requests allowed in the active rate-limit window. schema: type: string X-RateLimit-Remaining: description: Requests remaining in the active rate-limit window. schema: type: string X-RateLimit-Reset: description: Unix epoch milliseconds when the active rate-limit window resets. schema: type: string Retry-After: description: Seconds to wait before retrying the request. schema: type: string content: application/json: schema: oneOf: - $ref: '#/components/schemas/Error' - $ref: '#/components/schemas/RateLimitError' "503": description: Service unavailable. Billing-verification responses include code and X-Billing-Verification; other gateway infrastructure failures use the generic GatewayError shape. headers: Retry-After: description: Seconds to wait before retrying (1-60). schema: type: string X-Billing-Verification: description: Billing-verification state that produced this response (matches the body `code`). schema: type: string X-Validation-Mode: description: Present with value degraded when user API-key validation is temporarily unavailable. schema: type: string X-RateLimit-Mode: description: Present with value degraded when a fail-closed rate-limit dependency is unavailable. schema: type: string content: application/json: schema: oneOf: - $ref: '#/components/schemas/BillingVerificationError' - $ref: '#/components/schemas/GatewayError' default: description: Gateway or handler error response. content: application/json: schema: oneOf: - $ref: '#/components/schemas/Error' - $ref: '#/components/schemas/GatewayError' /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. Requires entitlement tier >= 1. operationId: GetSectorDependency security: - WorldMonitorKey: [] - ApiKeyHeader: [] - BearerAuth: [] parameters: - name: iso2 in: query description: ISO 3166-1 alpha-2 country code whose sector dependency should be analyzed. required: true example: "US" schema: type: string pattern: '^[A-Z]{2}$' - name: hs2 in: query description: HS2 chapter code, e.g. "27" (mineral fuels), "85" (electronics) required: true example: "27" schema: type: string - name: jmespath in: query description: |- Optional JMESPath expression applied server-side to project or reduce the JSON response before it is returned (mirrors the MCP jmespath argument). Invalid expressions, expressions larger than 1024 UTF-8 bytes, or projections that exceed the 256 KB output cap return HTTP 400 with a {_jmespath_error, original_keys} envelope. Grammar and worked examples: https://www.worldmonitor.app/docs/mcp-jmespath. required: false example: "keys(@)" schema: type: string responses: "200": description: Successful response content: application/json: example: "fetchedAt": "2026-01-15T12:00:00Z" "flags": - "DEPENDENCY_FLAG_SINGLE_SOURCE_CRITICAL" "hasViableBypass": true "hs2": "27" "hs2Label": "27" schema: $ref: '#/components/schemas/GetSectorDependencyResponse' "400": description: Validation error content: application/json: schema: oneOf: - $ref: '#/components/schemas/ValidationError' - $ref: '#/components/schemas/JmespathProjectionError' "401": description: Missing or invalid API key. content: application/json: schema: $ref: '#/components/schemas/UnauthorizedError' "403": description: PRO entitlement access denied. headers: X-Billing-Verification: description: Present when the 403 is a billing-provider-confirmed subscription lapse (value subscription_lapsed, matching the body `code`). schema: type: string content: application/json: schema: $ref: '#/components/schemas/ForbiddenError' "429": description: Rate limit exceeded. headers: X-RateLimit-Limit: description: Maximum requests allowed in the active rate-limit window. schema: type: string X-RateLimit-Remaining: description: Requests remaining in the active rate-limit window. schema: type: string X-RateLimit-Reset: description: Unix epoch milliseconds when the active rate-limit window resets. schema: type: string Retry-After: description: Seconds to wait before retrying the request. schema: type: string content: application/json: schema: oneOf: - $ref: '#/components/schemas/Error' - $ref: '#/components/schemas/RateLimitError' "503": description: Service unavailable. Billing-verification responses include code and X-Billing-Verification; other gateway infrastructure failures use the generic GatewayError shape. headers: Retry-After: description: Seconds to wait before retrying (1-60). schema: type: string X-Billing-Verification: description: Billing-verification state that produced this response (matches the body `code`). schema: type: string X-Validation-Mode: description: Present with value degraded when user API-key validation is temporarily unavailable. schema: type: string X-RateLimit-Mode: description: Present with value degraded when a fail-closed rate-limit dependency is unavailable. schema: type: string content: application/json: schema: oneOf: - $ref: '#/components/schemas/BillingVerificationError' - $ref: '#/components/schemas/GatewayError' default: description: Gateway or handler error response. content: application/json: schema: oneOf: - $ref: '#/components/schemas/Error' - $ref: '#/components/schemas/GatewayError' /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. Requires entitlement tier >= 1. operationId: GetRouteExplorerLane security: - WorldMonitorKey: [] - ApiKeyHeader: [] - BearerAuth: [] parameters: - name: fromIso2 in: query description: ISO 3166-1 alpha-2 origin country code for the trade lane. required: true example: "US" schema: type: string pattern: '^[A-Z]{2}$' - name: toIso2 in: query description: ISO 3166-1 alpha-2 destination country code for the trade lane. required: true example: "US" schema: type: string pattern: '^[A-Z]{2}$' - name: hs2 in: query description: HS2 chapter code, e.g. "27", "85" required: true example: "27" schema: type: string - name: cargoType in: query description: 'One of: container, tanker, bulk, roro' required: true example: "container" schema: type: string - name: jmespath in: query description: |- Optional JMESPath expression applied server-side to project or reduce the JSON response before it is returned (mirrors the MCP jmespath argument). Invalid expressions, expressions larger than 1024 UTF-8 bytes, or projections that exceed the 256 KB output cap return HTTP 400 with a {_jmespath_error, original_keys} envelope. Grammar and worked examples: https://www.worldmonitor.app/docs/mcp-jmespath. required: false example: "keys(@)" schema: type: string responses: "200": description: Successful response content: application/json: example: "bypassOptions": - "addedCostMultiplier": 75.25 "addedTransitDays": 7 "fromPort": "lat": 40.7128 "lon": -74.006 "id": "example-id" "name": "WorldMonitor Analyst" "cargoType": "container" "chokepointExposures": - "chokepointId": "suez" "chokepointName": "WorldMonitor Analyst" "exposurePct": 1 "disruptionScore": 42.5 "estFreightUsdPerTeuRange": "max": 1 "min": 1 schema: $ref: '#/components/schemas/GetRouteExplorerLaneResponse' "400": description: Validation error content: application/json: schema: oneOf: - $ref: '#/components/schemas/ValidationError' - $ref: '#/components/schemas/JmespathProjectionError' "401": description: Missing or invalid API key. content: application/json: schema: $ref: '#/components/schemas/UnauthorizedError' "403": description: PRO entitlement access denied. headers: X-Billing-Verification: description: Present when the 403 is a billing-provider-confirmed subscription lapse (value subscription_lapsed, matching the body `code`). schema: type: string content: application/json: schema: $ref: '#/components/schemas/ForbiddenError' "429": description: Rate limit exceeded. headers: X-RateLimit-Limit: description: Maximum requests allowed in the active rate-limit window. schema: type: string X-RateLimit-Remaining: description: Requests remaining in the active rate-limit window. schema: type: string X-RateLimit-Reset: description: Unix epoch milliseconds when the active rate-limit window resets. schema: type: string Retry-After: description: Seconds to wait before retrying the request. schema: type: string content: application/json: schema: oneOf: - $ref: '#/components/schemas/Error' - $ref: '#/components/schemas/RateLimitError' "503": description: Service unavailable. Billing-verification responses include code and X-Billing-Verification; other gateway infrastructure failures use the generic GatewayError shape. headers: Retry-After: description: Seconds to wait before retrying (1-60). schema: type: string X-Billing-Verification: description: Billing-verification state that produced this response (matches the body `code`). schema: type: string X-Validation-Mode: description: Present with value degraded when user API-key validation is temporarily unavailable. schema: type: string X-RateLimit-Mode: description: Present with value degraded when a fail-closed rate-limit dependency is unavailable. schema: type: string content: application/json: schema: oneOf: - $ref: '#/components/schemas/BillingVerificationError' - $ref: '#/components/schemas/GatewayError' default: description: Gateway or handler error response. content: application/json: schema: oneOf: - $ref: '#/components/schemas/Error' - $ref: '#/components/schemas/GatewayError' /api/supply-chain/v1/get-route-impact: get: tags: - SupplyChainService summary: GetRouteImpact description: 'GetRouteImpact returns route-level trade exposure: lane value, primary exporter concentration, strategic products, resilience score, dependency flags, and Comtrade provenance. PRO-gated. Requires entitlement tier >= 1.' operationId: GetRouteImpact security: - WorldMonitorKey: [] - ApiKeyHeader: [] - BearerAuth: [] parameters: - name: fromIso2 in: query description: ISO 3166-1 alpha-2 origin country code for the route. required: true example: "US" schema: type: string pattern: '^[A-Z]{2}$' - name: toIso2 in: query description: ISO 3166-1 alpha-2 destination country code for the route. required: true example: "US" schema: type: string pattern: '^[A-Z]{2}$' - name: hs2 in: query description: HS2 chapter code for the product sector on the route. required: true example: "27" schema: type: string - name: jmespath in: query description: |- Optional JMESPath expression applied server-side to project or reduce the JSON response before it is returned (mirrors the MCP jmespath argument). Invalid expressions, expressions larger than 1024 UTF-8 bytes, or projections that exceed the 256 KB output cap return HTTP 400 with a {_jmespath_error, original_keys} envelope. Grammar and worked examples: https://www.worldmonitor.app/docs/mcp-jmespath. required: false example: "keys(@)" schema: type: string responses: "200": description: Successful response content: application/json: example: "comtradeSource": "example" "dependencyFlags": - "DEPENDENCY_FLAG_SINGLE_SOURCE_CRITICAL" "fetchedAt": "2026-01-15T12:00:00Z" "hs2InSeededUniverse": true "laneValueUsd": 1.5 schema: $ref: '#/components/schemas/GetRouteImpactResponse' "400": description: Validation error content: application/json: schema: oneOf: - $ref: '#/components/schemas/ValidationError' - $ref: '#/components/schemas/JmespathProjectionError' "401": description: Missing or invalid API key. content: application/json: schema: $ref: '#/components/schemas/UnauthorizedError' "403": description: PRO entitlement access denied. headers: X-Billing-Verification: description: Present when the 403 is a billing-provider-confirmed subscription lapse (value subscription_lapsed, matching the body `code`). schema: type: string content: application/json: schema: $ref: '#/components/schemas/ForbiddenError' "429": description: Rate limit exceeded. headers: X-RateLimit-Limit: description: Maximum requests allowed in the active rate-limit window. schema: type: string X-RateLimit-Remaining: description: Requests remaining in the active rate-limit window. schema: type: string X-RateLimit-Reset: description: Unix epoch milliseconds when the active rate-limit window resets. schema: type: string Retry-After: description: Seconds to wait before retrying the request. schema: type: string content: application/json: schema: oneOf: - $ref: '#/components/schemas/Error' - $ref: '#/components/schemas/RateLimitError' "503": description: Service unavailable. Billing-verification responses include code and X-Billing-Verification; other gateway infrastructure failures use the generic GatewayError shape. headers: Retry-After: description: Seconds to wait before retrying (1-60). schema: type: string X-Billing-Verification: description: Billing-verification state that produced this response (matches the body `code`). schema: type: string X-Validation-Mode: description: Present with value degraded when user API-key validation is temporarily unavailable. schema: type: string X-RateLimit-Mode: description: Present with value degraded when a fail-closed rate-limit dependency is unavailable. schema: type: string content: application/json: schema: oneOf: - $ref: '#/components/schemas/BillingVerificationError' - $ref: '#/components/schemas/GatewayError' default: description: Gateway or handler error response. content: application/json: schema: oneOf: - $ref: '#/components/schemas/Error' - $ref: '#/components/schemas/GatewayError' /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 example: "oil" schema: type: string - name: jmespath in: query description: |- Optional JMESPath expression applied server-side to project or reduce the JSON response before it is returned (mirrors the MCP jmespath argument). Invalid expressions, expressions larger than 1024 UTF-8 bytes, or projections that exceed the 256 KB output cap return HTTP 400 with a {_jmespath_error, original_keys} envelope. Grammar and worked examples: https://www.worldmonitor.app/docs/mcp-jmespath. required: false example: "keys(@)" schema: type: string responses: "200": description: Successful response content: application/json: example: "classifierVersion": "example" "fetchedAt": "2026-01-15T12:00:00Z" "pipelines": - "capacityBcmYr": 1.5 "capacityMbd": 1.5 "commodityType": "oil" "endPoint": "lat": 40.7128 "lon": -74.006 "evidence": "classifierConfidence": 0.82 "classifierVersion": "example" "commercialState": "example" "lastEvidenceUpdate": "2026-01-15" "operatorStatement": "date": "2026-01-15" "text": "example" "url": "https://example.com/worldmonitor" "upstreamUnavailable": false schema: $ref: '#/components/schemas/ListPipelinesResponse' "400": description: Validation error content: application/json: schema: oneOf: - $ref: '#/components/schemas/ValidationError' - $ref: '#/components/schemas/JmespathProjectionError' "401": description: Missing or invalid API key. content: application/json: schema: $ref: '#/components/schemas/UnauthorizedError' "403": description: API access requires an active subscription (the API key's subscription is inactive or expired). headers: X-Billing-Verification: description: Present when the 403 is a billing-provider-confirmed subscription lapse (value subscription_lapsed, matching the body `code`). schema: type: string content: application/json: schema: $ref: '#/components/schemas/ForbiddenError' "429": description: Rate limit exceeded. headers: X-RateLimit-Limit: description: Maximum requests allowed in the active rate-limit window. schema: type: string X-RateLimit-Remaining: description: Requests remaining in the active rate-limit window. schema: type: string X-RateLimit-Reset: description: Unix epoch milliseconds when the active rate-limit window resets. schema: type: string Retry-After: description: Seconds to wait before retrying the request. schema: type: string content: application/json: schema: oneOf: - $ref: '#/components/schemas/Error' - $ref: '#/components/schemas/RateLimitError' "503": description: Service unavailable. Billing-verification responses include code and X-Billing-Verification; other gateway infrastructure failures use the generic GatewayError shape. headers: Retry-After: description: Seconds to wait before retrying (1-60). schema: type: string X-Billing-Verification: description: Billing-verification state that produced this response (matches the body `code`). schema: type: string X-Validation-Mode: description: Present with value degraded when user API-key validation is temporarily unavailable. schema: type: string X-RateLimit-Mode: description: Present with value degraded when a fail-closed rate-limit dependency is unavailable. schema: type: string content: application/json: schema: oneOf: - $ref: '#/components/schemas/BillingVerificationError' - $ref: '#/components/schemas/GatewayError' default: description: Gateway or handler error response. content: application/json: schema: oneOf: - $ref: '#/components/schemas/Error' - $ref: '#/components/schemas/GatewayError' /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 description: Pipeline identifier to load with full evidence details. required: true example: "transmed-pipeline" schema: type: string - name: jmespath in: query description: |- Optional JMESPath expression applied server-side to project or reduce the JSON response before it is returned (mirrors the MCP jmespath argument). Invalid expressions, expressions larger than 1024 UTF-8 bytes, or projections that exceed the 256 KB output cap return HTTP 400 with a {_jmespath_error, original_keys} envelope. Grammar and worked examples: https://www.worldmonitor.app/docs/mcp-jmespath. required: false example: "keys(@)" schema: type: string responses: "200": description: Successful response content: application/json: example: "fetchedAt": "2026-01-15T12:00:00Z" "pipeline": "capacityBcmYr": 1.5 "capacityMbd": 1.5 "commodityType": "oil" "endPoint": "lat": 40.7128 "lon": -74.006 "evidence": "classifierConfidence": 0.82 "classifierVersion": "example" "commercialState": "example" "lastEvidenceUpdate": "2026-01-15" "operatorStatement": "date": "2026-01-15" "text": "example" "url": "https://example.com/worldmonitor" "revisions": - "classifierVersion": "example" "date": "2026-01-15" "fieldChanged": "example" "newValue": "example" "previousValue": "example" "unavailable": false schema: $ref: '#/components/schemas/GetPipelineDetailResponse' "400": description: Validation error content: application/json: schema: oneOf: - $ref: '#/components/schemas/ValidationError' - $ref: '#/components/schemas/JmespathProjectionError' "401": description: Missing or invalid API key. content: application/json: schema: $ref: '#/components/schemas/UnauthorizedError' "403": description: API access requires an active subscription (the API key's subscription is inactive or expired). headers: X-Billing-Verification: description: Present when the 403 is a billing-provider-confirmed subscription lapse (value subscription_lapsed, matching the body `code`). schema: type: string content: application/json: schema: $ref: '#/components/schemas/ForbiddenError' "429": description: Rate limit exceeded. headers: X-RateLimit-Limit: description: Maximum requests allowed in the active rate-limit window. schema: type: string X-RateLimit-Remaining: description: Requests remaining in the active rate-limit window. schema: type: string X-RateLimit-Reset: description: Unix epoch milliseconds when the active rate-limit window resets. schema: type: string Retry-After: description: Seconds to wait before retrying the request. schema: type: string content: application/json: schema: oneOf: - $ref: '#/components/schemas/Error' - $ref: '#/components/schemas/RateLimitError' "503": description: Service unavailable. Billing-verification responses include code and X-Billing-Verification; other gateway infrastructure failures use the generic GatewayError shape. headers: Retry-After: description: Seconds to wait before retrying (1-60). schema: type: string X-Billing-Verification: description: Billing-verification state that produced this response (matches the body `code`). schema: type: string X-Validation-Mode: description: Present with value degraded when user API-key validation is temporarily unavailable. schema: type: string X-RateLimit-Mode: description: Present with value degraded when a fail-closed rate-limit dependency is unavailable. schema: type: string content: application/json: schema: oneOf: - $ref: '#/components/schemas/BillingVerificationError' - $ref: '#/components/schemas/GatewayError' default: description: Gateway or handler error response. content: application/json: schema: oneOf: - $ref: '#/components/schemas/Error' - $ref: '#/components/schemas/GatewayError' /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 example: "ugs" schema: type: string - name: jmespath in: query description: |- Optional JMESPath expression applied server-side to project or reduce the JSON response before it is returned (mirrors the MCP jmespath argument). Invalid expressions, expressions larger than 1024 UTF-8 bytes, or projections that exceed the 256 KB output cap return HTTP 400 with a {_jmespath_error, original_keys} envelope. Grammar and worked examples: https://www.worldmonitor.app/docs/mcp-jmespath. required: false example: "keys(@)" schema: type: string responses: "200": description: Successful response content: application/json: example: "classifierVersion": "example" "facilities": - "capacityMb": 1.5 "capacityMtpa": 1.5 "capacityTwh": 1.5 "country": "US" "evidence": "classifierConfidence": 0.82 "classifierVersion": "example" "commercialState": "example" "fillDisclosed": true "fillSource": "example" "fetchedAt": "2026-01-15T12:00:00Z" "upstreamUnavailable": false schema: $ref: '#/components/schemas/ListStorageFacilitiesResponse' "400": description: Validation error content: application/json: schema: oneOf: - $ref: '#/components/schemas/ValidationError' - $ref: '#/components/schemas/JmespathProjectionError' "401": description: Missing or invalid API key. content: application/json: schema: $ref: '#/components/schemas/UnauthorizedError' "403": description: API access requires an active subscription (the API key's subscription is inactive or expired). headers: X-Billing-Verification: description: Present when the 403 is a billing-provider-confirmed subscription lapse (value subscription_lapsed, matching the body `code`). schema: type: string content: application/json: schema: $ref: '#/components/schemas/ForbiddenError' "429": description: Rate limit exceeded. headers: X-RateLimit-Limit: description: Maximum requests allowed in the active rate-limit window. schema: type: string X-RateLimit-Remaining: description: Requests remaining in the active rate-limit window. schema: type: string X-RateLimit-Reset: description: Unix epoch milliseconds when the active rate-limit window resets. schema: type: string Retry-After: description: Seconds to wait before retrying the request. schema: type: string content: application/json: schema: oneOf: - $ref: '#/components/schemas/Error' - $ref: '#/components/schemas/RateLimitError' "503": description: Service unavailable. Billing-verification responses include code and X-Billing-Verification; other gateway infrastructure failures use the generic GatewayError shape. headers: Retry-After: description: Seconds to wait before retrying (1-60). schema: type: string X-Billing-Verification: description: Billing-verification state that produced this response (matches the body `code`). schema: type: string X-Validation-Mode: description: Present with value degraded when user API-key validation is temporarily unavailable. schema: type: string X-RateLimit-Mode: description: Present with value degraded when a fail-closed rate-limit dependency is unavailable. schema: type: string content: application/json: schema: oneOf: - $ref: '#/components/schemas/BillingVerificationError' - $ref: '#/components/schemas/GatewayError' default: description: Gateway or handler error response. content: application/json: schema: oneOf: - $ref: '#/components/schemas/Error' - $ref: '#/components/schemas/GatewayError' /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 description: Storage facility identifier to load with full evidence details. required: true example: "rough-storage" schema: type: string - name: jmespath in: query description: |- Optional JMESPath expression applied server-side to project or reduce the JSON response before it is returned (mirrors the MCP jmespath argument). Invalid expressions, expressions larger than 1024 UTF-8 bytes, or projections that exceed the 256 KB output cap return HTTP 400 with a {_jmespath_error, original_keys} envelope. Grammar and worked examples: https://www.worldmonitor.app/docs/mcp-jmespath. required: false example: "keys(@)" schema: type: string responses: "200": description: Successful response content: application/json: example: "facility": "capacityMb": 1.5 "capacityMtpa": 1.5 "capacityTwh": 1.5 "country": "US" "evidence": "classifierConfidence": 0.82 "classifierVersion": "example" "commercialState": "example" "fillDisclosed": true "fillSource": "example" "fetchedAt": "2026-01-15T12:00:00Z" "revisions": - "classifierVersion": "example" "date": "2026-01-15" "fieldChanged": "example" "newValue": "example" "previousValue": "example" "unavailable": false schema: $ref: '#/components/schemas/GetStorageFacilityDetailResponse' "400": description: Validation error content: application/json: schema: oneOf: - $ref: '#/components/schemas/ValidationError' - $ref: '#/components/schemas/JmespathProjectionError' "401": description: Missing or invalid API key. content: application/json: schema: $ref: '#/components/schemas/UnauthorizedError' "403": description: API access requires an active subscription (the API key's subscription is inactive or expired). headers: X-Billing-Verification: description: Present when the 403 is a billing-provider-confirmed subscription lapse (value subscription_lapsed, matching the body `code`). schema: type: string content: application/json: schema: $ref: '#/components/schemas/ForbiddenError' "429": description: Rate limit exceeded. headers: X-RateLimit-Limit: description: Maximum requests allowed in the active rate-limit window. schema: type: string X-RateLimit-Remaining: description: Requests remaining in the active rate-limit window. schema: type: string X-RateLimit-Reset: description: Unix epoch milliseconds when the active rate-limit window resets. schema: type: string Retry-After: description: Seconds to wait before retrying the request. schema: type: string content: application/json: schema: oneOf: - $ref: '#/components/schemas/Error' - $ref: '#/components/schemas/RateLimitError' "503": description: Service unavailable. Billing-verification responses include code and X-Billing-Verification; other gateway infrastructure failures use the generic GatewayError shape. headers: Retry-After: description: Seconds to wait before retrying (1-60). schema: type: string X-Billing-Verification: description: Billing-verification state that produced this response (matches the body `code`). schema: type: string X-Validation-Mode: description: Present with value degraded when user API-key validation is temporarily unavailable. schema: type: string X-RateLimit-Mode: description: Present with value degraded when a fail-closed rate-limit dependency is unavailable. schema: type: string content: application/json: schema: oneOf: - $ref: '#/components/schemas/BillingVerificationError' - $ref: '#/components/schemas/GatewayError' default: description: Gateway or handler error response. content: application/json: schema: oneOf: - $ref: '#/components/schemas/Error' - $ref: '#/components/schemas/GatewayError' /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 example: "US" schema: type: string - name: product in: query description: |- Filter to one product. Accepts: "petrol" | "diesel" | "jet" | "heating_oil". Omit for all products. required: false example: "diesel" schema: type: string - name: severity in: query description: 'Filter to one severity. Accepts: "confirmed" | "watch". Omit for both.' required: false example: "watch" schema: type: string - name: jmespath in: query description: |- Optional JMESPath expression applied server-side to project or reduce the JSON response before it is returned (mirrors the MCP jmespath argument). Invalid expressions, expressions larger than 1024 UTF-8 bytes, or projections that exceed the 256 KB output cap return HTTP 400 with a {_jmespath_error, original_keys} envelope. Grammar and worked examples: https://www.worldmonitor.app/docs/mcp-jmespath. required: false example: "keys(@)" schema: type: string responses: "200": description: Successful response content: application/json: example: "classifierVersion": "example" "fetchedAt": "2026-01-15T12:00:00Z" "shortages": - "causeChain": - "example" "country": "US" "evidence": "classifierConfidence": 0.82 "classifierVersion": "example" "evidenceSources": - "authority": "example" "date": "2026-01-15" "sourceType": "all" "title": "example" "url": "https://example.com/worldmonitor" "firstRegulatorConfirmation": "example" "lastEvidenceUpdate": "2026-01-15" "firstSeen": "example" "id": "example-id" "upstreamUnavailable": false schema: $ref: '#/components/schemas/ListFuelShortagesResponse' "400": description: Validation error content: application/json: schema: oneOf: - $ref: '#/components/schemas/ValidationError' - $ref: '#/components/schemas/JmespathProjectionError' "401": description: Missing or invalid API key. content: application/json: schema: $ref: '#/components/schemas/UnauthorizedError' "403": description: API access requires an active subscription (the API key's subscription is inactive or expired). headers: X-Billing-Verification: description: Present when the 403 is a billing-provider-confirmed subscription lapse (value subscription_lapsed, matching the body `code`). schema: type: string content: application/json: schema: $ref: '#/components/schemas/ForbiddenError' "429": description: Rate limit exceeded. headers: X-RateLimit-Limit: description: Maximum requests allowed in the active rate-limit window. schema: type: string X-RateLimit-Remaining: description: Requests remaining in the active rate-limit window. schema: type: string X-RateLimit-Reset: description: Unix epoch milliseconds when the active rate-limit window resets. schema: type: string Retry-After: description: Seconds to wait before retrying the request. schema: type: string content: application/json: schema: oneOf: - $ref: '#/components/schemas/Error' - $ref: '#/components/schemas/RateLimitError' "503": description: Service unavailable. Billing-verification responses include code and X-Billing-Verification; other gateway infrastructure failures use the generic GatewayError shape. headers: Retry-After: description: Seconds to wait before retrying (1-60). schema: type: string X-Billing-Verification: description: Billing-verification state that produced this response (matches the body `code`). schema: type: string X-Validation-Mode: description: Present with value degraded when user API-key validation is temporarily unavailable. schema: type: string X-RateLimit-Mode: description: Present with value degraded when a fail-closed rate-limit dependency is unavailable. schema: type: string content: application/json: schema: oneOf: - $ref: '#/components/schemas/BillingVerificationError' - $ref: '#/components/schemas/GatewayError' default: description: Gateway or handler error response. content: application/json: schema: oneOf: - $ref: '#/components/schemas/Error' - $ref: '#/components/schemas/GatewayError' /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 description: Fuel-shortage identifier to load with full evidence details. required: true example: "example-id" schema: type: string - name: jmespath in: query description: |- Optional JMESPath expression applied server-side to project or reduce the JSON response before it is returned (mirrors the MCP jmespath argument). Invalid expressions, expressions larger than 1024 UTF-8 bytes, or projections that exceed the 256 KB output cap return HTTP 400 with a {_jmespath_error, original_keys} envelope. Grammar and worked examples: https://www.worldmonitor.app/docs/mcp-jmespath. required: false example: "keys(@)" schema: type: string responses: "200": description: Successful response content: application/json: example: "fetchedAt": "2026-01-15T12:00:00Z" "shortage": "causeChain": - "example" "country": "US" "evidence": "classifierConfidence": 0.82 "classifierVersion": "example" "evidenceSources": - "authority": "example" "date": "2026-01-15" "sourceType": "all" "title": "example" "url": "https://example.com/worldmonitor" "firstRegulatorConfirmation": "example" "lastEvidenceUpdate": "2026-01-15" "firstSeen": "example" "id": "example-id" "unavailable": false schema: $ref: '#/components/schemas/GetFuelShortageDetailResponse' "400": description: Validation error content: application/json: schema: oneOf: - $ref: '#/components/schemas/ValidationError' - $ref: '#/components/schemas/JmespathProjectionError' "401": description: Missing or invalid API key. content: application/json: schema: $ref: '#/components/schemas/UnauthorizedError' "403": description: API access requires an active subscription (the API key's subscription is inactive or expired). headers: X-Billing-Verification: description: Present when the 403 is a billing-provider-confirmed subscription lapse (value subscription_lapsed, matching the body `code`). schema: type: string content: application/json: schema: $ref: '#/components/schemas/ForbiddenError' "429": description: Rate limit exceeded. headers: X-RateLimit-Limit: description: Maximum requests allowed in the active rate-limit window. schema: type: string X-RateLimit-Remaining: description: Requests remaining in the active rate-limit window. schema: type: string X-RateLimit-Reset: description: Unix epoch milliseconds when the active rate-limit window resets. schema: type: string Retry-After: description: Seconds to wait before retrying the request. schema: type: string content: application/json: schema: oneOf: - $ref: '#/components/schemas/Error' - $ref: '#/components/schemas/RateLimitError' "503": description: Service unavailable. Billing-verification responses include code and X-Billing-Verification; other gateway infrastructure failures use the generic GatewayError shape. headers: Retry-After: description: Seconds to wait before retrying (1-60). schema: type: string X-Billing-Verification: description: Billing-verification state that produced this response (matches the body `code`). schema: type: string X-Validation-Mode: description: Present with value degraded when user API-key validation is temporarily unavailable. schema: type: string X-RateLimit-Mode: description: Present with value degraded when a fail-closed rate-limit dependency is unavailable. schema: type: string content: application/json: schema: oneOf: - $ref: '#/components/schemas/BillingVerificationError' - $ref: '#/components/schemas/GatewayError' default: description: Gateway or handler error response. content: application/json: schema: oneOf: - $ref: '#/components/schemas/Error' - $ref: '#/components/schemas/GatewayError' /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 example: "asset-example-1" schema: type: string - name: assetType in: query description: 'Filter to one asset type. Accepts: "pipeline" | "storage".' required: false example: "pipeline" schema: type: string - name: ongoingOnly in: query description: If true, only return events with endAt empty (still ongoing). required: false example: true schema: type: boolean - name: jmespath in: query description: |- Optional JMESPath expression applied server-side to project or reduce the JSON response before it is returned (mirrors the MCP jmespath argument). Invalid expressions, expressions larger than 1024 UTF-8 bytes, or projections that exceed the 256 KB output cap return HTTP 400 with a {_jmespath_error, original_keys} envelope. Grammar and worked examples: https://www.worldmonitor.app/docs/mcp-jmespath. required: false example: "keys(@)" schema: type: string responses: "200": description: Successful response content: application/json: example: "classifierVersion": "example" "events": - "assetId": "asset-example-1" "assetType": "pipeline" "capacityOfflineBcmYr": 1.5 "capacityOfflineMbd": 1.5 "causeChain": - "example" "fetchedAt": "2026-01-15T12:00:00Z" "upstreamUnavailable": false schema: $ref: '#/components/schemas/ListEnergyDisruptionsResponse' "400": description: Validation error content: application/json: schema: oneOf: - $ref: '#/components/schemas/ValidationError' - $ref: '#/components/schemas/JmespathProjectionError' "401": description: Missing or invalid API key. content: application/json: schema: $ref: '#/components/schemas/UnauthorizedError' "403": description: API access requires an active subscription (the API key's subscription is inactive or expired). headers: X-Billing-Verification: description: Present when the 403 is a billing-provider-confirmed subscription lapse (value subscription_lapsed, matching the body `code`). schema: type: string content: application/json: schema: $ref: '#/components/schemas/ForbiddenError' "429": description: Rate limit exceeded. headers: X-RateLimit-Limit: description: Maximum requests allowed in the active rate-limit window. schema: type: string X-RateLimit-Remaining: description: Requests remaining in the active rate-limit window. schema: type: string X-RateLimit-Reset: description: Unix epoch milliseconds when the active rate-limit window resets. schema: type: string Retry-After: description: Seconds to wait before retrying the request. schema: type: string content: application/json: schema: oneOf: - $ref: '#/components/schemas/Error' - $ref: '#/components/schemas/RateLimitError' "503": description: Service unavailable. Billing-verification responses include code and X-Billing-Verification; other gateway infrastructure failures use the generic GatewayError shape. headers: Retry-After: description: Seconds to wait before retrying (1-60). schema: type: string X-Billing-Verification: description: Billing-verification state that produced this response (matches the body `code`). schema: type: string X-Validation-Mode: description: Present with value degraded when user API-key validation is temporarily unavailable. schema: type: string X-RateLimit-Mode: description: Present with value degraded when a fail-closed rate-limit dependency is unavailable. schema: type: string content: application/json: schema: oneOf: - $ref: '#/components/schemas/BillingVerificationError' - $ref: '#/components/schemas/GatewayError' default: description: Gateway or handler error response. content: application/json: schema: oneOf: - $ref: '#/components/schemas/Error' - $ref: '#/components/schemas/GatewayError' /api/supply-chain/v1/get-china-corridor-control-towers: get: tags: - SupplyChainService summary: GetChinaCorridorControlTowers description: |- GetChinaCorridorControlTowers composes reviewed China logistics corridors from existing source caches. Conditions retain canonical provenance and explicit unavailable states; the response never emits a single risk score. operationId: GetChinaCorridorControlTowers parameters: - name: jmespath in: query description: |- Optional JMESPath expression applied server-side to project or reduce the JSON response before it is returned (mirrors the MCP jmespath argument). Invalid expressions, expressions larger than 1024 UTF-8 bytes, or projections that exceed the 256 KB output cap return HTTP 400 with a {_jmespath_error, original_keys} envelope. Grammar and worked examples: https://www.worldmonitor.app/docs/mcp-jmespath. required: false example: "keys(@)" schema: type: string responses: "200": description: Successful response content: application/json: example: "generatedAt": "2026-07-25T12:00:00.000Z" "payloadJson": "{\"generatedAt\":\"2026-07-25T12:00:00.000Z\",\"corridors\":[{\"id\":\"china-yangtze-river-delta\",\"name\":\"Yangtze River Delta\",\"description\":\"Reviewed coastal logistics corridor joining Shanghai, Jiangsu, and Zhejiang gateways.\",\"boundary\":[{\"lat\":28.4,\"lon\":118.2},{\"lat\":28.4,\"lon\":123.2},{\"lat\":33.4,\"lon\":123.2},{\"lat\":33.4,\"lon\":118.2},{\"lat\":28.4,\"lon\":118.2}],\"nodes\":[{\"id\":\"china-node:yrd-port-shanghai\",\"name\":\"Shanghai\",\"type\":\"port\",\"lat\":31.1918,\"lon\":121.6442,\"sourceOwner\":\"IMF PortWatch\",\"sourceSelector\":{\"family\":\"port\",\"id\":\"port1188\"}}],\"availability\":\"partial\",\"conditions\":[{\"family\":\"port\",\"providerId\":\"portwatch\",\"availability\":\"available\",\"reason\":null,\"sourceSignals\":[{\"id\":\"signal:portwatch:port1188:2026-07-25T11:00:00.000Z\",\"family\":\"port\",\"selectorId\":\"port1188\",\"availability\":\"available\",\"publisher\":{\"id\":\"publisher:imf-portwatch\",\"name\":\"IMF PortWatch\",\"type\":\"official\"},\"sourceUrl\":\"https://portwatch.imf.org/\",\"sourceScope\":\"node\",\"observationTime\":\"2026-07-25T11:00:00.000Z\",\"observationTimePrecision\":\"instant\",\"releaseTime\":null,\"releaseTimePrecision\":\"unknown\",\"retrievalTime\":\"2026-07-25T11:05:00.000Z\",\"retrievalTimePrecision\":\"instant\",\"revision\":null,\"transportFreshness\":\"fresh\",\"contentFreshness\":\"current\",\"summary\":\"PortWatch activity observation available for Shanghai.\",\"metrics\":{\"tankerCalls30d\":14}}],\"provenance\":{\"contractVersion\":\"decision-signal-provenance/v1\",\"signalId\":\"signal:corridor-condition:china-yangtze-river-delta:port:2026-07-25T11:00:00.000Z\",\"familyId\":\"composed_corridor_condition\",\"claims\":{\"publisher\":{\"status\":\"known\",\"value\":{\"id\":\"publisher:worldmonitor-derived\",\"name\":\"WorldMonitor derived output\",\"type\":\"derived_output\",\"registryReference\":null}},\"observation_time\":{\"status\":\"known\",\"value\":{\"role\":\"observation\",\"value\":\"2026-07-25T11:00:00.000Z\",\"precision\":\"instant\"}},\"source_url\":{\"status\":\"not_applicable\",\"reason\":\"The corridor condition links source URLs through its input signals.\"},\"original_reference\":{\"status\":\"not_applicable\",\"reason\":\"The corridor condition is composed from multiple source records.\"},\"original_language\":{\"status\":\"not_applicable\",\"reason\":\"The deterministic composition has no original-language text.\"},\"translation\":{\"status\":\"not_applicable\",\"reason\":\"The deterministic composition has no translated source text.\"},\"effective_time\":{\"status\":\"known\",\"value\":{\"role\":\"effective\",\"value\":\"2026-07-25T11:00:00.000Z\",\"precision\":\"instant\"}},\"publication_time\":{\"status\":\"not_applicable\",\"reason\":\"The computed condition is not a publisher release.\"},\"retrieval_time\":{\"status\":\"known\",\"value\":{\"role\":\"retrieval\",\"value\":\"2026-07-25T11:05:00.000Z\",\"precision\":\"instant\"}},\"revision\":{\"status\":\"known\",\"value\":{\"vintageId\":\"china-yangtze-river-delta:port:2026-07-25T11:00:00.000Z\",\"sequence\":1,\"state\":\"original\"}},\"supersession\":{\"status\":\"known\",\"value\":{\"state\":\"current\"}},\"extraction_confidence\":{\"status\":\"not_applicable\",\"reason\":\"Each input signal owns its extraction confidence.\"},\"classification_confidence\":{\"status\":\"known\",\"value\":{\"score\":1,\"method\":\"exact-reviewed-selector/v1\"}},\"corroboration\":{\"status\":\"known\",\"value\":{\"state\":\"single_source\",\"sourceSignalIds\":[\"signal:portwatch:port1188:2026-07-25T11:00:00.000Z\"]}},\"transport_freshness\":{\"status\":\"known\",\"value\":{\"state\":\"fresh\",\"assessedAt\":\"2026-07-25T12:00:00.000Z\",\"lastSuccessAt\":\"2026-07-25T11:05:00.000Z\"}},\"content_freshness\":{\"status\":\"known\",\"value\":{\"state\":\"current\",\"assessedAt\":\"2026-07-25T12:00:00.000Z\",\"contentAsOf\":\"2026-07-25T11:00:00.000Z\"}},\"derivation\":{\"status\":\"known\",\"value\":{\"methodId\":\"worldmonitor:china-corridor-condition\",\"methodVersion\":\"1\",\"computedAt\":\"2026-07-25T12:00:00.000Z\",\"inputSignalIds\":[\"signal:portwatch:port1188:2026-07-25T11:00:00.000Z\"]}}}}},{\"family\":\"aviation\",\"providerId\":\"provider:aviation\",\"availability\":\"unavailable\",\"reason\":\"No reviewed source observation is available in this example.\",\"sourceSignals\":[],\"provenance\":null},{\"family\":\"hazard\",\"providerId\":\"provider:hazard\",\"availability\":\"unavailable\",\"reason\":\"No reviewed source observation is available in this example.\",\"sourceSignals\":[],\"provenance\":null},{\"family\":\"power_energy\",\"providerId\":\"provider:power_energy\",\"availability\":\"unavailable\",\"reason\":\"No reviewed source observation is available in this example.\",\"sourceSignals\":[],\"provenance\":null},{\"family\":\"strategic_industry\",\"providerId\":\"provider:strategic_industry\",\"availability\":\"unavailable\",\"reason\":\"No reviewed source observation is available in this example.\",\"sourceSignals\":[],\"provenance\":null},{\"family\":\"trade\",\"providerId\":\"provider:trade\",\"availability\":\"unavailable\",\"reason\":\"No reviewed source observation is available in this example.\",\"sourceSignals\":[],\"provenance\":null}]},{\"id\":\"china-greater-bay-area\",\"name\":\"Greater Bay Area\",\"description\":\"Reviewed Pearl River Delta corridor connecting Guangdong, Hong Kong, and Macao-facing port, airport, and industrial gateways.\",\"boundary\":[{\"lat\":20.5,\"lon\":111.5},{\"lat\":20.5,\"lon\":115.8},{\"lat\":24.8,\"lon\":115.8},{\"lat\":24.8,\"lon\":111.5},{\"lat\":20.5,\"lon\":111.5}],\"nodes\":[{\"id\":\"china-node:gba-port-shekou\",\"name\":\"Shekou Shenzhen\",\"type\":\"port\",\"lat\":22.47,\"lon\":113.9,\"sourceOwner\":\"IMF PortWatch\",\"sourceSelector\":{\"family\":\"port\",\"id\":\"port1189\"}}],\"availability\":\"partial\",\"conditions\":[{\"family\":\"port\",\"providerId\":\"portwatch\",\"availability\":\"available\",\"reason\":null,\"sourceSignals\":[{\"id\":\"signal:portwatch:port1189:2026-07-25T11:00:00.000Z\",\"family\":\"port\",\"selectorId\":\"port1189\",\"availability\":\"available\",\"publisher\":{\"id\":\"publisher:imf-portwatch\",\"name\":\"IMF PortWatch\",\"type\":\"official\"},\"sourceUrl\":\"https://portwatch.imf.org/\",\"sourceScope\":\"node\",\"observationTime\":\"2026-07-25T11:00:00.000Z\",\"observationTimePrecision\":\"instant\",\"releaseTime\":null,\"releaseTimePrecision\":\"unknown\",\"retrievalTime\":\"2026-07-25T11:05:00.000Z\",\"retrievalTimePrecision\":\"instant\",\"revision\":null,\"transportFreshness\":\"fresh\",\"contentFreshness\":\"current\",\"summary\":\"PortWatch activity observation available for Shekou Shenzhen.\",\"metrics\":{\"tankerCalls30d\":14}}],\"provenance\":{\"contractVersion\":\"decision-signal-provenance/v1\",\"signalId\":\"signal:corridor-condition:china-greater-bay-area:port:2026-07-25T11:00:00.000Z\",\"familyId\":\"composed_corridor_condition\",\"claims\":{\"publisher\":{\"status\":\"known\",\"value\":{\"id\":\"publisher:worldmonitor-derived\",\"name\":\"WorldMonitor derived output\",\"type\":\"derived_output\",\"registryReference\":null}},\"observation_time\":{\"status\":\"known\",\"value\":{\"role\":\"observation\",\"value\":\"2026-07-25T11:00:00.000Z\",\"precision\":\"instant\"}},\"source_url\":{\"status\":\"not_applicable\",\"reason\":\"The corridor condition links source URLs through its input signals.\"},\"original_reference\":{\"status\":\"not_applicable\",\"reason\":\"The corridor condition is composed from multiple source records.\"},\"original_language\":{\"status\":\"not_applicable\",\"reason\":\"The deterministic composition has no original-language text.\"},\"translation\":{\"status\":\"not_applicable\",\"reason\":\"The deterministic composition has no translated source text.\"},\"effective_time\":{\"status\":\"known\",\"value\":{\"role\":\"effective\",\"value\":\"2026-07-25T11:00:00.000Z\",\"precision\":\"instant\"}},\"publication_time\":{\"status\":\"not_applicable\",\"reason\":\"The computed condition is not a publisher release.\"},\"retrieval_time\":{\"status\":\"known\",\"value\":{\"role\":\"retrieval\",\"value\":\"2026-07-25T11:05:00.000Z\",\"precision\":\"instant\"}},\"revision\":{\"status\":\"known\",\"value\":{\"vintageId\":\"china-greater-bay-area:port:2026-07-25T11:00:00.000Z\",\"sequence\":1,\"state\":\"original\"}},\"supersession\":{\"status\":\"known\",\"value\":{\"state\":\"current\"}},\"extraction_confidence\":{\"status\":\"not_applicable\",\"reason\":\"Each input signal owns its extraction confidence.\"},\"classification_confidence\":{\"status\":\"known\",\"value\":{\"score\":1,\"method\":\"exact-reviewed-selector/v1\"}},\"corroboration\":{\"status\":\"known\",\"value\":{\"state\":\"single_source\",\"sourceSignalIds\":[\"signal:portwatch:port1189:2026-07-25T11:00:00.000Z\"]}},\"transport_freshness\":{\"status\":\"known\",\"value\":{\"state\":\"fresh\",\"assessedAt\":\"2026-07-25T12:00:00.000Z\",\"lastSuccessAt\":\"2026-07-25T11:05:00.000Z\"}},\"content_freshness\":{\"status\":\"known\",\"value\":{\"state\":\"current\",\"assessedAt\":\"2026-07-25T12:00:00.000Z\",\"contentAsOf\":\"2026-07-25T11:00:00.000Z\"}},\"derivation\":{\"status\":\"known\",\"value\":{\"methodId\":\"worldmonitor:china-corridor-condition\",\"methodVersion\":\"1\",\"computedAt\":\"2026-07-25T12:00:00.000Z\",\"inputSignalIds\":[\"signal:portwatch:port1189:2026-07-25T11:00:00.000Z\"]}}}}},{\"family\":\"aviation\",\"providerId\":\"provider:aviation\",\"availability\":\"unavailable\",\"reason\":\"No reviewed source observation is available in this example.\",\"sourceSignals\":[],\"provenance\":null},{\"family\":\"hazard\",\"providerId\":\"provider:hazard\",\"availability\":\"unavailable\",\"reason\":\"No reviewed source observation is available in this example.\",\"sourceSignals\":[],\"provenance\":null},{\"family\":\"power_energy\",\"providerId\":\"provider:power_energy\",\"availability\":\"unavailable\",\"reason\":\"No reviewed source observation is available in this example.\",\"sourceSignals\":[],\"provenance\":null},{\"family\":\"strategic_industry\",\"providerId\":\"provider:strategic_industry\",\"availability\":\"unavailable\",\"reason\":\"No reviewed source observation is available in this example.\",\"sourceSignals\":[],\"provenance\":null},{\"family\":\"trade\",\"providerId\":\"provider:trade\",\"availability\":\"unavailable\",\"reason\":\"No reviewed source observation is available in this example.\",\"sourceSignals\":[],\"provenance\":null}]},{\"id\":\"china-bohai-rim\",\"name\":\"Bohai Rim\",\"description\":\"Reviewed northern maritime-industrial corridor spanning Beijing-Tianjin, Hebei, Shandong, Liaoning, and their major gateways.\",\"boundary\":[{\"lat\":35.5,\"lon\":116},{\"lat\":35.5,\"lon\":123.5},{\"lat\":42.2,\"lon\":123.5},{\"lat\":42.2,\"lon\":116},{\"lat\":35.5,\"lon\":116}],\"nodes\":[{\"id\":\"china-node:bohai-port-qingdao\",\"name\":\"Qingdao\",\"type\":\"port\",\"lat\":36.07,\"lon\":120.32,\"sourceOwner\":\"IMF PortWatch\",\"sourceSelector\":{\"family\":\"port\",\"id\":\"port1069\"}}],\"availability\":\"unavailable\",\"conditions\":[{\"family\":\"port\",\"providerId\":\"provider:port\",\"availability\":\"unavailable\",\"reason\":\"No reviewed source observation is available in this example.\",\"sourceSignals\":[],\"provenance\":null},{\"family\":\"aviation\",\"providerId\":\"provider:aviation\",\"availability\":\"unavailable\",\"reason\":\"No reviewed source observation is available in this example.\",\"sourceSignals\":[],\"provenance\":null},{\"family\":\"hazard\",\"providerId\":\"provider:hazard\",\"availability\":\"unavailable\",\"reason\":\"No reviewed source observation is available in this example.\",\"sourceSignals\":[],\"provenance\":null},{\"family\":\"power_energy\",\"providerId\":\"provider:power_energy\",\"availability\":\"unavailable\",\"reason\":\"No reviewed source observation is available in this example.\",\"sourceSignals\":[],\"provenance\":null},{\"family\":\"strategic_industry\",\"providerId\":\"provider:strategic_industry\",\"availability\":\"unavailable\",\"reason\":\"No reviewed source observation is available in this example.\",\"sourceSignals\":[],\"provenance\":null},{\"family\":\"trade\",\"providerId\":\"provider:trade\",\"availability\":\"unavailable\",\"reason\":\"No reviewed source observation is available in this example.\",\"sourceSignals\":[],\"provenance\":null}]},{\"id\":\"china-western-land-sea-corridor\",\"name\":\"Western Land-Sea Corridor\",\"description\":\"Reviewed western corridor linking inland manufacturing hubs, Xinjiang land crossings, and Guangxi gateways to regional and maritime routes.\",\"boundary\":[{\"lat\":20.4,\"lon\":106.2},{\"lat\":20.4,\"lon\":110.4},{\"lat\":32.5,\"lon\":110.4},{\"lat\":47,\"lon\":91},{\"lat\":47,\"lon\":78.5},{\"lat\":41,\"lon\":78.5},{\"lat\":27,\"lon\":99.7},{\"lat\":22,\"lon\":105.8},{\"lat\":20.4,\"lon\":106.2}],\"nodes\":[{\"id\":\"china-node:western-port-qinzhou\",\"name\":\"Qinzhou\",\"type\":\"port\",\"lat\":21.6788,\"lon\":108.6383,\"sourceOwner\":\"IMF PortWatch\",\"sourceSelector\":{\"family\":\"port\",\"id\":\"port1071\"}}],\"availability\":\"unavailable\",\"conditions\":[{\"family\":\"port\",\"providerId\":\"provider:port\",\"availability\":\"unavailable\",\"reason\":\"No reviewed source observation is available in this example.\",\"sourceSignals\":[],\"provenance\":null},{\"family\":\"aviation\",\"providerId\":\"provider:aviation\",\"availability\":\"unavailable\",\"reason\":\"No reviewed source observation is available in this example.\",\"sourceSignals\":[],\"provenance\":null},{\"family\":\"hazard\",\"providerId\":\"provider:hazard\",\"availability\":\"unavailable\",\"reason\":\"No reviewed source observation is available in this example.\",\"sourceSignals\":[],\"provenance\":null},{\"family\":\"power_energy\",\"providerId\":\"provider:power_energy\",\"availability\":\"unavailable\",\"reason\":\"No reviewed source observation is available in this example.\",\"sourceSignals\":[],\"provenance\":null},{\"family\":\"strategic_industry\",\"providerId\":\"provider:strategic_industry\",\"availability\":\"unavailable\",\"reason\":\"No reviewed source observation is available in this example.\",\"sourceSignals\":[],\"provenance\":null},{\"family\":\"trade\",\"providerId\":\"provider:trade\",\"availability\":\"unavailable\",\"reason\":\"No reviewed source observation is available in this example.\",\"sourceSignals\":[],\"provenance\":null}]}]}" "upstreamUnavailable": false schema: $ref: '#/components/schemas/GetChinaCorridorControlTowersResponse' "400": description: Validation error content: application/json: schema: oneOf: - $ref: '#/components/schemas/ValidationError' - $ref: '#/components/schemas/JmespathProjectionError' "401": description: Missing or invalid API key. content: application/json: schema: $ref: '#/components/schemas/UnauthorizedError' "403": description: API access requires an active subscription (the API key's subscription is inactive or expired). headers: X-Billing-Verification: description: Present when the 403 is a billing-provider-confirmed subscription lapse (value subscription_lapsed, matching the body `code`). schema: type: string content: application/json: schema: $ref: '#/components/schemas/ForbiddenError' "429": description: Rate limit exceeded. headers: X-RateLimit-Limit: description: Maximum requests allowed in the active rate-limit window. schema: type: string X-RateLimit-Remaining: description: Requests remaining in the active rate-limit window. schema: type: string X-RateLimit-Reset: description: Unix epoch milliseconds when the active rate-limit window resets. schema: type: string Retry-After: description: Seconds to wait before retrying the request. schema: type: string content: application/json: schema: oneOf: - $ref: '#/components/schemas/Error' - $ref: '#/components/schemas/RateLimitError' "503": description: Service unavailable. Billing-verification responses include code and X-Billing-Verification; other gateway infrastructure failures use the generic GatewayError shape. headers: Retry-After: description: Seconds to wait before retrying (1-60). schema: type: string X-Billing-Verification: description: Billing-verification state that produced this response (matches the body `code`). schema: type: string X-Validation-Mode: description: Present with value degraded when user API-key validation is temporarily unavailable. schema: type: string X-RateLimit-Mode: description: Present with value degraded when a fail-closed rate-limit dependency is unavailable. schema: type: string content: application/json: schema: oneOf: - $ref: '#/components/schemas/BillingVerificationError' - $ref: '#/components/schemas/GatewayError' default: description: Gateway or handler error response. content: application/json: schema: oneOf: - $ref: '#/components/schemas/Error' - $ref: '#/components/schemas/GatewayError' /api/supply-chain/v1/get-country-vulnerabilities: get: tags: - SupplyChainService summary: GetCountryVulnerabilities description: GetCountryVulnerabilities returns the full per-commodity score evidence for one country. PRO-gated. Requires entitlement tier >= 1. operationId: GetCountryVulnerabilities security: - WorldMonitorKey: [] - ApiKeyHeader: [] - BearerAuth: [] parameters: - name: iso2 in: query description: Uppercase ISO 3166-1 alpha-2 country code. required: true example: "US" schema: type: string pattern: '^[A-Z]{2}$' - name: jmespath in: query description: |- Optional JMESPath expression applied server-side to project or reduce the JSON response before it is returned (mirrors the MCP jmespath argument). Invalid expressions, expressions larger than 1024 UTF-8 bytes, or projections that exceed the 256 KB output cap return HTTP 400 with a {_jmespath_error, original_keys} envelope. Grammar and worked examples: https://www.worldmonitor.app/docs/mcp-jmespath. required: false example: "keys(@)" schema: type: string responses: "200": description: Successful response content: application/json: example: "country": "US" "generatedAt": "2026-01-15T12:00:00Z" "iso2": "US" "methodologyVersion": "example" "upstreamUnavailable": false schema: $ref: '#/components/schemas/GetCountryVulnerabilitiesResponse' "400": description: Validation error content: application/json: schema: oneOf: - $ref: '#/components/schemas/ValidationError' - $ref: '#/components/schemas/JmespathProjectionError' "401": description: Missing or invalid API key. content: application/json: schema: $ref: '#/components/schemas/UnauthorizedError' "403": description: PRO entitlement access denied. headers: X-Billing-Verification: description: Present when the 403 is a billing-provider-confirmed subscription lapse (value subscription_lapsed, matching the body `code`). schema: type: string content: application/json: schema: $ref: '#/components/schemas/ForbiddenError' "429": description: Rate limit exceeded. headers: X-RateLimit-Limit: description: Maximum requests allowed in the active rate-limit window. schema: type: string X-RateLimit-Remaining: description: Requests remaining in the active rate-limit window. schema: type: string X-RateLimit-Reset: description: Unix epoch milliseconds when the active rate-limit window resets. schema: type: string Retry-After: description: Seconds to wait before retrying the request. schema: type: string content: application/json: schema: oneOf: - $ref: '#/components/schemas/Error' - $ref: '#/components/schemas/RateLimitError' "503": description: Service unavailable. Billing-verification responses include code and X-Billing-Verification; other gateway infrastructure failures use the generic GatewayError shape. headers: Retry-After: description: Seconds to wait before retrying (1-60). schema: type: string X-Billing-Verification: description: Billing-verification state that produced this response (matches the body `code`). schema: type: string X-Validation-Mode: description: Present with value degraded when user API-key validation is temporarily unavailable. schema: type: string X-RateLimit-Mode: description: Present with value degraded when a fail-closed rate-limit dependency is unavailable. schema: type: string content: application/json: schema: oneOf: - $ref: '#/components/schemas/BillingVerificationError' - $ref: '#/components/schemas/GatewayError' default: description: Gateway or handler error response. content: application/json: schema: oneOf: - $ref: '#/components/schemas/Error' - $ref: '#/components/schemas/GatewayError' /api/supply-chain/v1/get-chokepoint-dependencies: get: tags: - SupplyChainService summary: GetChokepointDependencies description: GetChokepointDependencies returns the inverse country/commodity dependency index. PRO-gated. Requires entitlement tier >= 1. operationId: GetChokepointDependencies security: - WorldMonitorKey: [] - ApiKeyHeader: [] - BearerAuth: [] parameters: - name: chokepointId in: query description: Stable chokepoint identifier, such as hormuz_strait or suez. required: true example: "suez" schema: type: string pattern: '^[a-z0-9_\-]+$' - name: pageSize in: query description: Maximum dependencies to return; zero uses the server default and the maximum is 100. required: false example: 25 schema: type: integer format: int32 - name: jmespath in: query description: |- Optional JMESPath expression applied server-side to project or reduce the JSON response before it is returned (mirrors the MCP jmespath argument). Invalid expressions, expressions larger than 1024 UTF-8 bytes, or projections that exceed the 256 KB output cap return HTTP 400 with a {_jmespath_error, original_keys} envelope. Grammar and worked examples: https://www.worldmonitor.app/docs/mcp-jmespath. required: false example: "keys(@)" schema: type: string responses: "200": description: Successful response content: application/json: example: "chokepoint": "example" "chokepointId": "suez" "dependencies": - "band": "example" "commodity": "example" "commodityId": "example-id" "countryIso2": "US" "countryName": "US" "generatedAt": "2026-01-15T12:00:00Z" "methodologyVersion": "example" schema: $ref: '#/components/schemas/GetChokepointDependenciesResponse' "400": description: Validation error content: application/json: schema: oneOf: - $ref: '#/components/schemas/ValidationError' - $ref: '#/components/schemas/JmespathProjectionError' "401": description: Missing or invalid API key. content: application/json: schema: $ref: '#/components/schemas/UnauthorizedError' "403": description: PRO entitlement access denied. headers: X-Billing-Verification: description: Present when the 403 is a billing-provider-confirmed subscription lapse (value subscription_lapsed, matching the body `code`). schema: type: string content: application/json: schema: $ref: '#/components/schemas/ForbiddenError' "429": description: Rate limit exceeded. headers: X-RateLimit-Limit: description: Maximum requests allowed in the active rate-limit window. schema: type: string X-RateLimit-Remaining: description: Requests remaining in the active rate-limit window. schema: type: string X-RateLimit-Reset: description: Unix epoch milliseconds when the active rate-limit window resets. schema: type: string Retry-After: description: Seconds to wait before retrying the request. schema: type: string content: application/json: schema: oneOf: - $ref: '#/components/schemas/Error' - $ref: '#/components/schemas/RateLimitError' "503": description: Service unavailable. Billing-verification responses include code and X-Billing-Verification; other gateway infrastructure failures use the generic GatewayError shape. headers: Retry-After: description: Seconds to wait before retrying (1-60). schema: type: string X-Billing-Verification: description: Billing-verification state that produced this response (matches the body `code`). schema: type: string X-Validation-Mode: description: Present with value degraded when user API-key validation is temporarily unavailable. schema: type: string X-RateLimit-Mode: description: Present with value degraded when a fail-closed rate-limit dependency is unavailable. schema: type: string content: application/json: schema: oneOf: - $ref: '#/components/schemas/BillingVerificationError' - $ref: '#/components/schemas/GatewayError' default: description: Gateway or handler error response. content: application/json: schema: oneOf: - $ref: '#/components/schemas/Error' - $ref: '#/components/schemas/GatewayError' /api/supply-chain/v1/list-vulnerability-rankings: get: tags: - SupplyChainService summary: ListVulnerabilityRankings description: ListVulnerabilityRankings returns a bounded global ranking with optional filters. PRO-gated. Requires entitlement tier >= 1. operationId: ListVulnerabilityRankings security: - WorldMonitorKey: [] - ApiKeyHeader: [] - BearerAuth: [] parameters: - name: commodityId in: query description: Optional stable commodity mapping identifier. required: false example: "crude_oil" schema: type: string pattern: '^$|^[a-z0-9_\-]+$' - name: band in: query description: 'Optional score band: low, moderate, high, or critical.' required: false example: "high" schema: type: string pattern: '^$|^(low|moderate|high|critical)$' - name: state in: query description: 'Optional evidence state: ok, insufficient_data, or stale_input.' required: false example: "ok" schema: type: string pattern: '^$|^(ok|insufficient_data|stale_input)$' - name: pageSize in: query description: Maximum rows to return; zero uses the server default and the maximum is 25. required: false example: 25 schema: type: integer format: int32 - name: jmespath in: query description: |- Optional JMESPath expression applied server-side to project or reduce the JSON response before it is returned (mirrors the MCP jmespath argument). Invalid expressions, expressions larger than 1024 UTF-8 bytes, or projections that exceed the 256 KB output cap return HTTP 400 with a {_jmespath_error, original_keys} envelope. Grammar and worked examples: https://www.worldmonitor.app/docs/mcp-jmespath. required: false example: "keys(@)" schema: type: string responses: "200": description: Successful response content: application/json: example: "generatedAt": "2026-01-15T12:00:00Z" "methodologyVersion": "example" "upstreamUnavailable": false "vulnerabilities": - "band": "high" "commodity": "example" "commodityId": "crude_oil" "components": "buffer": "inputs": - "detail": "example" "fetchedAt": "2026-01-15T12:00:00Z" "sourceKey": "example" "sourceName": "WorldMonitor Analyst" "sourceUrl": "https://example.com/worldmonitor" "kind": "example" "state": "ok" "vulnerability": 1.5 "sourceConcentration": "coverage": "example" "importHhi": 1.5 "inputs": - "detail": "example" "fetchedAt": "2026-01-15T12:00:00Z" "sourceKey": "example" "sourceName": "WorldMonitor Analyst" "sourceUrl": "https://example.com/worldmonitor" "mineHhi": 1.5 "productionCoverage": "diesel" "transitExposure": "chokepoints": - "id": "example-id" "inputs": [] "name": "WorldMonitor Analyst" "status": "example" "transitShare": 1.5 "value": 1.5 "countryIso2": "US" schema: $ref: '#/components/schemas/ListVulnerabilityRankingsResponse' "400": description: Validation error content: application/json: schema: oneOf: - $ref: '#/components/schemas/ValidationError' - $ref: '#/components/schemas/JmespathProjectionError' "401": description: Missing or invalid API key. content: application/json: schema: $ref: '#/components/schemas/UnauthorizedError' "403": description: PRO entitlement access denied. headers: X-Billing-Verification: description: Present when the 403 is a billing-provider-confirmed subscription lapse (value subscription_lapsed, matching the body `code`). schema: type: string content: application/json: schema: $ref: '#/components/schemas/ForbiddenError' "429": description: Rate limit exceeded. headers: X-RateLimit-Limit: description: Maximum requests allowed in the active rate-limit window. schema: type: string X-RateLimit-Remaining: description: Requests remaining in the active rate-limit window. schema: type: string X-RateLimit-Reset: description: Unix epoch milliseconds when the active rate-limit window resets. schema: type: string Retry-After: description: Seconds to wait before retrying the request. schema: type: string content: application/json: schema: oneOf: - $ref: '#/components/schemas/Error' - $ref: '#/components/schemas/RateLimitError' "503": description: Service unavailable. Billing-verification responses include code and X-Billing-Verification; other gateway infrastructure failures use the generic GatewayError shape. headers: Retry-After: description: Seconds to wait before retrying (1-60). schema: type: string X-Billing-Verification: description: Billing-verification state that produced this response (matches the body `code`). schema: type: string X-Validation-Mode: description: Present with value degraded when user API-key validation is temporarily unavailable. schema: type: string X-RateLimit-Mode: description: Present with value degraded when a fail-closed rate-limit dependency is unavailable. schema: type: string content: application/json: schema: oneOf: - $ref: '#/components/schemas/BillingVerificationError' - $ref: '#/components/schemas/GatewayError' default: description: Gateway or handler error response. content: application/json: schema: oneOf: - $ref: '#/components/schemas/Error' - $ref: '#/components/schemas/GatewayError' components: securitySchemes: WorldMonitorKey: type: apiKey in: header name: X-WorldMonitor-Key description: User-issued WorldMonitor API key. ApiKeyHeader: type: apiKey in: header name: X-Api-Key description: Alias header for the WorldMonitor API key (X-WorldMonitor-Key). BearerAuth: type: http scheme: bearer description: 'Bearer token: a Clerk-issued JWT for browser session flows, passed as Authorization: Bearer .' schemas: ChinaCorridorControlTowerResponse: type: "object" description: "Canonical transparent China logistics corridor composition decoded from payloadJson." required: - "generatedAt" - "corridors" properties: generatedAt: type: "string" format: "date-time" corridors: type: "array" items: "$ref": "#/components/schemas/ChinaCorridorControlTower" ChinaCorridorControlTower: type: "object" required: - "id" - "name" - "description" - "boundary" - "nodes" - "availability" - "conditions" properties: id: type: "string" enum: - "china-yangtze-river-delta" - "china-greater-bay-area" - "china-bohai-rim" - "china-western-land-sea-corridor" name: type: "string" description: type: "string" boundary: type: "array" items: type: "object" required: - "lat" - "lon" properties: lat: type: "number" format: "double" lon: type: "number" format: "double" nodes: type: "array" items: type: "object" required: - "id" - "name" - "type" - "lat" - "lon" - "sourceOwner" properties: id: type: "string" name: type: "string" type: type: "string" enum: - "port" - "airport" - "crossing" - "industrial" lat: type: "number" format: "double" lon: type: "number" format: "double" sourceOwner: type: "string" sourceSelector: type: "object" required: - "family" - "id" properties: family: type: "string" enum: - "port" - "aviation" - "hazard" - "power_energy" - "strategic_industry" - "trade" id: type: "string" availability: type: "string" enum: - "available" - "partial" - "stale" - "unavailable" conditions: type: "array" items: "$ref": "#/components/schemas/ChinaCorridorCondition" ChinaCorridorCondition: type: "object" required: - "family" - "providerId" - "availability" - "reason" - "sourceSignals" - "provenance" properties: family: type: "string" enum: - "port" - "aviation" - "hazard" - "power_energy" - "strategic_industry" - "trade" providerId: type: "string" availability: type: "string" enum: - "available" - "partial" - "stale" - "unavailable" reason: type: - "string" - "null" sourceSignals: type: "array" items: type: "object" required: - "id" - "family" - "selectorId" - "availability" - "publisher" - "sourceUrl" - "sourceScope" - "observationTime" - "observationTimePrecision" - "releaseTime" - "releaseTimePrecision" - "retrievalTime" - "retrievalTimePrecision" - "revision" - "transportFreshness" - "contentFreshness" - "summary" - "metrics" properties: id: type: "string" family: type: "string" enum: - "port" - "aviation" - "hazard" - "power_energy" - "strategic_industry" - "trade" selectorId: type: "string" corridorIds: type: "array" items: type: "string" enum: - "china-yangtze-river-delta" - "china-greater-bay-area" - "china-bohai-rim" - "china-western-land-sea-corridor" availability: type: "string" enum: - "available" - "stale" - "unavailable" publisher: type: "object" required: - "id" - "name" - "type" properties: id: type: "string" name: type: "string" type: type: "string" enum: - "official" - "market" - "independent" - "derived" - "unknown" sourceUrl: type: - "string" - "null" format: "uri" sourceScope: type: "string" enum: - "node" - "regional" - "national" observationTime: type: - "string" - "null" observationTimePrecision: type: "string" enum: - "instant" - "day" - "month" - "year" - "unknown" releaseTime: type: - "string" - "null" releaseTimePrecision: type: "string" enum: - "instant" - "day" - "month" - "year" - "unknown" retrievalTime: type: - "string" - "null" retrievalTimePrecision: type: "string" enum: - "instant" - "day" - "month" - "year" - "unknown" revision: oneOf: - type: "object" required: - "vintageId" - "sequence" - "state" properties: vintageId: type: "string" sequence: type: "number" state: type: "string" enum: - "original" - "revised" - "corrected" - type: "null" transportFreshness: type: "string" enum: - "fresh" - "stale" - "missing" - "error" contentFreshness: type: "string" enum: - "current" - "stale" - "unavailable" - "partial" - "timestamp_unknown" summary: type: "string" metrics: type: "object" additionalProperties: type: - "string" - "number" - "boolean" - "null" provenance: oneOf: - "$ref": "#/components/schemas/ChinaCorridorProvenance" - type: "null" ChinaCorridorProvenance: type: "object" description: "The #5581 decision-signal provenance envelope retained for the composed condition." required: - "contractVersion" - "signalId" - "familyId" - "claims" properties: contractVersion: type: "string" const: "decision-signal-provenance/v1" signalId: type: "string" familyId: type: "string" const: "composed_corridor_condition" claims: type: "object" required: - "publisher" - "source_url" - "original_reference" - "original_language" - "translation" - "observation_time" - "effective_time" - "publication_time" - "retrieval_time" - "revision" - "supersession" - "extraction_confidence" - "classification_confidence" - "corroboration" - "transport_freshness" - "content_freshness" - "derivation" properties: publisher: oneOf: - type: "object" additionalProperties: false required: - "status" - "value" properties: status: type: "string" const: "known" value: type: "object" additionalProperties: false required: - "id" - "name" - "type" - "registryReference" properties: id: type: "string" minLength: 1 pattern: "\\S" name: type: "string" minLength: 1 pattern: "\\S" type: type: "string" enum: - "official_government" - "state_controlled_media" - "official_exchange" - "independent_observation" - "independent_media" - "wire_service" - "market_publisher" - "derived_output" - "unknown" registryReference: oneOf: - type: "object" additionalProperties: false required: - "sourceName" - "sourceType" - "propagandaRisk" properties: sourceName: type: "string" minLength: 1 pattern: "\\S" sourceType: type: "string" minLength: 1 pattern: "\\S" propagandaRisk: type: "string" minLength: 1 pattern: "\\S" - type: "null" oneOf: - properties: type: const: "derived_output" registryReference: type: "null" - properties: type: enum: - "official_government" - "state_controlled_media" - "official_exchange" - "independent_observation" - "independent_media" - "wire_service" - "market_publisher" - "unknown" registryReference: type: "object" additionalProperties: false required: - "sourceName" - "sourceType" - "propagandaRisk" properties: sourceName: type: "string" minLength: 1 pattern: "\\S" sourceType: type: "string" minLength: 1 pattern: "\\S" propagandaRisk: type: "string" minLength: 1 pattern: "\\S" - "$ref": "#/components/schemas/ChinaCorridorProvenanceClaim" source_url: oneOf: - type: "object" additionalProperties: false required: - "status" - "value" properties: status: type: "string" const: "known" value: type: "string" format: "uri" pattern: "^https://(?![^/?#]*@)[^/?#\\s]+(?:[/?#]\\S*)?$" - "$ref": "#/components/schemas/ChinaCorridorProvenanceClaim" original_reference: oneOf: - type: "object" additionalProperties: false required: - "status" - "value" properties: status: type: "string" const: "known" value: type: "object" additionalProperties: false required: - "kind" - "id" properties: kind: type: "string" enum: - "document" - "text" - "observation" - "event" - "dataset" id: type: "string" minLength: 1 pattern: "\\S" contentHash: type: "string" pattern: "^sha256:[a-f0-9]{64}$" - "$ref": "#/components/schemas/ChinaCorridorProvenanceClaim" original_language: oneOf: - type: "object" additionalProperties: false required: - "status" - "value" properties: status: type: "string" const: "known" value: type: "string" minLength: 1 pattern: "\\S" - "$ref": "#/components/schemas/ChinaCorridorProvenanceClaim" translation: oneOf: - type: "object" additionalProperties: false required: - "status" - "value" properties: status: type: "string" const: "known" value: type: "object" additionalProperties: false required: - "state" properties: state: type: "string" enum: - "unavailable" - "not_translated" - "machine_assisted" - "human_reviewed" targetLanguage: type: "string" minLength: 1 pattern: "\\S" oneOf: - properties: state: enum: - "machine_assisted" - "human_reviewed" required: - "targetLanguage" - properties: state: enum: - "unavailable" - "not_translated" not: required: - "targetLanguage" - "$ref": "#/components/schemas/ChinaCorridorProvenanceClaim" observation_time: oneOf: - type: "object" additionalProperties: false required: - "status" - "value" properties: status: type: "string" const: "known" value: type: "object" additionalProperties: false required: - "role" - "value" - "precision" properties: role: type: "string" const: "observation" value: oneOf: - type: "string" format: "date-time" pattern: "^(?:(?:\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|02-(?:0[1-9]|1\\d|2[0-8])))|(?:(?:\\d{2}(?:0[48]|[2468][048]|[13579][26])|(?:00|0[48]|[2468][048]|[13579][26])00)-02-29))T(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d{1,3})?Z$" - type: "string" format: "date" pattern: "^(?:(?:\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|02-(?:0[1-9]|1\\d|2[0-8])))|(?:(?:\\d{2}(?:0[48]|[2468][048]|[13579][26])|(?:00|0[48]|[2468][048]|[13579][26])00)-02-29))$" - type: "string" pattern: "^\\d{4}-(?:0[1-9]|1[0-2])$" - type: "string" pattern: "^\\d{4}$" precision: type: "string" enum: - "instant" - "day" - "month" - "year" oneOf: - properties: precision: const: "instant" value: type: "string" format: "date-time" pattern: "^(?:(?:\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|02-(?:0[1-9]|1\\d|2[0-8])))|(?:(?:\\d{2}(?:0[48]|[2468][048]|[13579][26])|(?:00|0[48]|[2468][048]|[13579][26])00)-02-29))T(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d{1,3})?Z$" - properties: precision: const: "day" value: type: "string" format: "date" pattern: "^(?:(?:\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|02-(?:0[1-9]|1\\d|2[0-8])))|(?:(?:\\d{2}(?:0[48]|[2468][048]|[13579][26])|(?:00|0[48]|[2468][048]|[13579][26])00)-02-29))$" - properties: precision: const: "month" value: type: "string" pattern: "^\\d{4}-(?:0[1-9]|1[0-2])$" - properties: precision: const: "year" value: type: "string" pattern: "^\\d{4}$" - "$ref": "#/components/schemas/ChinaCorridorProvenanceClaim" effective_time: oneOf: - type: "object" additionalProperties: false required: - "status" - "value" properties: status: type: "string" const: "known" value: type: "object" additionalProperties: false required: - "role" - "value" - "precision" properties: role: type: "string" const: "effective" value: oneOf: - type: "string" format: "date-time" pattern: "^(?:(?:\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|02-(?:0[1-9]|1\\d|2[0-8])))|(?:(?:\\d{2}(?:0[48]|[2468][048]|[13579][26])|(?:00|0[48]|[2468][048]|[13579][26])00)-02-29))T(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d{1,3})?Z$" - type: "string" format: "date" pattern: "^(?:(?:\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|02-(?:0[1-9]|1\\d|2[0-8])))|(?:(?:\\d{2}(?:0[48]|[2468][048]|[13579][26])|(?:00|0[48]|[2468][048]|[13579][26])00)-02-29))$" - type: "string" pattern: "^\\d{4}-(?:0[1-9]|1[0-2])$" - type: "string" pattern: "^\\d{4}$" precision: type: "string" enum: - "instant" - "day" - "month" - "year" oneOf: - properties: precision: const: "instant" value: type: "string" format: "date-time" pattern: "^(?:(?:\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|02-(?:0[1-9]|1\\d|2[0-8])))|(?:(?:\\d{2}(?:0[48]|[2468][048]|[13579][26])|(?:00|0[48]|[2468][048]|[13579][26])00)-02-29))T(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d{1,3})?Z$" - properties: precision: const: "day" value: type: "string" format: "date" pattern: "^(?:(?:\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|02-(?:0[1-9]|1\\d|2[0-8])))|(?:(?:\\d{2}(?:0[48]|[2468][048]|[13579][26])|(?:00|0[48]|[2468][048]|[13579][26])00)-02-29))$" - properties: precision: const: "month" value: type: "string" pattern: "^\\d{4}-(?:0[1-9]|1[0-2])$" - properties: precision: const: "year" value: type: "string" pattern: "^\\d{4}$" - "$ref": "#/components/schemas/ChinaCorridorProvenanceClaim" publication_time: oneOf: - type: "object" additionalProperties: false required: - "status" - "value" properties: status: type: "string" const: "known" value: type: "object" additionalProperties: false required: - "role" - "value" - "precision" properties: role: type: "string" const: "publication" value: oneOf: - type: "string" format: "date-time" pattern: "^(?:(?:\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|02-(?:0[1-9]|1\\d|2[0-8])))|(?:(?:\\d{2}(?:0[48]|[2468][048]|[13579][26])|(?:00|0[48]|[2468][048]|[13579][26])00)-02-29))T(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d{1,3})?Z$" - type: "string" format: "date" pattern: "^(?:(?:\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|02-(?:0[1-9]|1\\d|2[0-8])))|(?:(?:\\d{2}(?:0[48]|[2468][048]|[13579][26])|(?:00|0[48]|[2468][048]|[13579][26])00)-02-29))$" - type: "string" pattern: "^\\d{4}-(?:0[1-9]|1[0-2])$" - type: "string" pattern: "^\\d{4}$" precision: type: "string" enum: - "instant" - "day" - "month" - "year" oneOf: - properties: precision: const: "instant" value: type: "string" format: "date-time" pattern: "^(?:(?:\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|02-(?:0[1-9]|1\\d|2[0-8])))|(?:(?:\\d{2}(?:0[48]|[2468][048]|[13579][26])|(?:00|0[48]|[2468][048]|[13579][26])00)-02-29))T(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d{1,3})?Z$" - properties: precision: const: "day" value: type: "string" format: "date" pattern: "^(?:(?:\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|02-(?:0[1-9]|1\\d|2[0-8])))|(?:(?:\\d{2}(?:0[48]|[2468][048]|[13579][26])|(?:00|0[48]|[2468][048]|[13579][26])00)-02-29))$" - properties: precision: const: "month" value: type: "string" pattern: "^\\d{4}-(?:0[1-9]|1[0-2])$" - properties: precision: const: "year" value: type: "string" pattern: "^\\d{4}$" - "$ref": "#/components/schemas/ChinaCorridorProvenanceClaim" retrieval_time: oneOf: - type: "object" additionalProperties: false required: - "status" - "value" properties: status: type: "string" const: "known" value: type: "object" additionalProperties: false required: - "role" - "value" - "precision" properties: role: type: "string" const: "retrieval" value: oneOf: - type: "string" format: "date-time" pattern: "^(?:(?:\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|02-(?:0[1-9]|1\\d|2[0-8])))|(?:(?:\\d{2}(?:0[48]|[2468][048]|[13579][26])|(?:00|0[48]|[2468][048]|[13579][26])00)-02-29))T(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d{1,3})?Z$" - type: "string" format: "date" pattern: "^(?:(?:\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|02-(?:0[1-9]|1\\d|2[0-8])))|(?:(?:\\d{2}(?:0[48]|[2468][048]|[13579][26])|(?:00|0[48]|[2468][048]|[13579][26])00)-02-29))$" - type: "string" pattern: "^\\d{4}-(?:0[1-9]|1[0-2])$" - type: "string" pattern: "^\\d{4}$" precision: type: "string" enum: - "instant" - "day" - "month" - "year" oneOf: - properties: precision: const: "instant" value: type: "string" format: "date-time" pattern: "^(?:(?:\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|02-(?:0[1-9]|1\\d|2[0-8])))|(?:(?:\\d{2}(?:0[48]|[2468][048]|[13579][26])|(?:00|0[48]|[2468][048]|[13579][26])00)-02-29))T(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d{1,3})?Z$" - properties: precision: const: "day" value: type: "string" format: "date" pattern: "^(?:(?:\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|02-(?:0[1-9]|1\\d|2[0-8])))|(?:(?:\\d{2}(?:0[48]|[2468][048]|[13579][26])|(?:00|0[48]|[2468][048]|[13579][26])00)-02-29))$" - properties: precision: const: "month" value: type: "string" pattern: "^\\d{4}-(?:0[1-9]|1[0-2])$" - properties: precision: const: "year" value: type: "string" pattern: "^\\d{4}$" - "$ref": "#/components/schemas/ChinaCorridorProvenanceClaim" revision: oneOf: - type: "object" additionalProperties: false required: - "status" - "value" properties: status: type: "string" const: "known" value: type: "object" additionalProperties: false required: - "vintageId" - "sequence" - "state" properties: vintageId: type: "string" minLength: 1 pattern: "\\S" sequence: type: "integer" minimum: 1 state: type: "string" enum: - "preliminary" - "original" - "revised" - "corrected" oneOf: - properties: state: enum: - "preliminary" - "original" sequence: const: 1 - properties: state: enum: - "revised" - "corrected" sequence: type: "integer" minimum: 2 - "$ref": "#/components/schemas/ChinaCorridorProvenanceClaim" supersession: oneOf: - type: "object" additionalProperties: false required: - "status" - "value" properties: status: type: "string" const: "known" value: type: "object" additionalProperties: false required: - "state" properties: state: type: "string" enum: - "current" - "corrected" - "cancelled" - "superseded" relatedSignalId: type: "string" minLength: 1 pattern: "\\S" reason: type: "string" minLength: 1 pattern: "\\S" oneOf: - properties: state: const: "current" not: anyOf: - required: - "relatedSignalId" - required: - "reason" - properties: state: enum: - "corrected" - "superseded" required: - "relatedSignalId" - properties: state: const: "cancelled" required: - "reason" - "$ref": "#/components/schemas/ChinaCorridorProvenanceClaim" extraction_confidence: oneOf: - type: "object" additionalProperties: false required: - "status" - "value" properties: status: type: "string" const: "known" value: type: "object" additionalProperties: false required: - "score" - "method" properties: score: type: "number" minimum: 0 maximum: 1 method: type: "string" minLength: 1 pattern: "\\S" - "$ref": "#/components/schemas/ChinaCorridorProvenanceClaim" classification_confidence: oneOf: - type: "object" additionalProperties: false required: - "status" - "value" properties: status: type: "string" const: "known" value: type: "object" additionalProperties: false required: - "score" - "method" properties: score: type: "number" minimum: 0 maximum: 1 method: type: "string" minLength: 1 pattern: "\\S" - "$ref": "#/components/schemas/ChinaCorridorProvenanceClaim" corroboration: oneOf: - type: "object" additionalProperties: false required: - "status" - "value" properties: status: type: "string" const: "known" value: type: "object" additionalProperties: false required: - "state" - "sourceSignalIds" properties: state: type: "string" enum: - "single_source" - "multi_source" - "independently_corroborated" - "contradicted" sourceSignalIds: type: "array" uniqueItems: true items: type: "string" minLength: 1 pattern: "\\S" oneOf: - properties: state: const: "single_source" sourceSignalIds: type: "array" uniqueItems: true items: type: "string" minLength: 1 pattern: "\\S" minItems: 1 maxItems: 1 - properties: state: enum: - "multi_source" - "independently_corroborated" - "contradicted" sourceSignalIds: type: "array" minItems: 2 uniqueItems: true items: type: "string" minLength: 1 pattern: "\\S" - "$ref": "#/components/schemas/ChinaCorridorProvenanceClaim" transport_freshness: oneOf: - type: "object" additionalProperties: false required: - "status" - "value" properties: status: type: "string" const: "known" value: type: "object" additionalProperties: false required: - "state" - "assessedAt" properties: state: type: "string" enum: - "fresh" - "stale" - "missing" - "error" assessedAt: type: "string" format: "date-time" pattern: "^(?:(?:\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|02-(?:0[1-9]|1\\d|2[0-8])))|(?:(?:\\d{2}(?:0[48]|[2468][048]|[13579][26])|(?:00|0[48]|[2468][048]|[13579][26])00)-02-29))T(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d{1,3})?Z$" lastSuccessAt: type: "string" format: "date-time" pattern: "^(?:(?:\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|02-(?:0[1-9]|1\\d|2[0-8])))|(?:(?:\\d{2}(?:0[48]|[2468][048]|[13579][26])|(?:00|0[48]|[2468][048]|[13579][26])00)-02-29))T(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d{1,3})?Z$" - "$ref": "#/components/schemas/ChinaCorridorProvenanceClaim" content_freshness: oneOf: - type: "object" additionalProperties: false required: - "status" - "value" properties: status: type: "string" const: "known" value: type: "object" additionalProperties: false required: - "state" - "assessedAt" properties: state: type: "string" enum: - "current" - "stale" - "unavailable" - "partial" - "timestamp_unknown" assessedAt: type: "string" format: "date-time" pattern: "^(?:(?:\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|02-(?:0[1-9]|1\\d|2[0-8])))|(?:(?:\\d{2}(?:0[48]|[2468][048]|[13579][26])|(?:00|0[48]|[2468][048]|[13579][26])00)-02-29))T(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d{1,3})?Z$" contentAsOf: oneOf: - type: "string" format: "date-time" pattern: "^(?:(?:\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|02-(?:0[1-9]|1\\d|2[0-8])))|(?:(?:\\d{2}(?:0[48]|[2468][048]|[13579][26])|(?:00|0[48]|[2468][048]|[13579][26])00)-02-29))T(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d{1,3})?Z$" - type: "string" format: "date" pattern: "^(?:(?:\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|02-(?:0[1-9]|1\\d|2[0-8])))|(?:(?:\\d{2}(?:0[48]|[2468][048]|[13579][26])|(?:00|0[48]|[2468][048]|[13579][26])00)-02-29))$" - type: "string" pattern: "^\\d{4}-(?:0[1-9]|1[0-2])$" - type: "string" pattern: "^\\d{4}$" oneOf: - properties: state: enum: - "current" - "stale" required: - "contentAsOf" - properties: state: const: "timestamp_unknown" not: required: - "contentAsOf" - properties: state: enum: - "unavailable" - "partial" - "$ref": "#/components/schemas/ChinaCorridorProvenanceClaim" derivation: oneOf: - type: "object" additionalProperties: false required: - "status" - "value" properties: status: type: "string" const: "known" value: type: "object" additionalProperties: false required: - "methodId" - "methodVersion" - "computedAt" - "inputSignalIds" properties: methodId: type: "string" minLength: 1 pattern: "\\S" methodVersion: type: "string" minLength: 1 pattern: "\\S" computedAt: type: "string" format: "date-time" pattern: "^(?:(?:\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|02-(?:0[1-9]|1\\d|2[0-8])))|(?:(?:\\d{2}(?:0[48]|[2468][048]|[13579][26])|(?:00|0[48]|[2468][048]|[13579][26])00)-02-29))T(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d{1,3})?Z$" inputSignalIds: type: "array" minItems: 1 uniqueItems: true items: type: "string" minLength: 1 pattern: "\\S" - "$ref": "#/components/schemas/ChinaCorridorProvenanceClaim" ChinaCorridorProvenanceClaim: type: "object" additionalProperties: false required: - "status" - "reason" properties: status: type: "string" enum: - "unknown" - "not_applicable" reason: type: "string" JmespathProjectionError: description: Returned when a REST jmespath projection is invalid or exceeds the expression/output byte limits. properties: _jmespath_error: description: Projection error discriminator and details. type: string original_keys: description: Top-level keys or shape of the unprojected response. items: type: string type: array required: - _jmespath_error - original_keys type: object UnauthorizedError: type: object properties: error: type: string description: Human-readable error message. required: - error description: Returned when the API key is missing, malformed, or lacks current API access. 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. BillingVerificationError: type: object description: "Returned with HTTP 503 when paid access cannot be confirmed right now: the billing provider is re-verifying a recently expired subscription, or the entitlement backend is unreachable. Retryable — honor Retry-After." properties: error: type: string description: Human-readable billing-verification failure reason. code: type: string enum: - renewal_verification_pending - renewal_verification_failed - entitlement_verification_unavailable description: Machine-readable billing-verification state, mirrored in the X-Billing-Verification response header. requiredTier: type: integer format: int32 description: Minimum entitlement tier required for this endpoint, when the denial came from a tier gate. required: - error - code InvalidRequestBodyError: type: object description: Returned when a JSON POST request body is empty or malformed. properties: message: type: string description: Invalid request body required: - message GatewayError: type: object description: Returned by gateway infrastructure errors before an RPC handler runs, such as origin, routing, method, authentication, or quota checks. properties: error: oneOf: - type: string - type: object additionalProperties: true description: Gateway error reason or structured gateway failure details. required: - error RateLimitError: type: object description: Returned when a gateway or handler rate limit rejects the request. properties: error: type: string description: Human-readable rate-limit failure reason. required: - error ForbiddenError: type: object properties: error: type: string description: Human-readable entitlement failure reason. code: type: string enum: - subscription_lapsed description: Machine-readable denial code, present when the 403 is a billing-provider-confirmed subscription lapse (mirrored in the X-Billing-Verification response header). requiredTier: type: integer format: int32 description: Minimum entitlement tier required for this endpoint. currentTier: type: integer format: int32 description: Caller entitlement tier when known. planKey: type: string description: Caller plan key when known. required: - error description: Returned when a PRO-gated endpoint denies access because the caller has no resolved authenticated user, entitlements cannot be verified, or the caller lacks the required entitlement tier. 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 description: |- Legacy display field. For the Shanghai Shipping Exchange indices (SCFI, CCFI) this DELIBERATELY falls back to the current level when the exchange published no comparable prior, so it cannot distinguish "unchanged week" from "no prior at all". Use prior_period_value for decision work. changePct: type: number format: double description: |- Legacy display field with the same fail-OPEN fallback as previous_value (a flat 0 when no prior exists). Use period_change_pct for decision work. unit: type: string history: type: array items: $ref: '#/components/schemas/ShippingRatePoint' spikeAlert: type: boolean periodChangePct: type: number format: double description: |- Decision-grade period-over-period move in percent (#6066). Optional so a missing reading is ABSENT from the response rather than collapsing to 0, which would render identically to a real unchanged period. Fails CLOSED: present only when the publisher reported its own percentage or a comparable prior-period level. A single index level never becomes a change. The endpoint normalizes a missing reading to ABSENT (canonical ProtoJSON: serializers omit, parsers treat null as unset) — a plain JSON client can still tell absent from null, so read absence, not null. periodChangeBasis: type: string enum: - PERIOD_CHANGE_BASIS_UNSPECIFIED - publisher_reported - derived_from_prior_period_level description: Basis for the decision-grade period-over-period change. priorPeriodValue: type: number format: double description: |- The publisher's own prior-period index level that period_change_pct was measured against. Absent when the publisher shipped no comparable prior. priorPeriodDate: type: string description: |- Observation date (YYYY-MM-DD) of prior_period_value, as published. Absent whenever prior_period_value is absent, or when the publisher dated the level only implicitly. 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 description: |- ISO-8601 time the status snapshot was fetched. Empty string with upstream_unavailable=true means the snapshot is unavailable/degraded. upstreamUnavailable: type: boolean description: |- True when upstream seed/relay data is unavailable or partial. When true, an empty chokepoints array is graceful degradation, not confirmed zero data. 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 description: |- Traffic-light score badge: green (<20), yellow (20-49), or red (>=50). Not an operational closure taxonomy. activeWarnings: type: integer format: int32 congestionLevel: type: string description: |- AIS-derived congestion level. "normal" is an observed AIS level, not a default. Empty when ais_snapshot_available is false. affectedRoutes: type: array items: type: string description: type: string aisDisruptions: type: integer format: int32 directions: type: array items: type: string directionalDwt: deprecated: true 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. Free field (no PRO gate). navigationalWarningsAvailable: type: boolean description: |- True when the NGA navigational-warning source returned a valid response, empty list included; a missing value fails closed. aisSnapshotAvailable: type: boolean description: |- True when the AIS snapshot source returned a valid response; owns ais_disruptions and congestion_level. A missing value fails closed. 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 PortWatch returned no history this cycle; wow_change_pct, history and official_*/baseline_* are then zero-state fill. todayCountsAvailable: type: boolean description: |- False when the relay's 24h AIS window held no crossings; today_* are then unsupplied, not a measured zero. officialLatestDate: type: string description: |- IMF PortWatch latest published day, YYYY-MM-DD (lag of several days); empty means withhold official_latest_total and official_avg_7d (absent below 7 days). officialLatestTotal: type: integer format: int32 officialAvg7d: type: number format: double baselineAvgDaily: type: number format: double description: |- Mean daily transits, 12 months ending a year before the seed; 0 means withhold. baseline_from/to: YYYY-MM-DD bounds, inclusive. baselineFrom: type: string baselineTo: type: string 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 description: |- Current estimated flow in million barrels/day. Computed as baseline_mbd * flow_ratio. baselineMbd: type: number format: double description: |- EIA 2023 annual reference level in million barrels/day for the mapped seven-item live-flow subset. flowRatio: type: number format: double description: |- Latest 7-day PortWatch average divided by the preceding rolling baseline window of up to 90 days, clamped to 0.0-1.5. disrupted: type: boolean description: |- True when each of the latest 3 daily ratios is below 85% of the same rolling baseline window. Separate from the green/yellow/red status badge. source: type: string enum: - FLOW_SOURCE_UNSPECIFIED - portwatch-dwt - portwatch-counts description: |- Coverage basis behind a PortWatch-derived flow estimate: "portwatch-dwt" when the rolling baseline window has DWT-majority coverage, otherwise "portwatch-counts" for vessel-count coverage. FLOW_SOURCE_UNSPECIFIED means the cached estimate carried a basis this taxonomy does not list, which the endpoint reports rather than passing through undeclared. hazardAlertLevel: type: string description: |- Nearest active GDACS hazard alert level within the configured radius: "RED", "ORANGE", or empty string when no nearby alert applies. hazardAlertName: type: string description: |- Name of the nearest active GDACS hazard event within the configured radius, or empty string when no nearby alert applies. latestDate: type: string description: Last PortWatch day behind flow_ratio, YYYY-MM-DD; may be empty. GetChokepointHistoryRequest: type: object properties: chokepointId: type: string description: Chokepoint identifier whose transit history should be returned. 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 GetMineralProductionRequest: type: object properties: commodity: type: string description: USGS commodity id or label (e.g. "cobalt"). Empty returns every commodity. iso2: type: string description: |- ISO 3166-1 alpha-2. When set, countries[] is scoped to this producer and the countries portfolio is populated. stage: type: string description: '"mine" or "refinery". Empty returns both stages when present.' GetMineralProductionResponse: type: object properties: commodities: type: array items: $ref: '#/components/schemas/MineralProductionRecord' countries: type: array items: $ref: '#/components/schemas/MineralCountryPortfolio' fetchedAt: type: string upstreamUnavailable: type: boolean dataYear: type: integer format: int32 MineralProductionRecord: type: object properties: commodityId: type: string commodity: type: string year: type: integer format: int32 unit: type: string mine: $ref: '#/components/schemas/MineralStageSnapshot' refinery: $ref: '#/components/schemas/MineralStageSnapshot' sources: type: array items: type: string MineralStageSnapshot: type: object properties: year: type: integer format: int32 unit: type: string countries: type: array items: $ref: '#/components/schemas/MineralCountryShare' hhi: type: number format: double worldTotal: type: number format: double withheldCount: type: integer format: int32 MineralCountryShare: type: object properties: iso2: type: string country: type: string output: type: number format: double share: type: number format: double withheld: type: boolean estimated: type: boolean residual: type: boolean MineralCountryPortfolio: type: object properties: iso2: type: string holdings: type: array items: $ref: '#/components/schemas/MineralCountryHolding' MineralCountryHolding: type: object properties: commodityId: type: string commodity: type: string stage: type: string output: type: number format: double share: type: number format: double withheld: type: boolean GetShippingStressRequest: type: object GetShippingStressResponse: type: object properties: carriers: type: array items: $ref: '#/components/schemas/ShippingStressCarrier' stressScore: type: number format: double description: Composite stress score 0–100 (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 0-100: top1 * 0.5 + top2 * 0.3 + top3 * 0.2.' 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 0-100; higher = more dependent on this chokepoint. With bilateral product data, sums routeCoverage * exporterShare * productWeight * 100 across matching products; fallback uses route overlap only. HS2 27 supported energy chokepoints receive a 1.5x boost capped at 100. 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 description: Chokepoint identifier to evaluate for bypass options. 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. Free field (no PRO gate). 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. Free field (no PRO gate). notes: type: string GetCountryCostShockRequest: type: object properties: iso2: type: string pattern: ^[A-Z]{2}$ description: ISO 3166-1 alpha-2 country code for the importing country. chokepointId: type: string description: Chokepoint identifier to model as disrupted. 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 at the pre-crisis Gulf crude share, after bypass rerouting for Hormuz when per-exporter shares exist (average over the products among Gasoline/Diesel/Jet fuel/LPG/Naphtha with recorded positive demand; 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. Free field (no PRO gate). 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}$ description: ISO 3166-1 alpha-2 country code whose strategic products should be returned. hs4: type: string description: Optional requested heading; permits bounded recovery of a missing product. 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). evidence: $ref: '#/components/schemas/CountryProductEvidence' 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 denominatorBasis: type: string description: |- Share denominator: "reported_world" (the provider's World import total for this heading and year) or "observed_partners" (the sum of observed partner values). Absent on legacy rows, whose denominator is unverified. fetchedAt: type: string description: |- ISO timestamp this heading alone was fetched at. Present only on a heading recovered on demand, whose fetch time differs from the payload's. partnerBasis: type: string description: |- How top_exporters was selected: "share_threshold" (every origin at or above 1% of the denominator, padded to 5 and capped at 25; served only for the requested hs4) or "leading_5" (the canonical leading five). Always present on a served row. omittedPartnerCount: type: integer format: int32 description: |- Origins ranked below the ones shown. Absent under "leading_5", where the omitted set is not measured. omittedPartnerShare: type: number format: double description: Combined share of the omitted origins, 0-1. Absent under "leading_5". ProductExporter: type: object properties: partnerCode: type: integer format: int32 partnerIso2: type: string value: type: number format: double share: type: number format: double netWeightKg: type: number format: double description: |- Net weight of the shown flow in kilograms. Absent when the provider reported no weight; "not reported" is never rendered as 0 trade. netWeightEstimated: type: boolean description: True when the provider flagged the net weight as its own estimate. quantity: type: number format: double description: |- Reported quantity in the unit named by quantity_unit_code. Absent when no quantity was reported or its unit is outside the pinned unit registry. quantityUnitCode: type: integer format: int32 description: |- UN Comtrade quantity unit code (8 = kg, 12 = m3, 5 = items, 7 = litres). Absent whenever quantity is absent. scale: $ref: '#/components/schemas/ExporterScale' ExporterScale: type: object properties: worldExportsUsd: type: number format: double description: Reported world exports of this heading by this origin, in USD. worldExportsKg: type: number format: double description: |- Reported world-export weight in kilograms. Absent when the origin reported no weight (the provider writes 0 for "not reported"), never 0 for absent. rank: type: integer format: int32 description: |- 1-based position by value among the reporters that filed this heading for `year` (see reporter_count), not among every world exporter. year: type: integer format: int32 description: |- Trade observation year of the world-export figures, not the fetch year. Always equal to the row's year: a scale from another year is not attached. reporterCount: type: integer format: int32 description: 'Reporters ranked for this heading and year: rank is out of this many.' unrankedReporterCount: type: integer format: int32 description: |- Reporters whose newest filing for this heading predates `year` (late filers or lapsed exporters). They are left out of the ranking, so one that files later can move every rank below it. Absent on a snapshot written before the count was recorded. description: |- An origin's reported world exports of the same heading, so a shown share can be read against the supplier's total capacity rather than this importer alone. CountryProductEvidence: type: object properties: state: type: string description: |- Reader state: "observed", "partial" (some catalogue headings absent, which includes a response holding only a heading recovered on demand), "stale_preserved" (older than 35 days; last-good data kept), "cache_unavailable", or, when no payload exists and nothing was recovered, the last attempt state (see last_attempt_state) or "missing". source: type: string description: |- Retrieval route of the cached payload; with no payload, the single-heading recovery route when a heading was recovered, else a legacy-cache label. requestedHs4s: type: array items: type: string description: HS4 headings the producing request asked for; empty when unknown (legacy cache). missingHs4s: type: array items: type: string description: Catalogue headings with no usable product row. lastAttemptAt: type: string description: ISO timestamp of the last refresh attempt; empty when unknown. lastAttemptState: type: string description: |- Result of the last refresh attempt: "observed", "no_records", "legacy_no_records", "unsupported_reporter", "rate_limited", "unavailable", "malformed", "incomplete", "regression_rejected", "cache_unavailable", "cache_write_failed", "busy", "not_attempted", "preserved_reason_unknown" or "unknown". recoveredHs4s: type: array items: type: string description: |- Headings served from an on-demand single-heading fetch rather than the stored payload. Empty when every row came from the stored payload. worldExportsFetchedAt: type: string description: |- ISO timestamp of the world-export snapshot the scale figures came from. Absent when no snapshot is cached or no hs4 was requested, in which case no row carries a scale. description: Cache evidence for the returned products. Missing data is not zero trade. GetMultiSectorCostShockRequest: type: object properties: iso2: type: string pattern: ^[A-Z]{2}$ description: ISO 3166-1 alpha-2 country code for the importing country. chokepointId: type: string description: Chokepoint identifier to model as disrupted. 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. Free field (no PRO gate). 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}$ description: ISO 3166-1 alpha-2 country code whose sector dependency should be analyzed. 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 (0–1). 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 (0–100). 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}$ description: ISO 3166-1 alpha-2 origin country code for the trade lane. toIso2: type: string pattern: ^[A-Z]{2}$ description: ISO 3166-1 alpha-2 destination country code for the trade lane. 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}$ description: ISO 3166-1 alpha-2 origin country code for the route. toIso2: type: string pattern: ^[A-Z]{2}$ description: ISO 3166-1 alpha-2 destination country code for the route. hs2: type: string description: HS2 chapter code for the product sector on the route. 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 description: Pipeline identifier to load with full evidence details. 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 description: Storage facility identifier to load with full evidence details. 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 description: Fuel-shortage identifier to load with full evidence details. 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 countries: type: array items: type: string description: |- Countries touched by the referenced asset (pipeline: fromCountry + toCountry + transitCountries; storage: country). Denormalised at seed time so CountryDeepDivePanel can filter events without a second RPC. Always non-empty in well-formed payloads; empty only if the upstream asset was removed without an event update. Per plan §R/#5 decision B. EnergyDisruptionSource: type: object properties: authority: type: string title: type: string url: type: string date: type: string sourceType: type: string GetChinaCorridorControlTowersRequest: type: object GetChinaCorridorControlTowersResponse: type: object properties: payloadJson: contentMediaType: "application/json" contentSchema: $ref: "#/components/schemas/ChinaCorridorControlTowerResponse" type: string description: |- Canonical JSON keeps the shared #5581 provenance envelope byte-for-byte equivalent across cache, API, UI, and later MCP adapters. generatedAt: type: string upstreamUnavailable: description: "True only when every reviewed corridor is unavailable. Agents and API callers must treat true as upstream degradation, not as evidence that corridor conditions are normal or zero." type: boolean GetCountryVulnerabilitiesRequest: type: object properties: iso2: type: string pattern: ^[A-Z]{2}$ description: Uppercase ISO 3166-1 alpha-2 country code. required: - iso2 GetCountryVulnerabilitiesResponse: type: object properties: iso2: type: string description: Uppercase ISO 3166-1 alpha-2 code for the requested country. country: type: string description: Human-readable name of the requested country. vulnerabilities: type: array items: $ref: '#/components/schemas/CommodityVulnerability' generatedAt: type: string description: ISO 8601 timestamp when the country index was generated. methodologyVersion: type: string description: Version of the scoring methodology used for every row. upstreamUnavailable: type: boolean description: True when the published country index could not be read. CommodityVulnerability: type: object properties: countryIso2: type: string description: ISO 3166-1 alpha-2 code for the scored country. countryName: type: string description: English display name for the scored country. commodityId: type: string description: Stable reviewed commodity mapping identifier. commodity: type: string description: Human-readable commodity name. score: type: number format: double description: Vulnerability score from 0 to 100; absent when evidence is insufficient. band: type: string description: 'Score band: low, moderate, high, or critical; empty when the score is absent.' components: $ref: '#/components/schemas/VulnerabilityComponents' coverage: type: array items: type: string description: Source coverage labels that contributed to this score. state: type: string description: 'Evidence state: ok, insufficient_data, or stale_input.' reasons: type: array items: type: string description: Machine-readable explanations for an insufficient or stale state. methodologyVersion: type: string description: Version of the scoring methodology that produced this row. VulnerabilityComponents: type: object properties: sourceConcentration: $ref: '#/components/schemas/VulnerabilitySourceConcentration' transitExposure: $ref: '#/components/schemas/VulnerabilityTransitExposure' buffer: $ref: '#/components/schemas/VulnerabilityBuffer' VulnerabilitySourceConcentration: type: object properties: value: type: number format: double description: Combined supplier or producer concentration from 0 to 1. importHhi: type: number format: double description: Import supplier Herfindahl-Hirschman concentration from 0 to 1. mineHhi: type: number format: double description: Mine-stage production concentration from 0 to 1. refineryHhi: type: number format: double description: Refinery-stage production concentration from 0 to 1. productionHhi: type: number format: double description: Combined mine and refinery production concentration from 0 to 1. productionCoverage: type: string description: Producer-stage coverage used for the combined concentration. coverage: type: string description: Overall concentration coverage state. inputs: type: array items: $ref: '#/components/schemas/VulnerabilityInput' VulnerabilityInput: type: object properties: sourceKey: type: string description: Redis or source-contract key that supplied this observation. sourceName: type: string description: Human-readable source name. sourceUrl: type: string description: Public source or methodology URL. value: type: number format: double description: Numeric observation used by the scorer; absent when the source is unknown. year: type: integer format: int32 description: Observation year when the source publishes annual data. fetchedAt: type: string description: ISO 8601 timestamp when the source snapshot was fetched. stale: type: boolean description: True when this observation is older than its source-specific freshness budget. detail: type: string description: Bounded explanation of the mapped input. VulnerabilityTransitExposure: type: object properties: value: type: number format: double description: Combined chokepoint exposure from 0 to 1. chokepoints: type: array items: $ref: '#/components/schemas/VulnerabilityTransitRoute' VulnerabilityTransitRoute: type: object properties: id: type: string description: Stable chokepoint identifier. name: type: string description: Human-readable chokepoint name. transitShare: type: number format: double description: Country and commodity exposure share using this route, from 0 to 1. weightedTransitShare: type: number format: double description: Transit share after the current disruption multiplier, from 0 to 1. status: type: string description: 'Current route state: baseline, disrupted, or unknown when the flow row is absent.' inputs: type: array items: $ref: '#/components/schemas/VulnerabilityInput' VulnerabilityBuffer: type: object properties: state: type: string description: 'Buffer evidence state: known or unknown.' vulnerability: type: number format: double description: Residual vulnerability after the available buffer, from 0 to 1. kind: type: string description: Buffer source class, such as stocks_to_use or gas_storage_fill. inputs: type: array items: $ref: '#/components/schemas/VulnerabilityInput' GetChokepointDependenciesRequest: type: object properties: chokepointId: type: string maxLength: 80 minLength: 1 pattern: ^[a-z0-9_\-]+$ description: Stable chokepoint identifier, such as hormuz_strait or suez. pageSize: type: integer maximum: 100 minimum: 0 format: int32 description: Maximum dependencies to return; zero uses the server default and the maximum is 100. required: - chokepointId GetChokepointDependenciesResponse: type: object properties: chokepointId: type: string description: Stable identifier of the requested chokepoint. chokepoint: type: string description: Human-readable chokepoint name. dependencies: type: array items: $ref: '#/components/schemas/ChokepointDependency' generatedAt: type: string description: ISO 8601 timestamp when the inverse index was generated. methodologyVersion: type: string description: Version of the scoring methodology used for every dependency. upstreamUnavailable: type: boolean description: True when the published inverse index could not be read. ChokepointDependency: type: object properties: countryIso2: type: string description: ISO 3166-1 alpha-2 code for the exposed country. countryName: type: string description: English display name for the exposed country. commodityId: type: string description: Stable reviewed commodity mapping identifier. commodity: type: string description: Human-readable commodity name. transitShare: type: number format: double description: Share of the country's mapped commodity exposure using this chokepoint, from 0 to 1. weightedTransitShare: type: number format: double description: Disruption-adjusted transit share, from 0 to 1. score: type: number format: double description: Commodity vulnerability score from 0 to 100; absent when evidence is insufficient. band: type: string description: 'Score band: low, moderate, high, or critical; empty when the score is absent.' state: type: string description: 'Evidence state: ok, insufficient_data, or stale_input.' reasons: type: array items: type: string description: Machine-readable explanations for an insufficient or stale state. methodologyVersion: type: string description: Version of the scoring methodology that produced this dependency. ListVulnerabilityRankingsRequest: type: object properties: commodityId: type: string maxLength: 80 pattern: ^$|^[a-z0-9_\-]+$ description: Optional stable commodity mapping identifier. band: type: string pattern: ^$|^(low|moderate|high|critical)$ description: 'Optional score band: low, moderate, high, or critical.' state: type: string pattern: ^$|^(ok|insufficient_data|stale_input)$ description: 'Optional evidence state: ok, insufficient_data, or stale_input.' pageSize: type: integer maximum: 25 minimum: 0 format: int32 description: Maximum rows to return; zero uses the server default and the maximum is 25. ListVulnerabilityRankingsResponse: type: object properties: vulnerabilities: type: array items: $ref: '#/components/schemas/CommodityVulnerability' generatedAt: type: string description: ISO 8601 timestamp when the country index was generated. methodologyVersion: type: string description: Version of the scoring methodology used for every row. upstreamUnavailable: type: boolean description: True when the published country index could not be read.