openapi: 3.1.0 info: title: ForecastService API version: 1.0.0 security: - WorldMonitorKey: [] - ApiKeyHeader: [] servers: - url: https://api.worldmonitor.app paths: /api/forecast/v1/get-forecasts: get: tags: - ForecastService summary: GetForecasts description: GetForecasts returns the latest generated probabilistic forecasts; the degraded flag distinguishes a backend outage from a healthy empty set. operationId: GetForecasts parameters: - name: domain in: query description: Forecast domain to retrieve, such as geopolitics, markets, or climate. required: false example: "conflict" schema: type: string enum: - 'conflict' - 'market' - 'supply_chain' - 'political' - 'military' - 'cyber' - 'infrastructure' - name: region in: query description: Optional geographic or thematic region filter for forecasts. 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: "degraded": true "error": "example" "forecasts": - "calibration": "drift": 1.5 "internalProbability": 0.62 "marketBlendedProbability": 0.62 "marketPrice": 75.25 "marketTitle": "example" "cascades": - "domain": "example" "effect": "example" "probability": 0.62 "caseFile": "actorLenses": - "example" "actors": - "category": "cs.AI" "constraints": - "example" "id": "example-id" "influenceScore": 42.5 "likelyActions": - "example" "baseCase": "example" "branches": - "kind": "example" "outcome": "example" "projectedProbability": 0.62 "rounds": - {} "summary": "Example WorldMonitor observation." "changeItems": - "example" "confidence": 0.82 "createdAt": 1717200000000 "generatedAt": 1717200000000 "stale": true schema: $ref: '#/components/schemas/GetForecastsResponse' "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/forecast/v1/get-forecast-scorecard: get: tags: - ForecastService summary: GetForecastScorecard description: GetForecastScorecard returns the latest forecast resolution scorecard; degraded distinguishes a backend outage from a healthy empty scorecard. operationId: GetForecastScorecard 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: "byDomain": - "brier": 1.5 "domain": "example" "logScore": 42.5 "resolved": 1 "scored": 42 "byGenerationOrigin": - "brier": 1.5 "generationOrigin": "example" "logScore": 42.5 "resolved": 1 "scored": 42 "calibration": - "brier": 1.5 "bucket": "example" "count": 1 "maxProbability": 0.62 "minProbability": 0.62 "degraded": true "error": "example" schema: $ref: '#/components/schemas/GetForecastScorecardResponse' "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/forecast/v1/get-simulation-package: get: tags: - ForecastService summary: GetSimulationPackage description: GetSimulationPackage returns the latest forecast simulation package; the response note is populated when a supplied runId does not match the returned package. operationId: GetSimulationPackage parameters: - name: runId in: query description: |- Optional run identifier. It does not select a package yet: the latest is always returned, and note says when it differs. required: false 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: "error": "example" "found": true "generatedAt": 1717200000000 "note": "example" "runId": "example-id" schema: $ref: '#/components/schemas/GetSimulationPackageResponse' "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/forecast/v1/get-simulation-outcome: get: tags: - ForecastService summary: GetSimulationOutcome description: |- GetSimulationOutcome returns the latest forecast simulation outcome, refreshed about hourly. The response note is set when a supplied runId does not match. operationId: GetSimulationOutcome parameters: - name: runId in: query description: |- Optional run ID (epoch ms, hyphen, 1-64 char suffix; max 128). Returns that run's outcome within 24h retention, processing=true while it is queued, or the latest outcome with a note. Empty returns the latest outcome. required: false "schema": "type": "string" "maxLength": 128 "pattern": "^([0-9]{13,}-[A-Za-z0-9-]{1,64})?$" "example": "1789387200000-abc123" example: "1789387200000-abc123" - 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: "allTheatersFailed": true "completionStatus": "example" "eligibleTheaterCount": 1 "error": "example" "failedTheaterCount": 1 schema: $ref: '#/components/schemas/GetSimulationOutcomeResponse' "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/forecast/v1/trigger-simulation: post: parameters: - name: Idempotency-Key in: header description: Optional client-generated idempotency key. Retrying a POST with the same key and an identical request body replays the original response (only the status, body, and Content-Type are reproduced) instead of re-executing; reusing the key with a different body is rejected with 422. For mutations this avoids duplicating the side effect, while for batch-read POSTs it replays a cached snapshot that can be up to 24 hours stale. Keys are scoped per authenticated caller (falling back to the source IP for unauthenticated endpoints) and retained for 24 hours. required: false example: "4f8b9c2e-1a3d-4b6f-8e0a-2c5d7f9b1e34" schema: type: string minLength: 1 maxLength: 255 pattern: "^[\\x21-\\x7E]{1,255}$" tags: - ForecastService summary: TriggerSimulation description: |- TriggerSimulation enqueues a simulation run for the current package outside the hourly cycle. PRO-gated. Poll GetSimulationOutcome with the returned runId. Requires entitlement tier >= 1. operationId: TriggerSimulation security: - WorldMonitorKey: [] - ApiKeyHeader: [] - BearerAuth: [] requestBody: content: application/json: example: "clientVersion": "example" schema: $ref: '#/components/schemas/TriggerSimulationRequest' required: true responses: "200": description: Successful response headers: Idempotency-Key: schema: type: string description: The idempotency key echoed from the request. Present only when the client opted into idempotency. Idempotent-Replayed: schema: type: boolean description: true when this response was replayed from an earlier request with the same key, false on the first (original) request. Present only when the client opted into idempotency. content: application/json: example: "pkgFingerprint": "example" "queued": true "reason": "example" "runId": "example-id" schema: $ref: '#/components/schemas/TriggerSimulationResponse' "400": description: Validation error, invalid Idempotency-Key header, or malformed JSON request body content: application/json: schema: oneOf: - $ref: '#/components/schemas/ValidationError' - type: object required: - error - message properties: error: type: string message: type: string - $ref: '#/components/schemas/InvalidRequestBodyError' "409": description: A request with this Idempotency-Key is still being processed headers: Idempotency-Key: schema: type: string description: The idempotency key supplied by the client. Retry-After: schema: type: string description: Seconds to wait before retrying the in-flight request. content: application/json: schema: type: object required: - error - message properties: error: type: string message: type: string "422": description: The Idempotency-Key was already used with a different request body headers: Idempotency-Key: schema: type: string description: The idempotency key supplied by the client. content: application/json: schema: type: object required: - error - message properties: error: type: string message: type: string "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: 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. GetForecastsRequest: type: object properties: domain: type: string description: Forecast domain to retrieve, such as geopolitics, markets, or climate. region: type: string description: Optional geographic or thematic region filter for forecasts. GetForecastsResponse: type: object properties: forecasts: type: array items: $ref: '#/components/schemas/Forecast' generatedAt: type: integer format: int64 description: 'Warning: Values > 2^53 may lose precision in JavaScript' degraded: type: boolean description: |- True when the forecast backend could not read the canonical cache. Distinguishes an outage from a healthy empty forecast set. stale: type: boolean description: 'Always false: get-forecasts has no stale fallback.' error: type: string description: |- Stable machine-readable reason when degraded=true, empty otherwise. Value: "forecast_backend_unavailable" on Redis/backend read failures. Forecast: type: object properties: id: type: string domain: type: string region: type: string title: type: string scenario: type: string feedSummary: type: string probability: type: number format: double confidence: type: number format: double timeHorizon: type: string signals: type: array items: $ref: '#/components/schemas/ForecastSignal' cascades: type: array items: $ref: '#/components/schemas/CascadeEffect' trend: type: string description: |- "rising", "falling", or "stable" versus the prior snapshot, with a +/-0.05 deadband on the probability delta. priorProbability: type: number format: double calibration: $ref: '#/components/schemas/CalibrationInfo' createdAt: type: integer format: int64 description: 'Warning: Values > 2^53 may lose precision in JavaScript' updatedAt: type: integer format: int64 description: 'Warning: Values > 2^53 may lose precision in JavaScript' perspectives: $ref: '#/components/schemas/Perspectives' projections: deprecated: true $ref: '#/components/schemas/Projections' caseFile: $ref: '#/components/schemas/ForecastCase' simulationAdjustment: type: number format: double description: |- Score delta from the deep simulation pipeline: +0.08 to +0.12, or -0.12 or -0.15; 0 when it has not run. simPathConfidence: type: number format: double description: Confidence in [0, 1] of the matched simulation top path; 0 when not set. demotedBySimulation: type: boolean description: True when a negative adjustment crossed the 0.50 acceptance threshold. resolution: $ref: '#/components/schemas/ResolutionSpec' scoredHorizons: type: array items: type: string description: Horizons whose projection is graded. ForecastSignal: type: object properties: type: type: string value: type: string weight: type: number format: double CascadeEffect: type: object properties: domain: type: string effect: type: string probability: type: number format: double CalibrationInfo: type: object properties: marketTitle: type: string marketPrice: type: number format: double drift: type: number format: double source: type: string internalProbability: type: number format: double description: Probability before the market blend. marketBlendedProbability: type: number format: double description: Probability after the market blend and domain cap. Perspectives: type: object properties: strategic: type: string regional: type: string contrarian: type: string Projections: type: object properties: h24: type: number format: double d7: type: number format: double d30: type: number format: double description: |- Deprecated (#8967): newly seeded payloads omit it; a payload cached before the change may carry it until the next seed-forecasts run. ForecastCase: type: object properties: supportingEvidence: type: array items: $ref: '#/components/schemas/ForecastCaseEvidence' counterEvidence: type: array items: $ref: '#/components/schemas/ForecastCaseEvidence' triggers: type: array items: type: string actorLenses: type: array items: type: string baseCase: type: string escalatoryCase: type: string contrarianCase: type: string changeSummary: type: string changeItems: type: array items: type: string actors: type: array items: $ref: '#/components/schemas/ForecastActor' worldState: $ref: '#/components/schemas/ForecastWorldState' branches: type: array items: $ref: '#/components/schemas/ForecastBranch' ForecastCaseEvidence: type: object properties: type: type: string summary: type: string weight: type: number format: double ForecastActor: type: object properties: id: type: string name: type: string category: type: string role: type: string objectives: type: array items: type: string constraints: type: array items: type: string likelyActions: type: array items: type: string influenceScore: type: number format: double ForecastWorldState: type: object properties: summary: type: string activePressures: type: array items: type: string stabilizers: type: array items: type: string keyUnknowns: type: array items: type: string ForecastBranch: type: object properties: kind: type: string title: type: string summary: type: string outcome: type: string projectedProbability: type: number format: double rounds: type: array items: $ref: '#/components/schemas/ForecastBranchRound' ForecastBranchRound: type: object properties: round: type: integer format: int32 focus: type: string developments: type: array items: type: string actorMoves: type: array items: type: string probabilityShift: type: number format: double ResolutionSpec: type: object properties: kind: type: string metricKey: type: string operator: type: string threshold: type: number format: double baselineValue: type: number format: double window: type: string deadline: type: integer format: int64 description: 'Warning: Values > 2^53 may lose precision in JavaScript' sourceFeed: type: string question: type: string required: - kind - deadline description: |- Resolution spec that makes a forecast scoreable. kind is "hard" (resolved by comparing metric_key from source_feed to threshold with operator ">=", "<=" or "crosses") or "judged" (an LLM judge answers question). Other fields apply per kind. baseline_value applies only to "crosses" specs. A judged spec's threshold is absent, never 0. GetForecastScorecardRequest: type: object GetForecastScorecardResponse: type: object properties: schemaVersion: type: integer format: int32 generatedAt: type: integer format: int64 description: 'Warning: Values > 2^53 may lose precision in JavaScript' rollingWindowDays: type: integer format: int32 methodology: type: string totals: $ref: '#/components/schemas/ScorecardTotals' overall: $ref: '#/components/schemas/ScorecardSummary' byDomain: type: array items: $ref: '#/components/schemas/ScorecardDomainGroup' byGenerationOrigin: type: array items: $ref: '#/components/schemas/ScorecardGenerationOriginGroup' calibration: type: array items: $ref: '#/components/schemas/ScorecardCalibrationBucket' vsMarketSkill: $ref: '#/components/schemas/ScorecardMarketSkill' degraded: type: boolean stale: type: boolean error: type: string skill: $ref: '#/components/schemas/ScorecardSkill' publishedByDomain: type: array items: $ref: '#/components/schemas/ScorecardPublishedDomain' uncertainty: $ref: '#/components/schemas/ScorecardUncertainty' funnel: $ref: '#/components/schemas/ScorecardFunnel' receipts: type: array items: $ref: '#/components/schemas/ScorecardReceipt' marketAlerts: $ref: '#/components/schemas/MarketAlertScorecard' familyOutcomes: type: array items: $ref: '#/components/schemas/ScorecardFamilyOutcome' underAudit: $ref: '#/components/schemas/ScorecardUnderAudit' ScorecardTotals: type: object properties: entries: type: integer format: int32 resolved: type: integer format: int32 pending: type: integer format: int32 pendingJudge: type: integer format: int32 scored: type: integer format: int32 void: type: integer format: int32 voidRate: type: number format: double publicationCoverage: deprecated: true type: number format: double ScorecardSummary: type: object properties: count: type: integer format: int32 brier: type: number format: double logScore: type: number format: double ScorecardDomainGroup: type: object properties: domain: type: string resolved: type: integer format: int32 scored: type: integer format: int32 void: type: integer format: int32 voidRate: type: number format: double brier: type: number format: double logScore: type: number format: double ScorecardGenerationOriginGroup: type: object properties: generationOrigin: type: string resolved: type: integer format: int32 scored: type: integer format: int32 void: type: integer format: int32 voidRate: type: number format: double brier: type: number format: double logScore: type: number format: double ScorecardCalibrationBucket: type: object properties: bucket: type: string minProbability: type: number format: double maxProbability: type: number format: double count: type: integer format: int32 predictedMean: type: number format: double realizedRate: type: number format: double brier: type: number format: double ScorecardMarketSkill: type: object properties: count: type: integer format: int32 forecastBrier: type: number format: double marketBrier: type: number format: double brierDelta: type: number format: double ScorecardSkill: type: object properties: count: type: integer format: int32 brier: type: number format: double logScore: type: number format: double excludedScored: type: integer format: int32 excludedOrigins: type: array items: type: string yesCount: type: integer format: int32 bssCi95: type: array items: type: number format: double description: |- Headline Brier/log score over scored entries that are neither synthetic backfill nor unpromoted shadow streams; count 0 with excluded_scored > 0 means every scored entry was excluded. ScorecardPublishedDomain: type: object properties: domain: type: string count: type: integer format: int32 brier: type: number format: double yesCount: type: integer format: int32 bss: type: number format: double ScorecardUncertainty: type: object properties: method: type: string overallBrier: $ref: '#/components/schemas/ScorecardInterval' skillBrier: $ref: '#/components/schemas/ScorecardInterval' ScorecardInterval: type: object properties: count: type: integer format: int32 mean: type: number format: double ci95: type: array items: type: number format: double description: '[low, high] at 95%.' insufficientSample: type: boolean description: True below the family minimums. description: Bootstrap interval on a mean Brier score. ScorecardFunnel: type: object properties: matured: type: integer format: int32 immature: type: integer format: int32 maturityUnknown: type: integer format: int32 resolved: type: integer format: int32 scored: type: integer format: int32 pendingHardMatured: type: integer format: int32 pendingJudgeMatured: type: integer format: int32 resolvedOfMatured: $ref: '#/components/schemas/ScorecardProportion' scoredOfMatured: $ref: '#/components/schemas/ScorecardProportion' description: Matured means past deadline or resolved. ScorecardProportion: type: object properties: count: type: integer format: int32 successes: type: integer format: int32 rate: type: number format: double ci95: type: array items: type: number format: double description: '[low, high] at 95%.' description: successes of count, with a Wilson interval. ScorecardReceipt: type: object properties: question: type: string forecastAt: type: integer format: int64 description: 'Warning: Values > 2^53 may lose precision in JavaScript' probability: type: number format: double outcome: type: string resolvedAt: type: integer format: int64 description: 'Warning: Values > 2^53 may lose precision in JavaScript' voidReason: type: string sourceFeed: type: string observedValue: type: number format: double citationTitle: type: string citationUrl: type: string MarketAlertScorecard: type: object properties: generatedAt: type: integer format: int64 description: 'Warning: Values > 2^53 may lose precision in JavaScript' windowHours: type: integer format: int32 rollingWindowDays: type: integer format: int32 methodology: type: string byType: type: array items: $ref: '#/components/schemas/MarketAlertRow' description: Rolling scorecard of the market-alert ledger. MarketAlertRow: type: object properties: type: type: string scored: type: integer format: int32 description: Alerts resolved HIT or MISS. hitRate: type: number format: double baseN: type: integer format: int32 baseHitRate: type: number format: double pairedHitRate: type: number format: double description: Hit rate over the rows whose control scored; compare with base_hit_rate. medianLeadTimeMs: type: integer format: int64 description: 'Median over hits; omitted below 30 hits.. Warning: Values > 2^53 may lose precision in JavaScript' description: One market-alert type's rolling hit rate beside its base rate. ScorecardFamilyOutcome: type: object properties: forecastId: type: string outcome: type: string voidReason: type: string ScorecardUnderAudit: type: object properties: since: type: string reason: type: string issue: type: integer format: int32 GetSimulationPackageRequest: type: object properties: runId: type: string description: |- Optional run identifier. It does not select a package yet: the latest is always returned, and note says when it differs. GetSimulationPackageResponse: type: object properties: found: type: boolean runId: type: string schemaVersion: type: string theaterCount: type: integer format: int32 generatedAt: type: integer format: int64 description: 'Unix timestamp in milliseconds.. Warning: Values > 2^53 may lose precision in JavaScript' note: type: string description: Set when run_id differs from the returned package's run_id. error: type: string description: |- Populated when the Redis lookup failed. Distinguish from healthy not-found (found=false, error=""). Value: "redis_unavailable" on Redis errors. GetSimulationOutcomeRequest: type: object properties: runId: type: string examples: - 1789387200000-abc123 maxLength: 128 pattern: ^([0-9]{13,}-[A-Za-z0-9-]{1,64})?$ description: |- Optional run ID (epoch ms, hyphen, 1-64 char suffix; max 128). Returns that run's outcome within 24h retention, processing=true while it is queued, or the latest outcome with a note. Empty returns the latest outcome. example: 1789387200000-abc123 GetSimulationOutcomeResponse: type: object properties: found: type: boolean runId: type: string schemaVersion: type: string theaterCount: type: integer format: int32 generatedAt: type: integer format: int64 description: 'Unix timestamp in milliseconds.. Warning: Values > 2^53 may lose precision in JavaScript' note: type: string description: |- Set when run_id was supplied but the latest outcome is returned instead; the text says why (run expired or not found, or its by-run record failed). error: type: string description: |- Populated when the Redis lookup failed. Distinguish from healthy not-found (found=false, error=""). Value: "redis_unavailable" on Redis errors. theaterSummariesJson: type: string description: |- JSON-encoded Array<{ theaterId, theaterLabel, stateKind, topPaths: [{label, summary, confidence, keyActors}], dominantReactions, stabilizers, invalidators }>; empty when found=false. processing: type: boolean description: True when the supplied runId is still queued, as opposed to expired. eligibleTheaterCount: type: integer format: int32 description: Number of theaters eligible for simulation in the package used by this outcome. failedTheaterCount: type: integer format: int32 description: Number of eligible theaters that failed before producing a Round 2 result. allTheatersFailed: type: boolean description: True when eligible_theater_count > 0 and no theater produced an outcome. completionStatus: type: string description: |- Machine-readable completion status. Current values: "completed", "partial", "no_eligible_theaters", or "all_theaters_failed". TriggerSimulationRequest: type: object properties: clientVersion: type: string description: Optional client version, such as "mcp-client/0.2". Logged, never stored. description: TriggerSimulationRequest enqueues a run for the current simulation package. TriggerSimulationResponse: type: object properties: queued: type: boolean description: |- True when the task was newly enqueued; false on idempotency hit or no_package. runId: type: string description: |- Server-derived runId from SIMULATION_PACKAGE_LATEST_KEY. Empty string when reason='no_package' (no package pointer was available). pkgFingerprint: type: string description: |- Opaque fingerprint of the package key; it changes when the key changes. Empty when reason='no_package'. reason: type: string description: |- '' when queued, 'no_package' when no package exists, or 'already-handled' when this cycle's run is already queued or done. description: |- TriggerSimulationResponse is the HTTP 200 result of an enqueue attempt. Errors return a non-200 status instead.