---
title: "Create Run"
method: POST
path: "/api/v1/runs"
tags: ["Runs"]
---

# Create Run

`POST /api/v1/runs`

Creates a new workflow run in `submitted` status from either a self-contained legacy manifest or an immutable workflow-version intent. Creation does not start or schedule the run.

Failures return the standard error body. The intent lane responds `404` (`workflow_version_not_found`, `environment_not_found`), `422` (`run_intent_invalid`, `target_invalid`, `target_environment_unsupported`, `workflow_version_unusable`, `run_compile_invalid`), `503` (`integration_unavailable`), or `500` (`workflow_version_store_error`, `credential_store_error`, `variable_store_error`, `run_persistence_failed`).

## Request body

- union — Transitional create body used while callers migrate independently from self-contained manifests to immutable workflow-version intents.
  - RunManifest — Self-contained workflow run manifest.
    - `version` integer, required — Manifest schema version.
    - `parent_id` string, nullable — Optional orchestration parent run ID. Fork and rewind lineage use separate fields and should not set this value.
    - `title` string, nullable — Optional explicit run title. The server trims leading/trailing whitespace, rejects blank values, rejects control characters and newline characters, and requires at most 100 characters.
    - `cwd` string, required — CLI working directory at invocation time.
    - `git` GitContext — Observable git state captured before the run starts.
      - `origin_url` string, required — Remote origin URL with any embedded credentials removed.
      - `branch` string, required — Current branch name.
      - `sha` string, nullable — Current commit SHA, when known.
      - `dirty` 'clean' | 'dirty' | 'unknown', required
    - `goal` ManifestGoal — Resolved goal kind and content.
      - `type` 'value' | 'file' | 'graph', required
      - `text` string, required — Resolved goal content.
    - `args` ManifestArgs — Sparse command-local args that affect run settings.
      - `model` string
      - `provider` string
      - `environment` string — Named environment slug to select for the run.
      - `verbose` boolean
      - `dry_run` boolean
      - `auto_approve` boolean
      - `preserve_sandbox` boolean
      - `label` string[]
      - `input` string[] — Raw repeated CLI input overrides, each in `KEY=VALUE` form.
    - `target` ManifestTarget, required
      - `path` string, required — Resolved path that keys into the workflows map.
    - `configs` ManifestConfig[]
      - `type` 'project' | 'user', required
      - `path` string, nullable
      - `source` string, nullable
    - `workflows` object, required
  - RunIntent — A request to create, but not start, one run from an immutable workflow version and an explicit workspace target.
    - `workflow_version_id` string, required — SHA-256 identity of validated canonical workflow-version bytes. Hex input is case-insensitive; Fabro emits the canonical lowercase form.
    - `target` union, required — Workspace content and location requested for a run.
      - GitRunTarget — Public github.com repository target. The branch names the attached working branch. An optional tag selects a release at worker start, and an optional exact SHA is authoritative when both are present.
        - `kind` 'git', required
        - `repo` string, required — GitHub repository slug in `owner/name` form.
        - `branch` string, required — Required attached working branch name, preserved exactly.
        - `tag` string — Optional bare tag name. Prefixes such as `refs/tags/` and `tags/` are rejected. Without `sha`, the worker resolves this tag when the sandbox starts and fails if it is unavailable.
        - `sha` string — Optional exact commit. The server lowercase-normalizes its syntax but does not resolve it, prove branch ancestry, or prove that it matches an accompanying tag. When present, this exact commit wins.
      - NoneRunTarget — Empty workspace with no repository. Docker and Daytona accept this target and suppress cloning even when workflow settings enable it. Local environments reject it; Local scratch allocation is a separate future capability.
        - `kind` 'none', required
      - FolderRunTarget — Existing directory on the Fabro server, executed in place by a Local environment. The submitted path must be absolute and name an existing directory; Fabro resolves symlinks and persists its canonical UTF-8 path. This target is intended for trusted single-tenant deployments. Docker and Daytona environments always reject it. This target does not add Local Git cloning or Local scratch workspaces. Folder runs execute in place without Fabro Git checkpoints, so fork and rewind are unavailable.
        - `kind` 'folder', required
        - `path` string, required — Absolute path on the Fabro server, not on the API caller's machine.
    - `args` RunIntentArgs, required — Structured run overrides accepted by workflow-version creation.
      - `model` string
      - `provider` string — LLM provider; this does not select the sandbox environment.
      - `inputs` object
      - `labels` object
    - `environment_id` string — Server environment catalog ID. Omission selects `default`.
    - `parent_id` string — Optional orchestration parent run ID.
    - `title` string — Optional explicit run title, normalized by the server.
    - `goal` string — Optional inline goal override.

## Response `201`

Run created

