ドキュメント本文へスキップ
Python

openemail.keys

この名前空間のすべてのメソッドの、シグネチャ、パラメーター、戻り値、例。

メソッド

Every key in the workspace: list, create, change, rotate, switch off and revoke them, never wider than the calling key, and read their request log and activity.

keys.list()

List one page of the workspace's API keys

スコープkeys:read結果をページ単位で取得
シグネチャ
def list(    *,    limit: int | None = None,    cursor: str | None = None,    api_key: str | None = None,    timeout: float | None = None,) -> Page[ApiKeyResource]

Returns one page of the workspace's keys, newest first, with what the Settings, API keys page shows: status, scopes, role, send scope, when each was last used, how often, and who made and last changed it. Revoked and expired keys stay listed until somebody deletes them. No secret is ever returned; maskedKey is enough to tell two keys apart.

A key narrowed to some domains or addresses only sees the keys whose send scope sits inside its own, so any other is a 404 rather than a refusal. Over OAuth only the workspace owner reaches it, and a member's token is 403 owner_only.

パラメーター

limitint

Rows per page, a whole number from 1 to 100. The server defaults to 25.

cursorstr

The nextCursor from the previous page, passed back unchanged. Never build one yourself.

api_keystr

Overrides the client API key for this call only.

timeoutfloat

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.

戻り値

Page[ApiKeyResource], a dict with items, hasMore and nextCursor. Each item is an ApiKeyResource: id, name, mode, maskedKey, keyLast4, status, scopes, roleId, roleName, addressAllowlist, domainAllowlist, expiresAt, lastUsedAt, totalUses, rotatedAt, rotationCount, deactivatedAt, revokedAt, revokedReason, createdAt, createdBy, updatedAt, updatedBy, lastChangeAt and lastChangeType. Never a secret.

例

from openemail import openemail page = openemail.keys.list() for key in page['items']:    print(key['maskedKey'], key['name'], key['status'], key['lastUsedAt'])

注意事項

  • It needs keys:read, which no key holds unless somebody gave it one.

  • The cursor is opaque: pass nextCursor back as it came.

ほかの提供先

API
GET /keys
TypeScript
keys.list()
Ruby
keys.list
CLI
openemail keys list

keys.list_all()

Collect every API key into one list

スコープkeys:read結果をページ単位で取得
シグネチャ
def list_all(    *,    limit: int | None = None,    cursor: str | None = None,    api_key: str | None = None,    timeout: float | None = None,) -> builtins.list[ApiKeyResource]

Walks every page of list and returns every key the caller can see, newest first, in one list.

パラメーター

limitint

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

cursorstr

Starts the walk from this cursor instead of the newest row.

api_keystr

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

timeoutfloat

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.

戻り値

list[ApiKeyResource], newest first.

例

from openemail import openemail keys = openemail.keys.list_all() idle = [key['name'] for key in keys if key['status'] == 'active' and key['lastUsedAt'] is None] print(idle)

注意事項

  • If any page fails, the call raises and the keys already fetched are discarded.

ほかの提供先

API
GET /keys
TypeScript
keys.listAll()
Ruby
keys.list_all

keys.iterate()

Stream the workspace's API keys one at a time

スコープkeys:read結果をページ単位で取得
シグネチャ
def iterate(    *,    limit: int | None = None,    cursor: str | None = None,    api_key: str | None = None,    timeout: float | None = None,) -> Iterator[ApiKeyResource]

A generator over list, fetching a page only when the one before is drained. Nothing is requested until you start iterating, and breaking out of the loop stops the requests.

パラメーター

limitint

Page size per request, 1 to 100. The server defaults to 25.

cursorstr

Starts the walk from this cursor instead of the newest row.

api_keystr

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

timeoutfloat

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.

戻り値

Iterator[ApiKeyResource], a generator yielding one key per step.

例

from datetime import datetime, timedelta, timezone from openemail import openemail soon = datetime.now(timezone.utc) + timedelta(days=7) for key in openemail.keys.iterate():    expires = key['expiresAt']     if expires and datetime.fromisoformat(expires.replace('Z', '+00:00')) < soon:        print(key['name'], 'expires soon')

ほかの提供先

API
GET /keys
TypeScript
keys.iterate()
Ruby
keys.iterate

keys.get()

Read one API key, without its secret

スコープkeys:read
シグネチャ
def get(    id: str,    *,    api_key: str | None = None,    timeout: float | None = None,) -> ApiKeyResource

Returns one key as list shows it. A key narrowed to some domains or addresses only sees the keys whose send scope sits inside its own, so any other is a 404 rather than a refusal, which is_not_found reports on the error. Over OAuth only the workspace owner reaches it, and a member's token is 403 owner_only.

openemail.me.get() describes the calling key itself and needs no scope; this reads any key the caller can see.

パラメーター

idstr必須

Key id, the 24 hex characters after oe_live_.

api_keystr

Overrides the client API key for this call only.

timeoutfloat

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.

戻り値

ApiKeyResource: id, name, mode, maskedKey, keyLast4, status, scopes, roleId, roleName, addressAllowlist, domainAllowlist, expiresAt, lastUsedAt, totalUses, rotatedAt, rotationCount, deactivatedAt, revokedAt, revokedReason, createdAt, createdBy, updatedAt, updatedBy, lastChangeAt and lastChangeType. Never a secret.

