GoodMemGoodMem

API Keys

Methods on this page are called as client.apikeys.<method>(...) where client is either a synchronous Goodmem or asynchronous AsyncGoodmem instance initialized below:

from goodmem import Goodmem
client = Goodmem(base_url='http://localhost:8080', api_key='gm_...')
from goodmem import AsyncGoodmem
client = AsyncGoodmem(base_url='http://localhost:8080', api_key='gm_...')

Create a new API key

apikeys.create(*, api_key_id: str = None, expires_at: int = None, labels: dict[str, str] = None) → CreateApiKeyResponse

Creates a new API key for authenticating with the API. New keys start in ACTIVE status and can be used immediately for authentication. The response includes the one-time raw API key value which will not be retrievable later - clients must save this value as it cannot be recovered. Requires CREATE_APIKEY_OWN permission (or CREATE_APIKEY_ANY for admin users). Side effects include generating cryptographically secure key material, recording creation timestamp, and tracking creator ID. Returns INVALID_ARGUMENT if expires_at is set to a time in the past.

Parameters:

  • api_key_id (str, format: uuid, optional) — Optional client-provided UUID for idempotent creation. If not provided, server generates a new UUID. Returns ALREADY_EXISTS if ID is already in use.
  • expires_at (int, format: int64, optional) — Expiration timestamp in milliseconds since epoch. If not provided, the key does not expire.
  • labels (dict[str, str], optional) — Key-value pairs of metadata associated with the API key. Used for organization and filtering.

Returns:

CreateApiKeyResponse

Raises:

  • BadRequestError — Malformed request or invalid argument.
  • PermissionDeniedError — The caller lacks the permission the operation requires.
  • ConflictError — The resource already exists or conflicts with existing state.
  • APIError — Any other non-2xx HTTP response (base class; exposes status_code and body).

Example

key = client.apikeys.create(
    labels={"env": "docs", "purpose": "sdk-doc-test"},
)


List API keys

apikeys.list() → list[ApiKeyResponse]

Retrieves a list of API keys belonging to the authenticated user. The list includes metadata about each key but not the actual key values or key hashes for security reasons. Requires LIST_APIKEY_OWN permission (or LIST_APIKEY_ANY for admin users to view keys from any user). This is a read-only operation with no side effects.

Returns:

list[ApiKeyResponse]

Raises:

  • PermissionDeniedError — The caller lacks the permission the operation requires.
  • APIError — Any other non-2xx HTTP response (base class; exposes status_code and body).

Example

for key in client.apikeys.list():
    print(key.api_key_id, key.status)


Update an API key

apikeys.update(*, id: str, request: UpdateApiKeyRequest | dict) → ApiKeyResponse

Updates an existing API key with new values for status or labels.

IMPORTANT: Key ID, user ownership, key material, and audit fields cannot be modified - only status (ACTIVE/INACTIVE) and labels are mutable. Requires UPDATE_APIKEY_OWN permission for keys you own (or UPDATE_APIKEY_ANY for admin users to modify any user's keys). Side effects include updating the updated_at timestamp and recording the updater's user ID. This operation is idempotent - repeated identical requests have no additional effect.

Parameters:

  • id (str) — The unique identifier of the resource to update.
  • request (UpdateApiKeyRequest | dict) — The update payload. Accepts a UpdateApiKeyRequest instance or a plain dict with the same fields. Only specified fields will be modified.

Returns:

ApiKeyResponse — Returns the API key metadata.

Raises:

  • PermissionDeniedError — The caller lacks the permission the operation requires.
  • APIError — Any other non-2xx HTTP response (base class; exposes status_code and body).

Example

from goodmem.types import UpdateApiKeyRequest
# Option 1: typed request object
updated = client.apikeys.update(id="your-api-key-id", request=UpdateApiKeyRequest(
    merge_labels={"updated": "true"},
))
assert updated.api_key_id == "your-api-key-id"
# Option 2: plain dict (validated via pydantic)
updated = client.apikeys.update(id="your-api-key-id", request={
    "merge_labels": {"updated": "true"},
})
assert updated.api_key_id == "your-api-key-id"


Delete an API key

apikeys.delete(*, id: str) → None

Permanently deletes an API key. This operation cannot be undone and immediately invalidates the key for all future authentication attempts.

TIP: For reversible deactivation, use PUT /v1/apikeys/{id} with status=INACTIVE instead. Requires DELETE_APIKEY_OWN permission for keys you own (or DELETE_APIKEY_ANY for admin users to delete any user's keys). Side effects include permanently removing the key record from the database and immediate authentication invalidation.

Parameters:

  • id (str) — The UUID of the API key to delete

Returns:

None

Raises:

  • PermissionDeniedError — The caller lacks the permission the operation requires.
  • APIError — Any other non-2xx HTTP response (base class; exposes status_code and body).

Example

client.apikeys.delete(id="your-api-key-id")


Async usage: client.apikeys exposes the same methods on AsyncGoodmem; use await / async for as needed.


Data Models

All data models are pydantic v2 models. Fields are shown with their Python attribute names; JSON responses use camelCase aliases (e.g., owner_idownerId).

CreateApiKeyResponse

Response returned when creating a new API key.

  • api_key_metadata (ApiKeyResponse, optional) — Metadata for the created API key.
  • raw_api_key (str, optional) — The actual API key value. This is only returned once and cannot be retrieved again.

ApiKeyResponse

API key metadata without sensitive information.

  • api_key_id (str) — Unique identifier for the API key.
  • user_id (str) — ID of the user that owns this API key.
  • key_prefix (str) — First few characters of the key for display/identification purposes.
  • status (Optional[Literal['STATUS_UNSPECIFIED', 'ACTIVE', 'INACTIVE']]) — Current status of the API key: ACTIVE, INACTIVE, or STATUS_UNSPECIFIED.
  • labels (dict[str, str]) — User-defined labels for organization and filtering.
  • expires_at (int, optional) — Expiration timestamp in milliseconds since epoch. If not provided, the key does not expire.
  • last_used_at (int, optional) — Last time this API key was used, in milliseconds since epoch.
  • created_at (int) — When the API key was created, in milliseconds since epoch.
  • updated_at (int) — When the API key was last updated, in milliseconds since epoch.
  • created_by_id (str) — ID of the user that created this API key.
  • updated_by_id (str) — ID of the user that last updated this API key.

UpdateApiKeyRequest

Request parameters for updating an API key.

  • status (Literal['ACTIVE', 'INACTIVE'], optional) — New status for the API key. Allowed values: ACTIVE, INACTIVE.
  • replace_labels (dict[str, str], optional) — Replace all existing labels with this set. Mutually exclusive with merge_labels.
  • merge_labels (dict[str, str], optional) — Merge these labels with existing ones. Mutually exclusive with replace_labels.