API Keys
.NET SDK reference for API keys: creation, lookup, listing, updates, and deletion.
API key lifecycle — create, list, update, soft-delete.
Namespace: Goodmem.Client.Api · Class: ApiKeysApi
Reach this surface as client.ApiKeys on a GoodmemClient. Every network method is asynchronous — it returns a Task<T> (or an IAsyncEnumerable<T> for pagination and streaming) and accepts a CancellationToken; the Async suffix marks the standard .NET Task-based async pattern.
Methods
| Method | Summary |
|---|---|
CreateAsync | Create a new API key. |
GetAsync | Get an API key. |
ListAsync | List API keys. |
UpdateAsync | Update an API key. |
DeleteAsync | Delete an API key. |
CreateAsync
Issues a new API key and returns its raw value exactly once. Omitted subject and authorityMode create a self-issued human key that inherits the subject's live authority. A SCOPED key requires a nonempty immutable ceiling, and every ceiling rule must be conservatively covered by both the subject's live authority and the issuing credential's effective authority. A scoped issuer can create only scoped children. SERVICE subjects require SCOPED mode and MANAGE_ACCESS on the service identity.
AUTHORIZATION: Requires CREATE_API_KEY on the proposed credential; subject and ceiling checks are repeated by the final insertion statement.
Declaration
public Task<CreateApiKeyResponse> CreateAsync(CreateApiKeyRequest request, CancellationToken ct = default)
HTTP — POST /v1/apikeys
Parameters
| Type | Name | Description |
|---|---|---|
CreateApiKeyRequest | request | The request payload; the linked model lists every field and its JSON wire name. |
CancellationToken | ct | Cancellation / deadline signal for the call. (optional) |
Returns
Task<CreateApiKeyResponse> — an awaitable that resolves to CreateApiKeyResponse.
Exceptions
| Type | Condition |
|---|---|
ArgumentNullException | request is null. |
NetworkException | The request could not reach the server (DNS, connection, or TLS failure). |
ApiException | The server returned a non-success (non-2xx) status. A status-specific subtype is thrown where it applies — e.g. NotFoundException (404), PermissionDeniedException (403), ConflictException (409). |
Example
var key = await client.ApiKeys.CreateAsync(
new CreateApiKeyRequest
{
Labels = new Dictionary<string, string>
{
["env"] = "docs",
["purpose"] = "sdk-doc-test",
},
}
);
Console.WriteLine(key.RawApiKey); // returned only once, at creationGetAsync
Returns complete non-secret metadata for one existing credential after requiring effective READ_API_KEY authority. The immutable ceiling is always complete and ceilingOmitted is false. Raw key material and hashes are never returned.
Declaration
public Task<ApiKeyResponse> GetAsync(string id, CancellationToken ct = default)
HTTP — GET /v1/apikeys/{id}
Parameters
| Type | Name | Description |
|---|---|---|
string | id | API-key UUID |
CancellationToken | ct | Cancellation / deadline signal for the call. (optional) |
Returns
Task<ApiKeyResponse> — an awaitable that resolves to ApiKeyResponse.
Exceptions
| Type | Condition |
|---|---|
ArgumentException | id is null or empty. |
NetworkException | The request could not reach the server (DNS, connection, or TLS failure). |
ApiException | The server returned a non-success (non-2xx) status. A status-specific subtype is thrown where it applies — e.g. NotFoundException (404), PermissionDeniedException (403), ConflictException (409). |
Example
var key = await client.ApiKeys.GetAsync("your-api-key-id");
Console.WriteLine($"{key.ApiKeyId} {key.LifecycleState}");ListAsync
Requires LIST_API_KEY on the singleton instance, then retrieves one UUID-ordered page containing only credentials that independently pass READ_API_KEY. Both gates use the authenticated principal's live authority and any scoped-key ceiling. Subject, owner, and lifecycle filters are applied after authorization. FULL includes complete immutable ceilings; BASIC omits them, sets ceilingOmitted=true, and permits larger pages. Raw key values and key hashes are never returned.
Declaration
public IAsyncEnumerable<ApiKeyResponse> ListAsync(ApiKeysListOptions? options = null, CancellationToken ct = default)
HTTP — GET /v1/apikeys
Parameters
| Type | Name | Description |
|---|---|---|
ApiKeysListOptions | options | Options bag carrying the lookup key(s) / convenience knobs; the linked type lists them all. (optional) |
CancellationToken | ct | Cancellation / deadline signal for the call. (optional) |
Returns
IAsyncEnumerable<ApiKeyResponse> — an async stream; await foreach yields each ApiKeyResponse across pages / events.
Exceptions
| Type | Condition |
|---|---|
NetworkException | The request could not reach the server (DNS, connection, or TLS failure). |
ApiException | The server returned a non-success (non-2xx) status. A status-specific subtype is thrown where it applies — e.g. NotFoundException (404), PermissionDeniedException (403), ConflictException (409). |
Example
await foreach (var key in client.ApiKeys.ListAsync())
Console.WriteLine($"{key.ApiKeyId} {key.Status}");UpdateAsync
Updates an existing API key's labels or lifecycle status. Key ID, subject, ownership, key material, validity window, and creation audit fields remain immutable. Label changes require UPDATE_API_KEY; setting status=INACTIVE permanently revokes the key and requires DELETE_API_KEY; a request doing both requires both operations. Revoked keys cannot be reactivated. Side effects include updating administrative audit fields and, for revocation, recording the revocation time and actor.
Declaration
public Task<ApiKeyResponse> UpdateAsync(string id, UpdateApiKeyRequest request, CancellationToken ct = default)
HTTP — PUT /v1/apikeys/{id}
Parameters
| Type | Name | Description |
|---|---|---|
string | id | The UUID of the API key to update |
UpdateApiKeyRequest | request | The request payload; the linked model lists every field and its JSON wire name. |
CancellationToken | ct | Cancellation / deadline signal for the call. (optional) |
Returns
Task<ApiKeyResponse> — an awaitable that resolves to ApiKeyResponse.
Exceptions
| Type | Condition |
|---|---|
ArgumentException | id is null or empty. |
ArgumentNullException | request is null. |
NetworkException | The request could not reach the server (DNS, connection, or TLS failure). |
ApiException | The server returned a non-success (non-2xx) status. A status-specific subtype is thrown where it applies — e.g. NotFoundException (404), PermissionDeniedException (403), ConflictException (409). |
Example
var updated = await client.ApiKeys.UpdateAsync(
"your-api-key-id",
new UpdateApiKeyRequest
{
MergeLabels = new Dictionary<string, string> { ["updated"] = "true" },
}
);
Console.WriteLine(updated.ApiKeyId);DeleteAsync
Delete an API key
Permanently revokes an API key and immediately rejects it for future authentication. The durable credential and audit history remain stored. This operation requires DELETE_API_KEY and records the revocation time and actor; it cannot be undone. PUT /v1/apikeys/{id} with status=INACTIVE performs the same permanent revocation.
Declaration
public Task DeleteAsync(string id, CancellationToken ct = default)
HTTP — DELETE /v1/apikeys/{id}
Parameters
| Type | Name | Description |
|---|---|---|
string | id | The UUID of the API key to delete |
CancellationToken | ct | Cancellation / deadline signal for the call. (optional) |
Returns
Task — completes when the operation finishes; there is no response body.
Exceptions
| Type | Condition |
|---|---|
ArgumentException | id is null or empty. |
NetworkException | The request could not reach the server (DNS, connection, or TLS failure). |
ApiException | The server returned a non-success (non-2xx) status. A status-specific subtype is thrown where it applies — e.g. NotFoundException (404), PermissionDeniedException (403), ConflictException (409). |
Example
await client.ApiKeys.DeleteAsync("your-api-key-id");Data Models
Types in the Goodmem.Client.Models namespace. Each row lists the C# property, its type, the JSON wire name, and a description.
CreateApiKeyRequest
Request parameters for creating a new API key.
| Property | Type | JSON (wire) | Description |
|---|---|---|---|
Labels | IReadOnlyDictionary<string, string> | labels | Key-value pairs of metadata associated with the API key. Used for organization and filtering. At most 20 entries; keys and values contain at most 255 characters; keys use [a-z0-9._-]. (optional) |
ExpiresAt | DateTimeOffset | expiresAt | Exclusive expiration timestamp in milliseconds since epoch. It must be later than validFrom, which defaults to issuance time; if omitted, the key does not expire. (optional) |
ApiKeyId | string | apiKeyId | Optional client-provided UUID for idempotent creation. If not provided, server generates a new UUID. Returns ALREADY_EXISTS if ID is already in use. (optional) |
SubjectPrincipalId | string | subjectPrincipalId | Principal authenticated by this key. Omit to use the authenticated principal. (optional) |
AuthorityMode | ApiKeyAuthorityMode | authorityMode | Authority mode. Omit to create a self-issued human key that inherits live authority. A scoped issuing credential may create only SCOPED children. (optional) |
Ceiling | IReadOnlyList<AccessPolicyRule> | ceiling | Immutable authorization ceiling. Required and nonempty for SCOPED; omitted for INHERIT_SUBJECT, with at most 1,000 rules. Every rule must be covered by both the subject's live authority and the issuing credential's effective authority. (optional) |
ValidFrom | DateTimeOffset | validFrom | Inclusive activation time in epoch milliseconds. Omit to activate at issuance time. (optional) |
CreateApiKeyResponse
Response returned when creating a new API key.
| Property | Type | JSON (wire) | Description |
|---|---|---|---|
ApiKeyMetadata | ApiKeyResponse | apiKeyMetadata | Metadata for the created API key. (optional) |
RawApiKey | string | rawApiKey | The actual API key value. This is only returned once and cannot be retrieved again. (optional) |
ListApiKeysResponse
One page of API keys discoverable to the authenticated principal.
| Property | Type | JSON (wire) | Description |
|---|---|---|---|
Keys | IReadOnlyList<ApiKeyResponse> | keys | API keys in stable UUID order. |
NextToken | string | nextToken | Opaque token for retrieving the next page; omitted on the last page. (optional) |
UpdateApiKeyRequest
Request parameters for updating an API key.
| Property | Type | JSON (wire) | Description |
|---|---|---|---|
Status | string | status | New status for the API key. INACTIVE is permanent; revoked keys cannot be reactivated. (optional) |
ReplaceLabels | IReadOnlyDictionary<string, string> | replaceLabels | Replace all existing labels with this set. Mutually exclusive with mergeLabels. The stored map may contain at most 20 entries; keys and values contain at most 255 characters; keys use [a-z0-9._-]. (optional) |
MergeLabels | IReadOnlyDictionary<string, string> | mergeLabels | Merge these labels with existing ones. Mutually exclusive with replaceLabels. The final stored map may contain at most 20 entries; keys and values contain at most 255 characters; keys use [a-z0-9._-]. (optional) |