例

from openemail import OpenEmailApiError, openemail try:    key = openemail.keys.get('4c1b257a66287fd113bd89d0')except OpenEmailApiError as error:    if not error.is_not_found:        raise     print('No such key, or one this key cannot see')else:    print(key['status'], key['scopes'], key['domainAllowlist'])

ほかの提供先

API
GET /keys/{id}
TypeScript
keys.get()
Ruby
keys.get
CLI
openemail keys get

keys.create()

Mint a new API key and receive its secret once

スコープkeys:manage
シグネチャ
def create(    body: ApiKeyCreate,    *,    api_key: str | None = None,    timeout: float | None = None,) -> CreatedApiKeyResource

Creates a live key and returns it plus token, the whole secret. That is the only time it appears, so store it before doing anything else.

Left out, scopes is ['emails:send'], the role is the caller's own or none, the send scope is the caller's own or none (none means every address the workspace owns), and the expiry is the caller's own or none. The workspace cap on live keys applies, as a 422 workspace_limit_reached.

A key never makes or reaches a key wider than itself. The target has to sit inside the caller on every axis: scopes the caller holds after its own role has narrowed them, the same role when the caller has one, an expiry no later than the caller's when the caller expires, the caller's mode, and a send scope inside the caller's own, where one address never covers its whole domain. Anything wider is 403 beyond_caller_authority, and the error's param names the axis.

Step-up verification, which the app asks for before it mints a key, cannot apply to a call made with a key, so keys:manage is a credential that makes credentials. Give it only to automation that provisions keys, narrow that key to the role and send scope it needs, and give it an expiry.

パラメーター

body['name']str必須

A name, 1 to 60 characters.

body['scopes']list[ApiScope]

The scopes the key holds, at least one, each held by the caller. Defaults to ['emails:send'].

body['roleId']str | None

A role to cap the key. Left out, the caller's own role. A caller with a role can only give its own, and None is refused for it.

body['addressAllowlist']list[str]

Single addresses the key may send as, at most 50, each owned by the workspace.

body['domainAllowlist']list[str]

Whole domains the key may send as, at most 25, including addresses added to them later. Leave both lists out to inherit the caller's own; send both empty for none.

body['expiresInMinutes']int

Minutes until the key expires, 5 to 5,256,000 (ten years). Left out, the caller's own expiry.

api_keystr

Overrides the client API key for this call only.

timeoutfloat

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.

戻り値

CreatedApiKeyResource: the ApiKeyResource fields id, name, mode, maskedKey, keyLast4, status, scopes, roleId, roleName, addressAllowlist, domainAllowlist, expiresAt, lastUsedAt, totalUses, rotatedAt, rotationCount, deactivatedAt, revokedAt, revokedReason, createdAt, createdBy, updatedAt, updatedBy, lastChangeAt and lastChangeType, plus token, oe_live_ followed by the id, an underscore and the secret.

例

from openemail import openemail key = openemail.keys.create(    {        'name': 'Billing sender',        'scopes': ['emails:send', 'emails:read'],        'domainAllowlist': ['billing.acme.com'],        'expiresInMinutes': 60 * 24 * 90,    }) print(key['maskedKey'], key['expiresAt'])print('Store this secret now, it is never shown again:', key['token'])

注意事項

  • Not retried automatically: a retry after a lost response would mint a second key.

  • The new key is recorded in the activity log as made by the calling key, with 'api' as the source in its detail.

  • The success status is 201.

ほかの提供先

API
POST /keys
TypeScript
keys.create()
Ruby
keys.create
CLI
openemail keys create

keys.update()

Rename a key, change its scopes or send scope, or switch it off and on

スコープkeys:manage
シグネチャ
def update(    id: str,    patch: ApiKeyPatch,    *,    api_key: str | None = None,    timeout: float | None = None,) -> ApiKeyResource

Applies a partial change and returns the key as it now stands. scopes, addressAllowlist and domainAllowlist REPLACE what the key had, and a field left out stays as it was. 'enabled': False switches the key off: every call with it is refused with inactive_api_key and it keeps its secret, scopes, role and send scope, so 'enabled': True restores it exactly. That is the reversible alternative to revoke. A revoked key cannot be changed, and answers 409 revoked.

A key never makes or reaches a key wider than itself. The target has to sit inside the caller on every axis: scopes the caller holds after its own role has narrowed them, the same role when the caller has one, an expiry no later than the caller's when the caller expires, the caller's mode, and a send scope inside the caller's own, where one address never covers its whole domain. Anything wider is 403 beyond_caller_authority, and the error's param names the axis. A key changing itself may only narrow itself.

A key narrowed to some domains or addresses only sees the keys whose send scope sits inside its own, so any other is a 404 rather than a refusal. Over OAuth only the workspace owner reaches it, and a member's token is 403 owner_only.

パラメーター

idstr必須

Key id, the 24 hex characters after oe_live_.

patch['name']str

A new name, 1 to 60 characters.

patch['scopes']list[ApiScope]

The whole new list of scopes, at least one.

patch['addressAllowlist']list[str]

The whole new list of single addresses.

