> ## Documentation Index
> Fetch the complete documentation index at: https://docs.nowadays.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# Making changes

> How a prepared change becomes a real one, which tools prepare, and the rules event changes follow.

A tool that changes something never acts when called. It prepares the change
and returns a preview. The change happens only when `confirm_change` runs,
after the person saw the preview and said yes.

| Behavior | Tools |
| - | - |
| Prepare a change for `confirm_change` | Every tool of kind Prepare in the [tool list](https://docs.nowadays.ai/mcp/tools.md) |
| Save at once, with no confirm | `shortlist_proposal` (a bookmark that no venue is told about), `select_organization` (which organization this client works in) |
| Change nothing | Every tool of kind Read |

Emails go out only on confirm. A tool that emails a hotel or a person, such
as `send_rfp`, `message_hotel` or `invite_to_org`, sends nothing until the
change is confirmed.

## Confirm a prepared change

**1. Prepare the change**

Call the tool that prepares it, for example `update_event`. The result has two
parts: a preview in plain words, then a handoff like this:

```json theme={null}
{
  "status": "needs_approval",
  "instruction": "Nothing has changed yet. Show the person the preview…",
  "draft_id": 31,
  "approval_token": "eyJ…",
  "change": "Update event 3f2b…: numPeople",
  "expires_at": "2027-03-01T10:10:00.000Z"
}
```

**2. Show the person the preview**

Show the preview word for word, then ask whether to go ahead.

**3. Wait for a yes**

If the person says no, or does not answer, do nothing. The prepared change
expires on its own.

**4. Call confirm\_change**

Pass the `approval_token`, the `change` copied exactly, and
`user_approved: true`. Never set `user_approved` unless the person said yes
in this conversation.

**5. Report the status**

Tell the person what the result's `status` and `message` say. See
[Statuses](#statuses) for what each status means.

## `confirm_change`

Applies a change that one of the prepare tools returned.

| Argument | Type | Description |
| - | - | - |
| `approval_token` | string | The `approval_token` from the prepare result. Required. |
| `change` | string | The prepare result's `change` line, copied exactly. Required. |
| `user_approved` | boolean | `true` only after the person said yes. Without it nothing changes. |

Returns `draft_id`, `status`, a `message` and the `rows` it changed. Every
status except `applied` flags the result as an error, so a client that reads
only the error flag never takes a partial or failed change for success.

The approval follows these rules:

* A token works only for the person who prepared it, and only in the
  organization that was selected then.
* A token expires after 10 minutes. Prepare the change again to get a new one.
* A `change` that differs from the prepared one is refused, and nothing runs.
* If the event changed after an `update_event` preview, the confirm applies
  nothing and says so. Call `get_event` and prepare the change again.
* The confirm checks again that you can still reach the change's event in the
  organization you have selected. If your access was revoked, or you switched
  organization, nothing runs.

### Statuses

| Status | What it means |
| - | - |
| `applied` | The change was made. |
| `partial` | Part of the change was made, for example two of three RFPs went out. The `rows` say which parts. Read the event back before you prepare the rest again. |
| `failed` | Nothing was applied. A failed change is not retried. Prepare it again to try once more. |
| `unknown` | The change may already have happened. Read the event back before you prepare it again. |

### Confirming twice

A change runs at most once. Confirming the same `approval_token` again never
runs it a second time. It reports the first outcome instead, for example "This
change was already applied. It was not run again." That makes it safe to
confirm again after a dropped connection.

If the confirm itself cannot reach the record of the change, the error says so.
Call `confirm_change` again with the same `approval_token` and `change` before
you prepare anything new.

## Event changes

`create_event` and `update_event` follow extra rules, covered here.

If an `update_event` change would alter nothing, the tool says so and prepares
nothing.

### Creating

The confirm result names the new event's `id` in its `message` and `rows`.

The organization comes from your session, so it is never an argument. The
preview names it, so the person can check where the event will land.

### Updating

`update_event` takes only the fields you are changing, under `changes`. Three
rules apply to every update:

> [accordion] Omitted means unchanged, null means cleared
>
> A field you leave out is not touched. Sending `null` clears it. You cannot
> blank a field by leaving it out, and you cannot clear one by guessing at an
> empty value.

> [accordion] All or nothing
>
> If any field is rejected, **nothing is written** and the error lists every
> problem at once. A rejected update always leaves the event untouched, so
> it is safe to correct and retry without checking what partially landed.

> [accordion] Some fields are derived, not writable
>
> `location` is derived from `formattedLocations`. Event dates are derived
> from the union of your guestroom nights and agenda date ranges. Neither is
> accepted as input. Send the inputs and the derived values follow.

### Editing the agenda

The agenda is edited by **operation**, not by replacement. Send
`agendaOperations` with `add`, `update` or `remove`, each addressed by a session
`id` from a prior `get_event`:

```json theme={null}
{
  "agendaOperations": [
    { "op": "update", "sessionId": "a1b2…", "session": { "startTime": "09:30" } },
    { "op": "remove", "sessionId": "c3d4…" },
    {
      "op": "add",
      "session": {
        "title": "Closing keynote",
        "dates": ["2027-03-17"],
        "startTime": "16:00",
        "endTime": "17:00"
      }
    }
  ]
}
```

There is no way to replace the whole agenda. Replacing it to change one session
is expensive, and it drops any session you forgot to include. An unknown
`sessionId` is an error, not a silent no-op.

### Two refusals worth planning for

**A canceled event cannot be edited.** Reopen it in Nowadays first.

**Shrinking the agenda dates is refused if any session would lose a date.** The
affected sessions are named in `orphanedSessions`:

```json theme={null}
{
  "message": "Those agenda dates would drop sessions…",
  "orphanedSessions": [
    {
      "sessionId": "a1b2…",
      "title": "Kickoff",
      "droppedDates": ["2027-03-14"],
      "fullyOrphaned": true
    }
  ]
}
```

The dashboard drops such sessions after an "are you sure" prompt. An agent has
no such prompt, so the write is refused instead. Move or remove the sessions,
then retry.

### Limits

A single call is bounded so one request cannot monopolize the service:

| Field | Limit |
| - | - |
| `agendaOperations` | 200 per request |
| `formattedLocations` | 50 per request |
| `decisionFactors`, `additionalServices` | 50 values each |
| `accommodations` | 400 nights |
| `meetingRoomDates` | 50 ranges, each ≤ 366 days |
| Free-text fields | 1,000 characters |
| `name` | 100 characters |

A value over a limit is rejected with the field named, and nothing is written.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.