---
title: "Save a project agent"
method: POST
path: "/api/v1/{forge}/{project}/agents"
tags: ["Project Agents"]
---

# Save a project agent

`POST /api/v1/{forge}/{project}/agents`

## Request

- Base URL: `https://entire.io` (the document declares no server; this is the origin it was published from)
- URL: `https://entire.io/api/v1/{forge}/{project}/agents`
- Auth: none declared. Required headers: `Idempotency-Key`

Saving runs, schedules and dispatches nothing. Reuse the Idempotency-Key with the same body to retry; a changed body needs a new key.

## Path parameters

- `forge` 'gh' | 'et', required
- `project` string, required

## Headers

- `Idempotency-Key` string, required

## Request body

- object: Send preset with only the fields that place it, or a custom agent's name, harness, timeout_ms, instructions and signal; and exactly one of environment_id and environment.
  - `preset` string, nullable: Run an Entire preset as it is now; omit or send null for a custom agent.
  - `name` string: Required without a preset.
  - `description` string
  - `is_enabled` boolean
  - `harness` 'claude' | 'codex'
  - `model` string, nullable
  - `reasoning_effort` 'low' | 'medium' | 'high' | 'xhigh' | 'max' | 'ultra', nullable
  - `timeout_ms` integer
  - `instructions` string
  - `signal` object
    - `value_type` 'boolean' | 'percent' | 'size', required
    - `polarity` 'higher_is_better' | 'lower_is_better' | 'neutral', nullable
  - `repository_ids` string[], required
  - `triggers` object[]: At most one trigger; omit or send [] for an agent that only runs when asked to.
    - `id` string
    - `kind` 'push', required
    - `when` 'ready' | 'always' | 'not_ready': Which Changes the push trigger runs on: ready, only one ready for review (and when one becomes ready); always, every push; not_ready, only one not yet ready for review. In a repository without an approvals gate every open Change is ready. A write that omits it saves ready.
    - `branches` string[]: Glob patterns over the Change's branch name (main, release/*, feature/**; never refs/…). Empty runs on every branch; a write that omits it saves [].
    - `paths` string[]: Glob patterns over the repository-relative paths the whole Change changes (frontend/**, **/*.go). Empty runs on every Change; a write that omits it saves []. Manual runs ignore both filters.
  - `environment_id` string
  - `environment` object
    - `name` string, required
    - `description` string
    - `auto_stop_minutes` integer, nullable

## Response `201`

Saved, or replayed from an earlier request with the same key

- object
  - `id` string, required
  - `project_id` string, required
  - `version` integer, required
  - `etag` string, required: Write token: send it unchanged as If-Match to replace or archive.
  - `created_at` string, required
  - `created_by` object, required
    - `kind` string, required
    - `id` string, required
  - `updated_at` string, required
  - `archived_at` string, nullable, required
  - `archived_by` object
    - `kind` string, required
    - `id` string, required
  - `name` string, required
  - `description` string, required
  - `harness` string, required
  - `model` string, nullable, required
  - `reasoning_effort` string, nullable, required
  - `timeout_ms` integer, required
  - `instructions` string, required
  - `signal` object, required
    - `value_type` 'boolean' | 'percent' | 'size', required
    - `polarity` 'higher_is_better' | 'lower_is_better' | 'neutral', required
  - `preset` object, nullable, required: The Entire preset the agent runs as it is now; null for a custom agent. A preset agent's name, model, instructions and signal are the preset's.
    - `id` string, required
    - `version` integer, required
  - `is_enabled` boolean, required: Whether its trigger runs it. A paused agent still runs when asked to.
  - `environment_id` string, required
  - `repository_ids` string[], required
  - `triggers` object[], required
    - `id` string, required
    - `kind` 'push', required
    - `when` 'ready' | 'always' | 'not_ready', required: Which Changes the push trigger runs on: ready, only one ready for review (and when one becomes ready); always, every push; not_ready, only one not yet ready for review. In a repository without an approvals gate every open Change is ready. A write that omits it saves ready.
    - `branches` string[], required: Glob patterns over the Change's branch name (main, release/*, feature/**; never refs/…). Empty runs on every branch; a write that omits it saves [].
    - `paths` string[], required: Glob patterns over the repository-relative paths the whole Change changes (frontend/**, **/*.go). Empty runs on every Change; a write that omits it saves []. Manual runs ignore both filters.
  - `stale_repository_ids` string[], required

## Other responses

- `400`: Invalid request
- `401`: Not authenticated
- `403`: Feature disabled, or repository push is missing
- `404`: Project or resource not found
- `409`: Conflict: archived, in use, scope changed, or Idempotency-Key reused
- `413`: Request body too large
- `422`: Validation failed
- `502`: Agents service unavailable

## Changes

- **2026-10-26** `3ff783b497b2`: 1 warning
  - removed the request property `environment/provider`
- **2026-10-25** `f4a534501f84`: 4 info
  - added the new optional request property `triggers/items/branches`
  - added the new optional request property `triggers/items/paths`
  - added the required property `triggers/items/branches` to the response with the `201` status
  - added the required property `triggers/items/paths` to the response with the `201` status
- **2026-10-25** `e8893f80c9f2`: 2 info
  - added the new optional request property `triggers/items/when`
  - added the required property `triggers/items/when` to the response with the `201` status
- **2026-10-23** `365f01543923`: 1 info
  - endpoint added

[Operation history](https://skmtc.dev/entire/apis/entire-api/changes/api/v1/:forge/:project/agents/post.md)

---

[API](https://skmtc.dev/entire/apis/entire-api.md) - [All operations](https://skmtc.dev/entire/apis/entire-api/llms.txt) - [OpenAPI document](https://skmtc.dev/entire/apis/entire-api/revisions/a24dfcc828d7?raw)
