---
title: "openemail.connectors"
description: "Every method in this namespace: its signature, its parameters, what it returns and an example."
url: "https://openemail.uk/docs/python/reference/connectors"
area: "Python"
category: "Reference"
---

# openemail.connectors

Every method in this namespace: its signature, its parameters, what it returns and an example.

## Methods

Outside apps a person connects so the assistant can look things up in them and act there: browse the apps that can be connected, connect one for the workspace or for one person, rename, pause, reconnect and disconnect it, list what it can do, run one of its actions, and read the record of what was done through it.

### `connectors.list_apps()`

List the apps that can be connected, a page at a time

```python
def list_apps(
    *,
    limit: int | None = None,
    cursor: str | None = None,
    search: str | None = None,
    category: str | None = None,
    api_key: str | None = None,
    timeout: float | None = None,
) -> Page[ConnectorAppResource]
```

Returns one page of the catalogue of outside apps, the most used first. `list_all_apps` collects every page and `iterate_apps` walks them lazily. A connector links one of these apps to the workspace, or to one person, so the assistant can look things up in the app and act there.

Give `search=` to find an app by its name or its description, or `category=` to read one category, by a `slug` that `list_categories` returns. Each app says how many actions it offers in `actions`, how a person signs in to it in `auth`, and in `connectable` whether it can be connected today. Pass its `slug` to `connect`.

Scopes: `connectors:read`.

**Parameters**

- `limit` (`int`): Page size, from 1 to 60. The server defaults to 24.
- `cursor` (`str`): The `nextCursor` of the previous page, passed back as it came. Leave it out for the first page.
- `search` (`str`): Words to look for in the name or the description of an app, trimmed, up to 200 characters.
- `category` (`str`): Only the apps in this category, by a `slug` that `list_categories` returns.
- `api_key` (`str`): Overrides the client API key for this call only.
- `timeout` (`float`): Seconds this call may take, the response included, before it raises `OpenEmailNetworkError` with `is_timeout`. It overrides the client's `timeout` for this call, and `0` turns the limit off.

**Returns**

`Page[ConnectorAppResource]`, a dict with `items`, `hasMore` and `nextCursor`. Each item has `slug`, `name`, `description`, `logo`, `website`, `categories`, `actions`, `auth` and `connectable`.

**Example**

```python
from openemail import openemail

page = openemail.connectors.list_apps(search='calendar', limit=10)

for app in page['items']:
    print(app['slug'], app['name'], app['actions'], app['connectable'])
```

**Notes**

- `auth` is `sign-in` when a person signs in to the app and `key` when they paste a key from it. It is `None` when the app cannot be connected yet, and `connectable` is then `False`.
- A page can hold fewer apps than `limit=` and still have more after it, so follow `hasMore`, not the count.
- The catalogue is the same for every caller, whatever addresses or domains a key or an app is limited to.
- While connectors are not switched on the call is refused with 503 `connectors_unavailable`, and with 503 `connector_provider_failed` when the connection service does not answer.
- Read only, so the SDK retries it after a network failure like any other read.

