# client.mail_triggers

> client.mail_triggers — the mailTriggers operations.

`client.mail_triggers` — the `mailTriggers` operations.

On `AsyncKindgi` every method is the same, awaited.

## `client.mail_triggers.list()`

```python signature
list(
    *,
    limit: int | None = None,
    cursor: str | None = None,
    status: Literal['active', 'paused'] | None = None,
    project_id: str | UUID | None = None,
    timeout: float | None = None,
) -> MailTriggerCollectionPage
```

List mail triggers. `GET /v1/mail-triggers`

The tenant's mail triggers whose project the caller may read; with `projectId`, that project's only (which needs `read` on it).

## `client.mail_triggers.register()`

```python signature
register(
    body: RegisterMailTriggerBody | Mapping[str, Any] | None = None,
    /,
    *,
    idempotency_key: str | None = None,
    timeout: float | None = None,
    **fields: Any,
) -> MailTriggerRecord
```

Register a mail trigger. `POST /v1/mail-triggers`

Each new mail in the mailbox's folder starts a run of the trigger's agent or flow, with the mail as the run's input, as the trigger's owner. A trigger on a person's mailbox (`config.mailbox.as: person`) reads the caller's own mail through their connection, so the caller owns it: it needs `write` on the project, and a service account can't own it. One on the company's mailbox (`company`) reads it through the company's connection and needs `admin` on the project; `runAsServiceAccountId` makes it shared, owned by that service account (which needs `act_as` on it), and `runAsProject` makes it shared, owned by the project's own account (made the first time, with the `editor` role on the project). Both need `execute` on what it runs. A trigger that names no `projectId` goes in the tenant's Default project. In its runs, every call that changes something, or uses the run's own mailbox, waits for a person's yes, unless `toolsAllowedUnattended` names it: naming it takes `admin` on the project, each id must be a tool the target calls, and it's audited (`trigger-tools-allowed-unattended-set`).

## `client.mail_triggers.get()`

```python signature
get(trigger_id: str | UUID, /, *, timeout: float | None = None) -> MailTriggerRecord
```

Fetch a mail trigger. `GET /v1/mail-triggers/{triggerId}`

## `client.mail_triggers.update()`

```python signature
update(
    trigger_id: str | UUID,
    body: PatchMailTriggerBody | Mapping[str, Any] | None = None,
    /,
    *,
    idempotency_key: str | None = None,
    timeout: float | None = None,
    **fields: Any,
) -> MailTriggerRecord
```

Update a mail trigger. `PATCH /v1/mail-triggers/{triggerId}`

