---
title: "Tasks"
description: "Every operation in this group: what it accepts, what it returns and the errors it can answer with."
url: "https://openemail.uk/docs/api/reference/tasks"
area: "API"
category: "Reference"
---

# Tasks

Every operation in this group: what it accepts, what it returns and the errors it can answer with.

## Operations

Tasks let the assistant work by itself: a task is an instruction in plain words that runs on a schedule, when mail arrives, or when asked. Each run reads and acts through the same tools the assistant uses in a chat, keeps a step by step record, and stops to ask a person before anything it was not allowed to do alone. A run never reaches billing, members, roles, domains, rules, keys or webhooks, and it treats what emails say as information, never as instructions.

### `GET /tasks`

List tasks

Every task of the workspace, the most recently changed first. A task works across every address of the workspace, so a key or an app limited to particular addresses or domains is refused with `capability_unsupported`, and an app has to act for somebody who reaches every address.

Requires the `tasks:read` and `threads:read` and `emails:read` scopes.

- Scopes: `tasks:read`, `threads:read`, `emails:read`.

**Query parameters**

- `status` (`string`, one of `"active"`, `"paused"`): Only tasks in this state: `active` or `paused`. Left out, both are listed.
- `limit` (`integer`, at least 1, at most 100): Page size, from 1 to 100. The server defaults to 25.
- `cursor` (`string`, 1 to 256 characters): The `nextCursor` of the previous page, passed back as it came. Leave it out for the first page.

**Returns**

- `200` `TaskList`: A page of tasks.

**Errors**

