Перейти к документации
C#

client.Me

Каждый метод этого пространства имён: его сигнатура, параметры, что он возвращает, и пример.

Методы

The API key or OAuth access token behind the client: its mode, scopes, role ceiling and workspace, and for a key its own request log, activity and stats.

Me.GetAsync

Describe the API key or access token making the call

Без области доступа
Сигнатура
Task<JsonObject> GetAsync(string? apiKey = null, CancellationToken cancellationToken = default)

Returns what the key is: its id, whether it is a live or test key, the workspace it belongs to, the scopes it can use and the allowlists that narrow who it may send as. It needs no scope, because a key may always describe itself, so it works with any valid key and is the first call to make when a request is refused.

scopes is the effective list and the only one that authorises anything. It is the scopes the key was created with intersected with the permissions of the role it was issued under, resolved on every request rather than frozen into the key. grantedScopes is what the key was created holding and roleId names the role that capped it, so a scope present in grantedScopes and missing from scopes was removed by that role. A 403 insufficient_scope on a key the console shows as holding the scope is almost always this, and the fix is to change the role rather than to mint another key.

A key can be narrowed by whole domains, by individual addresses, or by both. domainAllowlist holds whole domains, and the key may send as any address on one of them, including addresses created after the key was. addressAllowlist holds individual addresses and covers only those. Both null means the key may send as any address the workspace owns. When either is set the key is narrowed, and reads of sent mail, tracking and calendar narrow to the same set. An address whose domain is already in domainAllowlist is dropped from addressAllowlist when the key is saved, so the two lists never overlap.

Called with an OAuth access token it describes the token instead, and object tells the two apart. A key answers object: 'api_key' and kind: 'apiKey'. A token answers object: 'oauth_token' and kind: 'oauth', with id null, clientId naming the connected app, roleId null and mode always live. scopes and grantedScopes are the permissions the person approved for the app, and the allowlists are the addresses and domains the app may reach. expiresAt is when that approval runs out, or null when it never does. It is not the expiry of the access token, which the app renews with its refresh token.

Параметры

apiKeystring?

Describes this key instead of the credential the client was built with.

cancellationTokenCancellationToken

Cancels the request.

Возвращает

A JsonObject. For an API key it holds object set to api_key, kind, id, mode, scopes, grantedScopes, roleId, workspaceId, addressAllowlist and domainAllowlist. For an OAuth access token object is oauth_token, id and roleId are null, and it adds clientId and expiresAt.

Пример

var key = await client.Me.GetAsync(); Console.WriteLine($"{key["mode"]} {key["workspaceId"]}"); if ((string?)key["object"] == "oauth_token"){    Console.WriteLine($"{key["clientId"]} {key["expiresAt"]?.ToString() ?? "never"}");}

Примечания

  • Narrowing a role takes effect on the next request without touching the key itself, so scopes can shrink between two calls with the same secret. Replacing the secret is a separate act, and Me.RotateAsync is the call that does it.

  • roleId is null on a key with no ceiling, which is what every key issued before roles existed still has.

  • A failure here is a 401 naming the credential problem: missing_api_key, invalid_api_key, revoked_api_key, expired_api_key or inactive_api_key for a key switched off in the console.

  • An access token that has run out is a 401 expired_access_token, which the app answers by renewing it with its refresh token. invalid_access_token and the grant_* codes mean the app has to be connected again.

Также доступно в

API
GET /keys/self
TypeScript
me.get()
Python
me.get()
Ruby
me.get
PHP
me->get
Go
Me.Get
Java
me().get
CLI
openemail me get

Me.PingAsync

Check that a key or access token authenticates

Без области доступа
Сигнатура
Task<JsonObject> PingAsync(string? apiKey = null, CancellationToken cancellationToken = default)

An authentication smoke test. It runs the same key check every other endpoint runs and answers ok: true with the key id, its mode, the workspace and the effective scopes. It needs no scope, so a key with none at all still gets a 200.

Use it in a health check or at process start to fail fast on a revoked, expired or mistyped key. The answer carries the same scope detail as Me.GetAsync, scopes effective and grantedScopes as created with roleId naming the cap between them, but it leaves out both allowlists. Call Me.GetAsync when you need to know which domains and which addresses the key may send as.

