# chiefOfStaff.rules.save

Add or change a rule for some people: by Discord person or role, optionally only in some channels, give them tools, take tools away, answer them with a profile, or add instructions. A tool turned off anywhere else stays off. Pass id and expectedRevision to change a rule. Only the platform owner's workspace has a Chief of Staff. Administrator access required.

`POST /api/v1/accounting/chiefOfStaff.rules.save`

Permissions: `accounting:read`, `accounting:write`, `accounting:admin` · Roles: admin · Idempotency key required · Send `expectedRevision`

MCP tool: `accounting_chief_of_staff_rules_save`

## Fields

| Field | Type | Required | Notes |
| --- | --- | --- | --- |
| `id` | string (ID) |  | The rule to change. Leave it out to add a rule. |
| `name` | string | Yes | A display name. 1–100 characters. |
| `enabled` | boolean |  |  |
| `people` | array of objects |  | Discord people the rule applies to, each with the name to show. at most 50 items. |
| `people[].userId` | string | Yes | The ID of a person in your company. Matches ^\d{17,20}$. |
| `people[].name` | string or null |  | A display name. |
| `roles` | array of strings |  | Discord role names the rule applies to; anyone with one of them matches. at most 50 items; each 1–100 characters. |
| `channelIds` | array of strings |  | Only in these channels and their threads. Empty means everywhere. at most 50 items; each Matches ^\d{17,20}$. |
| `allowTools` | array of enum values |  | One of: `getCurrentEventsFromLuma`, `getEventStatsFromLuma`, `getEventDetailsFromLuma`, `getEventGuestsFromLuma`, `getCommunityContacts`, `webSearch`, `scrapeUrl`, `github`, `weather`. at most 9 items. |
| `blockTools` | array of enum values |  | One of: `getCurrentEventsFromLuma`, `getEventStatsFromLuma`, `getEventDetailsFromLuma`, `getEventGuestsFromLuma`, `getCommunityContacts`, `webSearch`, `scrapeUrl`, `github`, `weather`. at most 9 items. |
| `profileId` | enum or null |  | Answer these people with this profile. One of: `general`, `hackathon`, `organizer`, `news`. |
| `instructions` | string |  | Extra instructions the Chief of Staff follows there, in plain words. Empty clears them. at most 2000 characters. |
| `expectedRevision` | integer |  | The revision you last read: 0 for something never saved. A different revision means someone else changed it first. 0 to 9007199254740990. |
| `idempotencyKey` | string | Yes | Any unique text you generate once per intended change, so a retried request only happens once. Send it as the Idempotency-Key header instead if you prefer; if you send both they must match. 8–200 characters. |

## Example request

```bash
curl https://app.getoatmilk.com/api/v1/accounting/chiefOfStaff.rules.save \
  -H "Authorization: Bearer $OATMILK_API_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: $(uuidgen)" \
  -d '{
  "name": "Synthetic Ventures Inc."
}'
```

Reference page: https://app.getoatmilk.com/docs/api/chiefOfStaff.rules.save
