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

# Policies

> Per-crew autonomy posture and behavior mode that gate every HITL-relevant decision the orchestrator makes.

Each crew carries an autonomy posture that gates every HITL-relevant decision
the orchestrator makes -- memory writes, skill creation, behavior-monitor
escalations, persona suggestions, ephemeral spawns. The dial is read by every
subsystem via the shared policy resolver, so a `PUT` takes effect immediately
(the resolver cache is invalidated on write). The CLI counterpart is
[`crewship policy get/list/set`](/cli/policy).

All endpoints require authentication and workspace context.

| Field            | Values                                   | Meaning                                                                                                             |
| ---------------- | ---------------------------------------- | ------------------------------------------------------------------------------------------------------------------- |
| `autonomy_level` | `strict` / `guided` / `trusted` / `full` | How much an agent can do without operator approval. `strict` queues everything; `full` auto-applies most decisions. |
| `behavior_mode`  | `warn` / `block`                         | What the behavior monitor does on a flagged action -- `warn` lets it through with a journal entry, `block` rejects. |

**Validation rules:**

* `full` + `block` is forbidden.
* `reason` is required when setting `autonomy_level=full`.

***

## List Policies

```
GET /api/v1/policies?workspace_id={workspaceId}
```

Returns the policy for every (non-deleted) crew in the workspace, ordered by
crew name. Used by `crewship policy list` to render the overview table.

**Response:** `200 OK`

```json theme={null}
[
  {
    "crew_id": "crew_abc",
    "autonomy_level": "guided",
    "behavior_mode": "warn",
    "set_by_user_id": "user_123",
    "set_at": "2026-05-26T14:22:10Z",
    "reason": "Default for newly-onboarded crews"
  }
]
```

### Response Fields

| Field            | Type    | Description                                |
| ---------------- | ------- | ------------------------------------------ |
| `crew_id`        | string  | Crew ID                                    |
| `autonomy_level` | string  | `strict` / `guided` / `trusted` / `full`   |
| `behavior_mode`  | string  | `warn` / `block`                           |
| `set_by_user_id` | string? | User who last set the policy               |
| `set_at`         | string? | ISO 8601 timestamp of the last change      |
| `reason`         | string? | Audit reason recorded with the last change |

***

## Get Crew Policy

```
GET /api/v1/crews/{crewId}/policy?workspace_id={workspaceId}
```

Returns the current policy for one crew. Defaults (`guided` / `warn`) are
baked into the database, so this is always a single read.

| Path Parameter | Description |
| -------------- | ----------- |
| `crewId`       | Crew ID     |

**Response:** `200 OK`

```json theme={null}
{
  "crew_id": "crew_abc",
  "autonomy_level": "guided",
  "behavior_mode": "warn",
  "set_by_user_id": "user_123",
  "set_at": "2026-05-26T14:22:10Z",
  "reason": "Default for newly-onboarded crews"
}
```

`set_by_user_id` / `set_at` / `reason` are omitted on crews whose policy still
matches the seed defaults (no operator has ever flipped it).

| Status | Condition                        |
| ------ | -------------------------------- |
| `400`  | Missing crew ID                  |
| `404`  | Crew not found in this workspace |

***

## Set Crew Policy

```
PUT /api/v1/crews/{crewId}/policy?workspace_id={workspaceId}
Content-Type: application/json
```

Replaces the policy. Records the audit triple (`set_by_user_id`, `set_at`,
`reason`) atomically with the value change and invalidates the resolver cache
so the next decision sees the new state.

**Request Body:**

| Field            | Type   | Required    | Description                                                                                                    |
| ---------------- | ------ | ----------- | -------------------------------------------------------------------------------------------------------------- |
| `autonomy_level` | string | Yes         | One of `strict`, `guided`, `trusted`, `full`. Other values return `400`.                                       |
| `behavior_mode`  | string | Yes         | `warn` or `block`. A missing field returns `400` (no silent default).                                          |
| `reason`         | string | Conditional | Required (non-empty after trim) when `autonomy_level=full`; optional otherwise. Persisted on the audit triple. |

```json theme={null}
{
  "autonomy_level": "trusted",
  "behavior_mode": "block",
  "reason": "Crew has cleared 30 days of approvals without an override"
}
```

**Response:** `200 OK` -- the same shape as `GET`, reflecting the new state and the freshly-recorded audit triple.

| Status | Condition                                                                                                                    |
| ------ | ---------------------------------------------------------------------------------------------------------------------------- |
| `400`  | Invalid JSON, invalid enum value, the forbidden `full` + `block` combination, or missing `reason` when `autonomy_level=full` |
| `404`  | Crew not found in this workspace                                                                                             |

**Journal event:** `policy.changed` (workspace audit feed)
