문서로 건너뛰기
C#

client.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.ListAsync

List one page of the workspace's API keys

범위keys:read결과를 페이지 단위로 가져옴
시그니처
Task<Page> ListAsync(    int? limit = null,    string? cursor = null,    string? apiKey = null,    CancellationToken cancellationToken = default)

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.

cursorstring?

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

apiKeystring?

Overrides the client API key for this call only.

cancellationTokenCancellationToken

Cancels the request.

반환값

A Page with items, hasMore and nextCursor. Each item has 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.

예시

var page = await client.Keys.ListAsync(); foreach (var key in page){    Console.WriteLine($"{key["maskedKey"]} {key["name"]} {key["status"]}, last used {key["lastUsedAt"]?.ToString() ?? "never"}");}

참고

  • 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()
Python
keys.list()
Ruby
keys.list
PHP
keys->list
Go
Keys.List
Java
keys().list
CLI
openemail keys list

Keys.ListAllAsync

Collect every API key into one object

범위keys:read결과를 페이지 단위로 가져옴
시그니처
Task<IReadOnlyList<JsonObject>> ListAllAsync(    int? limit = null,    string? cursor = null,    string? apiKey = null,    CancellationToken cancellationToken = default)

Walks every page of ListAsync and returns every key the caller can see, newest first.

매개변수

limitint?

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

cursorstring?

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

apiKeystring?

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

cancellationTokenCancellationToken

Cancels the request.

반환값

A list of JsonObject items, one per key with the fields ListAsync returns, newest first.

예시

var keys = await client.Keys.ListAllAsync(); Console.WriteLine(keys.Count);

다른 사용처

API
GET /keys
TypeScript
keys.listAll()
Python
keys.list_all()
Ruby
keys.list_all
PHP
keys->listAll
Go
Keys.ListAll
Java
keys().listAll

Keys.IterateAsync

Stream the workspace's API keys one at a time

범위keys:read결과를 페이지 단위로 가져옴
시그니처
IAsyncEnumerable<JsonObject> IterateAsync(    int? limit = null,    string? cursor = null,    string? apiKey = null,    CancellationToken cancellationToken = default)

An IAsyncEnumerable<JsonObject> over ListAsync, fetching a page only when the one before is drained.

매개변수

limitint?

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

cursorstring?

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

apiKeystring?

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

cancellationTokenCancellationToken

Cancels the request.

반환값

An IAsyncEnumerable<JsonObject> that yields one key per step.

예시

var weekFromNow = DateTimeOffset.UtcNow.AddDays(7); await foreach (var key in client.Keys.IterateAsync()){    if ((string?)key["expiresAt"] is { } expiresAt && DateTimeOffset.Parse(expiresAt) < weekFromNow)    {        Console.WriteLine($"{key["name"]} expires {expiresAt}");    }}

다른 사용처

API
GET /keys
TypeScript
keys.iterate()
Python
keys.iterate()
Ruby
keys.iterate
PHP
keys->iterate
Go
Keys.Iterate
Java
keys().iterate

Keys.GetAsync

Read one API key, without its secret

범위keys:read
시그니처
Task<JsonObject> GetAsync(    string id,    string? apiKey = null,    CancellationToken cancellationToken = default)

Returns one key as ListAsync 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. Over OAuth only the workspace owner reaches it, and a member's token is 403 owner_only.

client.Me.GetAsync() describes the calling key itself and needs no scope; this reads any key the caller can see.

매개변수

idstring필수

Key id, the 24 hex characters after oe_live_.

apiKeystring?

Overrides the client API key for this call only.

cancellationTokenCancellationToken

Cancels the request.

반환값

A JsonObject with 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.

예시

var key = await client.Keys.GetAsync("4c1b257a66287fd113bd89d0"); Console.WriteLine($"{key["name"]} is {key["status"]}");Console.WriteLine($"Scopes: {string.Join(", ", key["scopes"]?.AsArray() ?? [])}");

다른 사용처

API
GET /keys/{id}
TypeScript
keys.get()
Python
keys.get()
Ruby
keys.get
PHP
keys->get
Go
Keys.Get
Java
keys().get
CLI
openemail keys get

Keys.CreateAsync

Mint a new API key and receive its secret once

