---
title: "Create automation"
method: POST
path: "/api/v1/automations"
tags: ["Automations"]
---

# Create automation

`POST /api/v1/automations`

Creates a new automation definition.

## Request body

- CreateAutomationRequest — Request body for creating an automation.
  - `id` string, required
  - `name` string, required
  - `description` string, nullable
  - `environment_id` string, required — Server-managed Docker or Daytona environment selected when the automation fires.
  - `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.
  - `workflow` string, required — Workflow slug or path resolved in the selected repository checkout.
  - `triggers` AutomationTrigger[], required
    - union — Automation trigger configuration. Unknown `type` discriminator values are reported by handlers as domain validation errors with HTTP 422.
      - AutomationApiTrigger — Trigger that allows callers to create runs through the automation API.
        - `id` string, required
        - `type` 'api', required
        - `enabled` boolean, required
      - AutomationScheduleTrigger — Cron schedule trigger evaluated in UTC.
        - `id` string, required
        - `type` 'schedule', required
        - `enabled` boolean, required
        - `expression` string, required — Five-field cron expression evaluated in UTC.

## Response `201`

Automation created

- Automation — Public automation definition.
  - `id` string, required
  - `revision` string, required — Stable revision used with `If-Match` for optimistic concurrency.
  - `name` string, required
  - `description` string, nullable, required
  - `environment_id` string, nullable, required — Server-managed Docker or Daytona environment selected when the automation fires. Null only for an incomplete definition migrated from a release that predated environment selection.
  - `last_error` string, nullable, required — Most recent scheduled-run failure, cleared after a scheduled run is queued successfully.
  - `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.
  - `workflow` string, required — Workflow slug or path resolved in the selected repository checkout.
  - `triggers` AutomationTrigger[], required
    - union — Automation trigger configuration. Unknown `type` discriminator values are reported by handlers as domain validation errors with HTTP 422.
      - AutomationApiTrigger — Trigger that allows callers to create runs through the automation API.
        - `id` string, required
        - `type` 'api', required
        - `enabled` boolean, required
      - AutomationScheduleTrigger — Cron schedule trigger evaluated in UTC.
        - `id` string, required
        - `type` 'schedule', required
        - `enabled` boolean, required
        - `expression` string, required — Five-field cron expression evaluated in UTC.

## Other responses

- `400` — Malformed JSON request body
- `409` — Automation id already exists
- `422` — Automation failed domain validation

## Changes

- **2026-08-30** `7bdeefd151cd` — 1 breaking, 2 info
  - added the new required request property `environment_id`
  - added the required property `environment_id` to the response with the `201` status
  - added the required property `last_error` to the response with the `201` status
- **2026-08-26** `0a0810535f53` — 7 breaking, 3 warning, 4 info
  - added the new required request property `workflow`
  - the `target` request property type/format changed from `object`/`` to ``/``
  - added `#/components/schemas/GitRunTarget, #/components/schemas/NoneRunTarget, #/components/schemas/FolderRunTarget` to the `target` response property `oneOf` list for the response status `201`
  - the `target` response's property type/format changed from `object`/`` to ``/`` for status `201`
  - …10 more
- **2026-05-30** `57aaacdfd18e` — 1 breaking, 1 warning
  - removed the required property `enabled` from the response with the `201` status
  - removed the request property `enabled`
- **2026-05-27** `5111129c5643` — 1 info
  - endpoint added

[Change history](https://skmtc.dev/fabro-sh/apis/fabro-run-api/changes/api/v1/automations/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)
