---
title: "Set or clear this account's operator instructions"
method: PUT
path: "/accounts/{account_id}/operator-instructions"
tags: ["accounts"]
---

# Set or clear this account's operator instructions

`PUT /accounts/{account_id}/operator-instructions`

## Request

- Base URL: `https://api.verdun.ai` (the document declares no server; this is the origin it was published from)
- URL: `https://api.verdun.ai/accounts/{account_id}/operator-instructions`
- Auth: HTTP bearer

Free-text instructions shown to the HUMAN monitoring operator on every alarm at any of this account's sites, and again at the escalation step. NEVER enters an AI prompt — the agent-context fields are what steer the model. Requires the owner, monitoring_manager or site_manager role; a site_manager needs the account's client granted in FULL (a grant narrowed to some of its sites is refused). An account id outside the caller's scope, or a retired one, answers 404 rather than 403: the status code must not tell a caller which of another client's account ids exist.

## Path parameters

- `account_id` string, uuid, required

## Request body

- UpdateOperatorInstructionsRequest: Body for the three owner-only operator-instruction writes. ONE MODEL FOR ACCOUNT, SITE AND CAMERA. The field, the cap, the trim rule and the null semantics are identical at all three levels by decision, and ops-view mirrors them in one editor component — see the package docstring for why this lives under `shared/` rather than in three copies. ABSOLUTE WRITE, NO PATCH SEMANTIC. Omitting the field is identical to sending `null` and means CLEAR, matching how `agent_context` is written. NO `examples=` ON THE FIELD, DELIBERATELY. Real instruction text is after-hours phone numbers and premise procedure; an example in the published OpenAPI would be a plausible-looking one sitting in every generated client and doc page, and "sample" premise procedure is exactly the sort of thing that gets pasted in and acted on. The description carries the contract instead.
  - `operator_instructions` string, nullable: Free-text instructions shown to the HUMAN monitoring operator on every alarm at this level, and again at the escalation step. NEVER enters an AI prompt — that is what the agent context fields are for. Leading and trailing whitespace is trimmed BEFORE the length check, so the 2000-character limit measures the value that will actually be stored and matches the editor's character counter exactly. Empty or whitespace-only is stored as null (= no instruction), as is an explicit null or an omitted field; there is no patch semantic.

## Response `200`

Successful Response

- OperatorInstructionsResponse: The three operator-instruction writes answer the written value, nothing else. MINIMAL BY DECISION (Round-0 ruling Q4), and a visible divergence from the `PUT /sites/{id}/agent-config` route these are modelled on — that one returns the full `EditSiteResponse`. Doing the same here would force `operator_instructions` into three large response models and, for sites, into `Sites.to_dict_complete()`: the serializer that feeds both SSE broadcast builders, the operator queue, history and `GET /events/{id}`. The whole design rests on that serializer never learning the field, so the response shape follows from it rather than the other way round. The service layer returns the resource's display name alongside these two keys — the router needs it for the activity-log summary — and pydantic drops it here (`extra="ignore"`). That is deliberate, not an oversight, and is pinned by a router test asserting the body carries exactly these two keys: the name is audit material, not part of this contract.
  - `id` string, uuid, required: Id of the account, site or camera that was written.
  - `operator_instructions` string, nullable: The stored instructions after the write, trimmed. Null means no instruction is set at this level.

## Other responses

- `422`: Validation Error

---

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