범위keys:manage
시그니처
Task<JsonObject> CreateAsync(    IReadOnlyDictionary<string, object?> body,    string? apiKey = null,    CancellationToken cancellationToken = default)

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 new[] { "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 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.

매개변수

namestring필수

A name, 1 to 60 characters.

scopeslist

The scopes the key holds, at least one, each held by the caller, as in OpenEmail\Constants\ApiScopes. Defaults to new[] { "emails:send" }.

roleIdstring

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

addressAllowlistIEnumerable<string>

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

domainAllowlistIEnumerable<string>

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.

expiresInMinutesint

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

apiKeystring?

Overrides the client API key for this call only.

cancellationTokenCancellationToken

Cancels the request.

반환값

A JsonObject with every field GetAsync returns: 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, none of them a secret. Plus token, oe_live_ followed by the id, an underscore and the secret.

예시

using OpenEmail.Constants; var key = await client.Keys.CreateAsync(new Body{    ["name"] = "Billing sender",    ["scopes"] = new[] { ApiScopes.EmailsSend, ApiScopes.EmailsRead },    ["domainAllowlist"] = new[] { "billing.acme.com" },    ["expiresInMinutes"] = 60 * 24 * 90,}); await File.WriteAllTextAsync(".openemail-billing-key", (string?)key["token"]); Console.WriteLine($"Made {key["maskedKey"]}, expiring {key["expiresAt"]}");

참고

  • 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 source set to api.

  • The success status is 201.

다른 사용처

API
POST /keys
TypeScript
keys.create()
Python
keys.create()
Ruby
keys.create
PHP
keys->create
Go
Keys.Create
Java
keys().create
CLI
openemail keys create

Keys.UpdateAsync

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

범위keys:manage
시그니처
Task<JsonObject> UpdateAsync(    string id,    IReadOnlyDictionary<string, object?> patch,    string? apiKey = null,    CancellationToken cancellationToken = default)

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

매개변수

idstring필수

Key id, the 24 hex characters after oe_live_.

namestring

A new name, 1 to 60 characters.

scopeslist

The whole new list of scopes, at least one.

addressAllowlistIEnumerable<string>

The whole new list of single addresses.

domainAllowlistIEnumerable<string>

The whole new list of whole domains.

enabledbool

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

apiKeystring?

Overrides the client API key for this call only.

cancellationTokenCancellationToken

Cancels the request.

반환값

A JsonObject with 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.

예시

await client.Keys.UpdateAsync("4c1b257a66287fd113bd89d0", new Body { ["enabled"] = false }); var key = await client.Keys.UpdateAsync("4c1b257a66287fd113bd89d0", new Body { ["name"] = "Billing sender (paused)" }); Console.WriteLine($"{key["name"]} {key["status"]}");

참고

  • An empty patch is a 422. A PATCH is retried on network failure because applying the same patch twice leaves the same key.

다른 사용처

API
PATCH /keys/{id}
TypeScript
keys.update()
Python
keys.update()
Ruby
keys.update
PHP
keys->update
Go
Keys.Update
Java
keys().update
CLI
openemail keys update

Keys.DeleteAsync

Remove a revoked key from the list

범위keys:manage
시그니처
Task<JsonObject> DeleteAsync(    string id,    string? apiKey = null,    CancellationToken cancellationToken = default)

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 param names the axis.

매개변수

idstring필수

Key id, the 24 hex characters after oe_live_.

apiKeystring?

Overrides the client API key for this call only.

cancellationTokenCancellationToken

Cancels the request.

반환값

A JsonObject with object set to api_key, the id, and deleted set to true.

예시

await client.Keys.RevokeAsync("4c1b257a66287fd113bd89d0", body: new Body { ["reason"] = "Leaked in a build log" }); var deleted = await client.Keys.DeleteAsync("4c1b257a66287fd113bd89d0"); Console.WriteLine($"{deleted["id"]} is off the list");

다른 사용처

API
DELETE /keys/{id}
TypeScript
keys.delete()
Python
keys.delete()
Ruby
keys.delete
PHP
keys->delete
Go
Keys.Delete
Java
keys().delete
CLI
openemail keys delete

Keys.RotateAsync

Give a key a new secret and receive it once

범위keys:manage
시그니처
Task<JsonObject> RotateAsync(    string id,    string? apiKey = null,    CancellationToken cancellationToken = default)

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 client.Me.RotateAsync() 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 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.

매개변수

idstring필수

Key id, the 24 hex characters after oe_live_.

apiKeystring?

Overrides the client API key for this call only.

cancellationTokenCancellationToken

Cancels the request.

반환값

A JsonObject with every field GetAsync returns: 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, none of them a secret. Plus token, rotationCount and rotatedAt.

예시

var rotated = await client.Keys.RotateAsync("4c1b257a66287fd113bd89d0"); await File.WriteAllTextAsync(".openemail-billing-key", (string?)rotated["token"]); Console.WriteLine($"Rotation {rotated["rotationCount"]} at {rotated["rotatedAt"]}");

참고

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

다른 사용처

API
POST /keys/{id}/rotate
TypeScript
keys.rotate()
Python
keys.rotate()
Ruby
keys.rotate
PHP
keys->rotate
Go
Keys.Rotate
Java
keys().rotate
CLI
openemail keys rotate

Keys.RevokeAsync

Revoke a key for good

범위keys:manage
시그니처
Task<JsonObject> RevokeAsync(    string id,    IReadOnlyDictionary<string, object?>? body = null,    string? apiKey = null,    CancellationToken cancellationToken = default)

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

매개변수

idstring필수

Key id, the 24 hex characters after oe_live_.

reasonstring

Why, at most 200 characters.

apiKeystring?

Overrides the client API key for this call only.

cancellationTokenCancellationToken

Cancels the request.

반환값

A JsonObject with 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.

예시

var key = await client.Keys.RevokeAsync("4c1b257a66287fd113bd89d0", body: new Body { ["reason"] = "Contractor offboarded" }); Console.WriteLine($"{key["status"]} at {key["revokedAt"]}");

참고

  • Retried on network failure, because revoking twice leaves the same key. Prefer UpdateAsync(id, new Body { ["enabled"] = false }) while you find out whether anything still depends on a key.

다른 사용처

API
POST /keys/{id}/revoke
TypeScript
keys.revoke()
Python
keys.revoke()
Ruby
keys.revoke
PHP
keys->revoke
Go
Keys.Revoke
Java
keys().revoke
CLI
openemail keys revoke

Keys.ListRequestsAsync

List one page of one key's request log

범위keys:read결과를 페이지 단위로 가져옴
시그니처
Task<Page> ListRequestsAsync(    string id,    bool? failedOnly = null,    IEnumerable<int>? statuses = null,    string? path = null,    DateTimeOffset? since = null,    DateTimeOffset? until = null,    int? limit = null,    string? cursor = null,    string? apiKey = null,    CancellationToken cancellationToken = default)

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. failedOnly:, statuses:, path:, since: and until: narrow it, and they combine.

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.

매개변수

idstring필수

Key id, the 24 hex characters after oe_live_.

failedOnlybool?

Only calls answered with a status of 400 or more.

statusesIEnumerable<int>?

Only calls answered with one of these HTTP status codes, such as new[] { 401, 403 }. At most 20, each from 100 to 599, sent comma-separated as status.

pathstring?

Only calls to this route, whatever the method, such as /emails or /emails/:id. It matches the route, not the exact path: an id counts as :id and an email address as :address. End it with * to read every route that starts with it, such as /emails/*.

sinceDateTimeOffset?

Only rows at or after this instant. A DateTimeOffset, sent as ISO 8601 in UTC.

untilDateTimeOffset?

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

limitint?

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

cursorstring?

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

apiKeystring?

Overrides the client API key for this call only.

cancellationTokenCancellationToken

Cancels the request.

반환값

A Page with items, hasMore and nextCursor. Each item has id, keyId, keyName, requestId, method, path, status, durationMs, ip, userAgent and createdAt, plus the error code, read with call["errorCode"].

예시

var page = await client.Keys.ListRequestsAsync("4c1b257a66287fd113bd89d0", failedOnly: true, limit: 50); foreach (var call in page){    Console.WriteLine($"{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.

  • path: matches the route rather than the exact path, because the log folds ids and addresses: every call to /emails/<id> is the one route /emails/:id, and passing a real id reads that whole route. Each row still carries the exact path, so filter the page yourself to follow one id.

  • The key making the call reads its own log with no scope through Me.ListRequestsAsync.

다른 사용처

API
GET /keys/{id}/requests
TypeScript
keys.listRequests()
Python
keys.list_requests()
Ruby
keys.list_requests
PHP
keys->listRequests
Go
Keys.ListRequests
Java
keys().listRequests
CLI
openemail keys list-requests

Keys.ListAllRequestsAsync

Collect one key's whole request log into one object

범위keys:read결과를 페이지 단위로 가져옴
시그니처
Task<IReadOnlyList<JsonObject>> ListAllRequestsAsync(    string id,    bool? failedOnly = null,    IEnumerable<int>? statuses = null,    string? path = null,    DateTimeOffset? since = null,    DateTimeOffset? until = null,    int? limit = null,    string? cursor = null,    string? apiKey = null,    CancellationToken cancellationToken = default)

Walks every page of ListRequestsAsync under the same filters. The log is never pruned, so give it a window unless you mean to read a busy key's whole history, or use IterateRequestsAsync to stop early.

매개변수

idstring필수

Key id, the 24 hex characters after oe_live_.

failedOnlybool?

Only calls answered with a status of 400 or more.

statusesIEnumerable<int>?

Only calls answered with one of these HTTP status codes, such as new[] { 401, 403 }. At most 20, each from 100 to 599, sent comma-separated as status.

pathstring?

Only calls to this route, whatever the method, such as /emails or /emails/:id. It matches the route, not the exact path: an id counts as :id and an email address as :address. End it with * to read every route that starts with it, such as /emails/*.

sinceDateTimeOffset?

Only rows at or after this instant. A DateTimeOffset, sent as ISO 8601 in UTC.

untilDateTimeOffset?

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

limitint?

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

cursorstring?

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

apiKeystring?

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

cancellationTokenCancellationToken

Cancels the request.

반환값

A list of JsonObject items, one per call with the fields ListRequestsAsync returns, newest first.

예시

var today = await client.Keys.ListAllRequestsAsync("4c1b257a66287fd113bd89d0", since: DateTimeOffset.UtcNow.AddDays(-1), limit: 100); Console.WriteLine(today.Count);

참고

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

다른 사용처

API
GET /keys/{id}/requests
TypeScript
keys.listAllRequests()
Python
keys.list_all_requests()
Ruby
keys.list_all_requests
PHP
keys->listAllRequests
Go
Keys.ListAllRequests
Java
keys().listAllRequests

Keys.IterateRequestsAsync

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

범위keys:read결과를 페이지 단위로 가져옴
시그니처
IAsyncEnumerable<JsonObject> IterateRequestsAsync(    string id,    bool? failedOnly = null,    IEnumerable<int>? statuses = null,    string? path = null,    DateTimeOffset? since = null,    DateTimeOffset? until = null,    int? limit = null,    string? cursor = null,    string? apiKey = null,    CancellationToken cancellationToken = default)

An IAsyncEnumerable<JsonObject> over ListRequestsAsync under the same filters, fetching a page only when the one before is drained.

매개변수

idstring필수

Key id, the 24 hex characters after oe_live_.

failedOnlybool?

Only calls answered with a status of 400 or more.

statusesIEnumerable<int>?

Only calls answered with one of these HTTP status codes, such as new[] { 401, 403 }. At most 20, each from 100 to 599, sent comma-separated as status.

pathstring?

Only calls to this route, whatever the method, such as /emails or /emails/:id. It matches the route, not the exact path: an id counts as :id and an email address as :address. End it with * to read every route that starts with it, such as /emails/*.

sinceDateTimeOffset?

Only rows at or after this instant. A DateTimeOffset, sent as ISO 8601 in UTC.

untilDateTimeOffset?

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

limitint?

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

cursorstring?

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

apiKeystring?

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

cancellationTokenCancellationToken

Cancels the request.

반환값

An IAsyncEnumerable<JsonObject> that yields one call per step.

예시

await foreach (var call in client.Keys.IterateRequestsAsync("4c1b257a66287fd113bd89d0", failedOnly: true)){    if ((string?)call["errorCode"] == "from_address_forbidden")    {        Console.WriteLine($"Latest refused send at {call["createdAt"]}");         break;    }}

다른 사용처

API
GET /keys/{id}/requests
TypeScript
keys.iterateRequests()
Python
keys.iterate_requests()
Ruby
keys.iterate_requests
PHP
keys->iterateRequests
Go
Keys.IterateRequests
Java
keys().iterateRequests

Keys.ListActivityAsync

List one page of what happened to one key

범위keys:read결과를 페이지 단위로 가져옴
시그니처
Task<Page> ListActivityAsync(    string id,    DateTimeOffset? since = null,    DateTimeOffset? until = null,    int? limit = null,    string? cursor = null,    string? apiKey = null,    CancellationToken cancellationToken = default)

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.

매개변수

idstring필수

Key id, the 24 hex characters after oe_live_.

sinceDateTimeOffset?

Only rows at or after this instant. A DateTimeOffset, sent as ISO 8601 in UTC.

untilDateTimeOffset?

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

limitint?

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

cursorstring?

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

apiKeystring?

Overrides the client API key for this call only.

cancellationTokenCancellationToken

Cancels the request.

반환값

A Page with items, hasMore and nextCursor. Each item has id, keyId, keyName, type, createdAt, actor and detail.

예시

var page = await client.Keys.ListActivityAsync("4c1b257a66287fd113bd89d0"); foreach (var change in page){    Console.WriteLine($"{change["createdAt"]} {change["type"]} by {change["actor"]?["label"]} from {change["detail"]?["source"]?.ToString() ?? "unknown"}");}

다른 사용처

API
GET /keys/{id}/activity
TypeScript
keys.listActivity()
Python
keys.list_activity()
Ruby
keys.list_activity
PHP
keys->listActivity
Go
Keys.ListActivity
Java
keys().listActivity
CLI
openemail keys list-activity

Keys.ListAllActivityAsync

Collect one key's whole audit log into one object

범위keys:read결과를 페이지 단위로 가져옴
시그니처
Task<IReadOnlyList<JsonObject>> ListAllActivityAsync(    string id,    DateTimeOffset? since = null,    DateTimeOffset? until = null,    int? limit = null,    string? cursor = null,    string? apiKey = null,    CancellationToken cancellationToken = default)

Walks every page of ListActivityAsync under the same window and returns every change, newest first.

매개변수

idstring필수

Key id, the 24 hex characters after oe_live_.

sinceDateTimeOffset?

Only rows at or after this instant. A DateTimeOffset, sent as ISO 8601 in UTC.

untilDateTimeOffset?

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

limitint?

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

cursorstring?

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

apiKeystring?

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

cancellationTokenCancellationToken

Cancels the request.

반환값

A list of JsonObject items, one per change with the fields ListActivityAsync returns, newest first.

예시

var history = await client.Keys.ListAllActivityAsync("4c1b257a66287fd113bd89d0"); Console.WriteLine(history.Count);

참고

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

다른 사용처

API
GET /keys/{id}/activity
TypeScript
keys.listAllActivity()
Python
keys.list_all_activity()
Ruby
keys.list_all_activity
PHP
keys->listAllActivity
Go
Keys.ListAllActivity
Java
keys().listAllActivity

Keys.IterateActivityAsync

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

범위keys:read결과를 페이지 단위로 가져옴
시그니처
IAsyncEnumerable<JsonObject> IterateActivityAsync(    string id,    DateTimeOffset? since = null,    DateTimeOffset? until = null,    int? limit = null,    string? cursor = null,    string? apiKey = null,    CancellationToken cancellationToken = default)

An IAsyncEnumerable<JsonObject> over ListActivityAsync under the same window, fetching a page only when the one before is drained.

매개변수

idstring필수

Key id, the 24 hex characters after oe_live_.

sinceDateTimeOffset?

Only rows at or after this instant. A DateTimeOffset, sent as ISO 8601 in UTC.

untilDateTimeOffset?

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

limitint?

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

cursorstring?

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

apiKeystring?

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

cancellationTokenCancellationToken

Cancels the request.

반환값

An IAsyncEnumerable<JsonObject> that yields one change per step.

예시

await foreach (var change in client.Keys.IterateActivityAsync("4c1b257a66287fd113bd89d0")){    if ((string?)change["type"] == "rotated")    {        Console.WriteLine($"Last rotated by {change["actor"]?["label"]} at {change["createdAt"]}");         break;    }}

다른 사용처

API
GET /keys/{id}/activity
TypeScript
keys.iterateActivity()
Python
keys.iterate_activity()
Ruby
keys.iterate_activity
PHP
keys->iterateActivity
Go
Keys.IterateActivity
Java
keys().iterateActivity

Keys.ListWorkspaceRequestsAsync

List one page of the request log of every key

범위keys:read결과를 페이지 단위로 가져옴
시그니처
Task<Page> ListWorkspaceRequestsAsync(    IEnumerable<string>? keyIds = null,    bool? failedOnly = null,    IEnumerable<int>? statuses = null,    string? path = null,    DateTimeOffset? since = null,    DateTimeOffset? until = null,    int? limit = null,    string? cursor = null,    string? apiKey = null,    CancellationToken cancellationToken = default)

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. keyIds:, failedOnly:, statuses:, path:, since: and until: narrow it, and they combine. keyIds: may name a deleted key.

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

매개변수

keyIdsIEnumerable<string>?

Key ids to read, at most 50, as a dictionary or one comma-separated string, sent comma-separated. Left out, every key the caller can see.

failedOnlybool?

Only calls answered with a status of 400 or more.

statusesIEnumerable<int>?

Only calls answered with one of these HTTP status codes, such as new[] { 401, 403 }. At most 20, each from 100 to 599, sent comma-separated as status.

pathstring?

Only calls to this route, whatever the method, such as /emails or /emails/:id. It matches the route, not the exact path: an id counts as :id and an email address as :address. End it with * to read every route that starts with it, such as /emails/*.

sinceDateTimeOffset?

Only rows at or after this instant. A DateTimeOffset, sent as ISO 8601 in UTC.

untilDateTimeOffset?

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

limitint?

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

cursorstring?

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

apiKeystring?

Overrides the client API key for this call only.

cancellationTokenCancellationToken

Cancels the request.

반환값

A Page with items, hasMore and nextCursor. Each item has id, keyId, keyName, requestId, method, path, status, durationMs, ip, userAgent and createdAt, plus the error code, read with call["errorCode"].

예시

var page = await client.Keys.ListWorkspaceRequestsAsync(failedOnly: true, since: DateTimeOffset.Parse("2026-09-22T00:00:00Z")); foreach (var call in page){    Console.WriteLine($"{call["keyName"]} {call["method"]} {call["path"]} {call["status"]}");}

다른 사용처

API
GET /keys/requests
TypeScript
keys.listWorkspaceRequests()
Python
keys.list_workspace_requests()
Ruby
keys.list_workspace_requests
PHP
keys->listWorkspaceRequests
Go
Keys.ListWorkspaceRequests
Java
keys().listWorkspaceRequests
CLI
openemail keys list-workspace-requests

Keys.ListAllWorkspaceRequestsAsync

Collect the request log of every key into one object

범위keys:read결과를 페이지 단위로 가져옴
시그니처
Task<IReadOnlyList<JsonObject>> ListAllWorkspaceRequestsAsync(    IEnumerable<string>? keyIds = null,    bool? failedOnly = null,    IEnumerable<int>? statuses = null,    string? path = null,    DateTimeOffset? since = null,    DateTimeOffset? until = null,    int? limit = null,    string? cursor = null,    string? apiKey = null,    CancellationToken cancellationToken = default)

Walks every page of ListWorkspaceRequestsAsync under the same filters. The log is never pruned, so give it a window, or use IterateWorkspaceRequestsAsync to stop early.

매개변수

keyIdsIEnumerable<string>?

Key ids to read, at most 50, as a dictionary or one comma-separated string, sent comma-separated. Left out, every key the caller can see.

failedOnlybool?

Only calls answered with a status of 400 or more.

statusesIEnumerable<int>?

Only calls answered with one of these HTTP status codes, such as new[] { 401, 403 }. At most 20, each from 100 to 599, sent comma-separated as status.

pathstring?

Only calls to this route, whatever the method, such as /emails or /emails/:id. It matches the route, not the exact path: an id counts as :id and an email address as :address. End it with * to read every route that starts with it, such as /emails/*.

sinceDateTimeOffset?

Only rows at or after this instant. A DateTimeOffset, sent as ISO 8601 in UTC.

untilDateTimeOffset?

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

limitint?

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

cursorstring?

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

apiKeystring?

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

cancellationTokenCancellationToken

Cancels the request.

반환값

A list of JsonObject items, one per call with the fields ListWorkspaceRequestsAsync returns, newest first.

예시

var failures = await client.Keys.ListAllWorkspaceRequestsAsync(failedOnly: true, since: DateTimeOffset.UtcNow.AddHours(-1), limit: 100); Console.WriteLine(failures.Count);

참고

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

다른 사용처

API
GET /keys/requests
TypeScript
keys.listAllWorkspaceRequests()
Python
keys.list_all_workspace_requests()
Ruby
keys.list_all_workspace_requests
PHP
keys->listAllWorkspaceRequests
Go
Keys.ListAllWorkspaceRequests
Java
keys().listAllWorkspaceRequests

Keys.IterateWorkspaceRequestsAsync

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

범위keys:read결과를 페이지 단위로 가져옴
시그니처
IAsyncEnumerable<JsonObject> IterateWorkspaceRequestsAsync(    IEnumerable<string>? keyIds = null,    bool? failedOnly = null,    IEnumerable<int>? statuses = null,    string? path = null,    DateTimeOffset? since = null,    DateTimeOffset? until = null,    int? limit = null,    string? cursor = null,    string? apiKey = null,    CancellationToken cancellationToken = default)

An IAsyncEnumerable<JsonObject> over ListWorkspaceRequestsAsync under the same filters, fetching a page only when the one before is drained.

매개변수

keyIdsIEnumerable<string>?

Key ids to read, at most 50, as a dictionary or one comma-separated string, sent comma-separated. Left out, every key the caller can see.

failedOnlybool?

Only calls answered with a status of 400 or more.

statusesIEnumerable<int>?

Only calls answered with one of these HTTP status codes, such as new[] { 401, 403 }. At most 20, each from 100 to 599, sent comma-separated as status.

pathstring?

Only calls to this route, whatever the method, such as /emails or /emails/:id. It matches the route, not the exact path: an id counts as :id and an email address as :address. End it with * to read every route that starts with it, such as /emails/*.

sinceDateTimeOffset?

Only rows at or after this instant. A DateTimeOffset, sent as ISO 8601 in UTC.

untilDateTimeOffset?

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

limitint?

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

cursorstring?

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

apiKeystring?

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

cancellationTokenCancellationToken

Cancels the request.

반환값

An IAsyncEnumerable<JsonObject> that yields one call per step.

예시

await foreach (var call in client.Keys.IterateWorkspaceRequestsAsync(failedOnly: true)){    if ((int?)call["status"] >= 500)    {        Console.WriteLine($"{call["requestId"]} {call["path"]}");    }}

다른 사용처

API
GET /keys/requests
TypeScript
keys.iterateWorkspaceRequests()
Python
keys.iterate_workspace_requests()
Ruby
keys.iterate_workspace_requests
PHP
keys->iterateWorkspaceRequests
Go
Keys.IterateWorkspaceRequests
Java
keys().iterateWorkspaceRequests

Keys.ListWorkspaceActivityAsync

List one page of what happened to every key

범위keys:read결과를 페이지 단위로 가져옴
시그니처
Task<Page> ListWorkspaceActivityAsync(    IEnumerable<string>? keyIds = null,    DateTimeOffset? since = null,    DateTimeOffset? until = null,    int? limit = null,    string? cursor = null,    string? apiKey = null,    CancellationToken cancellationToken = default)

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.

keyIds: 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.

매개변수

keyIdsIEnumerable<string>?

Key ids to read, at most 50, as a dictionary or one comma-separated string, sent comma-separated. Left out, every key the caller can see.

sinceDateTimeOffset?

Only rows at or after this instant. A DateTimeOffset, sent as ISO 8601 in UTC.

untilDateTimeOffset?

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

limitint?

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

cursorstring?

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

apiKeystring?

Overrides the client API key for this call only.

cancellationTokenCancellationToken

Cancels the request.

반환값

A Page with items, hasMore and nextCursor. Each item has id, keyId, keyName, type, createdAt, actor and detail.

예시

var page = await client.Keys.ListWorkspaceActivityAsync(since: DateTimeOffset.Parse("2026-09-01T00:00:00Z")); foreach (var change in page){    Console.WriteLine($"{change["keyName"]} {change["type"]} by {change["actor"]?["label"]}");}

다른 사용처

API
GET /keys/activity
TypeScript
keys.listWorkspaceActivity()
Python
keys.list_workspace_activity()
Ruby
keys.list_workspace_activity
PHP
keys->listWorkspaceActivity
Go
Keys.ListWorkspaceActivity
Java
keys().listWorkspaceActivity
CLI
openemail keys list-workspace-activity

Keys.ListAllWorkspaceActivityAsync

Collect the audit log of every key into one object

범위keys:read결과를 페이지 단위로 가져옴
시그니처
Task<IReadOnlyList<JsonObject>> ListAllWorkspaceActivityAsync(    IEnumerable<string>? keyIds = null,    DateTimeOffset? since = null,    DateTimeOffset? until = null,    int? limit = null,    string? cursor = null,    string? apiKey = null,    CancellationToken cancellationToken = default)

Walks every page of ListWorkspaceActivityAsync under the same filters and returns every change, newest first.

매개변수

keyIdsIEnumerable<string>?

Key ids to read, at most 50, as a dictionary or one comma-separated string, sent comma-separated. Left out, every key the caller can see.

sinceDateTimeOffset?

Only rows at or after this instant. A DateTimeOffset, sent as ISO 8601 in UTC.

untilDateTimeOffset?

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

limitint?

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

cursorstring?

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

apiKeystring?

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

cancellationTokenCancellationToken

Cancels the request.

반환값

A list of JsonObject items, one per change with the fields ListWorkspaceActivityAsync returns, newest first.

예시

var changes = await client.Keys.ListAllWorkspaceActivityAsync(since: DateTimeOffset.Parse("2026-09-01Z")); Console.WriteLine(changes.Count);

참고

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

다른 사용처

API
GET /keys/activity
TypeScript
keys.listAllWorkspaceActivity()
Python
keys.list_all_workspace_activity()
Ruby
keys.list_all_workspace_activity
PHP
keys->listAllWorkspaceActivity
Go
Keys.ListAllWorkspaceActivity
Java
keys().listAllWorkspaceActivity

Keys.IterateWorkspaceActivityAsync

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

범위keys:read결과를 페이지 단위로 가져옴
시그니처
IAsyncEnumerable<JsonObject> IterateWorkspaceActivityAsync(    IEnumerable<string>? keyIds = null,    DateTimeOffset? since = null,    DateTimeOffset? until = null,    int? limit = null,    string? cursor = null,    string? apiKey = null,    CancellationToken cancellationToken = default)

An IAsyncEnumerable<JsonObject> over ListWorkspaceActivityAsync under the same filters, fetching a page only when the one before is drained.

매개변수

keyIdsIEnumerable<string>?

Key ids to read, at most 50, as a dictionary or one comma-separated string, sent comma-separated. Left out, every key the caller can see.

sinceDateTimeOffset?

Only rows at or after this instant. A DateTimeOffset, sent as ISO 8601 in UTC.

untilDateTimeOffset?

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

limitint?

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

cursorstring?

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

apiKeystring?

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

cancellationTokenCancellationToken

Cancels the request.

반환값

An IAsyncEnumerable<JsonObject> that yields one change per step.

예시

await foreach (var change in client.Keys.IterateWorkspaceActivityAsync()){    if ((string?)change["type"] == "auth_failed")    {        Console.WriteLine($"{change["keyName"]} {change["detail"]?["reason"]?.ToString() ?? "refused"} {change["createdAt"]}");    }}

다른 사용처

API
GET /keys/activity
TypeScript
keys.iterateWorkspaceActivity()
Python
keys.iterate_workspace_activity()
Ruby
keys.iterate_workspace_activity
PHP
keys->iterateWorkspaceActivity
Go
Keys.IterateWorkspaceActivity
Java
keys().iterateWorkspaceActivity

Keys.StatsAsync

Read what the keys did inside a window

범위keys:reademails:read
시그니처
Task<JsonObject> StatsAsync(    IEnumerable<string>? keyIds = null,    DateTimeOffset? since = null,    DateTimeOffset? until = null,    string? grain = null,    int? offsetMinutes = null,    string? apiKey = null,    CancellationToken cancellationToken = default)

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 keyIds: 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 offsetMinutes: shifts the boundaries so days break where the reader's day does.

매개변수

keyIdsIEnumerable<string>?

Only these keys, at most 50, as a dictionary or one comma-separated string. Left out, every key you can see.

sinceDateTimeOffset?

The start of the window, a DateTimeOffset. Defaults to 30 days before until.

untilDateTimeOffset?

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

grainstring?

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

offsetMinutesint?

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

apiKeystring?

Overrides the client API key for this call only.

cancellationTokenCancellationToken

Cancels the request.

반환값

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

예시

var stats = await client.Keys.StatsAsync(grain: "day"); Console.WriteLine($"{stats["sends"]?["totals"]?["sends"]} sent from {stats["since"]} to {stats["until"]}"); foreach (var route in stats["routes"]?.AsArray() ?? []){    Console.WriteLine($"{route?["label"]}: {route?["count"]} calls, median {route?["medianMs"]} ms");}

참고

  • 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()
Python
keys.stats()
Ruby
keys.stats
PHP
keys->stats
Go
Keys.Stats
Java
keys().stats
CLI
openemail keys stats