patch['domainAllowlist']list[str]

The whole new list of whole domains.

patch['enabled']bool

False switches the key off, True switches it back on.

api_keystr

Overrides the client API key for this call only.

timeoutfloat

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.

戻り値

ApiKeyResource: id, name, mode, maskedKey, keyLast4, status, scopes, roleId, roleName, addressAllowlist, domainAllowlist, expiresAt, lastUsedAt, totalUses, rotatedAt, rotationCount, deactivatedAt, revokedAt, revokedReason, createdAt, createdBy, updatedAt, updatedBy, lastChangeAt and lastChangeType. Never a secret.

例

from openemail import openemail openemail.keys.update('4c1b257a66287fd113bd89d0', {'enabled': False}) key = openemail.keys.update('4c1b257a66287fd113bd89d0', {'name': 'Billing sender (paused)'}) print(key['status'], key['deactivatedAt'])

注意事項

  • An empty patch is a 422. The call is retried on network failure and retryable statuses, because applying the same patch twice leaves the same key.

ほかの提供先

API
PATCH /keys/{id}
TypeScript
keys.update()
Ruby
keys.update
CLI
openemail keys update

keys.delete()

Remove a revoked key from the list

スコープkeys:manage
シグネチャ
def delete(    id: str,    *,    api_key: str | None = None,    timeout: float | None = None,) -> DeletedApiKeyResource

Deletes a key that has already been revoked. Its request log and activity stay, under Deleted key, so the history of what it did is not lost with it. A key that has not been revoked is refused with 409 not_revoked, so nothing still calling with it loses its credential without somebody deciding that first.

A key never makes or reaches a key wider than itself. The target has to sit inside the caller on every axis: scopes the caller holds after its own role has narrowed them, the same role when the caller has one, an expiry no later than the caller's when the caller expires, the caller's mode, and a send scope inside the caller's own, where one address never covers its whole domain. Anything wider is 403 beyond_caller_authority, and the error's param names the axis.

パラメーター

idstr必須

Key id, the 24 hex characters after oe_live_.

api_keystr

Overrides the client API key for this call only.

timeoutfloat

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.

戻り値

DeletedApiKeyResource, a dict with 'object': 'api_key', the id and 'deleted': True.

例

from openemail import openemail revoked = openemail.keys.revoke('4c1b257a66287fd113bd89d0', {'reason': 'Leaked in a build log'}) openemail.keys.delete(revoked['id']) print('Deleted', revoked['name'], 'after revoking it at', revoked['revokedAt'])

注意事項

  • Not retried automatically. If you repeat it yourself after a lost response, a 404 means the first attempt already worked.

ほかの提供先

API
DELETE /keys/{id}
TypeScript
keys.delete()
Ruby
keys.delete
CLI
openemail keys delete

keys.rotate()

Give a key a new secret and receive it once

スコープkeys:manage
シグネチャ
def rotate(    id: str,    *,    api_key: str | None = None,    timeout: float | None = None,) -> RotatedApiKeyResource

Mints a new secret for a key and returns the key plus token, rotationCount and rotatedAt. The id, name, scopes, role, send scope, expiry and request history all carry on; only the secret and keyLast4 change. There is no overlap window: the old secret stops working the instant this returns.

Rotating the calling key itself is what openemail.me.rotate() does, and here it is allowed with keys:write as well as keys:manage. A revoked or expired key cannot be rotated, and answers 409 revoked or expired.

A key never makes or reaches a key wider than itself. The target has to sit inside the caller on every axis: scopes the caller holds after its own role has narrowed them, the same role when the caller has one, an expiry no later than the caller's when the caller expires, the caller's mode, and a send scope inside the caller's own, where one address never covers its whole domain. Anything wider is 403 beyond_caller_authority, and the error's param names the axis. Rotation hands the caller a working secret for the key, which is why the ceiling is checked against the key as it stands.

A key narrowed to some domains or addresses only sees the keys whose send scope sits inside its own, so any other is a 404 rather than a refusal. Over OAuth only the workspace owner reaches it, and a member's token is 403 owner_only.

パラメーター

idstr必須

Key id, the 24 hex characters after oe_live_.

api_keystr

Overrides the client API key for this call only.

timeoutfloat

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.

戻り値

RotatedApiKeyResource: the ApiKeyResource fields id, name, mode, maskedKey, keyLast4, status, scopes, roleId, roleName, addressAllowlist, domainAllowlist, expiresAt, lastUsedAt, totalUses, rotatedAt, rotationCount, deactivatedAt, revokedAt, revokedReason, createdAt, createdBy, updatedAt, updatedBy, lastChangeAt and lastChangeType, plus the new secret in token. rotationCount and rotatedAt already count this rotation.

例

from openemail import openemail rotated = openemail.keys.rotate('4c1b257a66287fd113bd89d0') print(rotated['rotationCount'], rotated['rotatedAt'])print('Store the new secret now, the old one has stopped working:', rotated['token'])

注意事項

  • Not retried automatically. Repeating a rotation would invalidate the secret the first attempt returned.

ほかの提供先

API
POST /keys/{id}/rotate
TypeScript
keys.rotate()
Ruby
keys.rotate
CLI
openemail keys rotate

keys.revoke()

