---
title: "Update Desk Org Settings"
method: PUT
path: "/desk/org-settings"
tags: ["Desk"]
---

# Update Desk Org Settings

`PUT /desk/org-settings`

## Request

- Base URL: `https://be.graph8.com/api/v1`
- URL: `https://be.graph8.com/api/v1/desk/org-settings`
- Auth: HTTP bearer

Update org-level desk settings. PARTIAL - unset fields are untouched.

Requires `settings:write`, declared on this route because the app's own
gate is a `Depends`-defaulted PARAMETER of the handler and a direct call
resolves nothing.

THIS IS THE ORG'S ON SWITCH, AND ITS SPEND CAPS. Saving here registers the
org on the desk worker's poll list - and saving every decision off
unregisters it - so this one call starts or stops the desk producing work
for the whole organisation. It also carries `max_auto_account_plans_per_day`,
`max_account_replans_per_day` and `max_skill_plans_per_day`, which are
daily caps on CHARGED model calls, and `desk_acts_on_signals`,
`desk_drafts_with_ai` and `stalled_deal_send_email`, which let the desk act
and email on its own. A plain `write` would make raising an org's spend cap
the same grant as renaming a record.

400 with the reason on anything the settings validator refuses, including
an empty body - "no settings provided" is an error here rather than a
silent no-op.

## Headers

- `Authorization` string, nullable
- `X-Target-Org-Id` string, nullable

## Request body

- DeskOrgSettingsUpdate: Org-level desk settings. PARTIAL - an unset field is left untouched. Mirrors `desk.interfaces.fastapi.dtos.DeskOrgSettingsUpdate` field for field, pinned by test, because it is constructed inside the proxy. THREE KINDS OF FIELD LIVE HERE AND THEY ARE NOT EQUALLY QUIET --------------------------------------------------------------- Most are thresholds and ids. But `max_auto_account_plans_per_day`, `max_account_replans_per_day` and `max_skill_plans_per_day` are the org's DAILY SPEND CAPS on charged model calls, and `desk_acts_on_signals`, `desk_drafts_with_ai`, `desk_writes_deal_plans`, `reps_may_fire_workflows` and `stalled_deal_send_email` are the switches that let the desk act - and email - on its own. That is why this operation is not tiered a plain `write`; see the router docstring. Every value is validated by the app's own `validated_payload()` and `save_desk_org_settings`, which answer 400 with the reason. This surface does not second-guess either.
  - `no_reply_threshold_days` integer, nullable
  - `no_reply_channels` string[], nullable
  - `enrichment_win_fields` string[], nullable
  - `max_cards_per_generator_per_day` integer, nullable
  - `max_auto_account_plans_per_day` integer, nullable: DAILY CAP on charged auto account plans.
  - `max_account_replans_per_day` integer, nullable: DAILY CAP on charged account re-plans.
  - `max_skill_plans_per_day` integer, nullable: DAILY CAP on charged skill plans.
  - `plan_required_stage_ids` string[], nullable
  - `signals_enabled` object, nullable: Per-signal kill switches. `ai_briefs` is the desk-wide LLM-spend gate and `morning_kickoff` gates the daily briefing.
  - `daily_action_target` integer, nullable
  - `pipeline_target_quarterly` integer, nullable
  - `lead_sla_minutes` integer, nullable
  - `desk_writes_deal_plans` boolean, nullable
  - `desk_acts_on_signals` boolean, nullable
  - `desk_keeps_crm_tidy` boolean, nullable
  - `desk_drafts_with_ai` boolean, nullable
  - `reps_may_fire_workflows` boolean, nullable
  - `desk_escalates_to_managers` boolean, nullable
  - `stalled_deal_enabled` boolean, nullable
  - `stalled_deal_stage_ids` string[], nullable
  - `stalled_deal_warn_after_days` integer, nullable
  - `stalled_deal_approve_after_days` integer, nullable
  - `stalled_deal_manager_user_id` string, nullable
  - `stalled_deal_fallback_manager_user_id` string, nullable
  - `stalled_deal_reassign_to_user_id` string, nullable
  - `stalled_deal_send_email` boolean, nullable: Let the stalled-deal escalation EMAIL the manager.
  - `stalled_deal_undo_window_minutes` integer, nullable
  - `stalled_deal_reminder_after_hours` integer, nullable
  - `stalled_deal_skip_crm_synced_transfer` boolean, nullable
  - `stalled_deal_require_activity_evidence` boolean, nullable
  - `stalled_deal_min_deal_age_days` integer, nullable
  - `stalled_deal_min_amount` integer, nullable
  - `overdue_self_task_enabled` boolean, nullable
  - `overdue_task_max_age_days` integer, nullable
  - `contact_update_planned_deals_only` boolean, nullable
  - `fallback_owner_emails` string[], nullable
  - `signal_policies` object, nullable

## Response `200`

Successful Response

- ApiResponseDeskPayload
  - `data` DeskPayload, required: An open envelope for one desk object. Open on purpose - see the module docstring. A rebuilder gets every field the desk returns, including ones added after this contract version.
  - `pagination` PaginationMeta
    - `page` integer, required: Current page number (1-indexed)
    - `limit` integer, required: Items per page
    - `total` integer, required: Total number of items
    - `has_next` boolean, required: Whether there are more pages
    - `next_cursor` string, nullable: Opaque cursor for the next page; null when there are no more items. Pass it back as the `cursor` query param to fetch the following page without computing page numbers.
    - `total_available` integer, nullable: Search endpoints only: how many records really match, when known. Can be larger than `total`, which is capped at the 10,000 results that can be paged. For company search this is a distinct-company estimate. Null when unknown; absent outside search.
    - `total_is_lower_bound` boolean, nullable: Search endpoints only: true when more records match than `total` shows (the result set is larger than the 10,000 results that can be paged). Absent outside search.
    - `notes` string[], nullable: Search endpoints only: plain-language notes about the result, e.g. that more records match than can be paged, or that a reversed `between` range was put in order.

## Other responses

- `422`: Validation Error

---

[API](https://skmtc.dev/graph8/apis/graph8-developer-api.md) · [All operations](https://skmtc.dev/graph8/apis/graph8-developer-api/llms.txt) · [OpenAPI document](https://skmtc.dev/graph8/apis/graph8-developer-api/revisions/2e7cfa0ca921?raw)