An OAuth access token gets the same answer with kind: 'oauth', keyId null, clientId naming the connected app, roleId null and mode always live. A key answers kind: 'apiKey'.

Параметры

apiKeystring?

Checks this key instead of the credential the client was built with.

cancellationTokenCancellationToken

Cancels the request.

Возвращает

A JsonObject with ok set to true, kind, keyId, mode, scopes, grantedScopes, roleId and workspaceId, plus clientId for an OAuth access token.

Пример

try{    var ping = await client.Me.PingAsync();     Console.WriteLine($"Authenticated as {ping["kind"]} in {ping["mode"]} mode");}catch (OpenEmailApiException error){    if (!error.IsAuth)    {        throw;    }     Console.WriteLine($"The key was refused: {error.Code}");}

Примечания

  • The id is keyId here and id on Me.GetAsync, and there is no object field on this response, so tell a key from a token by kind.

  • A bad key never returns ok: false. It throws an OpenEmailApiException with status 401, so IsAuth is the check to make.

Также доступно в

API
GET /ping
TypeScript
me.ping()
Python
me.ping()
Ruby
me.ping
PHP
me->ping
Go
Me.Ping
Java
me().ping
CLI
openemail me ping

Me.RotateAsync

Replace the calling key's own secret

Разрешенияkeys:write
Сигнатура
Task<JsonObject> RotateAsync(string? apiKey = null, CancellationToken cancellationToken = default)

Mints a new secret for the key making the call and returns the same body as Me.GetAsync plus token, the new key in full. That is the only place the value appears, so store it before anything else.

Everything else about the key survives. The id, the mode, the scopes, the role ceiling, the address allowlist and the domain allowlist all come back unchanged, so token is the only thing your configuration has to change. Because the id is stable, an audit trail joined on it stays joined up across rotations.

There is no overlap window. The old secret stops authenticating the moment this call commits, and neither secret can be shown again. Write token to wherever the key is read from before the next request. A lost response is the bad case: the rotation may have committed to a secret nobody saw, which leaves the key unusable until someone mints it a new secret in the console.

Параметры

apiKeystring?

Rotates this key instead of the one the client was built with.

cancellationTokenCancellationToken

Cancels the request.

Возвращает

A JsonObject with what Me.GetAsync returns plus token, the new key formatted oe_live_ or oe_test_ then the 24 character key id, an underscore and 43 base64url characters, and rotationCount and rotatedAt.

Пример

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

Примечания

  • It needs keys:write, and a key without it gets 403 insufficient_scope. No key holds that scope unless somebody gave it one in the console, so a key that cannot reach this call has to be rotated from there.

  • There is no request body and the success status is 200, not 201.

  • Not retried automatically. Repeating a rotation would invalidate the secret the first attempt returned, so a failure has to be judged rather than retried.

  • The 404 and the two 409s are races rather than everyday answers, because a key that is missing, revoked or expired cannot authenticate this call in the first place. They mean the key changed state between authenticating and rotating: 404 if the row went, 409 revoked or 409 expired otherwise. None of the three is rotatable, so the answer is a new key from the console.

  • rotationCount is the count after this call, so the first rotation of a key answers 1, and rotatedAt is when that rotation committed.

Также доступно в

API
POST /keys/self/rotate
TypeScript
me.rotate()
Python
me.rotate()
Ruby
me.rotate
PHP
me->rotate
Go
Me.Rotate
Java
me().rotate
CLI
openemail me rotate

Me.ListRequestsAsync

List one page of the calling key's own request log