Revoke a key for good

スコープkeys:manage
シグネチャ
def revoke(    id: str,    body: ApiKeyRevoke | None = None,    *,    api_key: str | None = None,    timeout: float | None = None,) -> ApiKeyResource

Revokes a key: every later call with it is refused with revoked_api_key, and it can never be switched back on, rotated or changed. reason is kept on the key and in the activity log. Revoking a key that is already revoked changes nothing and returns it as it is. A key may revoke itself, which is how an integration that believes its secret leaked retires it at once.

A key never makes or reaches a key wider than itself. The target has to sit inside the caller on every axis: scopes the caller holds after its own role has narrowed them, the same role when the caller has one, an expiry no later than the caller's when the caller expires, the caller's mode, and a send scope inside the caller's own, where one address never covers its whole domain. Anything wider is 403 beyond_caller_authority, and the error's param names the axis.

A key narrowed to some domains or addresses only sees the keys whose send scope sits inside its own, so any other is a 404 rather than a refusal. Over OAuth only the workspace owner reaches it, and a member's token is 403 owner_only.

パラメーター

idstr必須

Key id, the 24 hex characters after oe_live_.

body['reason']str

Why, at most 200 characters. The body is optional.

api_keystr

Overrides the client API key for this call only.

timeoutfloat

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.

戻り値

ApiKeyResource: id, name, mode, maskedKey, keyLast4, status, scopes, roleId, roleName, addressAllowlist, domainAllowlist, expiresAt, lastUsedAt, totalUses, rotatedAt, rotationCount, deactivatedAt, revokedAt, revokedReason, createdAt, createdBy, updatedAt, updatedBy, lastChangeAt and lastChangeType. Never a secret. status is 'revoked'.

例

from openemail import openemail key = openemail.keys.revoke('4c1b257a66287fd113bd89d0', {'reason': 'Contractor offboarded'}) print(key['status'], key['revokedAt'], key['revokedReason'])

注意事項

  • Retried on network failure and retryable statuses, because revoking twice leaves the same key. Prefer update(id, {'enabled': False}) while you find out whether anything still depends on a key.

ほかの提供先

API
POST /keys/{id}/revoke
TypeScript
keys.revoke()
Ruby
keys.revoke
CLI
openemail keys revoke

keys.list_requests()

List one page of one key's request log

スコープkeys:read結果をページ単位で取得
シグネチャ
def list_requests(    id: str,    *,    limit: int | None = None,    cursor: str | None = None,    since: datetime | str | None = None,    until: datetime | str | None = None,    failed_only: bool | None = None,    api_key: str | None = None,    timeout: float | None = None,) -> Page[ApiKeyRequestResource]

Returns one page of the calls one key made, newest first, the Requests tab of the key in the app. The request log records every authenticated call a key made: method, path, status, error code, duration, IP and user agent, and never a body or a query string. A call refused before a key could be identified is not in it, and neither is a call made with an OAuth access token. Nothing is pruned, so the log reaches back to a key's first call. failed_only=, since= and until= are the filters the app offers.

A deleted key's log stays readable to a key that is not narrowed. A key narrowed to some domains or addresses only sees the keys whose send scope sits inside its own, so any other is a 404 rather than a refusal. Over OAuth only the workspace owner reaches it, and a member's token is 403 owner_only.

パラメーター

idstr必須

Key id, the 24 hex characters after oe_live_.

limitint

Rows per page, a whole number from 1 to 100. The server defaults to 25.

cursorstr

The nextCursor from the previous page, passed back unchanged. Never build one yourself.

sincedatetime | str

Only rows at or after this instant. A datetime is sent as ISO 8601 in UTC, and a string must already be one.

untildatetime | str

Only rows before this instant. It has to be later than since, or the server answers 400 invalid_parameter.

failed_onlybool

Only calls answered with a status of 400 or more.

api_keystr

Overrides the client API key for this call only.

timeoutfloat

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.

戻り値

Page[ApiKeyRequestResource], a dict with items, hasMore and nextCursor. Each item has id, keyId, keyName, requestId, method, path, status, errorCode, durationMs, ip, userAgent and createdAt.

例

from openemail import openemail page = openemail.keys.list_requests('4c1b257a66287fd113bd89d0', failed_only=True, limit=50) for call in page['items']:    print(call['createdAt'], call['method'], call['path'], call['status'], call['errorCode'])

注意事項

  • The cursor is opaque and stays valid under the same filters. One this log did not hand out is a 400 invalid_cursor.

ほかの提供先

API
GET /keys/{id}/requests
TypeScript
keys.listRequests()
Ruby
keys.list_requests
CLI
openemail keys list-requests

keys.list_all_requests()

Collect one key's whole request log into one list

スコープkeys:read結果をページ単位で取得
シグネチャ
def list_all_requests(    id: str,    *,    limit: int | None = None,    cursor: str | None = None,    since: datetime | str | None = None,    until: datetime | str | None = None,    failed_only: bool | None = None,    api_key: str | None = None,    timeout: float | None = None,) -> builtins.list[ApiKeyRequestResource]

Walks every page of list_requests under the same filters and returns every call in one list. The log is never pruned, so give it a window unless you mean to read a busy key's whole history, or use iterate_requests to stop early.

