---
title: "Change a proactive program's mode"
method: PATCH
path: "/v1/admin/tenants/{tenant_id}/proactive-programs/{program_id}/mode"
tags: ["admin-proactive-programs"]
---

# Change a proactive program's mode

`PATCH /v1/admin/tenants/{tenant_id}/proactive-programs/{program_id}/mode`

## Request

- Base URL: `https://api.patricia.app` (the document declares no server; this is the origin it was published from)
- URL: `https://api.patricia.app/v1/admin/tenants/{tenant_id}/proactive-programs/{program_id}/mode`
- Auth: HTTP bearer

Set how much one program may do: `observe` (runs, never sends), `dm_only` (DMs and reactions), `full` (also channel posts), or `disabled` (does not run). Widening past `observe` permits unprompted messages, so the change is recorded durably against the acting admin. The fire cursor is reconciled in the same transaction: a program that becomes runnable gets one, a program that stops being runnable gives up its cursor and lease.

## Path parameters

- `tenant_id` string, uuid, required
- `program_id` string, uuid, required

## Request body

- SetProactiveProgramModeRequest: Change one program's mode. ``enabled`` defaults to "runnable unless disabled".
  - `mode_code` 'observe' | 'dm_only' | 'full' | 'disabled', required: How much a proactive program may do (the staged rollout — §5.1, §7). ``observe`` → the program runs (reads + reasons) but the delivery gate blocks EVERY outbound (it only records what it WOULD do); ``dm_only`` → DMs + reactions; ``full`` → also channel posts; ``disabled`` → the program does not run at all. Both programs seed ``dm_only``; a mode change is staff-only.
  - `enabled` boolean, nullable

## Response `200`

Successful Response

- AdminProactiveProgramResponse: One tenant program row as staff see it, including why it is dormant.
  - `id` string, uuid, required
  - `tenant_id` string, uuid, required
  - `program_type_code` string, required
  - `mode_code` string, required
  - `enabled` boolean, required
  - `schedule` string, required
  - `next_run_at` string, date-time, nullable, required
  - `last_run_at` string, date-time, nullable, required
  - `paused_reason` string, nullable, required
  - `paused_at` string, date-time, nullable, required
  - `consecutive_failures` integer, required
  - `scope` object, required

## Other responses

- `400`: Bad request
- `401`: Unauthorized
- `403`: Forbidden. Inspect response body `code` for the specific reason (for example: PERMISSION_DENIED, EMAIL_NOT_VERIFIED, TENANT_ACCESS_REQUIRED, ROLE_UNRESOLVED)
- `404`: Not found
- `409`: Conflict
- `422`: Validation error

---

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