Skip to the documentation
TypeScript

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.listApps()

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

Scopesconnectors:readPages through results
Signature
listApps(options?: ConnectorAppListOptions): Promise<Page<ConnectorAppResource>>

Resolves one page of the catalogue of outside apps, the most used first. listAllApps collects every page and iterateApps 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 listCategories 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.

Parameters

options.searchstring

Words to look for in the name or the description of an app, trimmed, up to 200 characters.

options.categorystring

Only the apps in this category, by a slug that listCategories returns.

options.limitnumber

Page size, from 1 to 60. The server defaults to 24.

options.cursorstring

The nextCursor of the previous page, passed back as it came. Leave it out for the first page.

options.signalAbortSignal

Cancels the request.

options.apiKeystring

Overrides the client API key for this call only.

Returns

Page<ConnectorAppResource> with items, hasMore and nextCursor. Each item has slug, name, description, logo, website, categories, actions, auth and connectable.

Example

const page = await openemail.connectors.listApps({ search: 'calendar', limit: 10 }) for (const app of page.items) {    console.log(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 null 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
Python
connectors.list_apps()
Ruby
connectors.list_apps
PHP
connectors->listApps
Go
Connectors.ListApps
Java
connectors().listApps
C#
Connectors.ListAppsAsync
CLI
openemail connectors list-apps

connectors.listAllApps()

Collect every app that can be connected into one array

Scopesconnectors:readPages through results
Signature
listAllApps(options?: ConnectorAppListOptions): Promise<Array<ConnectorAppResource>>

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

Parameters

options.searchstring

Words to look for in the name or the description of an app, trimmed, up to 200 characters.

options.categorystring

Only the apps in this category, by a slug that listCategories returns.

options.limitnumber

Page size for each request, from 1 to 60. The server defaults to 24.

options.cursorstring

Starts the walk after this cursor instead of the first page.

options.signalAbortSignal

Cancels the request in flight and the walk with it.

options.apiKeystring

Overrides the client API key for every page of this walk.

Returns

Array<ConnectorAppResource> holding every matching app across all pages.

Example

const apps = await openemail.connectors.listAllApps({ category: 'productivity', limit: 60 }) const ready = apps.filter((app) => app.connectable) console.log(`${ready.length} of ${apps.length} apps can be connected`)

Notes

  • If any page fails the promise rejects 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
Python
connectors.list_all_apps()
Ruby
connectors.list_all_apps
PHP
connectors->listAllApps
Go
Connectors.ListAllApps
Java
connectors().listAllApps
C#
Connectors.ListAllAppsAsync

connectors.iterateApps()

Stream the apps that can be connected one at a time

Scopesconnectors:readPages through results
Signature
iterateApps(options?: ConnectorAppListOptions): AsyncGenerator<ConnectorAppResource, void, undefined>

Returns an async 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.

Parameters

options.searchstring

Words to look for in the name or the description of an app, trimmed, up to 200 characters.

options.categorystring

Only the apps in this category, by a slug that listCategories returns.

options.limitnumber

Page size for each request, from 1 to 60. The server defaults to 24.

options.cursorstring

Starts the walk after this cursor instead of the first page.

options.signalAbortSignal

Cancels the request in flight and the walk with it.

options.apiKeystring

Overrides the client API key for every page of this walk.

Returns

AsyncGenerator<ConnectorAppResource, void, undefined> yielding one app per step.

Example

for await (const app of openemail.connectors.iterateApps({ search: 'notes' })) {    if (!app.connectable) continue     console.log(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 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
Python
connectors.iterate_apps()
Ruby
connectors.iterate_apps
PHP
connectors->iterateApps
Go
Connectors.IterateApps
Java
connectors().iterateApps
C#
Connectors.IterateAppsAsync

connectors.getApp()

Read one app of the catalogue by its slug

Scopesconnectors:read
Signature
getApp(slug: string, options?: RequestScope): Promise<ConnectorAppResource>

Looks up one app of the catalogue and returns it in the same shape as a row of listApps: 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 false and auth null.

Parameters

slugstringRequired

The slug of the app, as listApps returns it: letters, digits, hyphens and underscores, up to 80 characters. The case does not matter.

options.signalAbortSignal

Cancels the request.

options.apiKeystring

Overrides the client API key for this call only.

Returns

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

Example

const app = await openemail.connectors.getApp('example-app') if (app.connectable) console.log(app.name, 'takes a', app.auth, 'and offers', app.actions, 'actions')

Notes

  • A slug the catalogue does not have throws OpenEmailApiError with isNotFound 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}
Python
connectors.get_app()
Ruby
connectors.get_app
PHP
connectors->getApp
Go
Connectors.GetApp
Java
connectors().getApp
C#
Connectors.GetAppAsync
CLI
openemail connectors get-app

connectors.listCategories()

List the categories the catalogue sorts its apps into

Scopesconnectors:read
Signature
listCategories(options?: RequestScope): Promise<Array<ConnectorCategoryResource>>

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

Parameters

options.signalAbortSignal

Cancels the request.

options.apiKeystring

Overrides the client API key for this call only.

Returns

Array<ConnectorCategoryResource>. Each item has slug, the value to pass as category, and name.

Example

const categories = await openemail.connectors.listCategories() for (const category of categories) console.log(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
Python
connectors.list_categories()
Ruby
connectors.list_categories
PHP
connectors->listCategories
Go
Connectors.ListCategories
Java
connectors().listCategories
C#
Connectors.ListCategoriesAsync
CLI
openemail connectors list-categories

connectors.list()

List the connectors the caller can reach

Scopesconnectors:read
Signature
list(options?: ConnectorListOptions): Promise<Array<ConnectorResource>>

Resolves every connector the caller can reach in one array, 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.

Parameters

options.scopeConnectorScope

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.

options.statusConnectorStatus

Only connectors in this state: pending, active, expired or paused.

options.appstring

Only the connectors of this app, by its slug.

options.signalAbortSignal

Cancels the request.

options.apiKeystring

Overrides the client API key for this call only.

Returns

Array<ConnectorResource>. Each item has id, scope, app, appName, appLogo, label, status, failure, pausedReason, access, connectedAt, lastUsedAt, createdAt and updatedAt.

Example

const connectors = await openemail.connectors.list({ status: 'expired' }) for (const connector of connectors) {    console.log(connector.appName, connector.label, connector.failure)}

Notes

  • failure says why a connector stopped working: expired, revoked, failed or disabled. It is null 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 null. 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
Python
connectors.list()
Ruby
connectors.list
PHP
connectors->list
Go
Connectors.List
Java
connectors().list
C#
Connectors.ListAsync
CLI
openemail connectors list

connectors.get()

Read one connector by id

Scopesconnectors:read
Signature
get(id: string, options?: RequestScope): Promise<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.

Parameters

idstringRequired

Connector id such as cnr_5c1e9a7b3d2f48e6a0b4c7d1, as list returns it.

options.signalAbortSignal

Cancels the request.

options.apiKeystring

Overrides the client API key for this call only.

Returns

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

Example

const connector = await openemail.connectors.get('cnr_5c1e9a7b3d2f48e6a0b4c7d1') if (connector.status === 'active') console.log(connector.appName, 'is connected since', connector.connectedAt)

Notes

  • A missing connector, or one the caller cannot reach, throws OpenEmailApiError with isNotFound 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}
Python
connectors.get()
Ruby
connectors.get
PHP
connectors->get
Go
Connectors.Get
Java
connectors().get
C#
Connectors.GetAsync
CLI
openemail connectors get

connectors.connect()

Start connecting an app

Scopesconnectors:write
Signature
connect(body: ConnectorConnect, options?: RequestScope): Promise<ConnectorLinkResource>

Starts connecting an app and resolves with the new connector and 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: 'account' keeps it to the person an app acts for.

Parameters

body.appstringRequired

The app to connect, by the slug that listApps returns.

body.scopeConnectorScope

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.labelstring

A name of your own for the connector, trimmed, up to 80 characters. Left out, it has none.

body.accessConnectorAccess

What the assistant may do through the connector. read lets it look things up. full also lets it make changes and is the default.

options.signalAbortSignal

Cancels the request.

options.apiKeystring

Overrides the client API key for this call only.

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

const connector = await openemail.connectors.connect({ app: 'example-app', label: 'Team notes', access: 'read' }) console.log('Open this link and sign in:', connector.connectUrl) const fresh = await openemail.connectors.get(connector.id) console.log(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: '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
Python
connectors.connect()
Ruby
connectors.connect
PHP
connectors->connect
Go
Connectors.Connect
Java
connectors().connect
C#
Connectors.ConnectAsync
CLI
openemail connectors connect

connectors.update()

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

Scopesconnectors:write
Signature
update(id: string, patch: ConnectorPatch, options?: RequestScope): Promise<ConnectorResource>

Changes a connector and resolves with 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: true stops the assistant, tasks and runAction from using the connector until paused: 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 null or an empty string takes its name away.

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

Parameters

idstringRequired

Connector id such as cnr_5c1e9a7b3d2f48e6a0b4c7d1, as list returns it.

patch.labelstring | null

A name of your own for the connector, trimmed, up to 80 characters. Null or an empty string clears it. Left out, the name stays.

patch.accessConnectorAccess

read lets the assistant only look things up through the connector. full also lets it make changes. Left out, it stays.

patch.pausedboolean

true pauses the connector and false resumes it. Left out, it stays as it is.

options.signalAbortSignal

Cancels the request.

options.apiKeystring

Overrides the client API key for this call only.

Returns

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

Example

const connector = await openemail.connectors.update('cnr_5c1e9a7b3d2f48e6a0b4c7d1', {    label: 'Support desk',    access: 'read'}) console.log(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}
Python
connectors.update()
Ruby
connectors.update
PHP
connectors->update
Go
Connectors.Update
Java
connectors().update
C#
Connectors.UpdateAsync
CLI
openemail connectors update

connectors.disconnect()

Disconnect an app for good

Scopesconnectors:write
Signature
disconnect(id: string, options?: RequestScope): Promise<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: true. To use the app again later, start over with connect.

Parameters

idstringRequired

Connector id such as cnr_5c1e9a7b3d2f48e6a0b4c7d1, as list returns it.

options.signalAbortSignal

Cancels the request.

options.apiKeystring

Overrides the client API key for this call only.

Returns

DeletedConnectorResource, { object: 'connector', id, scope, app, deleted: true }, where app is the slug of the app it connected.

Example

const removed = await openemail.connectors.disconnect('cnr_5c1e9a7b3d2f48e6a0b4c7d1') console.log(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}
Python
connectors.disconnect()
Ruby
connectors.disconnect
PHP
connectors->disconnect
Go
Connectors.Disconnect
Java
connectors().disconnect
C#
Connectors.DisconnectAsync
CLI
openemail connectors disconnect

connectors.reconnect()

Get a fresh link to sign in to the app again

Scopesconnectors:write
Signature
reconnect(id: string, options?: RequestScope): Promise<ConnectorLinkResource>

Resolves with 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.

Parameters

idstringRequired

Connector id such as cnr_5c1e9a7b3d2f48e6a0b4c7d1, as list returns it.

options.signalAbortSignal

Cancels the request.

options.apiKeystring

Overrides the client API key for this call only.

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

const connector = await openemail.connectors.reconnect('cnr_5c1e9a7b3d2f48e6a0b4c7d1') console.log('Open this link and sign in again:', connector.connectUrl, 'before', 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
Python
connectors.reconnect()
Ruby
connectors.reconnect
PHP
connectors->reconnect
Go
Connectors.Reconnect
Java
connectors().reconnect
C#
Connectors.ReconnectAsync
CLI
openemail connectors reconnect

connectors.listActions()

List what a connector can do

Scopesconnectors:use
Signature
listActions(id: string, options?: ConnectorActionListOptions): Promise<Array<ConnectorActionResource>>

Resolves 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. getAction adds the input an action takes.

Parameters

idstringRequired

Connector id such as cnr_5c1e9a7b3d2f48e6a0b4c7d1, as list returns it.

options.searchstring

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.

options.limitnumber

How many actions to return, from 1 to 30. The server defaults to 12.

options.signalAbortSignal

Cancels the request.

options.apiKeystring

Overrides the client API key for this call only.

Returns

Array<ConnectorActionResource>. Each item has action, name, description and kind.

Example

const actions = await openemail.connectors.listActions('cnr_5c1e9a7b3d2f48e6a0b4c7d1', { search: 'send message', limit: 5 }) for (const action of actions) console.log(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
Python
connectors.list_actions()
Ruby
connectors.list_actions
PHP
connectors->listActions
Go
Connectors.ListActions
Java
connectors().listActions
C#
Connectors.ListActionsAsync
CLI
openemail connectors list-actions

connectors.getAction()

Read one action with the input it takes

Scopesconnectors:use
Signature
getAction(id: string, action: string, options?: RequestScope): Promise<ConnectorActionDetailResource>

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

Parameters

idstringRequired

Connector id such as cnr_5c1e9a7b3d2f48e6a0b4c7d1, as list returns it.

actionstringRequired

The name of the action, as listActions returns it in action: letters, digits and underscores, up to 160 characters. The case does not matter.

options.signalAbortSignal

Cancels the request.

options.apiKeystring

Overrides the client API key for this call only.

Returns

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

Example

const action = await openemail.connectors.getAction('cnr_5c1e9a7b3d2f48e6a0b4c7d1', 'SEND_MESSAGE') console.log(action.kind, action.description)console.log(JSON.stringify(action.input, null, 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}
Python
connectors.get_action()
Ruby
connectors.get_action
PHP
connectors->getAction
Go
Connectors.GetAction
Java
connectors().getAction
C#
Connectors.GetActionAsync
CLI
openemail connectors get-action

connectors.runAction()

Run one action in the connected app

Scopesconnectors:use
Signature
runAction(id: string, action: string, body?: ConnectorActionRun, options?: RequestScope): Promise<ConnectorRunResource>

Runs one action in the app behind a connector and resolves with 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 an object, shaped as the JSON Schema that getAction returns for it. Call it with no body for an action that takes none.

The promise resolves 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 listCalls, without its input and without its result.

Parameters

idstringRequired

Connector id such as cnr_5c1e9a7b3d2f48e6a0b4c7d1, as list returns it.

actionstringRequired

The name of the action, as listActions returns it in action: letters, digits and underscores, up to 160 characters. The case does not matter.

body.inputRecord<string, unknown>

The input of the action as an object, shaped as getAction describes it. Written as JSON it holds at most 60,000 characters. Left out, the action runs with no input.

options.signalAbortSignal

Cancels the request. The action may still run in the app.

options.apiKeystring

Overrides the client API key for this call only.

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 null when ok is true.

Example

const run = await openemail.connectors.runAction('cnr_5c1e9a7b3d2f48e6a0b4c7d1', 'SEND_MESSAGE', {    input: { channel: 'general', text: 'The report is ready.' }}) if (run.ok) console.log(run.data)else console.error(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 an object 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 timeoutMs, 30 seconds unless you set another, and the action can still finish in the app after that. Create the client with a longer timeoutMs 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. listCalls with connectorId shows the run once it has ended.

Also available in

API
POST /connectors/{id}/actions/{action}/run
Python
connectors.run_action()
Ruby
connectors.run_action
PHP
connectors->runAction
Go
Connectors.RunAction
Java
connectors().runAction
C#
Connectors.RunActionAsync
CLI
openemail connectors run-action

connectors.listCalls()

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

Scopesconnectors:readPages through results
Signature
listCalls(options?: ConnectorCallListOptions): Promise<Page<ConnectorCallResource>>

Resolves one page of the record of calls, newest first: every action that ran through a connector the caller can reach. listAllCalls collects every page and iterateCalls 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 connectorId 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.

Parameters

options.connectorIdstring

Only the calls made through this connector, by its id.

options.scopeConnectorScope

Only the calls of one kind of connector: workspace or account. Left out, both are listed.

options.limitnumber

Page size, from 1 to 100. The server defaults to 25.

options.cursorstring

The nextCursor of the previous page, passed back as it came. Leave it out for the first page.

options.signalAbortSignal

Cancels the request.

options.apiKeystring

Overrides the client API key for this call only.

Returns

Page<ConnectorCallResource> with items, hasMore and nextCursor. Each item has id, connectorId, app, appName, action, kind, status, errorCode, source, durationMs and at.

Example

const page = await openemail.connectors.listCalls({ connectorId: 'cnr_5c1e9a7b3d2f48e6a0b4c7d1', limit: 50 }) for (const call of page.items) {    console.log(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 null 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 runAction, 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
Python
connectors.list_calls()
Ruby
connectors.list_calls
PHP
connectors->listCalls
Go
Connectors.ListCalls
Java
connectors().listCalls
C#
Connectors.ListCallsAsync
CLI
openemail connectors list-calls

connectors.listAllCalls()

Collect every connector call into one array

Scopesconnectors:readPages through results
Signature
listAllCalls(options?: ConnectorCallListOptions): Promise<Array<ConnectorCallResource>>

Follows nextCursor from page to page and resolves with every call that matches, newest first, in the shape listCalls 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 connectorId or scope, or prefer iterateCalls when you do not need them all in memory.

Parameters

options.connectorIdstring

Only the calls made through this connector, by its id.

options.scopeConnectorScope

Only the calls of one kind of connector: workspace or account. Left out, both are collected.

options.limitnumber

Page size for each request, from 1 to 100. The server defaults to 25.

options.cursorstring

Starts the walk after this cursor instead of the first page.

options.signalAbortSignal

Cancels the request in flight and the walk with it.

options.apiKeystring

Overrides the client API key for every page of this walk.

Returns

Array<ConnectorCallResource> holding every matching call across all pages.

Example

const calls = await openemail.connectors.listAllCalls({ connectorId: 'cnr_5c1e9a7b3d2f48e6a0b4c7d1', limit: 100 }) const changes = calls.filter((call) => call.kind === 'change' && call.status === 'ok') console.log(`${changes.length} changes were made through this connector`)

Notes

  • If any page fails the promise rejects 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
Python
connectors.list_all_calls()
Ruby
connectors.list_all_calls
PHP
connectors->listAllCalls
Go
Connectors.ListAllCalls
Java
connectors().listAllCalls
C#
Connectors.ListAllCallsAsync

connectors.iterateCalls()

Stream the connector calls one at a time

Scopesconnectors:readPages through results
Signature
iterateCalls(options?: ConnectorCallListOptions): AsyncGenerator<ConnectorCallResource, void, undefined>

Returns an async 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.

Parameters

options.connectorIdstring

Only the calls made through this connector, by its id.

options.scopeConnectorScope

Only the calls of one kind of connector: workspace or account. Left out, both are walked.

options.limitnumber

Page size for each request, from 1 to 100. The server defaults to 25.

options.cursorstring

Starts the walk after this cursor instead of the first page.

options.signalAbortSignal

Cancels the request in flight and the walk with it.

options.apiKeystring

Overrides the client API key for every page of this walk.

Returns

AsyncGenerator<ConnectorCallResource, void, undefined> yielding one call per step.

Example

for await (const call of openemail.connectors.iterateCalls({ scope: 'workspace' })) {    if (call.status === 'ok') continue     console.log(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
Python
connectors.iterate_calls()
Ruby
connectors.iterate_calls
PHP
connectors->iterateCalls
Go
Connectors.IterateCalls
Java
connectors().iterateCalls
C#
Connectors.IterateCallsAsync