Changes what it runs (which needs `execute` on the new target, and must be the project's to reach), its mailbox (replaced whole), folder, pace or label (`null` clears it). To watch the inbox again, name it as the folder: `INBOX` on Gmail, `inbox` on Outlook. No edit moves the owner: a personal trigger's change is its owner's (who needs `write` on the project) or a project admin's, a shared one's is a project admin's, and the company's mailbox, before or after, takes a project admin. Only a personal trigger's owner chooses what it reads from a person's mailbox, another of their mailboxes or another folder: anyone else, a project admin included, gets a `403`, and may take the trigger over to watch their own. A project admin's other changes to a person's trigger, such as what it runs, its pace or a move to the company's mailbox, keep its owner, so its runs go on acting as that person, and they're audited as `trigger-changed-for-owner`, naming the trigger's version after each. Since no edit moves the owner, with an authorization store a new target (another flow or agent) must be one the owner can run, a person or a service account, else `409 trigger-owner-cannot-run-target`; that's not checked when the caller is the owner, nor for an owner that was unregistered or removed. `toolsAllowedUnattended` replaces the list (`[]` clears it; absent keeps it, a new version too), and a new target or mailbox while it lists any must name it again. Naming a list takes `admin` on the project; a personal trigger's owner may name `[]` with their own new target or mailbox.

## `client.mail_triggers.pause()`

```python signature
pause(
    trigger_id: str | UUID,
    /,
    *,
    idempotency_key: str | None = None,
    timeout: float | None = None,
) -> MailTriggerRecord
```

Pause a mail trigger. `POST /v1/mail-triggers/{triggerId}/pause`

A paused trigger doesn't poll. A personal trigger's pause is its owner's or a project admin's; a shared one's needs `write` on the project.

## `client.mail_triggers.resume()`

```python signature
resume(
    trigger_id: str | UUID,
    /,
    *,
    idempotency_key: str | None = None,
    timeout: float | None = None,
) -> MailTriggerRecord
```

Resume a mail trigger. `POST /v1/mail-triggers/{triggerId}/resume`

It starts afresh: mail that came while it was paused doesn't start runs. Who may resume it is as for a pause.

## `client.mail_triggers.unregister()`

```python signature
unregister(
    trigger_id: str | UUID,
    /,
    *,
    idempotency_key: str | None = None,
    timeout: float | None = None,
) -> WebhookTriggerUnregisterResult
```

Soft-delete a mail trigger (tombstone). `POST /v1/mail-triggers/{triggerId}/unregister`

Who may unregister it is as for a pause.

## `client.mail_triggers.fires()`

```python signature
fires(
    trigger_id: str | UUID,
    /,
    *,
    limit: int | None = None,
    cursor: str | None = None,
    timeout: float | None = None,
) -> MailFirePage
```

A mail trigger's mail. `GET /v1/mail-triggers/{triggerId}/fires`

Newest first: each mail the trigger found and what came of it (`MailFire`): the run it started, why it waits (`thread-busy:`), or why it was skipped, refused or failed.

## `client.mail_triggers.list_versions()`

```python signature
list_versions(
    trigger_id: str | UUID,
    /,
    *,
    limit: int | None = None,
    cursor: str | None = None,
    timeout: float | None = None,
) -> MailTriggerVersionPage
```

A mail trigger's versions. `GET /v1/mail-triggers/{triggerId}/versions`

Newest first: each version of the mail trigger, what it was from `createdAt` on, who made it (`createdBy`) and why (`cause`). Registering makes version 1, and each change makes the next (a PATCH that alters it, or a take-over to another owner): a PATCH that changes nothing makes none, nor do pausing, resuming or deleting. A version never changes once made. A new mail's run uses the newest when it starts, and keeps it whatever later edits make (the run's `trigger.version`). A mail trigger from before versions has none until its next change or its next look at the mailbox. Whoever can read the mail trigger can read its versions.

## `client.mail_triggers.get_version()`

```python signature
get_version(
    trigger_id: str | UUID,
    version: int,
    /,
    *,
    timeout: float | None = None,
) -> MailTriggerVersion
```

Fetch one version of a mail trigger. `GET /v1/mail-triggers/{triggerId}/versions/{version}`

## `client.mail_triggers.take_ownership()`

```python signature
take_ownership(
    trigger_id: str | UUID,
    body: TakeTriggerOwnerBody | Mapping[str, Any] | None = None,
    /,
    *,
    idempotency_key: str | None = None,
    timeout: float | None = None,
    **fields: Any,
) -> MailTriggerRecord
```

Take over a mail trigger. `POST /v1/mail-triggers/{triggerId}/owner`

The only way a mail trigger's owner changes. The caller becomes it, so its runs act as the caller, with the caller's connections, from the next poll; on a person's mailbox, the mailbox becomes the caller's own, and the next poll starts afresh. Needs `admin` on the trigger's project and `execute` on its target. On the company's mailbox, name `runAsServiceAccountId` instead to make a service account the owner: that needs `act_as` on the account, and the account must itself hold what its target needs. With an authorization store, that's checked when the account is named: an account that can't is refused (`409 trigger-owner-cannot-run-target`). Or name `runAsProject: true` to make the project's own service account the owner, made the first time with the `editor` role on the project. It runs only what the project's editors can, and is checked the same way. The trigger keeps its `toolsAllowedUnattended`; a body naming it is refused (change it with PATCH).
