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

# Create a Factory run

> Create a Factory run (a `factory_batch` cloud run) under the caller's credential and workspace. Requires `maxCostCents` (at least the estimate) and `Idempotency-Key`; the whole quote is held, and only accepted clips are charged, per camera-second. A replay with the same key and request returns the original run (200).



## OpenAPI

````yaml /api-reference/openapi.json post /api/v1/factory/runs
openapi: 3.1.0
info:
  title: SimForge Cloud API
  version: '2026-10-24'
  description: >-
    The public SimForge API: what `simforge --cloud`, `simforge login` and the
    Python client call. Authenticate with a bearer token: the access token
    `simforge login` stores, an AI agent's access token (its recipe is
    `/auth.md`), or an `sfk_` API key. A `/api/v1` 401 carries
    `WWW-Authenticate: Bearer
    resource_metadata="<host>/.well-known/oauth-protected-resource"`. `/api/v1`
    errors are an `ErrorEnvelope`; `/api/cli` and `/agent` errors are an OAuth
    error object.


    Versions: send `SimForge-Version: <date>` (2026-10-01, 2026-10-21,
    2026-10-22, 2026-10-23, 2026-10-24) and every `/api/v1` response is in that
    version's shape and names it in the same header; this document describes
    2026-10-24. A request without the header gets 2026-10-01, where an error's
    hint is `detail.hint` and `GET /api/v1/evaluations` names its rows `jobs`. A
    header that is not a date, or a date before 2026-10-01, is `400
    bad_request`. Every response also carries `SimForge-Cli-Minimum`: the oldest
    `simforge` CLI the server serves.


    Retries: from 2026-10-21, send a new `Idempotency-Key` (1-255 characters)
    with every POST, PUT, PATCH and DELETE, and the same key when retrying that
    request. The first request's answer is kept for 24 hours and a repeat gets
    it again with `Idempotent-Replayed: true`; the key with any other request,
    or while the first is still running, is `409 idempotency_conflict`
    (`retryable` while running). A 5xx answer is not kept. Creating an API key
    refuses a key (its secret is shown once).
  license:
    name: Apache-2.0
    identifier: Apache-2.0
servers:
  - url: https://dev.simforge.ai
    description: Development (dev.simforge.ai)
security: []
tags:
  - name: Sign-in
    description: >-
      `simforge login`: OAuth 2.0 device and browser sign-in for the CLI, the
      session behind a token. AI agents sign in through auth.md (`/auth.md`):
      register, a person approves, then the claim and JWT-bearer grants.
  - name: Account
    description: The principal, its workspaces, API keys and usage, and system status.
  - name: Runs
    description: >-
      Cloud runs (`--cloud`): renders, simulations, Recast log ingestion and
      transfers, their events and artifacts.
  - name: Models
    description: Customer fine-tunes and their workspace-owned model weights.
  - name: Datasets
    description: >-
      Datasets, their files as signed links (`simforge.dataset-files/v1`,
      `simforge datasets pull`), and copies out of shared datasets (SIMLOG-25k).
  - name: Maps and vehicles
    description: >-
      Maps the workspace can use, the vehicles a scenario can bind and the asset
      gallery.
  - name: Authoring
    description: >-
      Hosted scenario authoring: drafts, transactions, validation and map
      discovery.
  - name: Distribution
    description: >-
      The runtime and map pack agreement and signed downloads (`simforge runtime
      install`, `simforge maps pull`).
  - name: Telemetry
    description: Runtime usage telemetry, a condition of the runtime terms.
  - name: Benchmark
    description: Renderer benchmark results and scene packs (`simforge bench`).
  - name: Challenge
    description: >-
      The driving challenge: team, registry login and submissions (`simforge
      challenge`).
paths:
  /api/v1/factory/runs:
    post:
      tags:
        - Runs
      summary: Create a Factory run
      description: >-
        Create a Factory run (a `factory_batch` cloud run) under the caller's
        credential and workspace. Requires `maxCostCents` (at least the
        estimate) and `Idempotency-Key`; the whole quote is held, and only
        accepted clips are charged, per camera-second. A replay with the same
        key and request returns the original run (200).
      operationId: createFactoryRun
      parameters:
        - in: header
          name: Idempotency-Key
          required: true
          schema:
            type: string
            minLength: 1
            maxLength: 200
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/FactoryRunCreateRequest'
      responses:
        '200':
          description: Idempotent replay.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/FactoryRun'
        '201':
          description: Created run.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/FactoryRun'
        '400':
          description: The request failed.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorEnvelope'
        '401':
          description: The request failed.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorEnvelope'
        '402':
          description: The request failed.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorEnvelope'
        '403':
          description: >-
            `cloud_not_open`: SimForge Cloud is off here, or no worker here runs
            the work yet (the reason names it, `detail.code`
            `run_kind_unavailable`, `detail.kinds` its job kinds); or
            `insufficient_scope`.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorEnvelope'
        '404':
          description: The request failed.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorEnvelope'
        '409':
          description: The request failed.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorEnvelope'
        '429':
          description: The request failed.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorEnvelope'
      security:
        - simforgeToken:
            - runs:write
            - scenarios:read
            - maps:read
            - datasets:read