- Run — Canonical public run shape.
  - `id` string, required
  - `parent_id` string, nullable — Current orchestration parent run ID, if linked.
  - `children_count` integer, required — Number of runs currently linked to this run as their orchestration parent.
  - `title` string, required
  - `goal` string, required
  - `workflow` WorkflowRef, required
    - `slug` string, nullable, required
    - `name` string, nullable, required
    - `graph_name` string, nullable, required
    - `node_count` integer, required — Number of nodes in the workflow graph.
    - `edge_count` integer, required — Number of edges in the workflow graph.
  - `automation` AutomationRef, required
    - `id` string, required
    - `name` string, nullable, required
    - `trigger_id` string, nullable
  - `repository` RepositoryRef, required — Durable repository metadata for a run.
    - `name` string, required
    - `origin_url` string, nullable, required
    - `provider` 'github' | 'git' | 'unknown', required
  - `created_by` union, required
    - PrincipalUser
      - `kind` 'user', required
      - `identity` IdpIdentity, required
        - `issuer` string, required
        - `subject` string, required
      - `login` string, required
      - `auth_method` 'github' | 'dev_token', required — Runtime user authentication method.
      - `avatar_url` string, nullable
    - PrincipalWorker
      - `kind` 'worker', required
      - `run_id` string, required
    - PrincipalWebhook
      - `kind` 'webhook', required
      - `delivery_id` string, required
    - PrincipalSlack
      - `kind` 'slack', required
      - `team_id` string, required
      - `user_id` string, required
      - `user_name` string, nullable
    - PrincipalAgent
      - `kind` 'agent', required
      - `session_id` string, nullable
      - `parent_session_id` string, nullable
      - `model` string, nullable
    - PrincipalSystem
      - `kind` 'system', required
      - `system_kind` 'engine' | 'watchdog' | 'timeout', required
  - `origin` RunOrigin, required
    - `kind` 'api', required
  - `labels` object, required
  - `lifecycle` RunLifecycle, required
    - `status` union, required — Execution status of a run. Archive state is represented separately on `RunLifecycle.archived` so terminal status payloads remain intact.
      - RunStatusSubmitted
        - `kind` 'submitted', required
      - RunStatusPending
        - `kind` 'pending', required
        - `reason` 'approval_required', required — Reason a pre-execution run is pending instead of runnable.
      - RunStatusRunnable
        - `kind` 'runnable', required
      - RunStatusStarting
        - `kind` 'starting', required
      - RunStatusRunning
        - `kind` 'running', required
      - RunStatusBlocked
        - `kind` 'blocked', required
        - `blocked_reason` 'human_input_required', required — Specific reason a run is blocked on external intervention.
      - RunStatusPaused
        - `kind` 'paused', required
        - `prior_block` 'human_input_required', required — Specific reason a run is blocked on external intervention.
      - RunStatusRemoving
        - `kind` 'removing', required
      - RunStatusSucceeded
        - `kind` 'succeeded', required
        - `reason` 'completed' | 'partial_success', required — Reason attached to a successful terminal run status.
      - RunStatusFailed
        - `kind` 'failed', required
        - `reason` 'workflow_error' | 'publish_failed' | 'cancelled' | 'approval_denied' | 'terminated' | 'transient_infra' | 'budget_exhausted' | 'launch_failed' | 'bootstrap_failed' | 'sandbox_init_failed', required — Reason attached to a failed terminal run status.
      - RunStatusDead
        - `kind` 'dead', required
    - `approval` RunApproval, required — Pre-execution approval state for runs that require one-time human approval.
      - `state` 'pending' | 'approved' | 'denied', required — State of a run's pre-execution approval request.
      - `requested_at` string, date-time, required
      - `decided_at` string, date-time, nullable, required
      - `denial_reason` string, nullable, required
    - `pending_control` 'cancel' | 'pause' | 'unpause', required — Run control action requested by the API.
    - `queue_position` integer, nullable, required
    - `error` RunError, required — Error information for a failed run.
      - `message` string, required — Error message.
    - `archived` boolean, required
    - `archived_at` string, date-time, nullable, required
  - `sandbox` RunSandbox, required — Sandbox lifecycle record for a run. A run can have a requested sandbox plan before it has an initialized sandbox instance.
    - `kind` 'planned' | 'initializing' | 'ready' | 'failed', required — Lifecycle state for a run sandbox request.
    - `plan` RunSandboxPlan, required — Requested sandbox provider and base image/snapshot from run settings.
      - `provider` 'local' | 'docker' | 'daytona', required — Sandbox provider discriminator.
      - `image` string, nullable
      - `snapshot` string, nullable
    - `instance` RunSandboxInstance — Initialized sandbox provider and runtime metadata.
      - `provider` 'local' | 'docker' | 'daytona', required — Sandbox provider discriminator.
      - `image` string, nullable
      - `snapshot` string, nullable
      - `runtime` RunSandboxRuntime, required
        - `id` string, required
        - `working_directory` string, required
        - `repo_cloned` boolean, nullable, required
        - `clone_origin_url` string, nullable, required
        - `clone_branch` string, nullable, required
        - `workspace_root` string, nullable
        - `repos_root` string, nullable
        - `primary_repo_path` string, nullable
        - `primary_repo_link` string, nullable
    - `failure` RunSandboxFailure — Sandbox initialization failure details.
      - `provider` string, required — Provider reported by the sandbox initialization event.
      - `error` string, required
      - `causes` string[], required
      - `duration_ms` integer, required
  - `models` RunModel[], required
    - `provider` string, nullable, required
    - `name` string, required
  - `source_directory` string, nullable, required
  - `timestamps` RunTimestamps, required
    - `created_at` string, date-time, required
    - `started_at` string, date-time, nullable, required
    - `last_event_at` string, date-time, nullable, required
    - `completed_at` string, date-time, nullable, required
  - `timing` RunTiming, required — Timing rollup for an entire run. Active fields sum work across stage visits, so `active_time_ms` can exceed `wall_time_ms` when parallel branches run concurrently. For a running run, stages still in flight contribute a live estimate rather than nothing, so wall and active both advance continuously. Unlike `StageTiming`, active is not clamped to wall here — concurrent branches can legitimately sum past run wall time.
    - `wall_time_ms` integer, required
    - `inference_time_ms` integer, required
    - `tool_time_ms` integer, required
    - `active_time_ms` integer, required — Equals `inference_time_ms + tool_time_ms`.
  - `billing` RunBillingSummary, required
    - `total_usd_micros` integer, nullable, required
  - `size` 'XS' | 'S' | 'M' | 'L' | 'XL', required — Run size bucket derived from current best-effort billed usage.
  - `ask_fabro` AskFabro, required — Readiness and defaults for starting an Ask Fabro session on this run.
    - `available` boolean, required
    - `unavailable_reason` 'no_sandbox' | 'sandbox_not_ready' | 'llm_unconfigured' | 'null', nullable, required
    - `default_model` string, nullable, required
  - `diff` DiffSummary, required — Cheap aggregate file and line counts for a run diff.
    - `files_changed` integer, required — Total number of changed files, including binary files.
    - `additions` integer, required — Total lines added across text files.
    - `deletions` integer, required — Total lines deleted across text files.
  - `pull_request` PullRequestLink, required — Minimal GitHub pull request link associated with a run.
    - `owner` string, required
    - `repo` string, required
    - `number` integer, required
    - `html_url` string, uri, required — Computed GitHub web URL for the pull request.
  - `current_question` RunQuestion, required — A pending human-in-the-loop question summary.
    - `text` string, required — Question text.
  - `superseded_by` string, nullable, required — Run ID that superseded this run via rewind, if any.
  - `retried_from` string, nullable, required — Source run ID when this run was created by manual retry.
  - `links` RunLinks, required
    - `web` string, uri, nullable, required

