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

# Get forecast

> Estimates how long a migration will take and how much capacity it needs, before you launch it. Uses the same forecaster as an actual kickoff, so the numbers match what a real run would be sized with. No run is created.

The forecast follows your run's real scope:
- `selection` scopes the counts the ETA is priced from — a 10-of-10,000 product pick is not estimated as a whole-store run.
- `conflict_strategy` prices the extra work `update` and `replace` imply (reading the destination first, reconciling matched items, and for `replace` a prune pass).
- Orders are priced on the selected order statuses rather than the all-statuses total.

Calling this with only a source store means `update`/`replace` fall back to an assume-all-matched estimate, since the destination's size isn't known yet.



## OpenAPI

````yaml vortex-apps/staging-pro/api/openapi.json POST /forecast
openapi: 3.1.0
info:
  title: StagingPro V2 Migration API (BigCommerce)
  version: 2.0.0
  description: >-
    REST API for the StagingPro V2 BC Migration app. Browse a connected store's
    catalogue, size a migration before you run it, launch bulk or selective
    store-to-store migrations, control runs, and follow live progress.


    All endpoints are served from `https://app.vortexiq.ai/v2/api/bc-migration`
    and are scoped to your organisation. Authenticate with a bearer token from
    the Login endpoint (scripts and services) or your signed-in session
    (browser). See
    [Authentication](/vortex-apps/staging-pro/api/authentication).
  contact:
    name: Vortex IQ Support
    url: https://www.vortexiq.ai/contact-us
servers:
  - url: https://app.vortexiq.ai/v2/api/bc-migration
    description: Vortex IQ platform (production)
security:
  - sessionAuth: []
  - bearerAuth: []
tags:
  - name: Authentication
    description: >-
      Exchange your identity and your organisation's API credential for a bearer
      token.
  - name: Migrations
    description: >-
      Create migrations, list history, read run detail and per-item issues, and
      follow live progress.
  - name: Migration Controls
    description: Pause, resume, cancel, and verify-only re-runs.
  - name: Counts & Forecast
    description: Size a migration before launching it. Neither endpoint creates a run.