パラメーター

idstr必須

Key id, the 24 hex characters after oe_live_.

limitint

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

cursorstr

Starts the walk from this cursor instead of the newest row.

sincedatetime | str

Only rows at or after this instant. A datetime is sent as ISO 8601 in UTC, and a string must already be one.

untildatetime | str

Only rows before this instant. It has to be later than since, or the server answers 400 invalid_parameter.

failed_onlybool

Only calls answered with a status of 400 or more.

api_keystr

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

timeoutfloat

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.

戻り値

list[ApiKeyRequestResource], newest first.

例

from datetime import datetime, timedelta, timezone from openemail import openemail today = openemail.keys.list_all_requests(    '4c1b257a66287fd113bd89d0',    since=datetime.now(timezone.utc) - timedelta(days=1),    limit=100,) print(len(today), 'calls in the last 24 hours')

注意事項

  • If any page fails, the call raises and the rows already fetched are discarded.

ほかの提供先

API
GET /keys/{id}/requests
TypeScript
keys.listAllRequests()
Ruby
keys.list_all_requests

keys.iterate_requests()

Stream one key's request log one call at a time

スコープkeys:read結果をページ単位で取得
シグネチャ
def iterate_requests(    id: str,    *,    limit: int | None = None,    cursor: str | None = None,    since: datetime | str | None = None,    until: datetime | str | None = None,    failed_only: bool | None = None,    api_key: str | None = None,    timeout: float | None = None,) -> Iterator[ApiKeyRequestResource]

A generator over list_requests under the same filters, fetching a page only when the one before is drained. Nothing is requested until you start iterating, and breaking out of the loop stops the requests.

パラメーター

idstr必須

Key id, the 24 hex characters after oe_live_.

limitint

Page size per request, 1 to 100. The server defaults to 25.

cursorstr

Starts the walk from this cursor instead of the newest row.

sincedatetime | str

Only rows at or after this instant. A datetime is sent as ISO 8601 in UTC, and a string must already be one.

untildatetime | str

Only rows before this instant. It has to be later than since, or the server answers 400 invalid_parameter.

failed_onlybool

Only calls answered with a status of 400 or more.

api_keystr

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

timeoutfloat

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.

戻り値

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

例

from openemail import openemail for call in openemail.keys.iterate_requests('4c1b257a66287fd113bd89d0', failed_only=True):    if call['errorCode'] == 'from_address_forbidden':        print('First refused send at', call['createdAt'])        break

ほかの提供先

API
GET /keys/{id}/requests
TypeScript
keys.iterateRequests()
Ruby
keys.iterate_requests

keys.list_activity()

List one page of what happened to one key

スコープkeys:read結果をページ単位で取得
シグネチャ
def list_activity(    id: str,    *,    limit: int | None = None,    cursor: str | None = None,    since: datetime | str | None = None,    until: datetime | str | None = None,    api_key: str | None = None,    timeout: float | None = None,) -> Page[ApiKeyActivityResource]

Returns one page of one key's audit log, newest first, the Activity tab of the key in the app. Every change to a key is a row: created, updated, rotated, deactivated, reactivated, revoked and deleted, plus auth_failed for every call that presented the key and was refused. actor names who made the change, a person as @username or a key as API key <name> in label, and detail['source'] says where it came from: console, api, mcp or documentation.

A deleted key keeps its history, readable to a key that is not narrowed. A key narrowed to some domains or addresses only sees the keys whose send scope sits inside its own, so any other is a 404 rather than a refusal. Over OAuth only the workspace owner reaches it, and a member's token is 403 owner_only.

パラメーター

idstr必須

Key id, the 24 hex characters after oe_live_.

limitint

Rows per page, a whole number from 1 to 100. The server defaults to 25.

cursorstr

The nextCursor from the previous page, passed back unchanged. Never build one yourself.

sincedatetime | str

Only rows at or after this instant. A datetime is sent as ISO 8601 in UTC, and a string must already be one.

untildatetime | str

Only rows before this instant. It has to be later than since, or the server answers 400 invalid_parameter.

api_keystr

Overrides the client API key for this call only.

timeoutfloat

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.

戻り値

Page[ApiKeyActivityResource], a dict with items, hasMore and nextCursor. Each item has id, keyId, keyName, type, createdAt, actor and detail.

例

from openemail import openemail page = openemail.keys.list_activity('4c1b257a66287fd113bd89d0') for change in page['items']:    actor = change['actor']['label'] if change['actor'] else 'unknown'     print(change['createdAt'], change['type'], actor, change['detail'].get('source'))

ほかの提供先

API
GET /keys/{id}/activity
TypeScript
keys.listActivity()
Ruby
keys.list_activity
CLI
openemail keys list-activity

keys.list_all_activity()

Collect one key's whole audit log into one list

スコープkeys:read結果をページ単位で取得
シグネチャ
def list_all_activity(    id: str,    *,    limit: int | None = None,    cursor: str | None = None,    since: datetime | str | None = None,    until: datetime | str | None = None,    api_key: str | None = None,    timeout: float | None = None,) -> builtins.list[ApiKeyActivityResource]

Walks every page of list_activity under the same window and returns every change in one list, newest first.

パラメーター

