---
title: "Tasks"
description: "Every command for tasks, the runs they make and the approvals those runs ask for, with worked examples."
url: "https://openemail.uk/docs/cli/tasks"
area: "CLI"
category: "Commands by area"
---

# Tasks

Every command for tasks, the runs they make and the approvals those runs ask for, with worked examples.

## How it fits together

A task is an instruction the assistant runs by itself, with a trigger that starts it and an autonomy that says how much it may change without asking. Each run leaves a record, and anything it may not do alone waits as an approval request. Reading needs `tasks:read` with `threads:read` and `emails:read`. Creating, changing, resuming, running and approving need `tasks:write` with `threads:read`, `threads:write`, `emails:read`, `emails:send` and `labels:write`, and the scopes of each toolkit.

**Terminal**

```
openemail tasks create --name "Morning summary" --instruction "Tell me which conversations need a reply, most urgent first." --trigger-kind schedule --trigger-schedule-cadence daily --trigger-schedule-hour 8 --trigger-schedule-timezone Europe/London
openemail tasks run tsk_5c1e9a7b3d2f48e6a0b4c7d1
openemail tasks get-run run_2b8d4f6a1c3e5079b6d8f0a2
openemail tasks list-approvals
openemail tasks approve apr_9f3a1c5e7b2d4608a1c3e5f7
```

A trigger with many parts is easier as JSON: write the task to a file and pass it with `--data @task.json`. `openemail tasks get <id> --json` prints one in that shape.

A task whose `toolkits` hold `connectors` may use the apps connected for the workspace, never a connector that belongs to one person, and it then also needs `connectors:read` and `connectors:use`. Such a run reads through a connector alone, every change in an app waits as an approval request whatever the `autonomy`, and with `reply` every answer to an email waits for approval as well.

## Tasks

| Command | What it does |
| --- | --- |
| openemail tasks list | One page of the tasks, most recently changed first. `--status` narrows it to `active` or `paused` |
| openemail tasks create --name <value> --instruction <value> --trigger-kind <kind> | Save a task and turn it on. `--trigger-kind` is `schedule`, `mail` or `manual`, `--autonomy` is `ask`, `organize` or `reply`, and `--paused` saves it without turning it on |
| openemail tasks get <id> | One task with its trigger, its settings and its last and next run |
| openemail tasks update <id> | Change what you pass and leave the rest. A new trigger replaces the old one whole |
| openemail tasks pause <id> | Stop a task from starting runs. A run already going carries on |
| openemail tasks resume <id> | Turn a paused task back on and clear its count of failed runs |
| openemail tasks run <id> | Start a run now, whatever the trigger, and print the run |
| openemail tasks delete <id> | Delete a task for good with every run it made, once you confirm |

## Runs

| Command | What it does |
| --- | --- |
| openemail tasks list-runs | Runs across the workspace, newest first. `--task-id` and `--status` narrow it |
| openemail tasks get-run <id> | One run with every step it took, the tools it called and what it asked |
| openemail tasks start-run --instruction <value> | Hand the assistant one job to do in the background, with no task saved |
| openemail tasks cancel-run <id> | Stop a run that is queued, running or waiting, once you confirm. What it did stays done |

**Terminal**

```
openemail tasks start-run --instruction "Find every invoice that arrived this month and label it Invoices." --autonomy organize --max-steps 30
openemail tasks list-runs --status waiting
openemail tasks get-run run_2b8d4f6a1c3e5079b6d8f0a2 --json
```

A run is `queued`, then `running`, then `waiting` while a request is open, and ends `done`, `failed` or `cancelled`. `get-run --json` prints the `transcript`, so a script can read it again until the status settles.

## Approvals

| Command | What it does |
| --- | --- |
| openemail tasks list-approvals | What runs are waiting for you to allow, newest first. `--task-id`, `--run-id` and `--status` narrow it |
| openemail tasks get-approval <id> | One request with the tool and the exact arguments it would be called with |
| openemail tasks approve <id> | Let it happen, once you confirm. `--subject` and `--body` replace the words of a send or a reply |
| openemail tasks deny <id> | Refuse it, once you confirm. The run is told and carries on without it |

A request waits 7 days and then expires, which the run reads as a refusal. `--yes` skips the confirmation in a script.
