> ## Documentation Index
> Fetch the complete documentation index at: https://www.worldmonitor.app/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# TriggerSimulation

> TriggerSimulation enqueues a simulation task for the current
 SIMULATION_PACKAGE_LATEST_KEY package pointer. PRO-gated. The runId
 is server-derived; callers cannot supply one. The Railway worker
 (scripts/process-simulation-tasks.mjs) polls the queue and writes
 outcomes; callers poll GetSimulationOutcome with the returned runId
 to retrieve the result. Mirrors run-scenario.ts pattern. See #3734. Requires entitlement tier >= 1.



## OpenAPI

````yaml /api/ForecastService.openapi.yaml post /api/forecast/v1/trigger-simulation
openapi: 3.1.0
info:
  title: ForecastService API
  version: 1.0.0
servers:
  - url: https://api.worldmonitor.app
security:
  - WorldMonitorKey: []
  - ApiKeyHeader: []
paths:
  /api/forecast/v1/trigger-simulation:
    post:
      tags:
        - ForecastService
      summary: TriggerSimulation
      description: |-
        TriggerSimulation enqueues a simulation task for the current
         SIMULATION_PACKAGE_LATEST_KEY package pointer. PRO-gated. The runId
         is server-derived; callers cannot supply one. The Railway worker
         (scripts/process-simulation-tasks.mjs) polls the queue and writes
         outcomes; callers poll GetSimulationOutcome with the returned runId
         to retrieve the result. Mirrors run-scenario.ts pattern. See #3734. Requires entitlement tier >= 1.
      operationId: TriggerSimulation
      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}$
      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'
        '401':
          description: Missing or invalid API key.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/UnauthorizedError'
        '403':
          description: PRO entitlement access denied.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ForbiddenError'
        '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
        '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'
        default:
          description: Gateway or handler error response.
          content:
            application/json:
              schema:
                oneOf:
                  - $ref: '#/components/schemas/Error'
                  - $ref: '#/components/schemas/GatewayError'
      security:
        - WorldMonitorKey: []
        - ApiKeyHeader: []
        - BearerAuth: []
components:
  schemas:
    TriggerSimulationRequest:
      type: object
      properties:
        clientVersion:
          type: string
          description: |-
            Optional opaque client-version string for debugging (e.g., "claude-
             desktop/0.6.1", "mcp-client/0.2"). Server LOGS this with the success
             breadcrumb but never persists or branches on it. Present primarily so
             the generated client/server code has at least one field to reference
             (sebuf v0.11.1 emits a typecheck-broken POST client for fully-empty
             request messages). Safe to omit; default empty string.
      description: |-
        TriggerSimulationRequest enqueues a simulation task for the current
         SIMULATION_PACKAGE_LATEST_KEY package pointer. Caller-supplied
         run_id is intentionally absent — the runId is server-derived from
         the package pointer (avoids lock-key collision, queue stuffing, and
         race against cron rotation). See #3734 / docs/plans/2026-05-18-003-
         feat-simulation-trigger-and-runid-filter-plan.md D1.
    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 simulation package input (first 16 hex
             chars of sha256 over the package's R2 object key). Stable identifier
             for drift detection across trigger/read calls — clients can compare
             this against the fingerprint inside the by-run outcome payload to
             detect cron rotation. Do NOT decode. Returns empty string when
             reason='no_package'.
        reason:
          type: string
          description: |-
            External reason taxonomy:
               ''                  - happy path (queued=true)
               'no_package'        - SIMULATION_PACKAGE_LATEST_KEY pointer absent
               'already-handled'   - idempotency hit (covers both "already queued"
                                     and "already completed this cycle"; collapsed
                                     externally to avoid a cron-timing oracle —
                                     server logs retain the distinction).
      description: |-
        TriggerSimulationResponse carries the outcome of an enqueue attempt.
         On error states (premium gate, queue capacity, Redis transport), the
         handler throws ApiError with the appropriate HTTP status — there is
         NO error field on this message. All paths that return this message
         represent HTTP 200.
    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.
    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
    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.
    ForbiddenError:
      type: object
      properties:
        error:
          type: string
          description: Human-readable entitlement failure reason.
        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.
    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.
    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
    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
    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.
  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 <token>.

````