idstr必須

Key id, the 24 hex characters after oe_live_.

limitint

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

cursorstr

Starts the walk from this cursor instead of the newest row.

sincedatetime | str

Only rows at or after this instant. A datetime is sent as ISO 8601 in UTC, and a string must already be one.

untildatetime | str

Only rows before this instant. It has to be later than since, or the server answers 400 invalid_parameter.

api_keystr

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

timeoutfloat

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.

戻り値

list[ApiKeyActivityResource], newest first.

例

from openemail import openemail history = openemail.keys.list_all_activity('4c1b257a66287fd113bd89d0') refused = [change for change in history if change['type'] == 'auth_failed'] print(len(refused), 'refused attempts')

注意事項

  • If any page fails, the call raises and the rows already fetched are discarded.

ほかの提供先

API
GET /keys/{id}/activity
TypeScript
keys.listAllActivity()
Ruby
keys.list_all_activity

keys.iterate_activity()

Stream one key's audit log one change at a time

スコープkeys:read結果をページ単位で取得
シグネチャ
def iterate_activity(    id: str,    *,    limit: int | None = None,    cursor: str | None = None,    since: datetime | str | None = None,    until: datetime | str | None = None,    api_key: str | None = None,    timeout: float | None = None,) -> Iterator[ApiKeyActivityResource]

A generator over list_activity under the same window, fetching a page only when the one before is drained. Nothing is requested until you start iterating, and breaking out of the loop stops the requests.

パラメーター

idstr必須

Key id, the 24 hex characters after oe_live_.

limitint

Page size per request, 1 to 100. The server defaults to 25.

cursorstr

Starts the walk from this cursor instead of the newest row.

sincedatetime | str

Only rows at or after this instant. A datetime is sent as ISO 8601 in UTC, and a string must already be one.

untildatetime | str

Only rows before this instant. It has to be later than since, or the server answers 400 invalid_parameter.

api_keystr

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

timeoutfloat

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.

戻り値

Iterator[ApiKeyActivityResource], a generator yielding one change per step.

例

from openemail import openemail for change in openemail.keys.iterate_activity('4c1b257a66287fd113bd89d0'):    if change['type'] == 'rotated':        actor = change['actor']['label'] if change['actor'] else 'unknown'         print('Last rotated by', actor, 'at', change['createdAt'])        break

ほかの提供先

API
GET /keys/{id}/activity
TypeScript
keys.iterateActivity()
Ruby
keys.iterate_activity

keys.list_workspace_requests()

List one page of the request log of every key

スコープkeys:read結果をページ単位で取得
シグネチャ
def list_workspace_requests(    *,    limit: int | None = None,    cursor: str | None = None,    since: datetime | str | None = None,    until: datetime | str | None = None,    failed_only: bool | None = None,    key_ids: Sequence[str] | None = None,    api_key: str | None = None,    timeout: float | None = None,) -> Page[ApiKeyRequestResource]

Returns one page of every call the workspace's keys made, newest first, the Requests tab of Settings, API keys. The request log records every authenticated call a key made: method, path, status, error code, duration, IP and user agent, and never a body or a query string. A call refused before a key could be identified is not in it, and neither is a call made with an OAuth access token. Nothing is pruned, so the log reaches back to a key's first call. key_ids=, failed_only=, since= and until= are the filters the app offers, and key_ids= may name a deleted key.

A narrowed key reads only the log of the keys it can see, so naming another key in key_ids= matches nothing.

パラメーター

limitint

Rows per page, a whole number from 1 to 100. The server defaults to 25.

cursorstr

The nextCursor from the previous page, passed back unchanged. Never build one yourself.

sincedatetime | str

Only rows at or after this instant. A datetime is sent as ISO 8601 in UTC, and a string must already be one.

untildatetime | str

Only rows before this instant. It has to be later than since, or the server answers 400 invalid_parameter.

failed_onlybool

Only calls answered with a status of 400 or more.

key_idsSequence[str]

Key ids to read, at most 50, sent comma-separated. Left out, every key the caller can see.

api_keystr

Overrides the client API key for this call only.

timeoutfloat

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.

戻り値

Page[ApiKeyRequestResource], a dict with items, hasMore and nextCursor. Each item has id, keyId, keyName, requestId, method, path, status, errorCode, durationMs, ip, userAgent and createdAt.

例

from openemail import openemail page = openemail.keys.list_workspace_requests(failed_only=True, since='2026-09-22T00:00:00Z') for call in page['items']:    print(call['keyName'], call['method'], call['path'], call['status'])

ほかの提供先

API
GET /keys/requests
TypeScript
keys.listWorkspaceRequests()
Ruby
keys.list_workspace_requests
CLI
openemail keys list-workspace-requests

keys.list_all_workspace_requests()

Collect the request log of every key into one list

スコープkeys:read結果をページ単位で取得
シグネチャ
def list_all_workspace_requests(    *,    limit: int | None = None,    cursor: str | None = None,    since: datetime | str | None = None,    until: datetime | str | None = None,    failed_only: bool | None = None,    key_ids: Sequence[str] | None = None,    api_key: str | None = None,    timeout: float | None = None,) -> builtins.list[ApiKeyRequestResource]