components:
  schemas:
    FactoryRunCreateRequest:
      type: object
      properties:
        scenarioIds:
          type: array
          items:
            type: string
            minLength: 1
            maxLength: 128
          minItems: 1
          maxItems: 500
          description: >-
            The scenarios to make clips of, in this workspace. Exactly one of
            scenarioIds and datasetId.
        datasetId:
          type: string
          minLength: 1
          maxLength: 128
          description: >-
            Every scenario of this dataset (one this workspace owns, at most
            500). Exactly one of scenarioIds and datasetId.
        lookIds:
          type: array
          items:
            type: string
            pattern: ^[a-z0-9][a-z0-9-]{0,63}$
          minItems: 1
          maxItems: 14
          description: >-
            Looks from GET /api/v1/factory/looks, each once. In simulator mode
            every clip is made with `rendered` (Rendered lighting).
        mode:
          type: string
          enum:
            - positions
            - simulator
          default: positions
          description: >-
            `positions`: the generator sees the layout and the look.
            `simulator`: the layout and each camera's first Helios frame, so the
            clip keeps the render's lighting: its look is always `rendered`, and
            any other look asked is replaced with the warning
            factory_look_unavailable_in_mode.
        seedsPerLook:
          type: integer
          minimum: 1
          maximum: 10
          default: 1
          description: Clips per scenario and look, each on its own seed.
        cameras:
          type: array
          items:
            type: string
            enum:
              - camera_cross_left_120fov
              - camera_front_wide_120fov
              - camera_cross_right_120fov
              - camera_front_tele_30fov
          default:
            - camera_cross_left_120fov
            - camera_front_wide_120fov
            - camera_cross_right_120fov
            - camera_front_tele_30fov
          description: >-
            The Alpamayo 4-camera rig, the only rig offered: every clip has all
            four cameras.
        maxCostCents:
          type: integer
          minimum: 0
          description: >-
            The most this run may charge: every clip accepted. Below the
            estimate, the run is refused budget_exceeded.
      required:
        - lookIds
        - maxCostCents
      additionalProperties: false
    FactoryRun:
      type: object
      properties:
        id:
          type: string
        status:
          type: string
          enum:
            - queued
            - running
            - succeeded
            - partial
            - failed
            - cancelled
        mode:
          type: string
          enum:
            - positions
            - simulator
        lookIds:
          type: array
          items:
            type: string
            pattern: ^[a-z0-9][a-z0-9-]{0,63}$
        seedsPerLook:
          type: integer
          exclusiveMinimum: 0
        scenarios:
          type: integer
          minimum: 0
        clips:
          $ref: '#/components/schemas/FactoryClipCounts'
        costEstimateCents:
          type:
            - integer
            - 'null'
          minimum: 0
        costCents:
          type:
            - integer
            - 'null'
          minimum: 0
        createdAt:
          type: string
          format: date-time
        finishedAt:
          type:
            - string
            - 'null'
          format: date-time
      required:
        - id
        - status
        - mode
        - lookIds
        - seedsPerLook
        - scenarios
        - clips
        - costEstimateCents
        - costCents
        - createdAt
        - finishedAt
    ErrorEnvelope:
      type: object
      properties:
        error:
          type: object
          properties:
            code:
              type: string
              enum:
                - bad_request
                - validation_failed
                - unauthorized
                - insufficient_scope
                - workspace_required
                - not_found
                - conflict
                - gone
                - idempotency_conflict
                - lease_lost
                - budget_exceeded
                - max_cost_required
                - idempotency_key_required
                - insufficient_credits
                - checkout_closed
                - cloud_not_open
                - email_unverified
                - terms_acceptance_required
                - evaluation_launch_disabled
                - evaluation_admissions_paused
                - fine_tunes_not_enabled
                - model_name_reserved
                - model_name_invalid
                - model_name_taken
                - model_quota_exceeded
                - checkpoint_too_large
                - checkpoint_format_unsupported
                - model_family_not_fine_tunable
                - checkpoint_file_unexpected
                - checkpoint_is_offered_model
                - model_version_exists
                - param_unknown
                - param_invalid
                - param_override_not_allowed
                - upload_incomplete
                - upload_mismatch
                - model_in_use
                - rate_limited
                - internal_error
            reason:
              type: string
            hint:
              type: string
            param:
              type: string
            retryable:
              type: boolean
            detail: {}
            path:
              type: string
            requestId:
              type: string
              pattern: ^req_[0-9A-HJKMNP-TV-Z]{26}$
          required:
            - code
            - reason
            - retryable
            - requestId
      required:
        - error
    FactoryClipCounts:
      type: object
      properties:
        total:
          type: integer
          minimum: 0
        inProgress:
          type: integer
          minimum: 0
        accepted:
          type: integer
          minimum: 0
        flagged:
          type: integer
          minimum: 0
        rejected:
          type: integer
          minimum: 0
        failed:
          type: integer
          minimum: 0
      required:
        - total
        - inProgress
        - accepted
        - flagged
        - rejected
        - failed
  securitySchemes:
    simforgeToken:
      type: http
      scheme: bearer
      description: >-
        A `sfc_at_…` access token from `simforge login`, or an `sfk_…` API key.
        An operation's security lists the scopes the credential must hold.

````

This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.