Без области доступаПостранично перебирает результаты
Сигнатура
Task<Page> ListRequestsAsync(    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 the key making the request made, newest first. It needs no scope: a key may always read its own log, and it reads no other key's here. Keys.ListRequestsAsync and Keys.ListWorkspaceRequestsAsync are the ones that reach other keys, behind keys:read.

The request log records every authenticated call the key made: method, path, status, error code, duration, IP and user agent, and never a body or a query string. Nothing is pruned, so the log reaches back to the key's first call, and it runs straight through a rotation because it hangs off the key id. failedOnly:, statuses:, path:, since: and until: narrow it, and they combine.

Параметры

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?

Reads the log of this key instead of the one the client was built with.

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.Me.ListRequestsAsync(statuses: new[] { 429 }, since: DateTimeOffset.Parse("2026-10-01T00:00:00Z")); foreach (var call in page){    Console.WriteLine($"{call["createdAt"]} {call["method"]} {call["path"]} {call["status"]}");}

Примечания

  • An OAuth access token is refused with 403 api_key_only. Calls made with one are not logged, so there is nothing to read.

  • 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. Each row still carries the exact path.

  • The call that reads the log is logged too.

  • 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/self/requests
TypeScript
me.listRequests()
Python
me.list_requests()
Ruby
me.list_requests
PHP
me->listRequests
Go
Me.ListRequests
Java
me().listRequests
CLI
openemail me list-requests

Me.ListAllRequestsAsync

Collect the calling key's whole request log into one list

Без области доступаПостранично перебирает результаты
Сигнатура
Task<IReadOnlyList<JsonObject>> ListAllRequestsAsync(    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 Me.ListRequestsAsync under the same filters. The log is never pruned, so give it a window unless you mean to read the key's whole history, or use Me.IterateRequestsAsync to stop early.

Параметры

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?

Reads the log of this key instead of the one the client was built with, for every page of this walk.

cancellationTokenCancellationToken

Cancels the request.

Возвращает

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

Пример

var failures = await client.Me.ListAllRequestsAsync(failedOnly: true, since: DateTimeOffset.UtcNow.AddHours(-1), limit: 100); Console.WriteLine($"{failures.Count} failed calls in the last hour");

Примечания

  • An OAuth access token is refused with 403 api_key_only. Calls made with one are not logged, so there is nothing to read.

Также доступно в

API
GET /keys/self/requests
TypeScript
me.listAllRequests()
Python
me.list_all_requests()
Ruby
me.list_all_requests
PHP
me->listAllRequests
Go
Me.ListAllRequests
Java
me().listAllRequests

Me.IterateRequestsAsync

Stream the calling key's own request log one call at a time

Без области доступаПостранично перебирает результаты
Сигнатура
IAsyncEnumerable<JsonObject> IterateRequestsAsync(    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 Me.ListRequestsAsync under the same filters, fetching a page only when the one before is drained.

Параметры

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?

Reads the log of this key instead of the one the client was built with, 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.Me.IterateRequestsAsync(path: "/emails", statuses: new[] { 422 })){    Console.WriteLine($"{call["createdAt"]} {call["errorCode"]} {call["requestId"]}");}

Примечания

  • An OAuth access token is refused with 403 api_key_only. Calls made with one are not logged, so there is nothing to read.

Также доступно в

API
GET /keys/self/requests
TypeScript
me.iterateRequests()
Python
me.iterate_requests()
Ruby
me.iterate_requests
PHP
me->iterateRequests
Go
Me.IterateRequests
Java
me().iterateRequests

Me.ListActivityAsync

List one page of what happened to the calling key

Без области доступаПостранично перебирает результаты
Сигнатура
Task<Page> ListActivityAsync(    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 the key making the request, newest first. It needs no scope, and it reads no other key's history: Keys.ListActivityAsync and Keys.ListWorkspaceActivityAsync do that, behind keys:read.

Every change to the key is a row: created, updated, rotated, deactivated and reactivated, 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.

Параметры

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?

Reads the log of this key instead of the one the client was built with.

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.Me.ListActivityAsync(); foreach (var change in page){    Console.WriteLine($"{change["createdAt"]} {change["type"]} by {change["actor"]?["label"]} from {change["detail"]?["source"]?.ToString() ?? "unknown"}");}

Примечания

  • An OAuth access token is refused with 403 api_key_only. Calls made with one are not logged, so there is nothing to read.

  • A revoked or deleted key cannot authenticate, so revoked and deleted rows are only ever read by another key, through Keys.ListActivityAsync.

Также доступно в

API
GET /keys/self/activity
TypeScript
me.listActivity()
Python
me.list_activity()
Ruby
me.list_activity
PHP
me->listActivity
Go
Me.ListActivity
Java
me().listActivity
CLI
openemail me list-activity

Me.ListAllActivityAsync

Collect everything that happened to the calling key into one list

Без области доступаПостранично перебирает результаты
Сигнатура
Task<IReadOnlyList<JsonObject>> ListAllActivityAsync(    DateTimeOffset? since = null,    DateTimeOffset? until = null,    int? limit = null,    string? cursor = null,    string? apiKey = null,    CancellationToken cancellationToken = default)

Walks every page of Me.ListActivityAsync under the same window. Use Me.IterateActivityAsync to stop early.

Параметры

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?

Reads the log of this key instead of the one the client was built with, for every page of this walk.

cancellationTokenCancellationToken

Cancels the request.

Возвращает

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

Пример

var history = await client.Me.ListAllActivityAsync(); Console.WriteLine($"{history.Count(change => (string?)change["type"] == "rotated")} rotations");

Примечания

  • An OAuth access token is refused with 403 api_key_only. Calls made with one are not logged, so there is nothing to read.

Также доступно в

API
GET /keys/self/activity
TypeScript
me.listAllActivity()
Python
me.list_all_activity()
Ruby
me.list_all_activity
PHP
me->listAllActivity
Go
Me.ListAllActivity
Java
me().listAllActivity

Me.IterateActivityAsync

Stream what happened to the calling key one change at a time

Без области доступаПостранично перебирает результаты
Сигнатура
IAsyncEnumerable<JsonObject> IterateActivityAsync(    DateTimeOffset? since = null,    DateTimeOffset? until = null,    int? limit = null,    string? cursor = null,    string? apiKey = null,    CancellationToken cancellationToken = default)

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

Параметры

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?

Reads the log of this key instead of the one the client was built with, 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.Me.IterateActivityAsync()){    if ((string?)change["type"] == "auth_failed")    {        Console.WriteLine($"Last refused attempt at {change["createdAt"]}");         break;    }}

Примечания

  • An OAuth access token is refused with 403 api_key_only. Calls made with one are not logged, so there is nothing to read.

Также доступно в

API
GET /keys/self/activity
TypeScript
me.iterateActivity()
Python
me.iterate_activity()
Ruby
me.iterate_activity
PHP
me->iterateActivity
Go
Me.IterateActivity
Java
me().iterateActivity

Me.StatsAsync

Read what the calling key did inside a window

Без области доступа
Сигнатура
Task<JsonObject> StatsAsync(    DateTimeOffset? since = null,    DateTimeOffset? until = null,    string? grain = null,    int? offsetMinutes = null,    string? apiKey = null,    CancellationToken cancellationToken = default)

Returns the figures of the key making the request: the requests it made and how many failed, the calls refused because its secret was wrong, revoked or expired, the routes it called most with the median time each took, and the status codes it got back. It needs no scope, and it reads no other key's figures: Keys.StatsAsync does that.

sends, the mail the key sent and what became of it, is filled only when the key holds emails:read. Without that scope it is null, never zeros, so a missing permission cannot read as a quiet week.

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.

Параметры

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?

Reads the figures of this key instead of the one the client was built with.

cancellationTokenCancellationToken

Cancels the request.

Возвращает

A JsonObject with the window it covered, keyIds holding the id of the key alone, sends or null, rejected, requests, routes and codes.

Пример

var stats = await client.Me.StatsAsync(grain: "hour", since: DateTimeOffset.UtcNow.AddDays(-1));var failed = (stats["requests"]?.AsArray() ?? []).Sum(bucket => (int?)bucket?["failed"] ?? 0); Console.WriteLine($"{failed} failed calls in the last day");Console.WriteLine(stats["sends"]?["totals"]?["sends"]?.ToString() ?? "This key cannot read its sends");

Примечания

  • An OAuth access token is refused with 403 api_key_only. Calls made with one are not logged, so there is nothing to read.

  • 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/self/stats
TypeScript
me.stats()
Python
me.stats()
Ruby
me.stats
PHP
me->stats
Go
Me.Stats
Java
me().stats
CLI
openemail me stats