Walks every page of list_workspace_requests under the same filters and returns every call in one list. The log is never pruned, so give it a window, or use iterate_workspace_requests to stop early.

パラメーター

limitint

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

cursorstr

Starts the walk from this cursor instead of the newest row.

sincedatetime | str

Only rows at or after this instant. A datetime is sent as ISO 8601 in UTC, and a string must already be one.

untildatetime | str

Only rows before this instant. It has to be later than since, or the server answers 400 invalid_parameter.

failed_onlybool

Only calls answered with a status of 400 or more.

key_idsSequence[str]

Key ids to read, at most 50, sent comma-separated. Left out, every key the caller can see.

api_keystr

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

timeoutfloat

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.

戻り値

list[ApiKeyRequestResource], newest first.

例

from datetime import datetime, timedelta, timezone from openemail import openemail failures = openemail.keys.list_all_workspace_requests(    failed_only=True,    since=datetime.now(timezone.utc) - timedelta(hours=1),    limit=100,) print(len(failures), 'failed calls in the last hour')

注意事項

  • If any page fails, the call raises and the rows already fetched are discarded.

ほかの提供先

API
GET /keys/requests
TypeScript
keys.listAllWorkspaceRequests()
Ruby
keys.list_all_workspace_requests

keys.iterate_workspace_requests()

Stream the request log of every key one call at a time

スコープkeys:read結果をページ単位で取得
シグネチャ
def iterate_workspace_requests(    *,    limit: int | None = None,    cursor: str | None = None,    since: datetime | str | None = None,    until: datetime | str | None = None,    failed_only: bool | None = None,    key_ids: Sequence[str] | None = None,    api_key: str | None = None,    timeout: float | None = None,) -> Iterator[ApiKeyRequestResource]

A generator over list_workspace_requests under the same filters, fetching a page only when the one before is drained. Nothing is requested until you start iterating, and breaking out of the loop stops the requests.

パラメーター

limitint

Page size per request, 1 to 100. The server defaults to 25.

cursorstr

Starts the walk from this cursor instead of the newest row.

sincedatetime | str

Only rows at or after this instant. A datetime is sent as ISO 8601 in UTC, and a string must already be one.

untildatetime | str

Only rows before this instant. It has to be later than since, or the server answers 400 invalid_parameter.

failed_onlybool

Only calls answered with a status of 400 or more.

key_idsSequence[str]

Key ids to read, at most 50, sent comma-separated. Left out, every key the caller can see.

api_keystr

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

timeoutfloat

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.

戻り値

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

例

from openemail import openemail for call in openemail.keys.iterate_workspace_requests(failed_only=True):    if call['status'] >= 500:        print(call['requestId'], call['keyName'], call['path'])

ほかの提供先

API
GET /keys/requests
TypeScript
keys.iterateWorkspaceRequests()
Ruby
keys.iterate_workspace_requests

keys.list_workspace_activity()

List one page of what happened to every key

スコープkeys:read結果をページ単位で取得
シグネチャ
def list_workspace_activity(    *,    limit: int | None = None,    cursor: str | None = None,    since: datetime | str | None = None,    until: datetime | str | None = None,    key_ids: Sequence[str] | None = None,    api_key: str | None = None,    timeout: float | None = None,) -> Page[ApiKeyActivityResource]

Returns one page of the audit log of every key in the workspace, newest first, the Activity tab of Settings, API keys. Every change to a key is a row: created, updated, rotated, deactivated, reactivated, revoked and deleted, plus auth_failed for every call that presented the key and was refused. actor names who made the change, a person as @username or a key as API key <name> in label, and detail['source'] says where it came from: console, api, mcp or documentation.

key_ids= narrows it, deleted keys included, and since= and until= keep a window. A narrowed key reads only the activity of the keys it can see.

パラメーター

limitint

Rows per page, a whole number from 1 to 100. The server defaults to 25.

cursorstr

The nextCursor from the previous page, passed back unchanged. Never build one yourself.

sincedatetime | str

Only rows at or after this instant. A datetime is sent as ISO 8601 in UTC, and a string must already be one.

untildatetime | str

Only rows before this instant. It has to be later than since, or the server answers 400 invalid_parameter.

key_idsSequence[str]

Key ids to read, at most 50, sent comma-separated. Left out, every key the caller can see.

api_keystr

Overrides the client API key for this call only.

timeoutfloat

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.

戻り値

Page[ApiKeyActivityResource], a dict with items, hasMore and nextCursor. Each item has id, keyId, keyName, type, createdAt, actor and detail.

例

from openemail import openemail page = openemail.keys.list_workspace_activity(since='2026-09-01T00:00:00Z') for change in page['items']:    actor = change['actor']['label'] if change['actor'] else 'unknown'     print(change['keyName'], change['type'], actor)

ほかの提供先

API
GET /keys/activity
TypeScript
keys.listWorkspaceActivity()
Ruby
keys.list_workspace_activity
CLI
openemail keys list-workspace-activity

keys.list_all_workspace_activity()

Collect the audit log of every key into one list

スコープkeys:read結果をページ単位で取得
シグネチャ
def list_all_workspace_activity(    *,    limit: int | None = None,    cursor: str | None = None,    since: datetime | str | None = None,    until: datetime | str | None = None,    key_ids: Sequence[str] | None = None,    api_key: str | None = None,    timeout: float | None = None,) -> builtins.list[ApiKeyActivityResource]

