---
title: "Replace the workspace's hook rules (owner only) [write]"
method: PUT
path: "/hook_rules"
---

# Replace the workspace's hook rules (owner only) \[write\]

`PUT /hook_rules`

## Request

- Base URL: `https://api.agentsky.dev/v1`
- URL: `https://api.agentsky.dev/v1/hook_rules`
- Auth: HTTP bearer

The body is the whole ordered list (at most 20); the order is the order of evaluation. A rule sent with the `id` of an existing rule keeps it. Points: `session.start` (a session is about to be created), `tool.call` (a capability call, a call to a connected app, or a tool the gateway runs for a session reached the platform), `spend` (a session's consumed cost reached `match.amount`, whole US cents; read when a turn ends and at a capability call, once per session), `turn.end` (a turn ended). Actions: `notify` delivers a signed event (`hook.session_start`, `hook.tool_call`, `hook.spend`, `hook.turn_end`) to `webhook_id`, one of the workspace's webhook endpoints, whatever events that endpoint subscribed to; never a URL. `block` at `session.start` refuses the session with 403 `blocked_by_hook_rule`; at `tool.call` it refuses the call with `capability_denied` (`reason: hook_rule`). `require_approval` at `tool.call` asks the session's owner exactly as an `ask` capability policy does, and an answer covers one call. `require_approval` at `session.start` creates the session waiting: it has no sandbox and takes no turn (409 `start_not_approved`), and its task carries an `approval` request for the person who created it, answered `confirm` or `decline` through `POST /tasks/{id}/requests/{request_id}/answer`. Approved, it starts with what it was created with; declined, it is archived, never runs and is charged nothing. A session started in a way that cannot wait (a helper, a product run, a handoff) is refused with 403 `blocked_by_hook_rule`. The most restrictive of the matching rules and the capability policies wins. Refused with 400 and the reason: `block` and `require_approval` at `spend` and at `turn.end`. `match` narrows a rule: `{agent_id}` at `session.start` and `turn.end`, `{capability_id}` or `{connector_app}` (the slug of a connected app), not both, at `tool.call`; omitted, the rule applies to all. A notify rule that cannot be delivered never affects the session. 403 `not_enabled` where hook rules are not turned on; 503 `not_migrated` before the tables exist.

## Request body

- object
  - `rules` object[], required
    - `id` string: An existing rule's id, to keep it.
    - `point` 'session.start' | 'tool.call' | 'spend' | 'turn.end', required
    - `action` 'notify' | 'block' | 'require_approval', required
    - `match` object
      - `agent_id` string
      - `capability_id` string
      - `connector_app` string: The slug of a connected app, e.g. "slack".
      - `amount` string: Whole US cents, e.g. "125" for $1.25. Required at spend.
    - `webhook_id` string: Required for notify (whep_…); not allowed otherwise.
    - `enabled` boolean: Default true.

## Response `200`

OK

- object
  - `enabled` boolean, required: Whether hook rules are turned on for the workspace.
  - `can_edit` boolean, required: Whether the caller may replace the rules: they are turned on and the caller owns the workspace.
  - `hook_rules` object[], required
    - `id` string, required: hkr_…
    - `point` 'session.start' | 'tool.call' | 'spend' | 'turn.end', required
    - `match` object, required
    - `action` 'notify' | 'block' | 'require_approval', required
    - `webhook_id` string, nullable, required
    - `enabled` boolean, required
    - `created_at` string, date-time, required
    - `updated_at` string, date-time, required

## Other responses

- `default`: Error — { error: { code, message, request_id } }

## Changes

- **2026-11-02** `e5e8f0229a99`: 1 info
  - endpoint added

[Operation history](https://skmtc.dev/agentsky/apis/agentsky-developer-api/changes/hook_rules/put.md)

---

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