# Quick command (AI)

> Send one line or a braindump of free text. An AI model turns it into events, Inbox blocks, and logged moments, and applies them.

Source: https://reassign.dev/reference/command/

Use this endpoint to send free text to the Reassign command bar. An AI model turns the text into changes to the day plan, and Reassign applies them.

The machine-readable spec of all public endpoints: [openapi.json](https://reassign.dev/openapi.json).

> This endpoint is **Beta**. An AI model makes the output, so the same input can give a different result. The response format can change.

## The command result model

A command result tells you what the model understood and what Reassign wrote.

- The model uses these data:
  - The schedule of the day
  - The areas and activity types of the user
  - The live projects of the user. An archived project is not in the list.
  - The trackers
  - The writable calendars
  - The AI rules of the user
- The model sees the events of the day, and the events of the day before that cross midnight into the day. For an event from the day before, it sees only the part after midnight. For each event, it also sees the recurrence rule, the checklist, and the review mark.
- An `update` that changes only the length of an event from the day before is dropped with the notice `A new length was skipped because its event is unclear.` A new `start` or `end` works.
- A recurring event that crosses midnight can show two occurrences on one day. One is the part after midnight of the occurrence from the day before. The other is the occurrence of the day.
- The model names the occurrence that a change is for. For the occurrence of the day, Reassign checks a new `end` or a new length against its start. A change with no new `end`, for example a new name, goes to the occurrence of the day. A new `end` that fits the occurrence of the day also goes to that occurrence, also when the model names the part after midnight.
- An `update` for the part after midnight can have a new `end` and no `start`, for example "wake me at 06:00". With `scope: "occurrence"`, when that `end` fits only the part after midnight, Reassign changes only the occurrence of the day before. It gives no notice.
- An `update` for the occurrence of the day can have a new `end` that is not after its start. Reassign drops the `end` with the notice `A new end was skipped because it is not after the start.` The other changes of the `update` stay. A new length for the occurrence of the day uses the start of that occurrence.
- A question, for example "how much free time today?", gives an answer in `reply`. It writes nothing.
- A request that is not about the plan gets no intents and the reply `I can only help with your plan.`

| Field          | Meaning                                                                                                                                                                                                                         |
| -------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `date`         | The day that the command used, as `YYYY-MM-DD`.                                                                                                                                                                                 |
| `intents`      | The plan that the model made. Each item has an `op` field. The intents use the same shapes as the event write operations. Refer to the intent types below.                                                                      |
| `questions`    | The questions that the model asks when the text is not clear. Reassign does not apply questions.                                                                                                                                |
| `notices`      | The parts that Reassign could not do, and other notes.                                                                                                                                                                          |
| `reply`        | Optional. The short plain-text answer of the model, a maximum of 400 characters. It is absent when the model said nothing.                                                                                                      |
| `created`      | Optional. Each new event and Inbox block: `id`, `entity` (`event` or `inbox`), `name`, `kind`, and `areaId` and `activityTypeId` when set. A new event also has `start` and `end`. It is absent when Reassign made no new item. |
| `written`      | Optional. The indexes in `intents` that Reassign wrote. An intent that is not in the list was refused, and a notice tells why.                                                                                                  |
| `writtenLines` | Optional. One line for each written intent, in the order of `written`, with the name of its event. Each line has a maximum of 160 characters.                                                                                   |
| `undoToken`    | Only when Reassign wrote a change. Use it to undo all the changes of the command.                                                                                                                                               |
| `expiresAt`    | Only with `undoToken`. The time when the undo token expires, as an ISO 8601 UTC instant (30 minutes after the write).                                                                                                           |

A preview (`"apply": false`), or a plan that makes no writes, has no `undoToken`, no `expiresAt`, no `created`, no `written`, and no `writtenLines`.

The plan has a maximum of 4 notices. The input notices of Reassign come first, for example the notice for a cut braindump. The notices of the model come after them. When there are more, the last of the 4 notices is `<n> more notes were not shown.`. Reassign then adds its own write notices, for example the calendar refusals.

- `date` (_string, required_)
- `intents` (_object\[], required_)
  - One form: `op: "create"`
    - `start` (_string, required_)
    - `end` (_string, required_)
    - `name` (_string, required_)
    - `areaId` (_string | null, required_)
    - `activityTypeId` (_string | null, required_)
    - `recurrence` (_string_)
    - `kind` (_"blocking" | "non\_blocking" | "reference"_)
    - `focusIntervals` (_object_)
      - `focusMin` (_integer, required_)
      - `breakMin` (_integer, required_)
    - `calendarId` (_string_): The home calendar id. Absent: the account's default calendar if one is set, else the event stays on the dial only.
    - `checklist` (_string\[]_): Checklist items of the new event.
    - `projectId` (_string_): The project of the new item. Absent: no project. A project with an area also sets that area.
    - `priority` (_integer_): The priority of the new item: 4 urgent, 3 high, 2 medium, 1 low. Absent: none.
  - One form: `op: "update"`
    - `id` (_string, required_)
    - `start` (_string_)
    - `ripple` (_boolean_)
    - `focusIntervals` (_object | null_)
      - `focusMin` (_integer, required_)
      - `breakMin` (_integer, required_)
    - `kind` (_"blocking" | "non\_blocking" | "reference"_): A new kind; sent only when the user asks for it.
    - `name` (_string_)
    - `end` (_string_): A new end after the (new) start: it resizes the event.
    - `areaId` (_string_)
    - `activityTypeId` (_string_)
    - `appendNote` (_string_): One line added to the end of the notes.
    - `notes` (_string_): Notes that replace the old ones; "" clears them.
    - `scope` (_"occurrence" | "series" | "future"_): On a recurring event: "occurrence" = this day only, "series" = every occurrence, "future" = this day and every later one. A one-off event ignores it.
  - One form: `op: "shift"`
    - `id` (_string, required_)
    - `byMinutes` (_integer, required_)
    - `ripple` (_boolean_)
  - One form: `op: "delete"`
    - `id` (_string, required_)
    - `scope` (_"occurrence" | "series" | "future"_): On a recurring event: "occurrence" = this day only, "series" = every occurrence, "future" = this day and every later one. A one-off event ignores it.
  - One form: `op: "clear"`
    - `from` (_string, required_)
    - `to` (_string, required_)
  - One form: `op: "park"`
    - `id` (_string_)
    - `name` (_string, required_)
    - `durationMinutes` (_integer_)
    - `areaId` (_string | null, required_)
    - `activityTypeId` (_string | null, required_)
    - `projectId` (_string_): The project of the new item. Absent: no project. A project with an area also sets that area.
    - `priority` (_integer_): The priority of the new item: 4 urgent, 3 high, 2 medium, 1 low. Absent: none.
  - One form: `op: "log_moment"`
    - `mood` (_boolean_)
    - `trackerId` (_string_)
    - `value` (_number_)
    - `time` (_string_)
  - One form: `op: "checklist"`
    - `id` (_string, required_)
    - `add` (_string\[], required_)
    - `target` (_"backlog"_)
    - `scope` (_"occurrence" | "series" | "future"_): On a recurring event: "occurrence" = this day only, "series" = every occurrence, "future" = this day and every later one. A one-off event ignores it.
  - One form: `op: "checklist_edit"`
    - `id` (_string, required_)
    - `item` (_string, required_)
    - `edit` (_"check" | "uncheck" | "rename" | "remove", required_)
    - `newText` (_string_): The new item text; only with `edit: "rename"`.
    - `scope` (_"occurrence" | "series" | "future"_): On a recurring event: "occurrence" = this day only, "series" = every occurrence, "future" = this day and every later one. A one-off event ignores it.
  - One form: `op: "split"`
    - `id` (_string, required_)
    - `at` (_string, required_)
    - `secondName` (_string_): The name of the second part. Absent: the same name.
  - One form: `op: "remember"`
    - `text` (_string, required_)
  - One form: `op: "reflect"`
    - `status` (_"kept" | "skipped" | "changed" | "added", required_)
    - `id` (_string_): The event; absent only with `status: "added"`.
    - `actualStart` (_string_)
    - `actualEnd` (_string_)
    - `name` (_string_): The name of an `"added"` event.
    - `areaId` (_string_)
    - `activityTypeId` (_string_)
  - One form: `op: "day_note"`
    - `wentWell` (_string_)
    - `wentBadly` (_string_)
    - `lesson` (_string_)
    - `replace` (_boolean_)
- `questions` (_object\[], required_)
  - One form: `kind: "target"`
    - `question` (_string, required_)
    - `candidates` (_object\[], required_)
      - `id` (_string, required_)
      - `label` (_string, required_)
    - `op` (_object, required_)
      - One form: `op: "update"`
        - `start` (_string_)
        - `ripple` (_boolean_)
        - `focusIntervals` (_object | null_)
          - `focusMin` (_integer, required_)
          - `breakMin` (_integer, required_)
        - `kind` (_"blocking" | "non\_blocking" | "reference"_): A new kind; sent only when the user asks for it.
        - `name` (_string_)
        - `end` (_string_): A new end after the (new) start: it resizes the event.
        - `areaId` (_string_)
        - `activityTypeId` (_string_)
        - `appendNote` (_string_): One line added to the end of the notes.
        - `notes` (_string_): Notes that replace the old ones; "" clears them.
        - `scope` (_"occurrence" | "series" | "future"_): On a recurring event: "occurrence" = this day only, "series" = every occurrence, "future" = this day and every later one. A one-off event ignores it.
      - One form: `op: "shift"`
        - `byMinutes` (_integer, required_)
        - `ripple` (_boolean_)
      - One form: `op: "delete"`
        - `scope` (_"occurrence" | "series" | "future"_): On a recurring event: "occurrence" = this day only, "series" = every occurrence, "future" = this day and every later one. A one-off event ignores it.
      - One form: `op: "park"`
        - `name` (_string, required_)
        - `durationMinutes` (_integer_)
        - `areaId` (_string | null, required_)
        - `activityTypeId` (_string | null, required_)
        - `projectId` (_string_): The project of the new item. Absent: no project. A project with an area also sets that area.
        - `priority` (_integer_): The priority of the new item: 4 urgent, 3 high, 2 medium, 1 low. Absent: none.
      - One form: `op: "checklist"`
        - `add` (_string\[], required_)
        - `target` (_"backlog"_)
        - `scope` (_"occurrence" | "series" | "future"_): On a recurring event: "occurrence" = this day only, "series" = every occurrence, "future" = this day and every later one. A one-off event ignores it.
      - One form: `op: "checklist_edit"`
        - `item` (_string, required_)
        - `edit` (_"check" | "uncheck" | "rename" | "remove", required_)
        - `newText` (_string_): The new item text; only with `edit: "rename"`.
        - `scope` (_"occurrence" | "series" | "future"_): On a recurring event: "occurrence" = this day only, "series" = every occurrence, "future" = this day and every later one. A one-off event ignores it.
      - One form: `op: "split"`
        - `at` (_string, required_)
        - `secondName` (_string_): The name of the second part. Absent: the same name.
  - One form: `kind: "choice"`
    - `question` (_string, required_)
    - `options` (_object\[], required_)
      - `label` (_string, required_)
      - `ops` (_object\[], required_)
        - One form: `op: "create"`
          - `start` (_string, required_)
          - `end` (_string, required_)
          - `name` (_string, required_)
          - `areaId` (_string | null, required_)
          - `activityTypeId` (_string | null, required_)
          - `recurrence` (_string_)
          - `kind` (_"blocking" | "non\_blocking" | "reference"_)
          - `focusIntervals` (_object_)
            - `focusMin` (_integer, required_)
            - `breakMin` (_integer, required_)
          - `calendarId` (_string_): The home calendar id. Absent: the account's default calendar if one is set, else the event stays on the dial only.
          - `checklist` (_string\[]_): Checklist items of the new event.
          - `projectId` (_string_): The project of the new item. Absent: no project. A project with an area also sets that area.
          - `priority` (_integer_): The priority of the new item: 4 urgent, 3 high, 2 medium, 1 low. Absent: none.
        - One form: `op: "update"`
          - `id` (_string, required_)
          - `start` (_string_)
          - `ripple` (_boolean_)
          - `focusIntervals` (_object | null_)
            - `focusMin` (_integer, required_)
            - `breakMin` (_integer, required_)
          - `kind` (_"blocking" | "non\_blocking" | "reference"_): A new kind; sent only when the user asks for it.
          - `name` (_string_)
          - `end` (_string_): A new end after the (new) start: it resizes the event.
          - `areaId` (_string_)
          - `activityTypeId` (_string_)
          - `appendNote` (_string_): One line added to the end of the notes.
          - `notes` (_string_): Notes that replace the old ones; "" clears them.
          - `scope` (_"occurrence" | "series" | "future"_): On a recurring event: "occurrence" = this day only, "series" = every occurrence, "future" = this day and every later one. A one-off event ignores it.
        - One form: `op: "shift"`
          - `id` (_string, required_)
          - `byMinutes` (_integer, required_)
          - `ripple` (_boolean_)
        - One form: `op: "delete"`
          - `id` (_string, required_)
          - `scope` (_"occurrence" | "series" | "future"_): On a recurring event: "occurrence" = this day only, "series" = every occurrence, "future" = this day and every later one. A one-off event ignores it.
        - One form: `op: "clear"`
          - `from` (_string, required_)
          - `to` (_string, required_)
        - One form: `op: "park"`
          - `id` (_string_)
          - `name` (_string, required_)
          - `durationMinutes` (_integer_)
          - `areaId` (_string | null, required_)
          - `activityTypeId` (_string | null, required_)
          - `projectId` (_string_): The project of the new item. Absent: no project. A project with an area also sets that area.
          - `priority` (_integer_): The priority of the new item: 4 urgent, 3 high, 2 medium, 1 low. Absent: none.
        - One form: `op: "log_moment"`
          - `mood` (_boolean_)
          - `trackerId` (_string_)
          - `value` (_number_)
          - `time` (_string_)
        - One form: `op: "checklist"`
          - `id` (_string, required_)
          - `add` (_string\[], required_)
          - `target` (_"backlog"_)
          - `scope` (_"occurrence" | "series" | "future"_): On a recurring event: "occurrence" = this day only, "series" = every occurrence, "future" = this day and every later one. A one-off event ignores it.
        - One form: `op: "checklist_edit"`
          - `id` (_string, required_)
          - `item` (_string, required_)
          - `edit` (_"check" | "uncheck" | "rename" | "remove", required_)
          - `newText` (_string_): The new item text; only with `edit: "rename"`.
          - `scope` (_"occurrence" | "series" | "future"_): On a recurring event: "occurrence" = this day only, "series" = every occurrence, "future" = this day and every later one. A one-off event ignores it.
        - One form: `op: "split"`
          - `id` (_string, required_)
          - `at` (_string, required_)
          - `secondName` (_string_): The name of the second part. Absent: the same name.
        - One form: `op: "remember"`
          - `text` (_string, required_)
        - One form: `op: "reflect"`
          - `status` (_"kept" | "skipped" | "changed" | "added", required_)
          - `id` (_string_): The event; absent only with `status: "added"`.
          - `actualStart` (_string_)
          - `actualEnd` (_string_)
          - `name` (_string_): The name of an `"added"` event.
          - `areaId` (_string_)
          - `activityTypeId` (_string_)
        - One form: `op: "day_note"`
          - `wentWell` (_string_)
          - `wentBadly` (_string_)
          - `lesson` (_string_)
          - `replace` (_boolean_)
- `notices` (_string\[], required_)
- `reply` (_string_): The assistant's short plain-text answer, for example to a question about the plan. Absent when it said nothing.
- `created` (_object\[]_): Each new event (with its span) and Inbox block, with its kind, area and activity type. Absent when nothing was made.
  - `id` (_string, required_)
  - `entity` (_"event" | "inbox", required_)
  - `name` (_string, required_)
  - `kind` (_"blocking" | "non\_blocking" | "reference", required_)
  - `areaId` (_string_)
  - `activityTypeId` (_string_)
  - `start` (_string_)
  - `end` (_string_)
- `written` (_integer\[]_): The indexes in `intents` that were written. An intent that is not here was refused; a notice says why. Absent when nothing was written.
- `writtenLines` (_string\[]_): One line for each written intent, in the order of `written`, with the name of its event. Join them with newlines for the `written` of the next history turn. Absent when nothing was written.
- `undoToken` (_string_)
- `expiresAt` (_string_)

### Intent types

A span in an intent is a `start` and an `end` as local datetimes, `"YYYY-MM-DDTHH:MM"`, with no offset.

| `op`             | What it does                                                                                                                                                                                                                                                                                                                              |
| ---------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `create`         | Adds an event. It has `name`, `start`, `end`, `areaId`, `activityTypeId`, and optional fields, for example `checklist` (the checklist items). When the model gives no end, the end is 1 hour after the start.                                                                                                                             |
| `update`         | Changes an event. It can set a new `start` (a move), `end` (a resize), `name`, `kind`, `areaId`, `activityTypeId`, or `focusIntervals` (`null` removes them). `notes` replaces the notes (`""` clears them), and `appendNote` adds one line. With `ripple: true`, the later events of the day move too.                                   |
| `shift`          | Moves an event by `byMinutes`. With `ripple: true`, the later events move too.                                                                                                                                                                                                                                                            |
| `delete`         | Removes an event. Only in `line` mode.                                                                                                                                                                                                                                                                                                    |
| `clear`          | Deletes the events of the command day (`date`) when that day is in the range from `from` to `to` (`YYYY-MM-DD`). It does not delete events on other days, and it gives no notice for them. When it finds no event to delete, it adds the notice `Nothing was cleared because no deletable events are in that range.` Only in `line` mode. |
| `park`           | Adds a block to the Inbox, with an optional `durationMinutes` from 5 to 1440. It has `areaId` and `activityTypeId`. With an `id`, it moves that event to the Inbox. With no `id`, it adds a new Inbox block.                                                                                                                              |
| `log_moment`     | Logs a moment against a tracker. With no `trackerId`, it logs a mood (`mood: true`) against the first rating tracker. When the model gives no `time`, Reassign uses the current time of day. It uses the time zone of the user and the day of the command.                                                                                |
| `checklist`      | Adds checklist items (`add`) to an event. A bare series `id` adds them to the series. An `id` with `@YYYY-MM-DD` adds them to that day only. With `target: "backlog"`, the `id` is an Inbox item.                                                                                                                                         |
| `checklist_edit` | Changes one checklist item of an event. `item` finds the item by its text (not case-sensitive, exact after the trim). `edit` is `check`, `uncheck`, `rename` (with `newText`), or `remove`. When no item or more than one item matches, Reassign changes nothing and adds a notice.                                                       |
| `split`          | Cuts an event into two parts at `at`, a local datetime inside the event. `secondName` is the name of the second part. Without it, the two parts have the same name. On a recurring event, it splits only that occurrence.                                                                                                                 |
| `remember`       | A stable preference of the user, as `text` (a maximum of 200 characters). `POST /api/v1/command` returns it, but it does not save it.                                                                                                                                                                                                     |
| `reflect`        | Only in review mode. Records how a past event went: `status` is `kept`, `skipped`, `changed`, or `added`. `changed` can have `actualStart` and `actualEnd`. `added` creates an unplanned event from `name`, `actualStart`, and `actualEnd`, and it has no `id`.                                                                           |
| `day_note`       | Only in review mode. Adds a line to the note of the day in `wentWell`, `wentBadly`, or `lesson` (each a maximum of 500 characters). With `replace: true`, the text replaces the field.                                                                                                                                                    |

`update`, `delete`, `checklist`, and `checklist_edit` have an optional `scope` for a recurring event:

| `scope`      | Changes                             |
| ------------ | ----------------------------------- |
| `occurrence` | This day only                       |
| `series`     | Every occurrence                    |
| `future`     | This day and every later occurrence |

A one-off event ignores `scope`.

- A `delete` with `occurrence` hides that day only. With `series`, it deletes the series and each changed occurrence. With `future`, it ends the series on the day before. It also deletes each later changed occurrence. On the first day of the series, `future` deletes the full series.

- A `series` or `future` change from a changed occurrence goes to the series of that occurrence. The occurrence keeps its own changes.

- When such a change has a new end that is not after the start of the changed occurrence, the series gets the new end. The occurrence keeps its end, and the notice is `"<name>" on <date> keeps its end because its new end is not after its start on that day.`

- When the line does not give the scope of an edit or a delete on a recurring event, the plan has one `choice` question with an option for each scope. Reassign does not write that edit or delete. Each option label is a scope phrase, so the user can add the label to the line.

- A delete of an event from a calendar gets no scope question. A change or a delete of a changed occurrence with no scope gets no question either. It applies to that day only.

- `POST /api/v1/events` is different in two cases. A bare series id changes the series only. A `scope: "future"` op with a new time deletes the changed day. Refer to [Events](https://reassign.dev/reference/events.md#ids-of-recurring-events).

- The model can only use areas, activity types, trackers, and calendars that exist.

- Sometimes the model writes a name in an id field. When the name matches exactly one area, activity type, calendar, or tracker, Reassign uses the id of that item.

- An unknown area or activity type on a `create` or a new `park`: Reassign keeps the item without that label and adds a notice (table below).

- An unknown calendar on a `create`: Reassign skips the event and adds the notice `"<name>" was skipped because its calendar is unknown.`

- An unknown tracker on a `log_moment`: Reassign skips the log and adds the notice `A log was skipped because its tracker is unknown.`

- In a `create` or a `park` intent, `areaId` and `activityTypeId` are always present. Each one is `null` when it is not set.

- A `create` or a new `park` intent can have `projectId` and `priority`. They are absent when the line names no project and no priority. `priority` is `1` low, `2` medium, `3` high, or `4` urgent.

- The model can only use live projects. A project with an area also sets that area on the item.

- An unknown project, or a priority that is not from 1 to 4, is dropped with a notice. Reassign keeps the item (table below).

- In `line` mode, when the plan has exactly one new item, the typed tags of the line set its fields: `#name` (a project or an area), `@type` (an activity type), and `p1` to `p4` or `!` to `!!!!` (the priority). The order of the tags is the reverse of the values: `p1` or `!!!!` gives `4` (urgent), `p2` or `!!!` gives `3`, `p3` or `!!` gives `2`, and `p4` or `!` gives `1` (low). The tags must be in the run of tags and durations at the end of the line. A typed tag wins over the model.

- A `create` intent has `calendarId` only when the model names a calendar. It never has `calendarId: null` or `mirrorCalendarIds`. With no `calendarId`, Reassign publishes the event to the default calendar of the account, if one is set. Else the event stays on the dial only.

- Reassign does not change a `log_moment` value or a `park` length to make it valid. It drops the item and adds a notice:

| Value                                                            | Notice                                                                                               |
| ---------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------- |
| A new `park` item with a `durationMinutes` outside 5 to 1440     | `"<name>" was not added to the Inbox because its length of <minutes> minutes is not from 5 to 1440.` |
| A rating value outside the bounds of the tracker                 | `A log was skipped because its value <value> is not from <min> to <max>.`                            |
| A rating value that is not a whole number                        | `A log was skipped because its value is not a whole number.`                                         |
| A value that is not a number, on a `tally` or `quantity` tracker | `A log was skipped because its value is not a number.`                                               |

`POST /api/v1/moments` rejects the same rating values with `422`. Refer to [Moments & trackers](https://reassign.dev/reference/moments-and-trackers.md).

Notices for an unknown area or activity type, on an item that Reassign keeps:

| Cause                             | Notice                                                                                         |
| --------------------------------- | ---------------------------------------------------------------------------------------------- |
| An unknown area                   | `"<name>" has no area, because the AI chose one that is not in your list.`                     |
| An unknown activity type          | `"<name>" has no activity type, because the AI chose one that is not in your list.`            |
| An unknown area and activity type | `"<name>" has no area and activity type, because the AI chose ones that are not in your list.` |
| An unknown project                | `"<name>" has no project, because the AI chose one that is not in your list.`                  |
| A priority that is not valid      | `"<name>" has no priority, because the AI chose one that is not valid.`                        |

Other notices for an item that Reassign drops:

| Cause                                                                                                                                                                                                                                                                | Notice                                                                                                                                        |
| -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------- |
| A `delete` names an event that is not on the command day                                                                                                                                                                                                             | `A delete was skipped because its event is not on this day.`                                                                                  |
| A `park` names an event that is not on the command day                                                                                                                                                                                                               | `A park was skipped because its event is not on this day.` or `A move to Inbox was skipped because its event is not on this day.`             |
| An `update` names an event that is not on the command day                                                                                                                                                                                                            | `A change was skipped because its event is not on this day.`                                                                                  |
| An `update` has a new `end` that is not after the start, or that is more than 168 hours after the start. The start is the new `start` of the `update`, else the start of the event. The part after midnight of an event from the day before has no start to compare. | `A new end was skipped because it is not after the start.`                                                                                    |
| A `shift` names an event that is not on the command day                                                                                                                                                                                                              | `A move was skipped because its event is not on this day.` or `A shift was skipped because its event is not on this day.`                     |
| A `checklist` names an event that is not on the command day                                                                                                                                                                                                          | `A microtask add was skipped because its event is not on this day.`                                                                           |
| A `delete` names the part after midnight of a recurring event from the day before                                                                                                                                                                                    | `"<name>" was skipped because it is a carried-over tail of a recurring event.`                                                                |
| A `delete` with the scope `series` or `future` names an event from a calendar                                                                                                                                                                                        | `"<name>" was skipped because it is from a calendar, so delete more than one day in the event editor.`                                        |
| A scoped `delete` names a series that Reassign cannot read                                                                                                                                                                                                           | `"<name>" was skipped because its series could not be read.`                                                                                  |
| A `series` or `future` change from a changed occurrence names a series on a calendar that you do not own                                                                                                                                                             | `A change to "<name>" was skipped because it is on a calendar you do not own.`                                                                |
| A `series` or `future` change from a changed occurrence has an end that is not after the start of the series                                                                                                                                                         | `A change to "<name>" was skipped because its new end is not after its start.`                                                                |
| A `series` or `future` change names a series that Reassign cannot read                                                                                                                                                                                               | `A change to "<name>" was skipped because its series could not be read.`                                                                      |
| A `series` or `future` `checklist` from a changed occurrence names a series that Reassign cannot read                                                                                                                                                                | `A microtask add was skipped because its series could not be read.` or `A microtask change was skipped because its series could not be read.` |
| A `future` change names an event from a calendar                                                                                                                                                                                                                     | `A change to "<name>" was skipped because it is from a calendar, so change it from this day on in the event editor.`                          |
| A `shift` has a minute offset that is not valid                                                                                                                                                                                                                      | `A move was skipped because its time offset is not valid.`                                                                                    |
| A `checklist` with `target: "backlog"` names an Inbox item that does not exist                                                                                                                                                                                       | `A microtask add was skipped because its Inbox block was not found.`                                                                          |
| A `log_moment` names no tracker that exists                                                                                                                                                                                                                          | `A moment log was skipped because no matching tracker was found.` or `A log was skipped because its tracker is unknown.`                      |
| A `log_moment` has a time that is not valid                                                                                                                                                                                                                          | `A moment log was skipped because its time is not valid.` or `A log was skipped because its time is not valid.`                               |

### Questions

A question has one of these two shapes:

- `{ "kind": "target", "question", "candidates": [{ "id", "label" }], "op" }`
- `{ "kind": "choice", "question", "options": [{ "label", "ops" }] }`

Reassign never applies `questions` itself. When it applies a plan, it applies the other intents of the plan, also when a question is open.

- A `target` question needs an event `id`. Its `op` is an `update`, `shift`, `delete`, `park`, `checklist`, `checklist_edit`, or `split` intent with no `id`. Pick a candidate `id`, and complete the `op` with it.
- A `choice` question has complete `ops` for each option. Pick one option.
- The Reassign app answers questions in the client. It does not send the answer to the model.

The supported way for a REST client to handle questions is a preview. When the input can cause a question, do these steps:

1. Send the input with `"apply": false`. A preview writes nothing.
2. If the preview has `questions`, act on the answer yourself, for example with `POST /api/v1/events`. Refer to [Events](https://reassign.dev/reference/events.md).
3. To refine a preview, send `history`. Refer to [Run a quick command](https://reassign.dev/reference/command.md#run-a-quick-command-beta).

> The model reads each `plan` in `history` as a proposal that Reassign did not apply. Thus, after an applied call, leave that turn out of `history`. When a turn applied a part of the line and asked about the rest, keep that turn. Put the applied part in its `written` field, so that the model does not write it again.

### The modes

This endpoint supports only the `line` and `braindump` modes. Omit `mode` for `line`. Any other value returns `422`.

| Item                           | `line` (default)                                                         | `braindump`                                                                       |
| ------------------------------ | ------------------------------------------------------------------------ | --------------------------------------------------------------------------------- |
| Input                          | One free-form line                                                       | More lines, one item on each line                                                 |
| Text that the model sees       | 300 characters                                                           | 2,000 characters in total, a maximum of 40 lines, and 300 characters on each line |
| Maximum actions from one reply | 12                                                                       | 25                                                                                |
| Delete or clear events         | Yes, for events that the user owns and that are not linked to a calendar | No. Reassign refuses the removal and adds a notice.                               |
| Text over the limit            | Reassign cuts it with no notice                                          | Reassign cuts it and adds a notice                                                |

In `braindump` mode, Reassign only adds to the plan. It refuses a removal with this notice: `A braindump only adds to your plan, so the part that removes events was skipped.`

### Review mode

In `line` mode, the command goes into review mode in these cases:

- `date` is before today, in the time zone of the account.
- `date` is today, and the input is about how the day went. Examples are "how did today go", "I skipped gym", and "the meeting ran late".

In review mode, the model records how the day went. It does not change the plan.

- The plan has only `reflect`, `day_note`, `log_moment`, and `remember` intents.
- A request to delete an event becomes a `reflect` with `status: "skipped"`. The event stays in the plan.
- Reassign drops other changes with this notice: `In review I only record how the day went, so a change to the plan was skipped.`
- A plan with a `reflect` on a past day: when each planned event of the day has a mark, Reassign confirms the review of the day. It adds the notice `Day reviewed.` Else it adds `<n> events left to review.` Reference events do not need a mark.
- A day note longer than 500 characters gives the notice `The day note was cut to 500 characters.`

Outside review mode, Reassign drops a `reflect` or a `day_note` with this notice: `Reviews are for a past day, so a review mark was skipped.`

The undo token of a command also reverts its day notes and the review confirmation.

### Calendar-synced events

In the two modes, you cannot delete a calendar-synced event or move it to the Inbox. Reassign skips the change. For a `delete`, a `park`, or a `clear`, it adds this notice for each event:

`"<name>" is synced from a calendar, so the API cannot delete it or move it to the Inbox. Do that in the app.`

---

## Run a quick command (Beta)

**POST** `/api/v1/command`

> This route is in Beta. The response can change.

Send free text. By default, Reassign applies the plan. Send `"apply": false` to get a preview. A preview writes nothing.

- `input`: Reassign trims it. In `line` mode, the model sees the first 300 characters. In `braindump` mode, refer to the mode limits above.
- `date`: the default is today in the time zone of the account.
- `apply`: send `false` to get a preview. Omit it, or send `true`, to apply the plan.
- `sourceUrl`: optional. The http(s) address of the page where the user wrote the command. Each new event and Inbox block links to it. The maximum length is 2,048 characters.
- `history`: the prior turns, as `{ "user": string, "plan": string, "written"?: string }` items. Your client keeps them. Use `history` to refine a preview (`"apply": false`), for example "move that one later". After an applied call, send a turn only when it also asked a question, with its `written` field.
  - The model reads each `plan` as proposed actions that Reassign did not apply. It gives the full new action list, not only the changes.
  - Put one line for each proposed action in `plan`, for example `create "Gym" 2026-09-23T18:00 to 2026-09-23T19:00`. The Reassign app writes the lines in this form.
  - Send a maximum of 6 turns. More turns return `422`.
  - `written` names what Reassign already wrote in that turn. Join the `writtenLines` of the response with newlines to make it. The model does not write these items again.
  - Reassign cuts `user` to 300 characters, `plan` to 1,000 characters, each `plan` line to 160 characters, and `written` to 8,050 characters.

### Access

| Item       | Value                                                                                                                                                                                                                                                                                                                            |
| ---------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| Scope      | `events:write`. A preview (`"apply": false`) also needs `events:write`.                                                                                                                                                                                                                                                          |
| Plan       | A trial or Pro plan                                                                                                                                                                                                                                                                                                              |
| Rate limit | The shared API limit of 2,000 requests in 60 seconds for each IP address. Also 600 requests in 60 seconds for each OAuth grant or personal access token: over the limit, you get `429` with the code `rate_limited`, the message `Too many requests.`, and `Retry-After: 60`. Refer to [Errors](https://reassign.dev/errors.md). |
| Time       | The server lets a call run for up to 45 seconds.                                                                                                                                                                                                                                                                                 |

### Validation errors

Each error returns `422` with the code `validation`. The message names the first bad field by its path.

| Cause                                                                     | Message                                              |
| ------------------------------------------------------------------------- | ---------------------------------------------------- |
| The body is not JSON                                                      | `The request body is not valid JSON.`                |
| The body has a key that Reassign does not know                            | ``Unknown body key `<key>`.``                        |
| `input` is missing, or blank after the trim                               | Starts with `` `input`: ``                           |
| `mode` is not `line` or `braindump` (also `breakdown`)                    | Starts with `` `mode`: ``                            |
| `date` is not a real `YYYY-MM-DD` date                                    | Starts with `` `date`: ``                            |
| `history` has more than 6 turns, or a turn has a wrong shape              | Starts with `` `history`: `` or `` `history.<n>`: `` |
| `sourceUrl` is not an http(s) address, or is longer than 2,048 characters | Starts with `` `sourceUrl`: ``                       |

### Model errors

When the model call fails, the response is `503` with the code `internal`. The response is not an empty plan. Reassign writes nothing.

| Cause                                                 | Message                                            |
| ----------------------------------------------------- | -------------------------------------------------- |
| The model call fails, or takes more than 30 seconds   | `The AI model did not respond. Try again.`         |
| Reassign cannot read the reply of the model as a plan | `The AI model reply could not be read. Try again.` |

- A plan with no intents is a valid result. It means that the text had nothing to do.

### Undo

Send the `undoToken` to `POST /api/v1/actions/undo` before `expiresAt` (30 minutes). This undoes all the writes of the command. Refer to [Scheduling](https://reassign.dev/reference/scheduling.md). If Reassign cannot save the undo record, the response has no `undoToken`, but the writes stay.

### Request body

- `input` (_string, required_): The command line or braindump.
- `mode` (_"line" | "braindump"_): "line" (the default) or "braindump" (many lines).
- `date` (_string_): The day of the command; today if absent.
- `apply` (_boolean_): `false` returns the plan and writes nothing.
- `history` (_object\[]_): The earlier `{ user, plan }` turns, so a line can refer back. `written` names what that turn already wrote, so the reply does not write it again.
  - `user` (_string, required_)
  - `plan` (_string, required_)
  - `written` (_string_)
- `sourceUrl` (_string_): The page the command was captured from; each new event and Inbox block links to it.

### Response fields

- `date` (_string, required_)
- `intents` (_object\[], required_)
  - One form: `op: "create"`
    - `start` (_string, required_)
    - `end` (_string, required_)
    - `name` (_string, required_)
    - `areaId` (_string | null, required_)
    - `activityTypeId` (_string | null, required_)
    - `recurrence` (_string_)
    - `kind` (_"blocking" | "non\_blocking" | "reference"_)
    - `focusIntervals` (_object_)
      - `focusMin` (_integer, required_)
      - `breakMin` (_integer, required_)
    - `calendarId` (_string_): The home calendar id. Absent: the account's default calendar if one is set, else the event stays on the dial only.
    - `checklist` (_string\[]_): Checklist items of the new event.
    - `projectId` (_string_): The project of the new item. Absent: no project. A project with an area also sets that area.
    - `priority` (_integer_): The priority of the new item: 4 urgent, 3 high, 2 medium, 1 low. Absent: none.
  - One form: `op: "update"`
    - `id` (_string, required_)
    - `start` (_string_)
    - `ripple` (_boolean_)
    - `focusIntervals` (_object | null_)
      - `focusMin` (_integer, required_)
      - `breakMin` (_integer, required_)
    - `kind` (_"blocking" | "non\_blocking" | "reference"_): A new kind; sent only when the user asks for it.
    - `name` (_string_)
    - `end` (_string_): A new end after the (new) start: it resizes the event.
    - `areaId` (_string_)
    - `activityTypeId` (_string_)
    - `appendNote` (_string_): One line added to the end of the notes.
    - `notes` (_string_): Notes that replace the old ones; "" clears them.
    - `scope` (_"occurrence" | "series" | "future"_): On a recurring event: "occurrence" = this day only, "series" = every occurrence, "future" = this day and every later one. A one-off event ignores it.
  - One form: `op: "shift"`
    - `id` (_string, required_)
    - `byMinutes` (_integer, required_)
    - `ripple` (_boolean_)
  - One form: `op: "delete"`
    - `id` (_string, required_)
    - `scope` (_"occurrence" | "series" | "future"_): On a recurring event: "occurrence" = this day only, "series" = every occurrence, "future" = this day and every later one. A one-off event ignores it.
  - One form: `op: "clear"`
    - `from` (_string, required_)
    - `to` (_string, required_)
  - One form: `op: "park"`
    - `id` (_string_)
    - `name` (_string, required_)
    - `durationMinutes` (_integer_)
    - `areaId` (_string | null, required_)
    - `activityTypeId` (_string | null, required_)
    - `projectId` (_string_): The project of the new item. Absent: no project. A project with an area also sets that area.
    - `priority` (_integer_): The priority of the new item: 4 urgent, 3 high, 2 medium, 1 low. Absent: none.
  - One form: `op: "log_moment"`
    - `mood` (_boolean_)
    - `trackerId` (_string_)
    - `value` (_number_)
    - `time` (_string_)
  - One form: `op: "checklist"`
    - `id` (_string, required_)
    - `add` (_string\[], required_)
    - `target` (_"backlog"_)
    - `scope` (_"occurrence" | "series" | "future"_): On a recurring event: "occurrence" = this day only, "series" = every occurrence, "future" = this day and every later one. A one-off event ignores it.
  - One form: `op: "checklist_edit"`
    - `id` (_string, required_)
    - `item` (_string, required_)
    - `edit` (_"check" | "uncheck" | "rename" | "remove", required_)
    - `newText` (_string_): The new item text; only with `edit: "rename"`.
    - `scope` (_"occurrence" | "series" | "future"_): On a recurring event: "occurrence" = this day only, "series" = every occurrence, "future" = this day and every later one. A one-off event ignores it.
  - One form: `op: "split"`
    - `id` (_string, required_)
    - `at` (_string, required_)
    - `secondName` (_string_): The name of the second part. Absent: the same name.
  - One form: `op: "remember"`
    - `text` (_string, required_)
  - One form: `op: "reflect"`
    - `status` (_"kept" | "skipped" | "changed" | "added", required_)
    - `id` (_string_): The event; absent only with `status: "added"`.
    - `actualStart` (_string_)
    - `actualEnd` (_string_)
    - `name` (_string_): The name of an `"added"` event.
    - `areaId` (_string_)
    - `activityTypeId` (_string_)
  - One form: `op: "day_note"`
    - `wentWell` (_string_)
    - `wentBadly` (_string_)
    - `lesson` (_string_)
    - `replace` (_boolean_)
- `questions` (_object\[], required_)
  - One form: `kind: "target"`
    - `question` (_string, required_)
    - `candidates` (_object\[], required_)
      - `id` (_string, required_)
      - `label` (_string, required_)
    - `op` (_object, required_)
      - One form: `op: "update"`
        - `start` (_string_)
        - `ripple` (_boolean_)
        - `focusIntervals` (_object | null_)
          - `focusMin` (_integer, required_)
          - `breakMin` (_integer, required_)
        - `kind` (_"blocking" | "non\_blocking" | "reference"_): A new kind; sent only when the user asks for it.
        - `name` (_string_)
        - `end` (_string_): A new end after the (new) start: it resizes the event.
        - `areaId` (_string_)
        - `activityTypeId` (_string_)
        - `appendNote` (_string_): One line added to the end of the notes.
        - `notes` (_string_): Notes that replace the old ones; "" clears them.
        - `scope` (_"occurrence" | "series" | "future"_): On a recurring event: "occurrence" = this day only, "series" = every occurrence, "future" = this day and every later one. A one-off event ignores it.
      - One form: `op: "shift"`
        - `byMinutes` (_integer, required_)
        - `ripple` (_boolean_)
      - One form: `op: "delete"`
        - `scope` (_"occurrence" | "series" | "future"_): On a recurring event: "occurrence" = this day only, "series" = every occurrence, "future" = this day and every later one. A one-off event ignores it.
      - One form: `op: "park"`
        - `name` (_string, required_)
        - `durationMinutes` (_integer_)
        - `areaId` (_string | null, required_)
        - `activityTypeId` (_string | null, required_)
        - `projectId` (_string_): The project of the new item. Absent: no project. A project with an area also sets that area.
        - `priority` (_integer_): The priority of the new item: 4 urgent, 3 high, 2 medium, 1 low. Absent: none.
      - One form: `op: "checklist"`
        - `add` (_string\[], required_)
        - `target` (_"backlog"_)
        - `scope` (_"occurrence" | "series" | "future"_): On a recurring event: "occurrence" = this day only, "series" = every occurrence, "future" = this day and every later one. A one-off event ignores it.
      - One form: `op: "checklist_edit"`
        - `item` (_string, required_)
        - `edit` (_"check" | "uncheck" | "rename" | "remove", required_)
        - `newText` (_string_): The new item text; only with `edit: "rename"`.
        - `scope` (_"occurrence" | "series" | "future"_): On a recurring event: "occurrence" = this day only, "series" = every occurrence, "future" = this day and every later one. A one-off event ignores it.
      - One form: `op: "split"`
        - `at` (_string, required_)
        - `secondName` (_string_): The name of the second part. Absent: the same name.
  - One form: `kind: "choice"`
    - `question` (_string, required_)
    - `options` (_object\[], required_)
      - `label` (_string, required_)
      - `ops` (_object\[], required_)
        - One form: `op: "create"`
          - `start` (_string, required_)
          - `end` (_string, required_)
          - `name` (_string, required_)
          - `areaId` (_string | null, required_)
          - `activityTypeId` (_string | null, required_)
          - `recurrence` (_string_)
          - `kind` (_"blocking" | "non\_blocking" | "reference"_)
          - `focusIntervals` (_object_)
            - `focusMin` (_integer, required_)
            - `breakMin` (_integer, required_)
          - `calendarId` (_string_): The home calendar id. Absent: the account's default calendar if one is set, else the event stays on the dial only.
          - `checklist` (_string\[]_): Checklist items of the new event.
          - `projectId` (_string_): The project of the new item. Absent: no project. A project with an area also sets that area.
          - `priority` (_integer_): The priority of the new item: 4 urgent, 3 high, 2 medium, 1 low. Absent: none.
        - One form: `op: "update"`
          - `id` (_string, required_)
          - `start` (_string_)
          - `ripple` (_boolean_)
          - `focusIntervals` (_object | null_)
            - `focusMin` (_integer, required_)
            - `breakMin` (_integer, required_)
          - `kind` (_"blocking" | "non\_blocking" | "reference"_): A new kind; sent only when the user asks for it.
          - `name` (_string_)
          - `end` (_string_): A new end after the (new) start: it resizes the event.
          - `areaId` (_string_)
          - `activityTypeId` (_string_)
          - `appendNote` (_string_): One line added to the end of the notes.
          - `notes` (_string_): Notes that replace the old ones; "" clears them.
          - `scope` (_"occurrence" | "series" | "future"_): On a recurring event: "occurrence" = this day only, "series" = every occurrence, "future" = this day and every later one. A one-off event ignores it.
        - One form: `op: "shift"`
          - `id` (_string, required_)
          - `byMinutes` (_integer, required_)
          - `ripple` (_boolean_)
        - One form: `op: "delete"`
          - `id` (_string, required_)
          - `scope` (_"occurrence" | "series" | "future"_): On a recurring event: "occurrence" = this day only, "series" = every occurrence, "future" = this day and every later one. A one-off event ignores it.
        - One form: `op: "clear"`
          - `from` (_string, required_)
          - `to` (_string, required_)
        - One form: `op: "park"`
          - `id` (_string_)
          - `name` (_string, required_)
          - `durationMinutes` (_integer_)
          - `areaId` (_string | null, required_)
          - `activityTypeId` (_string | null, required_)
          - `projectId` (_string_): The project of the new item. Absent: no project. A project with an area also sets that area.
          - `priority` (_integer_): The priority of the new item: 4 urgent, 3 high, 2 medium, 1 low. Absent: none.
        - One form: `op: "log_moment"`
          - `mood` (_boolean_)
          - `trackerId` (_string_)
          - `value` (_number_)
          - `time` (_string_)
        - One form: `op: "checklist"`
          - `id` (_string, required_)
          - `add` (_string\[], required_)
          - `target` (_"backlog"_)
          - `scope` (_"occurrence" | "series" | "future"_): On a recurring event: "occurrence" = this day only, "series" = every occurrence, "future" = this day and every later one. A one-off event ignores it.
        - One form: `op: "checklist_edit"`
          - `id` (_string, required_)
          - `item` (_string, required_)
          - `edit` (_"check" | "uncheck" | "rename" | "remove", required_)
          - `newText` (_string_): The new item text; only with `edit: "rename"`.
          - `scope` (_"occurrence" | "series" | "future"_): On a recurring event: "occurrence" = this day only, "series" = every occurrence, "future" = this day and every later one. A one-off event ignores it.
        - One form: `op: "split"`
          - `id` (_string, required_)
          - `at` (_string, required_)
          - `secondName` (_string_): The name of the second part. Absent: the same name.
        - One form: `op: "remember"`
          - `text` (_string, required_)
        - One form: `op: "reflect"`
          - `status` (_"kept" | "skipped" | "changed" | "added", required_)
          - `id` (_string_): The event; absent only with `status: "added"`.
          - `actualStart` (_string_)
          - `actualEnd` (_string_)
          - `name` (_string_): The name of an `"added"` event.
          - `areaId` (_string_)
          - `activityTypeId` (_string_)
        - One form: `op: "day_note"`
          - `wentWell` (_string_)
          - `wentBadly` (_string_)
          - `lesson` (_string_)
          - `replace` (_boolean_)
- `notices` (_string\[], required_)
- `reply` (_string_): The assistant's short plain-text answer, for example to a question about the plan. Absent when it said nothing.
- `created` (_object\[]_): Each new event (with its span) and Inbox block, with its kind, area and activity type. Absent when nothing was made.
  - `id` (_string, required_)
  - `entity` (_"event" | "inbox", required_)
  - `name` (_string, required_)
  - `kind` (_"blocking" | "non\_blocking" | "reference", required_)
  - `areaId` (_string_)
  - `activityTypeId` (_string_)
  - `start` (_string_)
  - `end` (_string_)
- `written` (_integer\[]_): The indexes in `intents` that were written. An intent that is not here was refused; a notice says why. Absent when nothing was written.
- `writtenLines` (_string\[]_): One line for each written intent, in the order of `written`, with the name of its event. Join them with newlines for the `written` of the next history turn. Absent when nothing was written.
- `undoToken` (_string_)
- `expiresAt` (_string_)

### Responses

| Status | Codes                 | Meaning                                                                                                                                                                                                                                                                                                                                                                                                                                                                                |
| ------ | --------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `200`  | —                     | Success.                                                                                                                                                                                                                                                                                                                                                                                                                                                                               |
| `401`  | `unauthorized`        | No Bearer token and no session cookie, or the token is invalid, expired, or revoked. The response carries a `WWW-Authenticate` challenge that points at the protected-resource metadata.                                                                                                                                                                                                                                                                                               |
| `403`  | `permission`, `scope` | A token without `events:write` gets `scope` "This token is not authorized to modify events (missing events:write scope)." An account without Reassign Pro access gets `permission` "Reassign needs an active subscription." The 7-day free trial includes Reassign Pro. A cookie session from another site gets `permission` "Cross-origin request."                                                                                                                                   |
| `422`  | `validation`          | The request body is not valid. The message names the first bad field by its path. A repeated or unknown query parameter is also a 422.                                                                                                                                                                                                                                                                                                                                                 |
| `429`  | `rate_limited`        | Too many requests. The edge firewall limits each IP to 2000 requests per minute across `/api/v1`; that 429 comes from the edge and can have a body that is not this JSON and no `Retry-After` header. When an edge 429 has no `Retry-After`, retry after 60 seconds. The app also limits each Bearer credential to 600 requests per minute, and some routes limit each user. These limits return this body. This app 429 always has `Retry-After`: retry after that number of seconds. |
| `503`  | `internal`            | A fault on our side. The request is safe to retry.                                                                                                                                                                                                                                                                                                                                                                                                                                     |

**Request** — **POST** `/api/v1/command`

**cURL**

```bash
curl -X POST "https://reassign.app/api/v1/command" \
  -H "Authorization: Bearer rsk_live_YOUR_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
  "input": "also coffee with Ana noon, park: write the offsite agenda",
  "mode": "braindump",
  "history": [
    {
      "user": "gym at 7, deep work 9-11",
      "plan": "create \"Gym\" 2026-08-13T07:00 to 2026-08-13T08:00\ncreate \"Deep work\" 2026-08-13T09:00 to 2026-08-13T11:00 (area Work)"
    }
  ]
}'
```

**JavaScript**

```js
const res = await fetch("https://reassign.app/api/v1/command", {
  method: "POST",
  headers: {
    Authorization: "Bearer rsk_live_YOUR_TOKEN",
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    "input": "also coffee with Ana noon, park: write the offsite agenda",
    "mode": "braindump",
    "history": [
      {
        "user": "gym at 7, deep work 9-11",
        "plan": "create \"Gym\" 2026-08-13T07:00 to 2026-08-13T08:00\ncreate \"Deep work\" 2026-08-13T09:00 to 2026-08-13T11:00 (area Work)"
      }
    ]
  }),
});
const data = await res.json();
```

**Response**

```json
{
  "date": "2026-08-13",
  "intents": [
    {
      "op": "create",
      "name": "Gym",
      "start": "2026-08-13T07:00",
      "end": "2026-08-13T08:00",
      "areaId": null,
      "activityTypeId": null
    },
    {
      "op": "create",
      "name": "Deep work",
      "start": "2026-08-13T09:00",
      "end": "2026-08-13T11:00",
      "areaId": "3c9d2a41-6b7e-4f80-9a1b-2c3d4e5f6071",
      "activityTypeId": null
    },
    {
      "op": "create",
      "name": "Coffee with Ana",
      "start": "2026-08-13T12:00",
      "end": "2026-08-13T13:00",
      "areaId": null,
      "activityTypeId": null
    },
    {
      "op": "park",
      "name": "Write the offsite agenda",
      "durationMinutes": 60,
      "areaId": null,
      "activityTypeId": null
    }
  ],
  "questions": [],
  "notices": [],
  "undoToken": "00000000-0000-4000-8000-000000000001",
  "expiresAt": "2026-08-13T09:12:00.000Z"
}
```