Walks every page of list_workspace_activity under the same filters and returns every change in one list, newest first.

パラメーター

limitint

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

cursorstr

Starts the walk from this cursor instead of the newest row.

sincedatetime | str

Only rows at or after this instant. A datetime is sent as ISO 8601 in UTC, and a string must already be one.

untildatetime | str

Only rows before this instant. It has to be later than since, or the server answers 400 invalid_parameter.

key_idsSequence[str]

Key ids to read, at most 50, sent comma-separated. Left out, every key the caller can see.

api_keystr

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

timeoutfloat

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.

戻り値

list[ApiKeyActivityResource], newest first.

例

from datetime import datetime, timezone from openemail import openemail changes = openemail.keys.list_all_workspace_activity(    since=datetime(2026, 9, 1, tzinfo=timezone.utc)) over_api = [change for change in changes if change['detail'].get('source') == 'api'] print(len(over_api), 'changes made over the API')

注意事項

  • If any page fails, the call raises and the rows already fetched are discarded.

ほかの提供先

API
GET /keys/activity
TypeScript
keys.listAllWorkspaceActivity()
Ruby
keys.list_all_workspace_activity

keys.iterate_workspace_activity()

Stream the audit log of every key one change at a time

スコープkeys:read結果をページ単位で取得
シグネチャ
def iterate_workspace_activity(    *,    limit: int | None = None,    cursor: str | None = None,    since: datetime | str | None = None,    until: datetime | str | None = None,    key_ids: Sequence[str] | None = None,    api_key: str | None = None,    timeout: float | None = None,) -> Iterator[ApiKeyActivityResource]

A generator over list_workspace_activity under the same filters, fetching a page only when the one before is drained. Nothing is requested until you start iterating, and breaking out of the loop stops the requests.

パラメーター

limitint

Page size per request, 1 to 100. The server defaults to 25.

cursorstr

Starts the walk from this cursor instead of the newest row.

sincedatetime | str

Only rows at or after this instant. A datetime is sent as ISO 8601 in UTC, and a string must already be one.

untildatetime | str

Only rows before this instant. It has to be later than since, or the server answers 400 invalid_parameter.

key_idsSequence[str]

Key ids to read, at most 50, sent comma-separated. Left out, every key the caller can see.

api_keystr

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

timeoutfloat

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.

戻り値

Iterator[ApiKeyActivityResource], a generator yielding one change per step.

例

from openemail import openemail for change in openemail.keys.iterate_workspace_activity(    key_ids=['4c1b257a66287fd113bd89d0', '9e0f6b2c1d7a3e584b2c6f10']):    if change['type'] == 'auth_failed':        print(change['keyName'], change['detail'].get('reason'), change['createdAt'])

ほかの提供先

API
GET /keys/activity
TypeScript
keys.iterateWorkspaceActivity()
Ruby
keys.iterate_workspace_activity

keys.stats()

Read what the keys did inside a window

スコープkeys:reademails:read
シグネチャ
def stats(    *,    since: datetime | str | None = None,    until: datetime | str | None = None,    key_ids: Sequence[str] | None = None,    grain: TrackingGrain | None = None,    offset_minutes: int | None = None,    api_key: str | None = None,    timeout: float | None = None,) -> ApiKeyStatsResource

Returns the numbers behind the Analytics tab of the API keys page: the mail the keys sent and what became of it, the calls refused because a secret was wrong, revoked or expired, the requests they made and how many failed, the routes they called most with the median time each took, and the status codes they got back.

It covers every key you can see, or the ones key_ids= names. The window runs from since= to until=, and left out it is the 30 days before now. grain= sets the bucket width of the series and offset_minutes= shifts the boundaries so days break where the reader's day does.

パラメーター

sincedatetime | str

The start of the window, a datetime or an ISO 8601 instant. Defaults to 30 days before until.

untildatetime | str

The end of the window, not included. Defaults to now.

key_idsSequence[str]

Only these keys, at most 50. Left out, every key you can see.

grainTrackingGrain

Bucket width: 'minute', 'hour' or 'day', defaulting to 'day'.

offset_minutesint

Minutes east of UTC to bucket in, from -840 to 840, defaulting to 0.

api_keystr

Overrides the client API key for this call only.

timeoutfloat

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.

戻り値

ApiKeyStatsResource with the window it covered, sends, rejected, requests, routes and codes.

例

from openemail import openemail stats = openemail.keys.stats(grain='day', offset_minutes=60) print(stats['sends']['totals']['sends'], 'sent since', stats['since']) for route in stats['routes'][:3]:    print(route['label'], route['count'], route['medianMs'])

注意事項

  • A key narrowed to some domains or addresses only counts the keys whose send scope sits inside its own, and an access token is refused with 403 owner_only unless it acts for the owner of the workspace.

  • The series are sparse: a bucket with nothing in it has no entry, so a chart must fill the gaps.

  • Retried automatically on network failure, since it only reads.

ほかの提供先

API
GET /keys/stats
TypeScript
keys.stats()
Ruby
keys.stats
CLI
openemail keys stats