## Other responses

- `400` — Invalid JSON or legacy manifest

## Changes

- **2026-08-26** `13262755c97f` — 1 info
  - added the new optional request property `oneOf[#/components/schemas/RunIntent]/target/oneOf[#/components/schemas/GitRunTarget]/tag`
- **2026-08-26** `e7fd6d853204` — 2 info
  - added `folder` discriminator mapping keys to the `oneOf[#/components/schemas/RunIntent]/target` request property
  - added `#/components/schemas/FolderRunTarget` to the `oneOf[#/components/schemas/RunIntent]/target` request property `oneOf` list
- **2026-08-25** `9abd94e6cfbe` — 2 info
  - added `none` discriminator mapping keys to the `oneOf[#/components/schemas/RunIntent]/target` request property
  - added `#/components/schemas/NoneRunTarget` to the `oneOf[#/components/schemas/RunIntent]/target` request property `oneOf` list
- **2026-08-24** `5290add6d36f` — 1 breaking, 1 info
  - removed `#/components/schemas/NoneRunTarget` from the `oneOf[#/components/schemas/RunIntent]/target` request property `oneOf` list
  - removed `none` discriminator mapping keys from the `oneOf[#/components/schemas/RunIntent]/target` request property
- **2026-08-23** `cfd12cf45afb` — 6 info
  - added `none` discriminator mapping keys to the `oneOf[#/components/schemas/RunIntent]/target` request property
  - added `#/components/schemas/NoneRunTarget` to the `oneOf[#/components/schemas/RunIntent]/target` request property `oneOf` list
  - removed the non-success response with the status `404`
  - removed the non-success response with the status `422`
  - …2 more

[Full history](https://skmtc.dev/fabro-sh/apis/fabro-run-api/changes/api/v1/runs/post.md)

---

[API](https://skmtc.dev/fabro-sh/apis/fabro-run-api.md) · [All operations](https://skmtc.dev/fabro-sh/apis/fabro-run-api/llms.txt) · [OpenAPI document](https://skmtc-service-production.skmtc.workers.dev/v1/apis/fabro-sh/fabro-run-api/revisions/7bdeefd151cd/schema)