Also available in: API [`GET /connector-apps`](https://openemail.uk/docs/api/reference/connectors#get-connector-apps); TypeScript [`connectors.listApps()`](https://openemail.uk/docs/sdk/reference/connectors#listApps); Ruby [`connectors.list_apps`](https://openemail.uk/docs/ruby/reference/connectors#listApps); PHP [`connectors->listApps`](https://openemail.uk/docs/php/reference/connectors#listApps); Go [`Connectors.ListApps`](https://openemail.uk/docs/go/reference/connectors#listApps); Java [`connectors().listApps`](https://openemail.uk/docs/java/reference/connectors#listApps); C# [`Connectors.ListAppsAsync`](https://openemail.uk/docs/csharp/reference/connectors#listApps); CLI [`openemail connectors list-apps`](https://openemail.uk/docs/cli/reference/connectors#connectors-list-apps).

### `connectors.list_all_apps()`

Collect every app that can be connected into one list

```python
def list_all_apps(
    *,
    limit: int | None = None,
    cursor: str | None = None,
    search: str | None = None,
    category: str | None = None,
    api_key: str | None = None,
    timeout: float | None = None,
) -> builtins.list[ConnectorAppResource]
```

Follows `nextCursor` from page to page and returns every app that matches, the most used first, in the shape `list_apps` returns. `limit=` sets the page size of each request, not the total. The whole catalogue is long, so give `search=` or `category=`, or prefer `iterate_apps` when you do not need every app in memory.

Scopes: `connectors:read`.

**Parameters**

- `limit` (`int`): Page size for each request, from 1 to 60. The server defaults to 24.
- `cursor` (`str`): Starts the walk after this cursor instead of the first page.
- `search` (`str`): Words to look for in the name or the description of an app, trimmed, up to 200 characters.
- `category` (`str`): Only the apps in this category, by a `slug` that `list_categories` returns.
- `api_key` (`str`): Overrides the client API key for every page of this walk.
- `timeout` (`float`): Seconds this call may take, the response included, before it raises `OpenEmailNetworkError` with `is_timeout`. It overrides the client's `timeout` for this call, and `0` turns the limit off.

**Returns**

`list[ConnectorAppResource]` holding every matching app across all pages.

**Example**

```python
from openemail import openemail

apps = openemail.connectors.list_all_apps(category='productivity', limit=60)

ready = [app for app in apps if app['connectable']]

print(f'{len(ready)} of {len(apps)} apps can be connected')
```

**Notes**

- If any page fails, the call raises and the apps already fetched are discarded.
- While connectors are not switched on the call is refused with 503 `connectors_unavailable`, and with 503 `connector_provider_failed` when the connection service does not answer.

Also available in: API [`GET /connector-apps`](https://openemail.uk/docs/api/reference/connectors#get-connector-apps); TypeScript [`connectors.listAllApps()`](https://openemail.uk/docs/sdk/reference/connectors#listAllApps); Ruby [`connectors.list_all_apps`](https://openemail.uk/docs/ruby/reference/connectors#listAllApps); PHP [`connectors->listAllApps`](https://openemail.uk/docs/php/reference/connectors#listAllApps); Go [`Connectors.ListAllApps`](https://openemail.uk/docs/go/reference/connectors#listAllApps); Java [`connectors().listAllApps`](https://openemail.uk/docs/java/reference/connectors#listAllApps); C# [`Connectors.ListAllAppsAsync`](https://openemail.uk/docs/csharp/reference/connectors#listAllApps).

### `connectors.iterate_apps()`

Stream the apps that can be connected one at a time

```python
def iterate_apps(
    *,
    limit: int | None = None,
    cursor: str | None = None,
    search: str | None = None,
    category: str | None = None,
    api_key: str | None = None,
    timeout: float | None = None,
) -> Iterator[ConnectorAppResource]
```

Returns a generator that yields apps one by one, the most used first, and requests the next page only once the current one is drained. Nothing is fetched until you consume it, and breaking out of the loop stops the requests.

Scopes: `connectors:read`.

**Parameters**

- `limit` (`int`): Page size for each request, from 1 to 60. The server defaults to 24.
- `cursor` (`str`): Starts the walk after this cursor instead of the first page.
- `search` (`str`): Words to look for in the name or the description of an app, trimmed, up to 200 characters.
- `category` (`str`): Only the apps in this category, by a `slug` that `list_categories` returns.
- `api_key` (`str`): Overrides the client API key for every page of this walk.
- `timeout` (`float`): Seconds this call may take, the response included, before it raises `OpenEmailNetworkError` with `is_timeout`. It overrides the client's `timeout` for this call, and `0` turns the limit off.

**Returns**

`Iterator[ConnectorAppResource]`, a generator yielding one app per step.

**Example**

```python
from openemail import openemail

for app in openemail.connectors.iterate_apps(search='notes'):
    if not app['connectable']:
        continue

    print(app['slug'], app['name'], app['auth'])
```

**Notes**

- The generator is lazy, so an abandoned loop costs only the pages you consumed.
- While connectors are not switched on the first request is refused with 503 `connectors_unavailable`, and with 503 `connector_provider_failed` when the connection service does not answer.

Also available in: API [`GET /connector-apps`](https://openemail.uk/docs/api/reference/connectors#get-connector-apps); TypeScript [`connectors.iterateApps()`](https://openemail.uk/docs/sdk/reference/connectors#iterateApps); Ruby [`connectors.iterate_apps`](https://openemail.uk/docs/ruby/reference/connectors#iterateApps); PHP [`connectors->iterateApps`](https://openemail.uk/docs/php/reference/connectors#iterateApps); Go [`Connectors.IterateApps`](https://openemail.uk/docs/go/reference/connectors#iterateApps); Java [`connectors().iterateApps`](https://openemail.uk/docs/java/reference/connectors#iterateApps); C# [`Connectors.IterateAppsAsync`](https://openemail.uk/docs/csharp/reference/connectors#iterateApps).

### `connectors.get_app()`

Read one app of the catalogue by its slug

```python
def get_app(
    slug: str,
    *,
    api_key: str | None = None,
    timeout: float | None = None,
) -> ConnectorAppResource
```

Looks up one app of the catalogue and returns it in the same shape as a row of `list_apps`: its name and description, its logo and website, the categories it sits in, how many actions it offers and how a person signs in to it.

Read `connectable` before you call `connect`. An app that is listed but cannot be connected yet has `connectable` set to `False` and `auth` set to `None`.

Scopes: `connectors:read`.

**Parameters**

- `slug` (`str`, required): The slug of the app, as `list_apps` returns it: letters, digits, hyphens and underscores, up to 80 characters. The case does not matter.
- `api_key` (`str`): Overrides the client API key for this call only.
- `timeout` (`float`): Seconds this call may take, the response included, before it raises `OpenEmailNetworkError` with `is_timeout`. It overrides the client's `timeout` for this call, and `0` turns the limit off.

**Returns**

`ConnectorAppResource` with `slug`, `name`, `description`, `logo`, `website`, `categories`, `actions`, `auth` and `connectable`.

**Example**

```python
from openemail import openemail

app = openemail.connectors.get_app('example-app')

if app['connectable']:
    print(app['name'], 'takes a', app['auth'], 'and offers', app['actions'], 'actions')
```

**Notes**

- A slug the catalogue does not have raises `OpenEmailApiError` with `is_not_found` set to `True` and code `connector_app_not_found`. A slug with other characters is 422 `invalid_parameter`.
- `auth` is `sign-in` when a person signs in to the app and `key` when they paste a key from it.
- While connectors are not switched on the call is refused with 503 `connectors_unavailable`, and with 503 `connector_provider_failed` when the connection service does not answer.
- Read only, so the SDK retries it after a network failure like any other read.

Also available in: API [`GET /connector-apps/{slug}`](https://openemail.uk/docs/api/reference/connectors#get-connector-apps-slug); TypeScript [`connectors.getApp()`](https://openemail.uk/docs/sdk/reference/connectors#getApp); Ruby [`connectors.get_app`](https://openemail.uk/docs/ruby/reference/connectors#getApp); PHP [`connectors->getApp`](https://openemail.uk/docs/php/reference/connectors#getApp); Go [`Connectors.GetApp`](https://openemail.uk/docs/go/reference/connectors#getApp); Java [`connectors().getApp`](https://openemail.uk/docs/java/reference/connectors#getApp); C# [`Connectors.GetAppAsync`](https://openemail.uk/docs/csharp/reference/connectors#getApp); CLI [`openemail connectors get-app`](https://openemail.uk/docs/cli/reference/connectors#connectors-get-app).

### `connectors.list_categories()`

List the categories the catalogue sorts its apps into

```python
def list_categories(
    *,
    api_key: str | None = None,
    timeout: float | None = None,
) -> builtins.list[ConnectorCategoryResource]
```

Returns every category of the catalogue in one list. The list comes whole and is never paged. Pass the `slug` of a category as `category=` to `list_apps` to read only the apps in it. An app names the categories it sits in under `categories`.

Scopes: `connectors:read`.

**Parameters**

- `api_key` (`str`): Overrides the client API key for this call only.
- `timeout` (`float`): Seconds this call may take, the response included, before it raises `OpenEmailNetworkError` with `is_timeout`. It overrides the client's `timeout` for this call, and `0` turns the limit off.

**Returns**

`list[ConnectorCategoryResource]`. Each item has `slug`, the value to pass as `category=`, and `name`.

**Example**

```python
from openemail import openemail

categories = openemail.connectors.list_categories()

for category in categories:
    print(category['slug'], category['name'])
```

**Notes**

- While connectors are not switched on the call is refused with 503 `connectors_unavailable`, and with 503 `connector_provider_failed` when the connection service does not answer.
- Read only, so the SDK retries it after a network failure like any other read.

Also available in: API [`GET /connector-categories`](https://openemail.uk/docs/api/reference/connectors#get-connector-categories); TypeScript [`connectors.listCategories()`](https://openemail.uk/docs/sdk/reference/connectors#listCategories); Ruby [`connectors.list_categories`](https://openemail.uk/docs/ruby/reference/connectors#listCategories); PHP [`connectors->listCategories`](https://openemail.uk/docs/php/reference/connectors#listCategories); Go [`Connectors.ListCategories`](https://openemail.uk/docs/go/reference/connectors#listCategories); Java [`connectors().listCategories`](https://openemail.uk/docs/java/reference/connectors#listCategories); C# [`Connectors.ListCategoriesAsync`](https://openemail.uk/docs/csharp/reference/connectors#listCategories); CLI [`openemail connectors list-categories`](https://openemail.uk/docs/cli/reference/connectors#connectors-list-categories).

### `connectors.list()`

List the connectors the caller can reach

```python
def list(
    *,
    scope: ConnectorScope | None = None,
    status: ConnectorStatus | None = None,
    app: str | None = None,
    api_key: str | None = None,
    timeout: float | None = None,
) -> builtins.list[ConnectorResource]
```

Returns every connector the caller can reach in one list, by scope and then by the name of the app. The list comes whole and is never paged. A connector is one outside app that somebody connected, so the assistant can look things up in it and act there. It belongs to the workspace, where tasks and everyone allowed to use connectors reach it, or to one person. `scope` says which: `workspace` or `account`.

`status` is `pending` until the person has finished signing in to the app, `active` while it works, `paused` while a person or the plan holds it back, and `expired` when the app stopped accepting the connection and it has to be reconnected. `access` is `read` when the assistant may only look things up through the connector and `full` when it may also make changes.

Narrow the list with `scope=`, `status=` or `app=`.

Scopes: `connectors:read`.

**Parameters**

- `scope` (`ConnectorScope`): Only one kind of connector: `workspace` for the ones shared with the workspace, `account` for the ones that belong to the person an app acts for. Left out, both are listed.
- `status` (`ConnectorStatus`): Only connectors in this state: `pending`, `active`, `expired` or `paused`.
- `app` (`str`): Only the connectors of this app, by its slug.
- `api_key` (`str`): Overrides the client API key for this call only.
- `timeout` (`float`): Seconds this call may take, the response included, before it raises `OpenEmailNetworkError` with `is_timeout`. It overrides the client's `timeout` for this call, and `0` turns the limit off.

**Returns**

`list[ConnectorResource]`. Each item has `id`, `scope`, `app`, `appName`, `appLogo`, `label`, `status`, `failure`, `pausedReason`, `access`, `connectedAt`, `lastUsedAt`, `createdAt` and `updatedAt`.

**Example**

```python
from openemail import openemail

connectors = openemail.connectors.list(status='expired')

for connector in connectors:
    print(connector['appName'], connector['label'], connector['failure'])
```

**Notes**

- `failure` says why a connector stopped working: `expired`, `revoked`, `failed` or `disabled`. It is `None` while nothing is wrong. `pausedReason` is `user` when a person paused the connector and `plan` when the workspace moved to a plan that holds fewer connectors.
- `app` is the slug of the connected app and `appName` its name. `label` is the name a person gave the connector, or `None`. `connectedAt` is when the sign-in was last finished and `lastUsedAt` when an action last ran through it.
- An API key acts for the workspace and reaches the connectors of the workspace only. A connector that belongs to one person is reached only by an app that person connected, which also needs `account:read`.
- A key or an app limited to particular addresses or domains does not reach the connectors of the workspace, so it is given none of them.
- Read only, so the SDK retries it after a network failure like any other read.

Also available in: API [`GET /connectors`](https://openemail.uk/docs/api/reference/connectors#get-connectors); TypeScript [`connectors.list()`](https://openemail.uk/docs/sdk/reference/connectors#list); Ruby [`connectors.list`](https://openemail.uk/docs/ruby/reference/connectors#list); PHP [`connectors->list`](https://openemail.uk/docs/php/reference/connectors#list); Go [`Connectors.List`](https://openemail.uk/docs/go/reference/connectors#list); Java [`connectors().list`](https://openemail.uk/docs/java/reference/connectors#list); C# [`Connectors.ListAsync`](https://openemail.uk/docs/csharp/reference/connectors#list); CLI [`openemail connectors list`](https://openemail.uk/docs/cli/reference/connectors#connectors-list).

### `connectors.get()`

Read one connector by id

```python
def get(
    id: str,
    *,
    api_key: str | None = None,
    timeout: float | None = None,
) -> ConnectorResource
```

Looks up one connector and returns it in the same shape as a row of `list`, read fresh. While a sign-in is still open, after `connect` or `reconnect`, the call also checks whether the person has finished it. So this is the call to make after sending somebody to `connectUrl`: `status` is `active` once they are done.

A connector that is still `pending` when its link runs out is removed, and so is one whose sign-in failed. The call then answers 404 `connector_not_found`. Start over with `connect`.

Scopes: `connectors:read`.

**Parameters**

- `id` (`str`, required): Connector id such as `cnr_5c1e9a7b3d2f48e6a0b4c7d1`, as `list` returns it.
- `api_key` (`str`): Overrides the client API key for this call only.
- `timeout` (`float`): Seconds this call may take, the response included, before it raises `OpenEmailNetworkError` with `is_timeout`. It overrides the client's `timeout` for this call, and `0` turns the limit off.

**Returns**

`ConnectorResource` with `id`, `scope`, `app`, `appName`, `appLogo`, `label`, `status`, `failure`, `pausedReason`, `access`, `connectedAt`, `lastUsedAt`, `createdAt` and `updatedAt`.

**Example**

```python
from openemail import openemail

connector = openemail.connectors.get('cnr_5c1e9a7b3d2f48e6a0b4c7d1')

if connector['status'] == 'active':
    print(connector['appName'], 'is connected since', connector['connectedAt'])
```

**Notes**

- A missing connector, or one the caller cannot reach, raises `OpenEmailApiError` with `is_not_found` set to `True` and code `connector_not_found`.
- An API key acts for the workspace and reaches the connectors of the workspace only. A connector that belongs to one person is reached only by an app that person connected, which also needs `account:read`.
- A key or an app limited to particular addresses or domains does not reach the connectors of the workspace.
- Read only, so the SDK retries it after a network failure like any other read.

Also available in: API [`GET /connectors/{id}`](https://openemail.uk/docs/api/reference/connectors#get-connectors-id); TypeScript [`connectors.get()`](https://openemail.uk/docs/sdk/reference/connectors#get); Ruby [`connectors.get`](https://openemail.uk/docs/ruby/reference/connectors#get); PHP [`connectors->get`](https://openemail.uk/docs/php/reference/connectors#get); Go [`Connectors.Get`](https://openemail.uk/docs/go/reference/connectors#get); Java [`connectors().get`](https://openemail.uk/docs/java/reference/connectors#get); C# [`Connectors.GetAsync`](https://openemail.uk/docs/csharp/reference/connectors#get); CLI [`openemail connectors get`](https://openemail.uk/docs/cli/reference/connectors#connectors-get).

### `connectors.connect()`

Start connecting an app

```python
def connect(
    body: ConnectorConnect,
    *,
    api_key: str | None = None,
    timeout: float | None = None,
) -> ConnectorLinkResource
```

Starts connecting an app and returns the new connector with a `connectUrl`. A person has to open that link and sign in to the app there, or enter its key. That happens on a page outside this API, so the secret never passes through the caller. Until they have finished, the connector is `pending` and nothing can run through it. Read it again with `get`: `status` is `active` once they are done.

The link works until `connectExpiresAt`, at most 30 minutes, and only this answer shows it. A connector that is still `pending` when its link runs out is removed. Until then `reconnect` gives it a fresh link.

With no `scope` the connector is shared with the workspace, where tasks and everyone allowed to use connectors reach it. `scope` set to `account` keeps it to the person an app acts for.

Scopes: `connectors:write`.

**Parameters**

- `body['app']` (`str`, required): The app to connect, by the `slug` that `list_apps` returns.
- `body['scope']` (`ConnectorScope`): Who the connector is for. `workspace` shares it with the workspace and is the default. `account` keeps it to the person connecting it, which only an app that person connected may ask for.
- `body['label']` (`str`): A name of your own for the connector, trimmed, up to 80 characters. Left out, it has none.
- `body['access']` (`ConnectorAccess`): What the assistant may do through the connector. `read` lets it look things up. `full` also lets it make changes and is the default.
- `api_key` (`str`): Overrides the client API key for this call only.
- `timeout` (`float`): Seconds this call may take, the response included, before it raises `OpenEmailNetworkError` with `is_timeout`. It overrides the client's `timeout` for this call, and `0` turns the limit off.

**Returns**

`ConnectorLinkResource`: the connector with a new `id` and `status` `pending`, plus `connectUrl`, the page to send the person to, and `connectExpiresAt`, when that link stops working.

**Example**

```python
from openemail import openemail

connector = openemail.connectors.connect(
    {'app': 'example-app', 'label': 'Team notes', 'access': 'read'}
)

print('Open this link and sign in:', connector['connectUrl'])

fresh = openemail.connectors.get(connector['id'])

print(fresh['status'])
```

**Notes**

- A workspace holds 2 connectors on Free, 10 on Starter and 50 on Business, with no cap on Enterprise, and at most 200 whatever the plan. A person holds as many again of their own. One more is refused with 403 `connector_limit_reached`, and a connector that is still `pending` counts.
- An app the catalogue does not have is a 404 `connector_app_not_found`, and one that cannot be connected yet a 422 `connector_app_unavailable`. A field of the wrong type or length is 422 `invalid_parameter`, and a key the body does not take 422 `unknown_parameter`.
- An API key acts for the workspace, so it connects an app for the workspace only. `scope` set to `account` needs an app the person connected, holding `account:write` beside `connectors:write`. Anything else is refused with 403 `insufficient_scope`.
- A key or an app limited to particular addresses or domains does not reach the connectors of the workspace, so it cannot connect an app for it.
- While connectors are not switched on the call is refused with 503 `connectors_unavailable`, and with 503 `connector_provider_failed` when the connection service does not answer. Nothing is created either way.
- Not retried automatically: every call makes another connector with a link of its own, so a retry after a lost response can leave two. `list` with `status='pending'` shows a spare, and `disconnect` removes it.

Also available in: API [`POST /connectors`](https://openemail.uk/docs/api/reference/connectors#post-connectors); TypeScript [`connectors.connect()`](https://openemail.uk/docs/sdk/reference/connectors#connect); Ruby [`connectors.connect`](https://openemail.uk/docs/ruby/reference/connectors#connect); PHP [`connectors->connect`](https://openemail.uk/docs/php/reference/connectors#connect); Go [`Connectors.Connect`](https://openemail.uk/docs/go/reference/connectors#connect); Java [`connectors().connect`](https://openemail.uk/docs/java/reference/connectors#connect); C# [`Connectors.ConnectAsync`](https://openemail.uk/docs/csharp/reference/connectors#connect); CLI [`openemail connectors connect`](https://openemail.uk/docs/cli/reference/connectors#connectors-connect).

### `connectors.update()`

Rename a connector, pause or resume it, or change its access

```python
def update(
    id: str,
    patch: ConnectorPatch,
    *,
    api_key: str | None = None,
    timeout: float | None = None,
) -> ConnectorResource
```

Changes a connector and returns it as it is stored. Send only what changes: a field left out stays as it is, and a patch with nothing in it is a 422.

`paused` set to `True` stops the assistant, tasks and `run_action` from using the connector until `paused` set to `False` resumes it. Only an `active` connector can be paused. `access` switches between `read`, where only actions that look something up may run, and `full`. `label` renames the connector, and `None` or an empty string takes its name away.

It does not sign in again. A connector that is `expired` needs `reconnect`.

Scopes: `connectors:write`.

**Parameters**

- `id` (`str`, required): Connector id such as `cnr_5c1e9a7b3d2f48e6a0b4c7d1`, as `list` returns it.
- `patch['label']` (`str | None`): A name of your own for the connector, trimmed, up to 80 characters. `None` or an empty string clears it. Left out, the name stays.
- `patch['access']` (`ConnectorAccess`): `read` lets the assistant only look things up through the connector. `full` also lets it make changes. Left out, it stays.
- `patch['paused']` (`bool`): `True` pauses the connector and `False` resumes it. Left out, it stays as it is.
- `api_key` (`str`): Overrides the client API key for this call only.
- `timeout` (`float`): Seconds this call may take, the response included, before it raises `OpenEmailNetworkError` with `is_timeout`. It overrides the client's `timeout` for this call, and `0` turns the limit off.

**Returns**

`ConnectorResource` with the unchanged `id`, and `label`, `access`, `status` and `pausedReason` as they are now.

**Example**

```python
from openemail import openemail

connector = openemail.connectors.update(
    'cnr_5c1e9a7b3d2f48e6a0b4c7d1',
    {'label': 'Support desk', 'access': 'read'},
)

print(connector['label'], connector['access'], connector['status'])
```

**Notes**

- Pausing a connector that is `pending` or `expired` answers 409 `connector_not_active`. Pausing one that is already paused leaves it paused, with `pausedReason` as it was.
- Resuming a connector the plan paused is refused with 403 `connector_limit_reached` while the plan covers no more connectors. A connector whose sign-in stopped working comes back as `expired`, not `active`.
- An empty patch or a value of the wrong type or length is 422 `invalid_parameter`, and a key the patch does not take 422 `unknown_parameter`. A missing connector is a 404 `connector_not_found`.
- An API key acts for the workspace and changes the connectors of the workspace only. A connector that belongs to one person is changed only by an app that person connected, which also needs `account:write`. Without it the call is refused with 403 `insufficient_scope`.
- A key or an app limited to particular addresses or domains does not reach the connectors of the workspace.
- Not retried automatically. A retry that arrives after somebody else changed the connector would make the change a second time, such as pausing a connector that was just resumed. Read it with `get` before you try again.

Also available in: API [`PATCH /connectors/{id}`](https://openemail.uk/docs/api/reference/connectors#patch-connectors-id); TypeScript [`connectors.update()`](https://openemail.uk/docs/sdk/reference/connectors#update); Ruby [`connectors.update`](https://openemail.uk/docs/ruby/reference/connectors#update); PHP [`connectors->update`](https://openemail.uk/docs/php/reference/connectors#update); Go [`Connectors.Update`](https://openemail.uk/docs/go/reference/connectors#update); Java [`connectors().update`](https://openemail.uk/docs/java/reference/connectors#update); C# [`Connectors.UpdateAsync`](https://openemail.uk/docs/csharp/reference/connectors#update); CLI [`openemail connectors update`](https://openemail.uk/docs/cli/reference/connectors#connectors-update).

### `connectors.disconnect()`

Disconnect an app for good

```python
def disconnect(
    id: str,
    *,
    api_key: str | None = None,
    timeout: float | None = None,
) -> DeletedConnectorResource
```

Disconnects the app and removes the connector for good. The access it held in the outside app is given up there too, and the record of the calls made through it goes with it. A task that named the connector can no longer reach the app.

There is no undo. To stop a connector and keep it, use `update` with `paused` set to `True`. To use the app again later, start over with `connect`.

Scopes: `connectors:write`.

**Parameters**

- `id` (`str`, required): Connector id such as `cnr_5c1e9a7b3d2f48e6a0b4c7d1`, as `list` returns it.
- `api_key` (`str`): Overrides the client API key for this call only.
- `timeout` (`float`): Seconds this call may take, the response included, before it raises `OpenEmailNetworkError` with `is_timeout`. It overrides the client's `timeout` for this call, and `0` turns the limit off.

**Returns**

`DeletedConnectorResource`, a dict with `object` set to `connector`, the `id`, the `scope`, `app`, the slug of the app it connected, and `deleted` set to `True`.

**Example**

```python
from openemail import openemail

removed = openemail.connectors.disconnect('cnr_5c1e9a7b3d2f48e6a0b4c7d1')

print(removed['app'], removed['deleted'])
```

**Notes**

- A missing connector, or one the caller cannot reach, is a 404 `connector_not_found`.
- An API key acts for the workspace and disconnects the connectors of the workspace only. A connector that belongs to one person is disconnected only by an app that person connected, which also needs `account:write`. Without it the call is refused with 403 `insufficient_scope`.
- A key or an app limited to particular addresses or domains does not reach the connectors of the workspace.
- The SDK retries this call after a network failure. When the first attempt went through and only its answer was lost, the retry answers 404 `connector_not_found`, which then means the connector is gone.

Also available in: API [`DELETE /connectors/{id}`](https://openemail.uk/docs/api/reference/connectors#delete-connectors-id); TypeScript [`connectors.disconnect()`](https://openemail.uk/docs/sdk/reference/connectors#disconnect); Ruby [`connectors.disconnect`](https://openemail.uk/docs/ruby/reference/connectors#disconnect); PHP [`connectors->disconnect`](https://openemail.uk/docs/php/reference/connectors#disconnect); Go [`Connectors.Disconnect`](https://openemail.uk/docs/go/reference/connectors#disconnect); Java [`connectors().disconnect`](https://openemail.uk/docs/java/reference/connectors#disconnect); C# [`Connectors.DisconnectAsync`](https://openemail.uk/docs/csharp/reference/connectors#disconnect); CLI [`openemail connectors disconnect`](https://openemail.uk/docs/cli/reference/connectors#connectors-disconnect).

### `connectors.reconnect()`

Get a fresh link to sign in to the app again

```python
def reconnect(
    id: str,
    *,
    api_key: str | None = None,
    timeout: float | None = None,
) -> ConnectorLinkResource
```

Returns a fresh `connectUrl` for a connector that is `expired`, or that is still `pending` because nobody finished its first link. As with `connect`, a person has to open the link and sign in to the app there, or enter its key, on a page outside this API. Read the connector again with `get` afterwards: it is `active` once they are done.

The connector keeps its `id`, `label` and `access`. The answer shows it as it is now, before anybody has signed in again, and a connector that still works keeps working on its old sign-in until the new one is finished. It takes no body.

Scopes: `connectors:write`.

**Parameters**

- `id` (`str`, required): Connector id such as `cnr_5c1e9a7b3d2f48e6a0b4c7d1`, as `list` returns it.
- `api_key` (`str`): Overrides the client API key for this call only.
- `timeout` (`float`): Seconds this call may take, the response included, before it raises `OpenEmailNetworkError` with `is_timeout`. It overrides the client's `timeout` for this call, and `0` turns the limit off.

**Returns**

`ConnectorLinkResource`: the connector with its unchanged `id` and its `status` as it is now, plus a new `connectUrl` and `connectExpiresAt`, when that link stops working.

**Example**

```python
from openemail import openemail

connector = openemail.connectors.reconnect('cnr_5c1e9a7b3d2f48e6a0b4c7d1')

print('Open this link and sign in again:', connector['connectUrl'])
print('It works until', connector['connectExpiresAt'])
```

**Notes**

- The link works for at most 30 minutes and only this answer shows it. A new link replaces the one before it, which no longer connects anything.
- A missing connector is a 404 `connector_not_found`, and an app that can no longer be connected a 422 `connector_app_unavailable`.
- An API key acts for the workspace and reconnects the connectors of the workspace only. A connector that belongs to one person is reconnected only by an app that person connected, which also needs `account:write`. Without it the call is refused with 403 `insufficient_scope`.
- A key or an app limited to particular addresses or domains does not reach the connectors of the workspace.
- While connectors are not switched on the call is refused with 503 `connectors_unavailable`, and with 503 `connector_provider_failed` when the connection service does not answer.
- Not retried automatically: every call makes a second link and the one before it no longer connects anything, so a retry after a lost response could cancel a link somebody is already using.

Also available in: API [`POST /connectors/{id}/reconnect`](https://openemail.uk/docs/api/reference/connectors#post-connectors-id-reconnect); TypeScript [`connectors.reconnect()`](https://openemail.uk/docs/sdk/reference/connectors#reconnect); Ruby [`connectors.reconnect`](https://openemail.uk/docs/ruby/reference/connectors#reconnect); PHP [`connectors->reconnect`](https://openemail.uk/docs/php/reference/connectors#reconnect); Go [`Connectors.Reconnect`](https://openemail.uk/docs/go/reference/connectors#reconnect); Java [`connectors().reconnect`](https://openemail.uk/docs/java/reference/connectors#reconnect); C# [`Connectors.ReconnectAsync`](https://openemail.uk/docs/csharp/reference/connectors#reconnect); CLI [`openemail connectors reconnect`](https://openemail.uk/docs/cli/reference/connectors#connectors-reconnect).

### `connectors.list_actions()`

List what a connector can do

```python
def list_actions(
    id: str,
    *,
    search: str | None = None,
    limit: int | None = None,
    api_key: str | None = None,
    timeout: float | None = None,
) -> builtins.list[ConnectorActionResource]
```

Returns the actions of the app behind a connector that match `search=`, or its most used ones when `search=` is left out. An action is one thing the app can do, such as finding a record or sending a message. Each one has the name to run it by in `action`, what it is called in `name`, what it does in `description`, and its `kind`: `read` when it only looks something up, and `change` when it creates, updates, sends or deletes something, or when the app does not say.

The list is not paged and holds at most 30 actions, so use `search=` to find one that is not among the first. A connector whose `access` is `read` lists only the actions that read. `get_action` adds the input an action takes.

Scopes: `connectors:use`.

**Parameters**

- `id` (`str`, required): Connector id such as `cnr_5c1e9a7b3d2f48e6a0b4c7d1`, as `list` returns it.
- `search` (`str`): Words to look for in the name or the description of an action, trimmed, up to 200 characters. Left out, the most used actions are listed.
- `limit` (`int`): How many actions to return, from 1 to 30. The server defaults to 12.
- `api_key` (`str`): Overrides the client API key for this call only.
- `timeout` (`float`): Seconds this call may take, the response included, before it raises `OpenEmailNetworkError` with `is_timeout`. It overrides the client's `timeout` for this call, and `0` turns the limit off.

**Returns**

`list[ConnectorActionResource]`. Each item has `action`, `name`, `description` and `kind`.

**Example**

```python
from openemail import openemail

actions = openemail.connectors.list_actions(
    'cnr_5c1e9a7b3d2f48e6a0b4c7d1',
    search='send message',
    limit=5,
)

for action in actions:
    print(action['action'], action['kind'], action['name'])
```

**Notes**

- The connector has to be `active`. One that is paused, pending or expired answers 409 `connector_not_active`, and a missing one 404 `connector_not_found`.
- An API key acts for the workspace and uses the connectors of the workspace only. A connector that belongs to one person is used only by an app that person connected, which also needs `account:read`.
- A key or an app limited to particular addresses or domains does not reach the connectors of the workspace.
- When the connection service does not answer the call is refused with 503 `connector_provider_failed`.
- Read only, so the SDK retries it after a network failure like any other read.

Also available in: API [`GET /connectors/{id}/actions`](https://openemail.uk/docs/api/reference/connectors#get-connectors-id-actions); TypeScript [`connectors.listActions()`](https://openemail.uk/docs/sdk/reference/connectors#listActions); Ruby [`connectors.list_actions`](https://openemail.uk/docs/ruby/reference/connectors#listActions); PHP [`connectors->listActions`](https://openemail.uk/docs/php/reference/connectors#listActions); Go [`Connectors.ListActions`](https://openemail.uk/docs/go/reference/connectors#listActions); Java [`connectors().listActions`](https://openemail.uk/docs/java/reference/connectors#listActions); C# [`Connectors.ListActionsAsync`](https://openemail.uk/docs/csharp/reference/connectors#listActions); CLI [`openemail connectors list-actions`](https://openemail.uk/docs/cli/reference/connectors#connectors-list-actions).

### `connectors.get_action()`

Read one action with the input it takes

```python
def get_action(
    id: str,
    action: str,
    *,
    api_key: str | None = None,
    timeout: float | None = None,
) -> ConnectorActionDetailResource
```

Looks up one action of the app behind a connector and returns it as `list_actions` does, with `input` added: the input the action takes, as a JSON Schema. Build the `input` of `run_action` from it. `kind` says whether running the action only reads or changes something in the app.

Scopes: `connectors:use`.

**Parameters**

- `id` (`str`, required): Connector id such as `cnr_5c1e9a7b3d2f48e6a0b4c7d1`, as `list` returns it.
- `action` (`str`, required): The name of the action, as `list_actions` returns it in `action`: letters, digits and underscores, up to 160 characters. The case does not matter.
- `api_key` (`str`): Overrides the client API key for this call only.
- `timeout` (`float`): Seconds this call may take, the response included, before it raises `OpenEmailNetworkError` with `is_timeout`. It overrides the client's `timeout` for this call, and `0` turns the limit off.

**Returns**

`ConnectorActionDetailResource` with `action`, `name`, `description`, `kind` and `input`, the JSON Schema of what the action takes.

**Example**

```python
import json

from openemail import openemail

action = openemail.connectors.get_action('cnr_5c1e9a7b3d2f48e6a0b4c7d1', 'SEND_MESSAGE')

print(action['kind'], action['description'])
print(json.dumps(action['input'], indent=2))
```

**Notes**

- An action the app does not have is a 404 `connector_action_not_found`, and a name with other characters a 422 `invalid_parameter`.
- The connector has to be `active`. One that is paused, pending or expired answers 409 `connector_not_active`, and a missing one 404 `connector_not_found`.
- An API key acts for the workspace and uses the connectors of the workspace only. A connector that belongs to one person is used only by an app that person connected, which also needs `account:read`.
- A key or an app limited to particular addresses or domains does not reach the connectors of the workspace.
- When the connection service does not answer the call is refused with 503 `connector_provider_failed`.
- Read only, so the SDK retries it after a network failure like any other read.

Also available in: API [`GET /connectors/{id}/actions/{action}`](https://openemail.uk/docs/api/reference/connectors#get-connectors-id-actions-action); TypeScript [`connectors.getAction()`](https://openemail.uk/docs/sdk/reference/connectors#getAction); Ruby [`connectors.get_action`](https://openemail.uk/docs/ruby/reference/connectors#getAction); PHP [`connectors->getAction`](https://openemail.uk/docs/php/reference/connectors#getAction); Go [`Connectors.GetAction`](https://openemail.uk/docs/go/reference/connectors#getAction); Java [`connectors().getAction`](https://openemail.uk/docs/java/reference/connectors#getAction); C# [`Connectors.GetActionAsync`](https://openemail.uk/docs/csharp/reference/connectors#getAction); CLI [`openemail connectors get-action`](https://openemail.uk/docs/cli/reference/connectors#connectors-get-action).

### `connectors.run_action()`

Run one action in the connected app

```python
def run_action(
    id: str,
    action: str,
    body: ConnectorActionRun | None = None,
    *,
    api_key: str | None = None,
    timeout: float | None = None,
) -> ConnectorRunResource
```

Runs one action in the app behind a connector and returns what the app answered. An action that reads runs at once, and so does one that changes something: over the API nobody is asked first, so the caller decides. In the OpenEmail app the assistant asks a person before every change. A change made in the outside app cannot be taken back from here.

`input` is the input of the action as a dict, shaped as the JSON Schema that `get_action` returns for it. Call it with no body for an action that takes none.

The call returns whether or not the app carried the action out. `ok` is `True` when it did, with the answer of the app in `data`. When the app itself refuses, `ok` is `False` and `error` holds what it said. Every run is listed by `list_calls`, without its input and without its result.

Scopes: `connectors:use`.

**Parameters**

- `id` (`str`, required): Connector id such as `cnr_5c1e9a7b3d2f48e6a0b4c7d1`, as `list` returns it.
- `action` (`str`, required): The name of the action, as `list_actions` returns it in `action`: letters, digits and underscores, up to 160 characters. The case does not matter.
- `body['input']` (`dict[str, Any]`): The input of the action as a dict, shaped as `get_action` describes it. Written as JSON it holds at most 60,000 characters. Left out, the action runs with no input.
- `api_key` (`str`): Overrides the client API key for this call only.
- `timeout` (`float`): Seconds this call may take, the response included, before it raises `OpenEmailNetworkError` with `is_timeout`. It overrides the client's `timeout` for this call, and `0` turns the limit off.

**Returns**

`ConnectorRunResource` with `connectorId`, `app`, `action`, `kind`, `ok`, `data`, `error` and `truncated`. `data` is what the app answered, in its own shape. When `truncated` is `True` the answer was too long to return whole, and `data` is the start of it as text. `error` is `None` when `ok` is `True`.

**Example**

```python
from openemail import openemail

run = openemail.connectors.run_action(
    'cnr_5c1e9a7b3d2f48e6a0b4c7d1',
    'SEND_MESSAGE',
    {'input': {'channel': 'general', 'text': 'The report is ready.'}},
)

if run['ok']:
    print(run['data'])
else:
    print(run['error'])
```

**Notes**

- A connector whose `access` is `read` refuses an action that changes something with 403 `connector_read_only`. A connector that is paused, pending or expired answers 409 `connector_not_active`, and a missing one 404 `connector_not_found`.
- An action the app does not have is a 404 `connector_action_not_found`. An `input` that is not a dict or is too large is 422 `invalid_parameter`, and a key the body does not take 422 `unknown_parameter`. A request the app refuses as it was sent, most often because `input` does not match what the action takes, is 422 `connector_action_failed` with what the app said in the message.
- An action may take up to a minute. The client stops waiting after its `timeout`, 30 seconds unless you set another, and the action can still finish in the app after that. Pass a longer `timeout=` for slow actions.
- A 503 `connector_provider_failed` means the connection service did not answer in time. The app may still have carried the action out, so look in the app before you run it again.
- An API key acts for the workspace and uses the connectors of the workspace only. A connector that belongs to one person is used only by an app that person connected, which also needs `account:read`.
- A key or an app limited to particular addresses or domains does not reach the connectors of the workspace.
- Not retried automatically: a retry after a lost response could make the same change twice. `list_calls` with `connector_id=` shows the run once it has ended.

Also available in: API [`POST /connectors/{id}/actions/{action}/run`](https://openemail.uk/docs/api/reference/connectors#post-connectors-id-actions-action-run); TypeScript [`connectors.runAction()`](https://openemail.uk/docs/sdk/reference/connectors#runAction); Ruby [`connectors.run_action`](https://openemail.uk/docs/ruby/reference/connectors#runAction); PHP [`connectors->runAction`](https://openemail.uk/docs/php/reference/connectors#runAction); Go [`Connectors.RunAction`](https://openemail.uk/docs/go/reference/connectors#runAction); Java [`connectors().runAction`](https://openemail.uk/docs/java/reference/connectors#runAction); C# [`Connectors.RunActionAsync`](https://openemail.uk/docs/csharp/reference/connectors#runAction); CLI [`openemail connectors run-action`](https://openemail.uk/docs/cli/reference/connectors#connectors-run-action).

### `connectors.list_calls()`

List what was done through connectors, a page at a time

```python
def list_calls(
    *,
    limit: int | None = None,
    cursor: str | None = None,
    connector_id: str | None = None,
    scope: ConnectorScope | None = None,
    api_key: str | None = None,
    timeout: float | None = None,
) -> Page[ConnectorCallResource]
```

Returns one page of the record of calls, newest first: every action that ran through a connector the caller can reach. `list_all_calls` collects every page and `iterate_calls` walks them lazily. Each call names the connector and its app, the `action`, whether it read or changed something in `kind`, how it ended in `status`, where it came from in `source` and how long it took in `durationMs`.

A call record holds no input and no result. Those are never kept. Calls are kept for 90 days, and the calls of a connector go with it when it is disconnected.

Give `connector_id=` to read the calls of one connector, or `scope=` to read only the calls of workspace connectors or only those of a person's own.

Scopes: `connectors:read`.

**Parameters**

- `limit` (`int`): Page size, from 1 to 100. The server defaults to 25.
- `cursor` (`str`): The `nextCursor` of the previous page, passed back as it came. Leave it out for the first page.
- `connector_id` (`str`): Only the calls made through this connector, by its id.
- `scope` (`ConnectorScope`): Only the calls of one kind of connector: `workspace` or `account`. Left out, both are listed.
- `api_key` (`str`): Overrides the client API key for this call only.
- `timeout` (`float`): Seconds this call may take, the response included, before it raises `OpenEmailNetworkError` with `is_timeout`. It overrides the client's `timeout` for this call, and `0` turns the limit off.

**Returns**

`Page[ConnectorCallResource]`, a dict with `items`, `hasMore` and `nextCursor`. Each item has `id`, `connectorId`, `app`, `appName`, `action`, `kind`, `status`, `errorCode`, `source`, `durationMs` and `at`.

**Example**

```python
from openemail import openemail

page = openemail.connectors.list_calls(connector_id='cnr_5c1e9a7b3d2f48e6a0b4c7d1', limit=50)

for call in page['items']:
    print(call['at'], call['action'], call['kind'], call['status'], call['source'])
```

**Notes**

- `status` is `ok` when the action ran, `failed` when the app or the connection refused it, and `refused` when a rule here stopped it before it reached the app, such as a change through a connector set to `read`. `errorCode` names the reason and is `None` on an `ok` call.
- `source` is `chat` for the assistant in a conversation, `task` for a task run, `api` for a call over the API such as `run_action`, and `mcp` for an agent.
- An API key acts for the workspace and reads the calls of workspace connectors only. The calls of a connector that belongs to one person are read only by an app that person connected, which also needs `account:read`.
- A key or an app limited to particular addresses or domains does not reach the connectors of the workspace, so it is given none of their calls.
- The cursor is opaque and holds where the last row sat in this order, so a call made between pages never breaks the walk. One that cannot be read is a 400 `invalid_cursor`.
- Read only, so the SDK retries it after a network failure like any other read.

Also available in: API [`GET /connector-calls`](https://openemail.uk/docs/api/reference/connectors#get-connector-calls); TypeScript [`connectors.listCalls()`](https://openemail.uk/docs/sdk/reference/connectors#listCalls); Ruby [`connectors.list_calls`](https://openemail.uk/docs/ruby/reference/connectors#listCalls); PHP [`connectors->listCalls`](https://openemail.uk/docs/php/reference/connectors#listCalls); Go [`Connectors.ListCalls`](https://openemail.uk/docs/go/reference/connectors#listCalls); Java [`connectors().listCalls`](https://openemail.uk/docs/java/reference/connectors#listCalls); C# [`Connectors.ListCallsAsync`](https://openemail.uk/docs/csharp/reference/connectors#listCalls); CLI [`openemail connectors list-calls`](https://openemail.uk/docs/cli/reference/connectors#connectors-list-calls).

### `connectors.list_all_calls()`

Collect every connector call into one list

```python
def list_all_calls(
    *,
    limit: int | None = None,
    cursor: str | None = None,
    connector_id: str | None = None,
    scope: ConnectorScope | None = None,
    api_key: str | None = None,
    timeout: float | None = None,
) -> builtins.list[ConnectorCallResource]
```

Follows `nextCursor` from page to page and returns every call that matches, newest first, in the shape `list_calls` returns. `limit=` sets the page size of each request, not the total. A busy workspace keeps a great many calls for its 90 days, so give `connector_id=` or `scope=`, or prefer `iterate_calls` when you do not need them all in memory.

Scopes: `connectors:read`.

**Parameters**

- `limit` (`int`): Page size for each request, from 1 to 100. The server defaults to 25.
- `cursor` (`str`): Starts the walk after this cursor instead of the first page.
- `connector_id` (`str`): Only the calls made through this connector, by its id.
- `scope` (`ConnectorScope`): Only the calls of one kind of connector: `workspace` or `account`. Left out, both are collected.
- `api_key` (`str`): Overrides the client API key for every page of this walk.
- `timeout` (`float`): Seconds this call may take, the response included, before it raises `OpenEmailNetworkError` with `is_timeout`. It overrides the client's `timeout` for this call, and `0` turns the limit off.

**Returns**

`list[ConnectorCallResource]` holding every matching call across all pages.

**Example**

```python
from openemail import openemail

calls = openemail.connectors.list_all_calls(
    connector_id='cnr_5c1e9a7b3d2f48e6a0b4c7d1',
    limit=100,
)

changes = [call for call in calls if call['kind'] == 'change' and call['status'] == 'ok']

print(f'{len(changes)} changes were made through this connector')
```

**Notes**

- If any page fails, the call raises and the calls already fetched are discarded.
- A call record holds no input and no result, and calls older than 90 days are gone.
- A key or an app limited to particular addresses or domains does not reach the connectors of the workspace, so it is given none of their calls.

Also available in: API [`GET /connector-calls`](https://openemail.uk/docs/api/reference/connectors#get-connector-calls); TypeScript [`connectors.listAllCalls()`](https://openemail.uk/docs/sdk/reference/connectors#listAllCalls); Ruby [`connectors.list_all_calls`](https://openemail.uk/docs/ruby/reference/connectors#listAllCalls); PHP [`connectors->listAllCalls`](https://openemail.uk/docs/php/reference/connectors#listAllCalls); Go [`Connectors.ListAllCalls`](https://openemail.uk/docs/go/reference/connectors#listAllCalls); Java [`connectors().listAllCalls`](https://openemail.uk/docs/java/reference/connectors#listAllCalls); C# [`Connectors.ListAllCallsAsync`](https://openemail.uk/docs/csharp/reference/connectors#listAllCalls).

### `connectors.iterate_calls()`

Stream the connector calls one at a time

```python
def iterate_calls(
    *,
    limit: int | None = None,
    cursor: str | None = None,
    connector_id: str | None = None,
    scope: ConnectorScope | None = None,
    api_key: str | None = None,
    timeout: float | None = None,
) -> Iterator[ConnectorCallResource]
```

Returns a generator that yields calls one by one, newest first, and requests the next page only once the current one is drained. Nothing is fetched until you consume it, and breaking out of the loop stops the requests.

Scopes: `connectors:read`.

**Parameters**

- `limit` (`int`): Page size for each request, from 1 to 100. The server defaults to 25.
- `cursor` (`str`): Starts the walk after this cursor instead of the first page.
- `connector_id` (`str`): Only the calls made through this connector, by its id.
- `scope` (`ConnectorScope`): Only the calls of one kind of connector: `workspace` or `account`. Left out, both are walked.
- `api_key` (`str`): Overrides the client API key for every page of this walk.
- `timeout` (`float`): Seconds this call may take, the response included, before it raises `OpenEmailNetworkError` with `is_timeout`. It overrides the client's `timeout` for this call, and `0` turns the limit off.

**Returns**

`Iterator[ConnectorCallResource]`, a generator yielding one call per step.

**Example**

```python
from openemail import openemail

for call in openemail.connectors.iterate_calls(scope='workspace'):
    if call['status'] == 'ok':
        continue

    print(call['at'], call['appName'], call['action'], call['status'], call['errorCode'])
```

**Notes**

- The generator is lazy, so an abandoned loop costs only the pages you consumed.
- A key or an app limited to particular addresses or domains does not reach the connectors of the workspace, so it is given none of their calls.

Also available in: API [`GET /connector-calls`](https://openemail.uk/docs/api/reference/connectors#get-connector-calls); TypeScript [`connectors.iterateCalls()`](https://openemail.uk/docs/sdk/reference/connectors#iterateCalls); Ruby [`connectors.iterate_calls`](https://openemail.uk/docs/ruby/reference/connectors#iterateCalls); PHP [`connectors->iterateCalls`](https://openemail.uk/docs/php/reference/connectors#iterateCalls); Go [`Connectors.IterateCalls`](https://openemail.uk/docs/go/reference/connectors#iterateCalls); Java [`connectors().iterateCalls`](https://openemail.uk/docs/java/reference/connectors#iterateCalls); C# [`Connectors.IterateCallsAsync`](https://openemail.uk/docs/csharp/reference/connectors#iterateCalls).