paths:
  /forecast:
    post:
      tags:
        - Counts & Forecast
      summary: Get forecast
      description: >-
        Estimates how long a migration will take and how much capacity it needs,
        before you launch it. Uses the same forecaster as an actual kickoff, so
        the numbers match what a real run would be sized with. No run is
        created.


        The forecast follows your run's real scope:

        - `selection` scopes the counts the ETA is priced from — a 10-of-10,000
        product pick is not estimated as a whole-store run.

        - `conflict_strategy` prices the extra work `update` and `replace` imply
        (reading the destination first, reconciling matched items, and for
        `replace` a prune pass).

        - Orders are priced on the selected order statuses rather than the
        all-statuses total.


        Calling this with only a source store means `update`/`replace` fall back
        to an assume-all-matched estimate, since the destination's size isn't
        known yet.
      operationId: getForecast
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/CountsRequest'
            example:
              source_store_hash: abc123xyz
              selected_entities:
                - products
                - categories
              conflict_strategy: update
      responses:
        '200':
          description: Sizing and ETA forecast.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Forecast'
        '403':
          $ref: '#/components/responses/Forbidden'
        '422':
          $ref: '#/components/responses/StoreNotFound'
        '502':
          description: >-
            Forecast could not be computed (`forecast_failed`), or the migration
            service is unreachable (`proxy_failed`).
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
components:
  schemas:
    CountsRequest:
      type: object
      required:
        - source_store_hash
        - selected_entities
      description: >-
        Counts and forecast read the **source** store only, so
        `destination_store_hash` is optional.
      properties:
        source_store_hash:
          type: string
          description: BigCommerce store hash to read.
        destination_store_hash:
          type: string
          description: >-
            Optional. Supplying it lets the forecast price `update`/`replace`
            against the destination's real size.
        selected_entities:
          type: array
          items:
            type: string
          minItems: 1
          description: Entity keys to count or price.
        selection:
          $ref: '#/components/schemas/Selection'
        conflict_strategy:
          type: string
          enum:
            - skip
            - update
            - replace
          description: 'Forecast only: price the ETA for this strategy.'
        channel_map:
          type: object
          additionalProperties:
            type: integer
          description: Optional channel map.
        source_channel_id:
          type: integer
          minimum: 1
          description: Optional storefront scope.
        destination_channel_id:
          type: integer
          minimum: 1
          description: Optional storefront scope.
    Forecast:
      type: object
      description: >-
        Sizing and ETA estimate.


        Sizing and ETA are priced from different bases deliberately: the ETA
        follows the run's real scope (picks, strategy, order statuses), while
        memory is pinned to **store scale** — the engine's working set does not
        shrink with a small pick, so sizing on picked counts alone would
        under-provision the run.
      properties:
        products:
          type: integer
        variants:
          type: integer
        brands:
          type: integer
        categories:
          type: integer
        counts:
          type: object
          additionalProperties:
            type: integer
          description: >-
            Per-entity counts the estimate was priced from, scoped by
            `selection` when supplied.
        estimated:
          type: array
          items:
            type: string
          description: Count keys that are sampled estimates rather than exact totals.
        memMB:
          type: integer
          description: >-
            Memory the run will be given (MiB). Pinned to store scale, not to
            the picked subset.
        cpus:
          type: number
          description: CPUs the run will be given.
        etaSeconds:
          type: integer
          description: Estimated total wall-clock for the run.
        etaBreakdown:
          type: object
          additionalProperties:
            type: number
          description: Per-phase seconds.
        etaAssumedRttMs:
          type: number
          description: The blended latency the estimate assumed.
        etaAssumedMs:
          type: object
          description: >-
            Per-operation-class latencies the estimate assumed, so heavy writes
            are not judged against a blended baseline.
          properties:
            read:
              type: number
            write:
              type: number
            heavy:
              type: number
        strategy:
          type: string
          enum:
            - skip
            - update
            - replace
          description: >-
            The conflict strategy the ETA was priced with. Absent means
            create-only.
        destProducts:
          type: integer
          description: >-
            Destination catalogue size at kickoff. Absent or `0` when the
            destination wasn't known.
        tier:
          type: string
          enum:
            - small
            - medium
            - large
            - xlarge
            - xxlarge
            - xxxlarge
          description: Capacity band the run was placed in.
        basis:
          type: string
          enum:
            - forecast
            - fallback
            - fix
          description: '`fallback` means counts were unavailable and defaults were used.'
        at:
          type: string
          format: date-time
    Error:
      type: object
      properties:
        error:
          type: string
          description: Machine-readable error code.
        message:
          type: string
          description: Human-readable explanation.
        status:
          type: integer
          description: 'Present on `bc_error`: the status BigCommerce returned.'
        errors:
          type: object
          additionalProperties: true
          description: 'Present on validation failures: field-level messages.'
    Selection:
      type: object
      description: >-
        Selective migration picks. Parents and ancestors are included
        automatically, and products pull in their brands and categories.


        Find the ids to pass here in the StagingPro app's Selective Migration
        tab. A selection also scopes [entity
        counts](/vortex-apps/staging-pro/api/get-entity-counts) and the
        [forecast](/vortex-apps/staging-pro/api/get-forecast).
      properties:
        products:
          type: array
          items:
            type: integer
          maxItems: 5000
          description: Product ids.
        categories:
          type: array
          items:
            type: integer
          maxItems: 5000
          description: Category ids.
        pages:
          type: array
          items:
            type: integer
          maxItems: 2000
          description: Page ids.
        promotions:
          type: array
          items:
            type: integer
          maxItems: 2000
          description: Promotion ids.
        themes:
          type: array
          items:
            type: string
            format: uuid
          maxItems: 20
          description: >-
            Theme **UUIDs** (BigCommerce theme ids are uuids, not integers).
            When present, `activate_theme` is ignored in favour of
            `theme_activation`.
        page_templates:
          type: array
          items:
            type: string
            pattern: ^pages/
          maxItems: 50
          description: >-
            Page template files, all beginning `pages/` (for example
            `pages/home`). Template-level Page Builder content only — content
            scoped to a specific product, category, or page is not included.
        page_template_globals:
          type: array
          items:
            type: string
            pattern: ^pages/
          maxItems: 50
          description: >-
            Page templates whose **global** widget content also migrates. Must
            be a subset of `page_templates`.
  responses:
    Forbidden:
      description: >-
        Store Migration is not enabled for your organisation. Requests with no
        valid bearer token or session return `401` instead.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error'
          example:
            message: Store Migration is not enabled for this organization.
    StoreNotFound:
      description: >-
        The store is not found or not authorised for your organisation
        (`store_not_found`).
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error'
          example:
            error: store_not_found
            message: >-
              source or destination store not found / not authorized for this
              organization
  securitySchemes:
    sessionAuth:
      type: apiKey
      in: cookie
      name: vortexiq_session
      description: >-
        Your signed-in Vortex IQ session (browser calls). Requests are scoped to
        your organisation, which must have Store Migration enabled. For
        server-to-server calls use a bearer token instead — see
        [Authentication](/vortex-apps/staging-pro/api/authentication).
    bearerAuth:
      type: http
      scheme: bearer
      bearerFormat: JWT
      description: >-
        A bearer token from [Login](/vortex-apps/staging-pro/api/login). Valid
        for 10 days; scoped to the user and organisation it was issued for.
        Rotating or disabling the organisation's API credential immediately
        invalidates all outstanding tokens.

````