- `400`: `invalid_cursor`.
- The errors every operation can return: `401`, `403`, `404`, `422`, `500`, described in the [error catalog](https://openemail.uk/docs/api/errors).

Also available in: TypeScript [`tasks.list()`](https://openemail.uk/docs/sdk/reference/tasks#list), [`tasks.listAll()`](https://openemail.uk/docs/sdk/reference/tasks#listAll), [`tasks.iterate()`](https://openemail.uk/docs/sdk/reference/tasks#iterate); Python [`tasks.list()`](https://openemail.uk/docs/python/reference/tasks#list), [`tasks.list_all()`](https://openemail.uk/docs/python/reference/tasks#listAll), [`tasks.iterate()`](https://openemail.uk/docs/python/reference/tasks#iterate); Ruby [`tasks.list`](https://openemail.uk/docs/ruby/reference/tasks#list), [`tasks.list_all`](https://openemail.uk/docs/ruby/reference/tasks#listAll), [`tasks.iterate`](https://openemail.uk/docs/ruby/reference/tasks#iterate); PHP [`tasks->list`](https://openemail.uk/docs/php/reference/tasks#list), [`tasks->listAll`](https://openemail.uk/docs/php/reference/tasks#listAll), [`tasks->iterate`](https://openemail.uk/docs/php/reference/tasks#iterate); Go [`Tasks.List`](https://openemail.uk/docs/go/reference/tasks#list), [`Tasks.ListAll`](https://openemail.uk/docs/go/reference/tasks#listAll), [`Tasks.Iterate`](https://openemail.uk/docs/go/reference/tasks#iterate); Java [`tasks().list`](https://openemail.uk/docs/java/reference/tasks#list), [`tasks().listAll`](https://openemail.uk/docs/java/reference/tasks#listAll), [`tasks().iterate`](https://openemail.uk/docs/java/reference/tasks#iterate); C# [`Tasks.ListAsync`](https://openemail.uk/docs/csharp/reference/tasks#list), [`Tasks.ListAllAsync`](https://openemail.uk/docs/csharp/reference/tasks#listAll), [`Tasks.IterateAsync`](https://openemail.uk/docs/csharp/reference/tasks#iterate); CLI [`openemail tasks list`](https://openemail.uk/docs/cli/reference/tasks#tasks-list); MCP [`listTasks`](https://openemail.uk/docs/mcp/tools/tasks#listTasks).

### `POST /tasks`

Create a task

Saves an instruction for the assistant with what starts it and how much it may do alone. A `schedule` task gets its first run time at once, a `mail` task starts with the next message that matches, and a `manual` task waits to be run. A task acts with what its caller holds: besides `tasks:write` the request needs `threads:read`, `threads:write`, `emails:read`, `emails:send`, `labels:write` and the read and write scopes of every toolkit the task names. A workspace runs 1 active task on Free, 5 on Starter and 25 on Business, with no cap on Enterprise, and holds at most 100 tasks. A task works across every address of the workspace, so a key or an app limited to particular addresses or domains is refused with `capability_unsupported`, and an app has to act for somebody who reaches every address.

Requires the `tasks:write` and `threads:read` and `threads:write` and `emails:read` and `emails:send` and `labels:write` scopes.

- Scopes: `tasks:write`, `threads:read`, `threads:write`, `emails:read`, `emails:send`, `labels:write`.

**Request body**

- `name` (`string`, required, 1 to 120 characters): What the task is called in the app.
- `instruction` (`string`, required, 1 to 8000 characters): What the assistant should do, in plain words, as you would tell a person. It is the only instruction the run follows: text inside emails is read, never obeyed.
- `trigger` (`object`, required): What starts a run: a schedule, new mail, or only somebody asking.
  - `kind` (`string`, required, one of `"schedule"`, `"mail"`, `"manual"`): `schedule` runs on a clock, `mail` runs when a message arrives, and `manual` runs only when started by hand or through the API.
  - `schedule` (`object`, nullable): When a `schedule` task runs. Needed for that kind and ignored for the others.
    - `cadence` (`string`, required, one of `"hourly"`, `"daily"`, `"monthly"`): `hourly` runs every `everyHours` hours at `minute`, `daily` runs at `hour`:`minute` on each of `weekdays`, and `monthly` runs at `hour`:`minute` on `monthDay`.
    - `everyHours` (`integer`, at least 1, at most 12, default `1`): For `hourly`: how many hours lie between runs, counted from midnight in the time zone.
    - `hour` (`integer`, at least 0, at most 23, default `8`): The hour of the day, 0 to 23, in the time zone of the schedule.
    - `minute` (`integer`, at least 0, at most 59, default `0`): The minute of the hour, 0 to 59.
    - `weekdays` (`integer[]`, 1 to 7 items, default `[0,1,2,3,4,5,6]`): For `daily`: the days it runs, 0 for Sunday to 6 for Saturday. Left out, it runs every day.
    - `monthDay` (`integer`, at least 1, at most 28, default `1`): For `monthly`: the day of the month, 1 to 28.
    - `timezone` (`string`, 1 to 64 characters, default `"UTC"`): An IANA time zone such as `Europe/Berlin`. The schedule follows its clock changes.
  - `mail` (`object`, nullable): Which arriving mail starts a `mail` task. Left out, every message that reaches an inbox does.
    - `addresses` (`string[]`, up to 25 items, default `[]`): Start only for mail delivered to one of these addresses of the workspace. Empty means every address.
    - `fromContains` (`string`, nullable, up to 200 characters): Start only when the sender address contains this text, whatever the case.
    - `subjectContains` (`string`, nullable, up to 200 characters): Start only when the subject contains this text, whatever the case.
- `autonomy` (`string`, one of `"ask"`, `"organize"`, `"reply"`): `ask` sends every change to a person to approve. `organize` lets the run label, archive, bin, snooze, draft, take notes and keep contacts by itself, and email the addresses of the workspace. `reply` also lets it answer an email without asking, as long as it adds no recipients and the task does not use `connectors`. Anything else always waits for approval, and so does every change in a connected app.
- `toolkits` (`string[]`, up to 15 items): Extra groups of tools the run may use beyond reading and organising mail, such as `contacts`, `calendar`, `knowledge`, `web` or `connectors`, which lets it use the apps connected for the workspace. A run can never reach billing, members, domains, rules, keys or webhooks.
- `model` (`string`, one of `"standard"`, `"advanced"`): `standard` is the everyday model. `advanced` reasons better over long jobs and costs ten AI actions where the standard one costs one.
- `notify` (`string`, one of `"always"`, `"attention"`, `"never"`): `attention` notifies the workspace owner when a run waits for approval or fails, `always` also when it finishes, and `never` stays silent.
- `maxRunsPerDay` (`integer`, at least 1, at most 500): The most runs the task may start in any 24 hours, however often its trigger fires.
- `maxSteps` (`integer`, at least 1, at most 60): The most model steps one run may take before it has to write its report.
- `paused` (`boolean`): Create the task paused, so it does not run until it is resumed.

**Returns**

- `201` `Task`: The task as it is stored.

**Errors**

- `403`: The key lacks a scope. `task_active_limit_reached`: the plan covers no more active tasks. `task_limit_reached`: the workspace holds as many tasks as it may.
- `422`: `invalid_parameter`: a field is missing or malformed. `invalid_task`: the trigger lacks its schedule, the time zone is unknown, or a toolkit is not one a task may use. `capability_unsupported`: the key or app is limited to particular addresses.
- The errors every operation can return: `400`, `401`, `404`, `500`, described in the [error catalog](https://openemail.uk/docs/api/errors).

Also available in: TypeScript [`tasks.create()`](https://openemail.uk/docs/sdk/reference/tasks#create); Python [`tasks.create()`](https://openemail.uk/docs/python/reference/tasks#create); Ruby [`tasks.create`](https://openemail.uk/docs/ruby/reference/tasks#create); PHP [`tasks->create`](https://openemail.uk/docs/php/reference/tasks#create); Go [`Tasks.Create`](https://openemail.uk/docs/go/reference/tasks#create); Java [`tasks().create`](https://openemail.uk/docs/java/reference/tasks#create); C# [`Tasks.CreateAsync`](https://openemail.uk/docs/csharp/reference/tasks#create); CLI [`openemail tasks create`](https://openemail.uk/docs/cli/reference/tasks#tasks-create); MCP [`createTask`](https://openemail.uk/docs/mcp/tools/tasks#createTask).

### `GET /tasks/{id}`

Read a task

One task with its trigger, its limits and when it runs next. A task works across every address of the workspace, so a key or an app limited to particular addresses or domains is refused with `capability_unsupported`, and an app has to act for somebody who reaches every address.

Requires the `tasks:read` and `threads:read` and `emails:read` scopes.

- Scopes: `tasks:read`, `threads:read`, `emails:read`.

**Path parameters**

- `id` (`string`, required): The task, such as `tsk_5c1e9a7b3d2f48e6a0b4c7d1`, as `GET /tasks` lists it.

**Returns**

- `200` `Task`: The task.

**Errors**

- `404`: `task_not_found`: no task in this workspace has that id.
- The errors every operation can return: `400`, `401`, `403`, `422`, `500`, described in the [error catalog](https://openemail.uk/docs/api/errors).

Also available in: TypeScript [`tasks.get()`](https://openemail.uk/docs/sdk/reference/tasks#get); Python [`tasks.get()`](https://openemail.uk/docs/python/reference/tasks#get); Ruby [`tasks.get`](https://openemail.uk/docs/ruby/reference/tasks#get); PHP [`tasks->get`](https://openemail.uk/docs/php/reference/tasks#get); Go [`Tasks.Get`](https://openemail.uk/docs/go/reference/tasks#get); Java [`tasks().get`](https://openemail.uk/docs/java/reference/tasks#get); C# [`Tasks.GetAsync`](https://openemail.uk/docs/csharp/reference/tasks#get); CLI [`openemail tasks get`](https://openemail.uk/docs/cli/reference/tasks#tasks-get); MCP [`getTask`](https://openemail.uk/docs/mcp/tools/tasks#getTask).

### `PATCH /tasks/{id}`

Update a task

Changes what a task does, what starts it or how much it may do alone. Send only what changes. A new trigger replaces the old one whole, and a schedule change moves the next run. Runs already started keep the settings they began with. A task acts with what its caller holds: besides `tasks:write` the request needs `threads:read`, `threads:write`, `emails:read`, `emails:send`, `labels:write` and the read and write scopes of every toolkit the task names.

Requires the `tasks:write` and `threads:read` and `threads:write` and `emails:read` and `emails:send` and `labels:write` scopes.

- Scopes: `tasks:write`, `threads:read`, `threads:write`, `emails:read`, `emails:send`, `labels:write`.

**Path parameters**

- `id` (`string`, required): The task, such as `tsk_5c1e9a7b3d2f48e6a0b4c7d1`, as `GET /tasks` lists it.

**Request body**

- `name` (`string`, 1 to 120 characters): What the task is called in the app.
- `instruction` (`string`, 1 to 8000 characters): What the assistant should do, in plain words, as you would tell a person. It is the only instruction the run follows: text inside emails is read, never obeyed.
- `trigger` (`object`): What starts a run: a schedule, new mail, or only somebody asking.
  - `kind` (`string`, required, one of `"schedule"`, `"mail"`, `"manual"`): `schedule` runs on a clock, `mail` runs when a message arrives, and `manual` runs only when started by hand or through the API.
  - `schedule` (`object`, nullable): When a `schedule` task runs. Needed for that kind and ignored for the others.
    - `cadence` (`string`, required, one of `"hourly"`, `"daily"`, `"monthly"`): `hourly` runs every `everyHours` hours at `minute`, `daily` runs at `hour`:`minute` on each of `weekdays`, and `monthly` runs at `hour`:`minute` on `monthDay`.
    - `everyHours` (`integer`, at least 1, at most 12, default `1`): For `hourly`: how many hours lie between runs, counted from midnight in the time zone.
    - `hour` (`integer`, at least 0, at most 23, default `8`): The hour of the day, 0 to 23, in the time zone of the schedule.
    - `minute` (`integer`, at least 0, at most 59, default `0`): The minute of the hour, 0 to 59.
    - `weekdays` (`integer[]`, 1 to 7 items, default `[0,1,2,3,4,5,6]`): For `daily`: the days it runs, 0 for Sunday to 6 for Saturday. Left out, it runs every day.
    - `monthDay` (`integer`, at least 1, at most 28, default `1`): For `monthly`: the day of the month, 1 to 28.
    - `timezone` (`string`, 1 to 64 characters, default `"UTC"`): An IANA time zone such as `Europe/Berlin`. The schedule follows its clock changes.
  - `mail` (`object`, nullable): Which arriving mail starts a `mail` task. Left out, every message that reaches an inbox does.
    - `addresses` (`string[]`, up to 25 items, default `[]`): Start only for mail delivered to one of these addresses of the workspace. Empty means every address.
    - `fromContains` (`string`, nullable, up to 200 characters): Start only when the sender address contains this text, whatever the case.
    - `subjectContains` (`string`, nullable, up to 200 characters): Start only when the subject contains this text, whatever the case.
- `autonomy` (`string`, one of `"ask"`, `"organize"`, `"reply"`): `ask` sends every change to a person to approve. `organize` lets the run label, archive, bin, snooze, draft, take notes and keep contacts by itself, and email the addresses of the workspace. `reply` also lets it answer an email without asking, as long as it adds no recipients and the task does not use `connectors`. Anything else always waits for approval, and so does every change in a connected app.
- `toolkits` (`string[]`, up to 15 items): Extra groups of tools the run may use beyond reading and organising mail, such as `contacts`, `calendar`, `knowledge`, `web` or `connectors`, which lets it use the apps connected for the workspace. A run can never reach billing, members, domains, rules, keys or webhooks.
- `model` (`string`, one of `"standard"`, `"advanced"`): `standard` is the everyday model. `advanced` reasons better over long jobs and costs ten AI actions where the standard one costs one.
- `notify` (`string`, one of `"always"`, `"attention"`, `"never"`): `attention` notifies the workspace owner when a run waits for approval or fails, `always` also when it finishes, and `never` stays silent.
- `maxRunsPerDay` (`integer`, at least 1, at most 500): The most runs the task may start in any 24 hours, however often its trigger fires.
- `maxSteps` (`integer`, at least 1, at most 60): The most model steps one run may take before it has to write its report.

**Returns**

- `200` `Task`: The task after the change.

**Errors**

- `404`: `task_not_found`: no task in this workspace has that id.
- `422`: `invalid_parameter`: nothing to change was sent or a field is malformed. `invalid_task`: the trigger, the time zone or a toolkit is not valid.
- The errors every operation can return: `400`, `401`, `403`, `500`, described in the [error catalog](https://openemail.uk/docs/api/errors).

Also available in: TypeScript [`tasks.update()`](https://openemail.uk/docs/sdk/reference/tasks#update); Python [`tasks.update()`](https://openemail.uk/docs/python/reference/tasks#update); Ruby [`tasks.update`](https://openemail.uk/docs/ruby/reference/tasks#update); PHP [`tasks->update`](https://openemail.uk/docs/php/reference/tasks#update); Go [`Tasks.Update`](https://openemail.uk/docs/go/reference/tasks#update); Java [`tasks().update`](https://openemail.uk/docs/java/reference/tasks#update); C# [`Tasks.UpdateAsync`](https://openemail.uk/docs/csharp/reference/tasks#update); CLI [`openemail tasks update`](https://openemail.uk/docs/cli/reference/tasks#tasks-update); MCP [`updateTask`](https://openemail.uk/docs/mcp/tools/tasks#updateTask).

### `DELETE /tasks/{id}`

Delete a task

Deletes a task for good, with every run it made and their records. A run in flight is stopped and its open approval requests are closed.

Requires the `tasks:write` scope.

- Scopes: `tasks:write`.

**Path parameters**

- `id` (`string`, required): The task, such as `tsk_5c1e9a7b3d2f48e6a0b4c7d1`, as `GET /tasks` lists it.

**Returns**

- `200` `DeletedTask`: Deleted.

**Errors**

- `404`: `task_not_found`: no task in this workspace has that id.
- The errors every operation can return: `400`, `401`, `403`, `422`, `500`, described in the [error catalog](https://openemail.uk/docs/api/errors).

Also available in: TypeScript [`tasks.delete()`](https://openemail.uk/docs/sdk/reference/tasks#delete); Python [`tasks.delete()`](https://openemail.uk/docs/python/reference/tasks#delete); Ruby [`tasks.delete`](https://openemail.uk/docs/ruby/reference/tasks#delete); PHP [`tasks->delete`](https://openemail.uk/docs/php/reference/tasks#delete); Go [`Tasks.Delete`](https://openemail.uk/docs/go/reference/tasks#delete); Java [`tasks().delete`](https://openemail.uk/docs/java/reference/tasks#delete); C# [`Tasks.DeleteAsync`](https://openemail.uk/docs/csharp/reference/tasks#delete); CLI [`openemail tasks delete`](https://openemail.uk/docs/cli/reference/tasks#tasks-delete); MCP [`deleteTask`](https://openemail.uk/docs/mcp/tools/tasks#deleteTask).

### `POST /tasks/{id}/pause`

Pause a task

Stops a task from starting new runs. A run already going carries on, and its approval requests can still be answered.

Requires the `tasks:write` scope.

- Scopes: `tasks:write`.

**Path parameters**

- `id` (`string`, required): The task, such as `tsk_5c1e9a7b3d2f48e6a0b4c7d1`, as `GET /tasks` lists it.

**Returns**

- `200` `Task`: The task, paused.

**Errors**

- `404`: `task_not_found`: no task in this workspace has that id.
- The errors every operation can return: `400`, `401`, `403`, `422`, `500`, described in the [error catalog](https://openemail.uk/docs/api/errors).

Also available in: TypeScript [`tasks.pause()`](https://openemail.uk/docs/sdk/reference/tasks#pause); Python [`tasks.pause()`](https://openemail.uk/docs/python/reference/tasks#pause); Ruby [`tasks.pause`](https://openemail.uk/docs/ruby/reference/tasks#pause); PHP [`tasks->pause`](https://openemail.uk/docs/php/reference/tasks#pause); Go [`Tasks.Pause`](https://openemail.uk/docs/go/reference/tasks#pause); Java [`tasks().pause`](https://openemail.uk/docs/java/reference/tasks#pause); C# [`Tasks.PauseAsync`](https://openemail.uk/docs/csharp/reference/tasks#pause); CLI [`openemail tasks pause`](https://openemail.uk/docs/cli/reference/tasks#tasks-pause); MCP [`pauseTask`](https://openemail.uk/docs/mcp/tools/tasks#pauseTask).

### `POST /tasks/{id}/resume`

Resume a task

Turns a paused task back on, whoever or whatever paused it, clears its failure count and gives a `schedule` task its next run time. A task acts with what its caller holds: besides `tasks:write` the request needs `threads:read`, `threads:write`, `emails:read`, `emails:send`, `labels:write` and the read and write scopes of every toolkit the task names. A workspace runs 1 active task on Free, 5 on Starter and 25 on Business, with no cap on Enterprise, and holds at most 100 tasks.

Requires the `tasks:write` and `threads:read` and `threads:write` and `emails:read` and `emails:send` and `labels:write` scopes.

- Scopes: `tasks:write`, `threads:read`, `threads:write`, `emails:read`, `emails:send`, `labels:write`.

**Path parameters**

- `id` (`string`, required): The task, such as `tsk_5c1e9a7b3d2f48e6a0b4c7d1`, as `GET /tasks` lists it.

**Returns**

- `200` `Task`: The task, active again.

**Errors**

- `403`: The key lacks a scope. `task_active_limit_reached`: the plan covers no more active tasks.
- `404`: `task_not_found`: no task in this workspace has that id.
- The errors every operation can return: `400`, `401`, `422`, `500`, described in the [error catalog](https://openemail.uk/docs/api/errors).

Also available in: TypeScript [`tasks.resume()`](https://openemail.uk/docs/sdk/reference/tasks#resume); Python [`tasks.resume()`](https://openemail.uk/docs/python/reference/tasks#resume); Ruby [`tasks.resume`](https://openemail.uk/docs/ruby/reference/tasks#resume); PHP [`tasks->resume`](https://openemail.uk/docs/php/reference/tasks#resume); Go [`Tasks.Resume`](https://openemail.uk/docs/go/reference/tasks#resume); Java [`tasks().resume`](https://openemail.uk/docs/java/reference/tasks#resume); C# [`Tasks.ResumeAsync`](https://openemail.uk/docs/csharp/reference/tasks#resume); CLI [`openemail tasks resume`](https://openemail.uk/docs/cli/reference/tasks#tasks-resume); MCP [`resumeTask`](https://openemail.uk/docs/mcp/tools/tasks#resumeTask).

### `POST /tasks/{id}/run`

Run a task now

Starts a run of a task at once, whatever its trigger and whether or not it is paused. The answer is the run as it was queued: read it again with `GET /task-runs/{id}` to follow it. A task acts with what its caller holds: besides `tasks:write` the request needs `threads:read`, `threads:write`, `emails:read`, `emails:send`, `labels:write` and the read and write scopes of every toolkit the task names.

Requires the `tasks:write` and `threads:read` and `threads:write` and `emails:read` and `emails:send` and `labels:write` scopes.

- Scopes: `tasks:write`, `threads:read`, `threads:write`, `emails:read`, `emails:send`, `labels:write`.

**Path parameters**

- `id` (`string`, required): The task, such as `tsk_5c1e9a7b3d2f48e6a0b4c7d1`, as `GET /tasks` lists it.

**Returns**

- `201` `TaskRunDetail`: The run, queued.

**Errors**

- `404`: `task_not_found`: no task in this workspace has that id.
- `409`: `task_run_limit_reached`: the task has run as often as it may today.
- The errors every operation can return: `400`, `401`, `403`, `422`, `500`, described in the [error catalog](https://openemail.uk/docs/api/errors).

Also available in: TypeScript [`tasks.run()`](https://openemail.uk/docs/sdk/reference/tasks#run); Python [`tasks.run()`](https://openemail.uk/docs/python/reference/tasks#run); Ruby [`tasks.run`](https://openemail.uk/docs/ruby/reference/tasks#run); PHP [`tasks->run`](https://openemail.uk/docs/php/reference/tasks#run); Go [`Tasks.Run`](https://openemail.uk/docs/go/reference/tasks#run); Java [`tasks().run`](https://openemail.uk/docs/java/reference/tasks#run); C# [`Tasks.RunAsync`](https://openemail.uk/docs/csharp/reference/tasks#run); CLI [`openemail tasks run`](https://openemail.uk/docs/cli/reference/tasks#tasks-run); MCP [`runTask`](https://openemail.uk/docs/mcp/tools/tasks#runTask).

### `GET /task-runs`

List task runs

Every run in the workspace, newest first, or the runs of one task with `taskId`. Runs are kept for 90 days. A task works across every address of the workspace, so a key or an app limited to particular addresses or domains is refused with `capability_unsupported`, and an app has to act for somebody who reaches every address.

Requires the `tasks:read` and `threads:read` and `emails:read` scopes.

- Scopes: `tasks:read`, `threads:read`, `emails:read`.

**Query parameters**

- `taskId` (`string`, 1 to 64 characters): Only the runs of this task, by its id. Left out, the runs of every task and the one-off runs are listed.
- `status` (`string`, one of `"queued"`, `"running"`, `"waiting"`, `"done"`, `"failed"`, `"cancelled"`): Only runs in this state: `queued`, `running`, `waiting`, `done`, `failed` or `cancelled`.
- `limit` (`integer`, at least 1, at most 100): Page size, from 1 to 100. The server defaults to 25.
- `cursor` (`string`, 1 to 256 characters): The `nextCursor` of the previous page, passed back as it came. Leave it out for the first page.

**Returns**

- `200` `TaskRunList`: A page of runs.

**Errors**

- `400`: `invalid_cursor`.
- The errors every operation can return: `401`, `403`, `404`, `422`, `500`, described in the [error catalog](https://openemail.uk/docs/api/errors).

Also available in: TypeScript [`tasks.listRuns()`](https://openemail.uk/docs/sdk/reference/tasks#listRuns), [`tasks.listAllRuns()`](https://openemail.uk/docs/sdk/reference/tasks#listAllRuns), [`tasks.iterateRuns()`](https://openemail.uk/docs/sdk/reference/tasks#iterateRuns); Python [`tasks.list_runs()`](https://openemail.uk/docs/python/reference/tasks#listRuns), [`tasks.list_all_runs()`](https://openemail.uk/docs/python/reference/tasks#listAllRuns), [`tasks.iterate_runs()`](https://openemail.uk/docs/python/reference/tasks#iterateRuns); Ruby [`tasks.list_runs`](https://openemail.uk/docs/ruby/reference/tasks#listRuns), [`tasks.list_all_runs`](https://openemail.uk/docs/ruby/reference/tasks#listAllRuns), [`tasks.iterate_runs`](https://openemail.uk/docs/ruby/reference/tasks#iterateRuns); PHP [`tasks->listRuns`](https://openemail.uk/docs/php/reference/tasks#listRuns), [`tasks->listAllRuns`](https://openemail.uk/docs/php/reference/tasks#listAllRuns), [`tasks->iterateRuns`](https://openemail.uk/docs/php/reference/tasks#iterateRuns); Go [`Tasks.ListRuns`](https://openemail.uk/docs/go/reference/tasks#listRuns), [`Tasks.ListAllRuns`](https://openemail.uk/docs/go/reference/tasks#listAllRuns), [`Tasks.IterateRuns`](https://openemail.uk/docs/go/reference/tasks#iterateRuns); Java [`tasks().listRuns`](https://openemail.uk/docs/java/reference/tasks#listRuns), [`tasks().listAllRuns`](https://openemail.uk/docs/java/reference/tasks#listAllRuns), [`tasks().iterateRuns`](https://openemail.uk/docs/java/reference/tasks#iterateRuns); C# [`Tasks.ListRunsAsync`](https://openemail.uk/docs/csharp/reference/tasks#listRuns), [`Tasks.ListAllRunsAsync`](https://openemail.uk/docs/csharp/reference/tasks#listAllRuns), [`Tasks.IterateRunsAsync`](https://openemail.uk/docs/csharp/reference/tasks#iterateRuns); CLI [`openemail tasks list-runs`](https://openemail.uk/docs/cli/reference/tasks#tasks-list-runs); MCP [`listTaskRuns`](https://openemail.uk/docs/mcp/tools/tasks#listTaskRuns).

### `POST /task-runs`

Start a one-off run

Hands the assistant one job to do in the background, with no task saved: a long tidy-up, a report, or anything that should not wait on an open chat. A workspace starts at most 100 of these a day. A task acts with what its caller holds: besides `tasks:write` the request needs `threads:read`, `threads:write`, `emails:read`, `emails:send`, `labels:write` and the read and write scopes of every toolkit the task names. A task works across every address of the workspace, so a key or an app limited to particular addresses or domains is refused with `capability_unsupported`, and an app has to act for somebody who reaches every address.

Requires the `tasks:write` and `threads:read` and `threads:write` and `emails:read` and `emails:send` and `labels:write` scopes.

- Scopes: `tasks:write`, `threads:read`, `threads:write`, `emails:read`, `emails:send`, `labels:write`.

**Request body**

- `instruction` (`string`, required, 1 to 8000 characters): What the assistant should do, in plain words, as you would tell a person. It is the only instruction the run follows: text inside emails is read, never obeyed.
- `autonomy` (`string`, one of `"ask"`, `"organize"`, `"reply"`): `ask` sends every change to a person to approve. `organize` lets the run label, archive, bin, snooze, draft, take notes and keep contacts by itself, and email the addresses of the workspace. `reply` also lets it answer an email without asking, as long as it adds no recipients and the task does not use `connectors`. Anything else always waits for approval, and so does every change in a connected app.
- `toolkits` (`string[]`, up to 15 items): Extra groups of tools the run may use beyond reading and organising mail, such as `contacts`, `calendar`, `knowledge`, `web` or `connectors`, which lets it use the apps connected for the workspace. A run can never reach billing, members, domains, rules, keys or webhooks.
- `model` (`string`, one of `"standard"`, `"advanced"`): `standard` is the everyday model. `advanced` reasons better over long jobs and costs ten AI actions where the standard one costs one.
- `maxSteps` (`integer`, at least 1, at most 60): The most model steps one run may take before it has to write its report.
- `threadId` (`string`, 1 to 255 characters): A conversation to hand the run as its starting point, as `GET /threads` lists it.

**Returns**

- `201` `TaskRunDetail`: The run, queued.

**Errors**

- `409`: `task_run_limit_reached`: the workspace has started as many as it may today.
- `422`: `invalid_parameter`: a field is missing or malformed. `invalid_task`: a toolkit is not one a run may use.
- The errors every operation can return: `400`, `401`, `403`, `404`, `500`, described in the [error catalog](https://openemail.uk/docs/api/errors).

Also available in: TypeScript [`tasks.startRun()`](https://openemail.uk/docs/sdk/reference/tasks#startRun); Python [`tasks.start_run()`](https://openemail.uk/docs/python/reference/tasks#startRun); Ruby [`tasks.start_run`](https://openemail.uk/docs/ruby/reference/tasks#startRun); PHP [`tasks->startRun`](https://openemail.uk/docs/php/reference/tasks#startRun); Go [`Tasks.StartRun`](https://openemail.uk/docs/go/reference/tasks#startRun); Java [`tasks().startRun`](https://openemail.uk/docs/java/reference/tasks#startRun); C# [`Tasks.StartRunAsync`](https://openemail.uk/docs/csharp/reference/tasks#startRun); CLI [`openemail tasks start-run`](https://openemail.uk/docs/cli/reference/tasks#tasks-start-run); MCP [`startTaskRun`](https://openemail.uk/docs/mcp/tools/tasks#startTaskRun).

### `GET /task-runs/{id}`

Read a task run

One run with its report, every step it took, the tools it called with what they answered, and its approval requests. A task works across every address of the workspace, so a key or an app limited to particular addresses or domains is refused with `capability_unsupported`, and an app has to act for somebody who reaches every address.

Requires the `tasks:read` and `threads:read` and `emails:read` scopes.

- Scopes: `tasks:read`, `threads:read`, `emails:read`.

**Path parameters**

- `id` (`string`, required): The run, such as `run_2b8d4f6a1c3e5079b6d8f0a2`, as `GET /task-runs` lists it.

**Returns**

- `200` `TaskRunDetail`: The run.

**Errors**

- `404`: `task_run_not_found`: no run in this workspace has that id.
- The errors every operation can return: `400`, `401`, `403`, `422`, `500`, described in the [error catalog](https://openemail.uk/docs/api/errors).

Also available in: TypeScript [`tasks.getRun()`](https://openemail.uk/docs/sdk/reference/tasks#getRun); Python [`tasks.get_run()`](https://openemail.uk/docs/python/reference/tasks#getRun); Ruby [`tasks.get_run`](https://openemail.uk/docs/ruby/reference/tasks#getRun); PHP [`tasks->getRun`](https://openemail.uk/docs/php/reference/tasks#getRun); Go [`Tasks.GetRun`](https://openemail.uk/docs/go/reference/tasks#getRun); Java [`tasks().getRun`](https://openemail.uk/docs/java/reference/tasks#getRun); C# [`Tasks.GetRunAsync`](https://openemail.uk/docs/csharp/reference/tasks#getRun); CLI [`openemail tasks get-run`](https://openemail.uk/docs/cli/reference/tasks#tasks-get-run); MCP [`getTaskRun`](https://openemail.uk/docs/mcp/tools/tasks#getTaskRun).

### `POST /task-runs/{id}/cancel`

Cancel a task run

Stops a run that is queued, running or waiting for approval, and closes its open approval requests. What the run already did stays done.

Requires the `tasks:write` scope.

- Scopes: `tasks:write`.

**Path parameters**

- `id` (`string`, required): The run, such as `run_2b8d4f6a1c3e5079b6d8f0a2`, as `GET /task-runs` lists it.

**Returns**

- `200` `TaskRunDetail`: The run, cancelled.

**Errors**

- `404`: `task_run_not_found`: no run in this workspace has that id.
- `409`: `task_run_finished`: the run has already ended.
- The errors every operation can return: `400`, `401`, `403`, `422`, `500`, described in the [error catalog](https://openemail.uk/docs/api/errors).

Also available in: TypeScript [`tasks.cancelRun()`](https://openemail.uk/docs/sdk/reference/tasks#cancelRun); Python [`tasks.cancel_run()`](https://openemail.uk/docs/python/reference/tasks#cancelRun); Ruby [`tasks.cancel_run`](https://openemail.uk/docs/ruby/reference/tasks#cancelRun); PHP [`tasks->cancelRun`](https://openemail.uk/docs/php/reference/tasks#cancelRun); Go [`Tasks.CancelRun`](https://openemail.uk/docs/go/reference/tasks#cancelRun); Java [`tasks().cancelRun`](https://openemail.uk/docs/java/reference/tasks#cancelRun); C# [`Tasks.CancelRunAsync`](https://openemail.uk/docs/csharp/reference/tasks#cancelRun); CLI [`openemail tasks cancel-run`](https://openemail.uk/docs/cli/reference/tasks#tasks-cancel-run); MCP [`cancelTaskRun`](https://openemail.uk/docs/mcp/tools/tasks#cancelTaskRun).

### `GET /task-approvals`

List approval requests

What runs are waiting for a person to allow, newest first: the tool the run wants to call and the exact arguments it would call it with. A request waits 7 days, then expires and the run carries on without it. A task works across every address of the workspace, so a key or an app limited to particular addresses or domains is refused with `capability_unsupported`, and an app has to act for somebody who reaches every address.

Requires the `tasks:read` and `threads:read` and `emails:read` scopes.

- Scopes: `tasks:read`, `threads:read`, `emails:read`.

**Query parameters**

- `status` (`string`, one of `"pending"`, `"approved"`, `"denied"`, `"expired"`, `"cancelled"`): Only requests in this state: `pending`, `approved`, `denied`, `expired` or `cancelled`. Left out, the list holds the ones still pending.
- `runId` (`string`, 1 to 64 characters): Only the requests of this run, by its id.
- `taskId` (`string`, 1 to 64 characters): Only the requests of the runs of this task, by its id.
- `limit` (`integer`, at least 1, at most 100): Page size, from 1 to 100. The server defaults to 25.
- `cursor` (`string`, 1 to 256 characters): The `nextCursor` of the previous page, passed back as it came. Leave it out for the first page.

**Returns**

- `200` `TaskApprovalList`: A page of approval requests.

**Errors**

- `400`: `invalid_cursor`.
- The errors every operation can return: `401`, `403`, `404`, `422`, `500`, described in the [error catalog](https://openemail.uk/docs/api/errors).

Also available in: TypeScript [`tasks.listApprovals()`](https://openemail.uk/docs/sdk/reference/tasks#listApprovals), [`tasks.listAllApprovals()`](https://openemail.uk/docs/sdk/reference/tasks#listAllApprovals), [`tasks.iterateApprovals()`](https://openemail.uk/docs/sdk/reference/tasks#iterateApprovals); Python [`tasks.list_approvals()`](https://openemail.uk/docs/python/reference/tasks#listApprovals), [`tasks.list_all_approvals()`](https://openemail.uk/docs/python/reference/tasks#listAllApprovals), [`tasks.iterate_approvals()`](https://openemail.uk/docs/python/reference/tasks#iterateApprovals); Ruby [`tasks.list_approvals`](https://openemail.uk/docs/ruby/reference/tasks#listApprovals), [`tasks.list_all_approvals`](https://openemail.uk/docs/ruby/reference/tasks#listAllApprovals), [`tasks.iterate_approvals`](https://openemail.uk/docs/ruby/reference/tasks#iterateApprovals); PHP [`tasks->listApprovals`](https://openemail.uk/docs/php/reference/tasks#listApprovals), [`tasks->listAllApprovals`](https://openemail.uk/docs/php/reference/tasks#listAllApprovals), [`tasks->iterateApprovals`](https://openemail.uk/docs/php/reference/tasks#iterateApprovals); Go [`Tasks.ListApprovals`](https://openemail.uk/docs/go/reference/tasks#listApprovals), [`Tasks.ListAllApprovals`](https://openemail.uk/docs/go/reference/tasks#listAllApprovals), [`Tasks.IterateApprovals`](https://openemail.uk/docs/go/reference/tasks#iterateApprovals); Java [`tasks().listApprovals`](https://openemail.uk/docs/java/reference/tasks#listApprovals), [`tasks().listAllApprovals`](https://openemail.uk/docs/java/reference/tasks#listAllApprovals), [`tasks().iterateApprovals`](https://openemail.uk/docs/java/reference/tasks#iterateApprovals); C# [`Tasks.ListApprovalsAsync`](https://openemail.uk/docs/csharp/reference/tasks#listApprovals), [`Tasks.ListAllApprovalsAsync`](https://openemail.uk/docs/csharp/reference/tasks#listAllApprovals), [`Tasks.IterateApprovalsAsync`](https://openemail.uk/docs/csharp/reference/tasks#iterateApprovals); CLI [`openemail tasks list-approvals`](https://openemail.uk/docs/cli/reference/tasks#tasks-list-approvals); MCP [`listTaskApprovals`](https://openemail.uk/docs/mcp/tools/tasks#listTaskApprovals).

### `GET /task-approvals/{id}`

Read an approval request

One approval request. A task works across every address of the workspace, so a key or an app limited to particular addresses or domains is refused with `capability_unsupported`, and an app has to act for somebody who reaches every address.

Requires the `tasks:read` and `threads:read` and `emails:read` scopes.

- Scopes: `tasks:read`, `threads:read`, `emails:read`.

**Path parameters**

- `id` (`string`, required): The approval request, such as `apr_9f3a1c5e7b2d4608a1c3e5f7`, as `GET /task-approvals` lists it.

**Returns**

- `200` `TaskApproval`: The approval request.

**Errors**

- `404`: `task_approval_not_found`: no approval request in this workspace has that id.
- The errors every operation can return: `400`, `401`, `403`, `422`, `500`, described in the [error catalog](https://openemail.uk/docs/api/errors).

Also available in: TypeScript [`tasks.getApproval()`](https://openemail.uk/docs/sdk/reference/tasks#getApproval); Python [`tasks.get_approval()`](https://openemail.uk/docs/python/reference/tasks#getApproval); Ruby [`tasks.get_approval`](https://openemail.uk/docs/ruby/reference/tasks#getApproval); PHP [`tasks->getApproval`](https://openemail.uk/docs/php/reference/tasks#getApproval); Go [`Tasks.GetApproval`](https://openemail.uk/docs/go/reference/tasks#getApproval); Java [`tasks().getApproval`](https://openemail.uk/docs/java/reference/tasks#getApproval); C# [`Tasks.GetApprovalAsync`](https://openemail.uk/docs/csharp/reference/tasks#getApproval); CLI [`openemail tasks get-approval`](https://openemail.uk/docs/cli/reference/tasks#tasks-get-approval).

### `POST /task-approvals/{id}/approve`

Approve a request

Lets the run do what it asked for, with the arguments the request shows. For a send or a reply, `subject` and `body` replace what the run wrote. The run picks up again once every request of its step is answered. A task acts with what its caller holds: besides `tasks:write` the request needs `threads:read`, `threads:write`, `emails:read`, `emails:send`, `labels:write` and the read and write scopes of every toolkit the task names.

Requires the `tasks:write` and `threads:read` and `threads:write` and `emails:read` and `emails:send` and `labels:write` scopes.

- Scopes: `tasks:write`, `threads:read`, `threads:write`, `emails:read`, `emails:send`, `labels:write`.

**Path parameters**

- `id` (`string`, required): The approval request, such as `apr_9f3a1c5e7b2d4608a1c3e5f7`, as `GET /task-approvals` lists it.

**Request body**

- `subject` (`string`, 1 to 998 characters): For a send or a reply: the subject to use instead of the one the run wrote.
- `body` (`string`, 1 to 100000 characters): For a send or a reply: the words to send instead of the ones the run wrote.

**Returns**

- `200` `TaskApproval`: The request, approved.

**Errors**

- `404`: `task_approval_not_found`: no approval request in this workspace has that id.
- `409`: `task_approval_decided`: the request was already answered, has expired, or its run has ended.
- The errors every operation can return: `400`, `401`, `403`, `422`, `500`, described in the [error catalog](https://openemail.uk/docs/api/errors).

Also available in: TypeScript [`tasks.approve()`](https://openemail.uk/docs/sdk/reference/tasks#approve); Python [`tasks.approve()`](https://openemail.uk/docs/python/reference/tasks#approve); Ruby [`tasks.approve`](https://openemail.uk/docs/ruby/reference/tasks#approve); PHP [`tasks->approve`](https://openemail.uk/docs/php/reference/tasks#approve); Go [`Tasks.Approve`](https://openemail.uk/docs/go/reference/tasks#approve); Java [`tasks().approve`](https://openemail.uk/docs/java/reference/tasks#approve); C# [`Tasks.ApproveAsync`](https://openemail.uk/docs/csharp/reference/tasks#approve); CLI [`openemail tasks approve`](https://openemail.uk/docs/cli/reference/tasks#tasks-approve); MCP [`approveTaskApproval`](https://openemail.uk/docs/mcp/tools/tasks#approveTaskApproval).

### `POST /task-approvals/{id}/deny`

Deny a request

Refuses what the run asked for. The run is told, does not try again, and carries on with the rest of its task.

Requires the `tasks:write` scope.

- Scopes: `tasks:write`.

**Path parameters**

- `id` (`string`, required): The approval request, such as `apr_9f3a1c5e7b2d4608a1c3e5f7`, as `GET /task-approvals` lists it.

**Returns**

- `200` `TaskApproval`: The request, denied.

**Errors**

- `404`: `task_approval_not_found`: no approval request in this workspace has that id.
- `409`: `task_approval_decided`: the request was already answered, has expired, or its run has ended.
- The errors every operation can return: `400`, `401`, `403`, `422`, `500`, described in the [error catalog](https://openemail.uk/docs/api/errors).

Also available in: TypeScript [`tasks.deny()`](https://openemail.uk/docs/sdk/reference/tasks#deny); Python [`tasks.deny()`](https://openemail.uk/docs/python/reference/tasks#deny); Ruby [`tasks.deny`](https://openemail.uk/docs/ruby/reference/tasks#deny); PHP [`tasks->deny`](https://openemail.uk/docs/php/reference/tasks#deny); Go [`Tasks.Deny`](https://openemail.uk/docs/go/reference/tasks#deny); Java [`tasks().deny`](https://openemail.uk/docs/java/reference/tasks#deny); C# [`Tasks.DenyAsync`](https://openemail.uk/docs/csharp/reference/tasks#deny); CLI [`openemail tasks deny`](https://openemail.uk/docs/cli/reference/tasks#tasks-deny); MCP [`denyTaskApproval`](https://openemail.uk/docs/mcp/tools/tasks#denyTaskApproval).

### Objects

#### `DeletedTask`

`object`

- `object` (`string`, required, one of `"task"`)
- `id` (`string`, required)
- `deleted` (`boolean`, required, one of `true`)

#### `Task`

`object`

- `object` (`string`, required, one of `"task"`)
- `id` (`string`, required): The id, which starts with `tsk_`.
- `name` (`string`, required): What the task is called in the app.
- `instruction` (`string`, required): What the assistant should do, in plain words, as you would tell a person. It is the only instruction the run follows: text inside emails is read, never obeyed.
- `status` (`string`, required, one of `"active"`, `"paused"`): Whether the task starts runs. A paused task can still be run by hand.
- `pausedReason` (`string`, required, nullable, one of `"user"`, `"failures"`, `"plan_limit"`): Why a paused task is paused: `user` when somebody paused it, `failures` after 5 failed runs in a row, and `plan_limit` when the plan no longer covers it.
- `trigger` (`TaskTrigger`, required)
- `autonomy` (`string`, required, one of `"ask"`, `"organize"`, `"reply"`): `ask` sends every change to a person to approve. `organize` lets the run label, archive, bin, snooze, draft, take notes and keep contacts by itself, and email the addresses of the workspace. `reply` also lets it answer an email without asking, as long as it adds no recipients and the task does not use `connectors`. Anything else always waits for approval, and so does every change in a connected app.
- `toolkits` (`string[]`, required, one of `"contacts"`, `"audiences"`, `"templates"`, `"tracking"`, `"translate"`, `"files"`, `"notes"`, `"drafts"`, `"sent"`, `"insights"`, `"subscriptions"`, `"calendar"`, `"knowledge"`, `"connectors"`, `"web"`): Extra groups of tools the run may use beyond reading and organising mail, such as `contacts`, `calendar`, `knowledge`, `web` or `connectors`, which lets it use the apps connected for the workspace. A run can never reach billing, members, domains, rules, keys or webhooks.
- `model` (`string`, required, one of `"standard"`, `"advanced"`): `standard` is the everyday model. `advanced` reasons better over long jobs and costs ten AI actions where the standard one costs one.
- `notify` (`string`, required, one of `"always"`, `"attention"`, `"never"`): `attention` notifies the workspace owner when a run waits for approval or fails, `always` also when it finishes, and `never` stays silent.
- `maxRunsPerDay` (`integer`, required): The most runs the task may start in any 24 hours, however often its trigger fires.
- `maxSteps` (`integer`, required): The most model steps one run may take before it has to write its report.
- `nextRunAt` (`string`, required, nullable, format `date-time`): When a `schedule` task runs next. Null for the other kinds and while paused.
- `heldUntil` (`string`, required, nullable, format `date-time`): Set when the workspace ran out of AI actions for the day: the task starts nothing until then.
- `lastRunAt` (`string`, required, nullable, format `date-time`): When the last run of the task ended.
- `lastRunStatus` (`string`, required, nullable, one of `"queued"`, `"running"`, `"waiting"`, `"done"`, `"failed"`, `"cancelled"`): How the last run ended.
- `runCount` (`integer`, required, at least 0): How many runs the task has started.
- `pendingApprovals` (`integer`, required, at least 0): How many approval requests of the task wait for an answer.
- `chatId` (`string`, required, nullable): The assistant conversation the task was created in, as `GET /chats` lists it. Null for a task made anywhere else: in the Tasks page, over the API or by an MCP client.
- `createdAt` (`string`, required, format `date-time`): When the task was created.
- `updatedAt` (`string`, required, format `date-time`): When the task last changed or last ran.

#### `TaskApproval`

`object`

- `object` (`string`, required, one of `"task_approval"`)
- `id` (`string`, required): The id, which starts with `apr_`.
- `runId` (`string`, required): The run that asked.
- `taskId` (`string`, required, nullable): The task of that run, or null for a one-off run.
- `taskName` (`string`, required, nullable)
- `tool` (`string`, required): The tool the run wants to call.
- `summary` (`string`, required): One line that says what would happen.
- `args` (`object`, required): The exact arguments the tool would be called with. A reply shows the recipients worked out from the message it answers.
- `status` (`string`, required, one of `"pending"`, `"approved"`, `"denied"`, `"expired"`, `"cancelled"`)
- `createdAt` (`string`, required, format `date-time`): When the run asked.
- `expiresAt` (`string`, required, format `date-time`): When the request stops waiting.
- `decidedAt` (`string`, required, nullable, format `date-time`): When it was answered.

#### `TaskApprovalList`

`object`

- `object` (`string`, one of `"list"`)
- `data` (`TaskApproval[]`)
- `hasMore` (`boolean`): True when another page follows. Pass `nextCursor` back as `cursor` to read it.
- `nextCursor` (`string`, nullable): An opaque cursor for the next page, or null on the last page. Pass it back unchanged.

#### `TaskList`

`object`

- `object` (`string`, one of `"list"`)
- `data` (`Task[]`)
- `hasMore` (`boolean`): True when another page follows. Pass `nextCursor` back as `cursor` to read it.
- `nextCursor` (`string`, nullable): An opaque cursor for the next page, or null on the last page. Pass it back unchanged.

#### `TaskRun`

`object`

- `object` (`string`, required, one of `"task_run"`)
- `id` (`string`, required): The id, which starts with `run_`.
- `taskId` (`string`, required, nullable): The task the run belongs to, or null for a one-off run.
- `taskName` (`string`, required, nullable): The name of that task.
- `trigger` (`string`, required, one of `"schedule"`, `"mail"`, `"manual"`): What started the run.
- `threadId` (`string`, required, nullable): The conversation whose new message started the run, or the one a one-off run was handed.
- `status` (`string`, required, one of `"queued"`, `"running"`, `"waiting"`, `"done"`, `"failed"`, `"cancelled"`): `queued` until a runner picks it up, `running` while it works, `waiting` while an approval request is open, then `done`, `failed` or `cancelled`.
- `instruction` (`string`, required): The instruction the run started with, kept as it was then.
- `autonomy` (`string`, required, one of `"ask"`, `"organize"`, `"reply"`)
- `model` (`string`, required, one of `"standard"`, `"advanced"`)
- `steps` (`integer`, required, at least 0): How many times the model was asked what to do next.
- `toolCalls` (`integer`, required, at least 0): How many tool calls ran.
- `actions` (`integer`, required, at least 0): How many AI actions the run has cost the workspace.
- `result` (`string`, required, nullable): The report the run wrote when it finished.
- `error` (`string`, required, nullable, one of `"ai_limit"`, `"ai_unavailable"`, `"no_progress"`, `"attempts"`): Why a failed run failed: `ai_limit` when the workspace ran out of AI actions for the day, `ai_unavailable` when AI is not set up, and `attempts` or `no_progress` when it kept failing or stood still.
- `errorDetail` (`string`, required, nullable): A sentence about the failure.
- `pendingApprovals` (`integer`, required, at least 0): How many approval requests of the run wait for an answer.
- `chatId` (`string`, required, nullable): The assistant conversation the run belongs to: the one that started it, or else the one its task was created in. Null when neither came from a conversation. The app shows the run in that conversation.
- `createdAt` (`string`, required, format `date-time`): When the run was queued.
- `updatedAt` (`string`, required, format `date-time`): When the run last changed: a step it took, an approval it started waiting for, or its end.
- `startedAt` (`string`, required, nullable, format `date-time`): When a runner first picked it up.
- `finishedAt` (`string`, required, nullable, format `date-time`): When it ended.

#### `TaskRunDetail`

`object`

- `object` (`string`, required, one of `"task_run"`)
- `id` (`string`, required): The id, which starts with `run_`.
- `taskId` (`string`, required, nullable): The task the run belongs to, or null for a one-off run.
- `taskName` (`string`, required, nullable): The name of that task.
- `trigger` (`string`, required, one of `"schedule"`, `"mail"`, `"manual"`): What started the run.
- `threadId` (`string`, required, nullable): The conversation whose new message started the run, or the one a one-off run was handed.
- `status` (`string`, required, one of `"queued"`, `"running"`, `"waiting"`, `"done"`, `"failed"`, `"cancelled"`): `queued` until a runner picks it up, `running` while it works, `waiting` while an approval request is open, then `done`, `failed` or `cancelled`.
- `instruction` (`string`, required): The instruction the run started with, kept as it was then.
- `autonomy` (`string`, required, one of `"ask"`, `"organize"`, `"reply"`)
- `model` (`string`, required, one of `"standard"`, `"advanced"`)
- `steps` (`integer`, required, at least 0): How many times the model was asked what to do next.
- `toolCalls` (`integer`, required, at least 0): How many tool calls ran.
- `actions` (`integer`, required, at least 0): How many AI actions the run has cost the workspace.
- `result` (`string`, required, nullable): The report the run wrote when it finished.
- `error` (`string`, required, nullable, one of `"ai_limit"`, `"ai_unavailable"`, `"no_progress"`, `"attempts"`): Why a failed run failed: `ai_limit` when the workspace ran out of AI actions for the day, `ai_unavailable` when AI is not set up, and `attempts` or `no_progress` when it kept failing or stood still.
- `errorDetail` (`string`, required, nullable): A sentence about the failure.
- `pendingApprovals` (`integer`, required, at least 0): How many approval requests of the run wait for an answer.
- `chatId` (`string`, required, nullable): The assistant conversation the run belongs to: the one that started it, or else the one its task was created in. Null when neither came from a conversation. The app shows the run in that conversation.
- `createdAt` (`string`, required, format `date-time`): When the run was queued.
- `updatedAt` (`string`, required, format `date-time`): When the run last changed: a step it took, an approval it started waiting for, or its end.
- `startedAt` (`string`, required, nullable, format `date-time`): When a runner first picked it up.
- `finishedAt` (`string`, required, nullable, format `date-time`): When it ended.
- `transcript` (`TaskRunStep[]`, required): The record of the run in order: the instruction it started with, then every step it took with the tools that step called.
- `approvals` (`TaskApproval[]`, required): Every approval request of the run, newest first.

#### `TaskRunList`

`object`

- `object` (`string`, one of `"list"`)
- `data` (`TaskRun[]`)
- `hasMore` (`boolean`): True when another page follows. Pass `nextCursor` back as `cursor` to read it.
- `nextCursor` (`string`, nullable): An opaque cursor for the next page, or null on the last page. Pass it back unchanged.

#### `TaskRunStep`

`object`

- `role` (`string`, required, one of `"user"`, `"assistant"`): `user` for the instruction the run started with, `assistant` for each step it took.
- `text` (`string`, required): What was said at this step.
- `at` (`string`, required, nullable, format `date-time`): When the step was taken.
- `calls` (`object[]`, required): The tools the step called.
  - `id` (`string`, required)
  - `tool` (`string`, required): The tool, by the name the MCP server lists it under.
  - `args` (`object`, required): What it was called with.
  - `done` (`boolean`, required): False while the call waits for approval or has not run yet.
  - `result` (`any`, required): What the tool answered, or null until it has.

#### `TaskTrigger`

`object`

- `kind` (`string`, required, one of `"schedule"`, `"mail"`, `"manual"`): `schedule` runs on a clock, `mail` runs when a message arrives, and `manual` runs only when started by hand or through the API.
- `schedule` (`object`, nullable): When a `schedule` task runs. Needed for that kind and ignored for the others.
  - `cadence` (`string`, required, one of `"hourly"`, `"daily"`, `"monthly"`): `hourly` runs every `everyHours` hours at `minute`, `daily` runs at `hour`:`minute` on each of `weekdays`, and `monthly` runs at `hour`:`minute` on `monthDay`.
  - `everyHours` (`integer`, at least 1, at most 12, default `1`): For `hourly`: how many hours lie between runs, counted from midnight in the time zone.
  - `hour` (`integer`, at least 0, at most 23, default `8`): The hour of the day, 0 to 23, in the time zone of the schedule.
  - `minute` (`integer`, at least 0, at most 59, default `0`): The minute of the hour, 0 to 59.
  - `weekdays` (`integer[]`, 1 to 7 items, default `[0,1,2,3,4,5,6]`): For `daily`: the days it runs, 0 for Sunday to 6 for Saturday. Left out, it runs every day.
  - `monthDay` (`integer`, at least 1, at most 28, default `1`): For `monthly`: the day of the month, 1 to 28.
  - `timezone` (`string`, 1 to 64 characters, default `"UTC"`): An IANA time zone such as `Europe/Berlin`. The schedule follows its clock changes.
- `mail` (`object`, nullable): Which arriving mail starts a `mail` task. Left out, every message that reaches an inbox does.
  - `addresses` (`string[]`, up to 25 items, default `[]`): Start only for mail delivered to one of these addresses of the workspace. Empty means every address.
  - `fromContains` (`string`, nullable, up to 200 characters): Start only when the sender address contains this text, whatever the case.
  - `subjectContains` (`string`, nullable, up to 200 characters): Start only when the subject contains this text, whatever the case.
