---
title: "Update Worker"
method: PATCH
path: "/worker/{worker_id}"
tags: ["workers"]
---

# Update Worker

`PATCH /worker/{worker_id}`

## Request

- Base URL: `https://api.traversal.com` (the document declares no server; this is the origin it was published from)
- URL: `https://api.traversal.com/worker/{worker_id}`
- Auth: none declared

Patch a worker's standing configuration or enabled state.

State-changing, so it goes through the standard ``AuthorizedUserDep`` chain
(authenticated + CSRF-validated). The organization comes from the
authenticated user, never the request body. A private chat's owner can set
``enabled`` to archive or unarchive it; instruction and mode edits stay refused.

## Path parameters

- `worker_id` string, required

## Request body

- UpdateWorkerRequest: Patch a worker's operator-managed configuration and lifecycle. The instruction is read from durable worker state on each fresh agent run, so changes apply on the next revival without redeploying. Pass a non-null string to overwrite it; omit it or pass ``null`` to leave it unchanged. ``enabled=false`` gracefully stops the worker through the same path as the Slack kill switch. ``enabled=true`` deliberately clears that terminal stop; the next eligible message revives a dormant execution normally. ``name`` changes a web worker's display name. Omit (null) to leave it unchanged. Slack and Teams workers use their external channel names and cannot be renamed here. ``mode`` changes the worker's standing mission. Omit (null) to leave it unchanged; unlike the instruction it cannot be cleared, because every worker has a mission. It is read from the row on each fresh run, so it takes effect at the next roll — which is unbounded on a channel busy enough never to idle until PRD-3874 makes it prompt.
  - `custom_instruction` string, nullable
  - `enabled` boolean, nullable
  - `name` string, nullable
  - `mode` 'incident' | 'alerts' | 'custom': The kind of channel the agent lives in — its standing mission. Drives the swappable mode block in the system prompt (and, later, the toolset). ``escalation`` and others land as localized drop-ins (their standing block + tooling) when that work begins. ``incident`` and ``alerts`` each state a mission the worker owns whatever the operator writes. ``custom`` states none: it supplies only the conduct floor the identity block forward-references, and the operator's ``custom_instruction`` is what gives the worker something to do. A channel that is neither working an incident nor triaging alert fires gets this one rather than being told it is in an incident (PRD-3766). The value is what customer-facing surfaces render, so it reads as the operator's own word for it rather than as an internal category. A member's *name* is persisted, in ``resident_agent_workflow.mode`` and ``resident_agent_template.mode`` — plain varchars with no DB-side value set — and read back through this enum, so adding a member is one deploy but removing or renaming one orphans every row holding it. It also makes a member forward-only: code that predates it raises on a row that carries it, rather than degrading. So a new member wants its read deployed everywhere before anything can write it — either landing the member ahead of the paths that create it, or gating creation while it rolls out. The same names are stored in usage policy bodies. Renaming or removing a member stops a body naming it from parsing, and that disables the template's policies.

## Response `200`

Successful Response

- WorkerResponse
  - `id` string, required
  - `organization_id` string, required
  - `resource_id` string, required
  - `display_name` string, required
  - `platform` 'slack' | 'teams' | 'web', required: A supported chat platform. Values align with ``integration_instances.type`` so a chat install's platform and its integration row stay in lockstep.
  - `channel_url` string, nullable, required
  - `agent_type` string, required
  - `mode` 'incident' | 'alerts' | 'custom', required: The kind of channel the agent lives in — its standing mission. Drives the swappable mode block in the system prompt (and, later, the toolset). ``escalation`` and others land as localized drop-ins (their standing block + tooling) when that work begins. ``incident`` and ``alerts`` each state a mission the worker owns whatever the operator writes. ``custom`` states none: it supplies only the conduct floor the identity block forward-references, and the operator's ``custom_instruction`` is what gives the worker something to do. A channel that is neither working an incident nor triaging alert fires gets this one rather than being told it is in an incident (PRD-3766). The value is what customer-facing surfaces render, so it reads as the operator's own word for it rather than as an internal category. A member's *name* is persisted, in ``resident_agent_workflow.mode`` and ``resident_agent_template.mode`` — plain varchars with no DB-side value set — and read back through this enum, so adding a member is one deploy but removing or renaming one orphans every row holding it. It also makes a member forward-only: code that predates it raises on a row that carries it, rather than degrading. So a new member wants its read deployed everywhere before anything can write it — either landing the member ahead of the paths that create it, or gating creation while it rolls out. The same names are stored in usage policy bodies. Renaming or removing a member stops a body naming it from parsing, and that disables the template's policies.
  - `custom_instruction` string, nullable
  - `created_at` string, date-time, required
  - `updated_at` string, date-time, required
  - `stopped_at` string, date-time, nullable, required
  - `status` 'critical' | 'attention' | 'working' | 'stable', required: The worker's present-tense status top-line, shown as a pill on the /workers list. Only these agent-picked values are ever stored in the `status` column; a null column means none has been emitted yet (the UI renders that as `starting`), and the terminal `stopped` state is derived from `stopped_at` — neither is stored here, so there is no second source of truth. The agent-facing definitions live on the ``status`` field in ``prompts.py`` (the only copy the model reads); keep this summary in sync with it. Values: CRITICAL: Immediate coordinated response is warranted because user-facing impact is severe or escalating. ATTENTION: A specific person or team should act now, but immediate coordinated incident response is not warranted. STABLE: Resting floor — no specific person or team needs to act now and no coordinated incident response is warranted. WORKING: Legacy — no longer emittable, see ``EmittableWorkerStatus``.
  - `status_message` string, nullable, required
  - `status_updated_at` string, date-time, nullable, required

## Other responses

- `422`: Validation Error

## Changes

> 66 revisions in range; 9 not diffed.

- **2026-10-03** `609da234e5da`: 1 info
  - added the new optional request property `name`
- **2026-09-09** `50f9ba1b135c`: 1 info
  - added the required property `organization_id` to the response with the `200` status
- **2026-09-05** `b3082d58954d`: 2 info
  - added the new optional request property `mode`
  - added the required property `channel_url` to the response with the `200` status
- **2026-09-02** `3025330cc50d`: 1 warning
  - added the new `custom` enum value to the `mode/anyOf[subschema #1: Mode]/` response property for the response status `200`
- **2026-08-16** `3b1335484485`: 1 info
  - endpoint added

[Operation history](https://skmtc.dev/traversal/apis/traversal-api/changes/worker/:worker_id/patch.md)

---

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