Skip to content

Python SDK

Types

Pydantic models, enums, and discriminated unions returned across the SDK surface.

Every model is a frozen Pydantic BaseModel. Fields are snake_case and match the wire format. Models are exported from alter_sdk and alter_sdk.models.

from alter_sdk import (
TokenResponse, GrantInfo, ConnectSession, ConnectResult,
UnifiedGrantListResult, OAuthGrantItem, ManagedSecretGrantItem,
GrantListItem, GrantPolicy,
CreateGrantResult, RevokeGrantResult,
Principal, UserPrincipal, GroupPrincipal, SystemPrincipal, AgentPrincipal,
AgentInfo, AgentCreateResult, AgentListResult,
AgentKey, AgentKeyList, AgentKeyMintResult,
APIKeyInfo, MintedKey, ScopeCatalog, ResourceScopes,
ApprovalResult, ApprovalStatus, ApprovalStatusValue, PendingApproval,
AuthResult, AuthSession, APICallAuditLog,
OAuthProviderCatalog, OAuthProviderCatalogItem, OAuthProviderScopeInfo,
RetryInfo, RetryErrorInfo,
IdentityContext, IdentityTrace, MemoryScope, IdentityAssertion,
HttpMethod, CallerType, Provider,
)
HttpMethod.GET # "GET"
HttpMethod.POST # "POST"
HttpMethod.PUT # "PUT"
HttpMethod.PATCH # "PATCH"
HttpMethod.DELETE # "DELETE"
HttpMethod.HEAD # "HEAD"
HttpMethod.OPTIONS # "OPTIONS"

Plain strings are also accepted by every SDK method that takes method.

CallerType.AGENT # "agent"
CallerType.SERVICE # "service"

App defaults to SERVICE. Agent pins AGENT internally.

Static enum of OAuth provider identifiers. Members include GOOGLE, GITHUB, SLACK, STRIPE, MICROSOFT, NOTION, HUBSPOT, SALESFORCE, SHOPIFY, ZOOM, and dozens more (60+ values; see the source for the full list). Plain strings are also accepted for forward compatibility with providers not yet in the enum.

from alter_sdk import Provider
grants = await app.list_grants(provider_id=Provider.GOOGLE)
# str(Provider.GOOGLE) == "google"

OAuth token response. The plaintext access token is NOT stored as a readable attribute — the SDK injects it into outbound requests but never exposes it.

FieldTypeDescription
grant_idstrGrant id that provided this token.
token_typestrToken type. Default "Bearer".
expires_inint | NoneSeconds until expiry.
expires_atdatetime | NoneAbsolute expiration time.
scopeslist[str]OAuth scopes granted.
provider_idstr | NoneProvider id.
scope_mismatchboolTrue when the backend has flagged this grant as requiring re-authorization.

Methods: is_expired(buffer_seconds=0) -> bool, needs_refresh(buffer_seconds=300) -> bool.

Attached to response.retry_info when the backend refreshed a token after transient failures.

FieldTypeDescription
total_attemptsintTotal attempts made.
successful_attemptintWhich attempt succeeded (0 if none).
errorstuple[RetryErrorInfo, ...]Failed attempts (immutable).
FieldTypeDescription
attemptint1-based attempt index.
errorstrError message, truncated to 500 chars.
error_typestrError classification.
delay_sfloatSleep duration before the next attempt.
permanentboolWhether the error is permanent.

Legacy single-table grant shape. New code should use OAuthGrantItem / ManagedSecretGrantItem from the unified list.

FieldType
grant_idstr
provider_idstr
scopeslist[str]
account_identifierstr | None
account_display_namestr | None
statusstr
scope_mismatchbool
expires_atstr | None
created_atstr
last_used_atstr | None
principal_type"user" | "group" | "system" | "agent"

Returned by App.list_grants() and Agent.list_grants().

FieldTypeDescription
grantslist[GrantListItem]Discriminated-union items.
totalintTotal matching rows.
limitintPage size.
offsetintPage offset.
has_moreboolCanonical “more pages” signal. Prefer this over computing offsets against total.

Discriminated union by grant_kind:

GrantListItem = OAuthGrantItem | ManagedSecretGrantItem

grant_kind="oauth".

FieldTypeDescription
grant_kind"oauth"Discriminator.
grant_idstr
provider_idstr
scopeslist[str]
account_identifierstr | None
account_display_namestr | None
statusstr
scope_mismatchbool
expires_atstr | None
created_atstr
last_used_atstr | None
principal_type"user" | "system"
access_via"ownership" | "oauth_delegation"How the caller reached the grant.
delegated_atstr | NoneAgent-branch field: when the calling agent’s delegation row was created.
delegated_agent_idslist[str]Operator-branch field: agent UUIDs this grant is currently delegated to.

grant_kind="managed_secret". Returned for any managed-secret grant the caller can reach — an operator (App) list surfaces every principal kind the app owns; an agent list surfaces its own and delegated grants.

FieldType
grant_kind"managed_secret"
grant_idstr
managed_secret_idstr
managed_secret_slugstr
managed_secret_namestr
agent_idstr | None
labelstr | None
statusstr
account_identifierstr | None
grant_policydict | None
expires_atstr | None
created_atstr
last_used_atstr | None
principal_type"user" | "group" | "system" | "agent"
access_via"ownership" | "ms_delegation"
delegated_atstr | None
FieldType
grantslist[GrantInfo]
totalint
limitint
offsetint
has_morebool
FieldType
successbool
messagestr
grant_idstr
revoked_atstr
FieldType
grant_idstr
principal_type"user" | "group" | "system" | "agent"
labelstr | None
created_atstr
FieldTypeDescription
expires_atstr | NoneHard expiry timestamp (ISO 8601 UTC).
created_bystr | None"developer" or "end_user".
created_atstr | None

Principal = UserPrincipal | GroupPrincipal | SystemPrincipal | AgentPrincipal

The discriminator is type.

FieldTypeDescription
type"user"Discriminator.
user_tokenstrIDP JWT (1-8192 chars).
labelstr1-255 chars.
FieldTypeDescription
type"group"Discriminator.
external_group_idstr1-255 chars.
idp_idstrIdentity provider id (UUID), 1-255 chars.
labelstr1-255 chars.
FieldTypeDescription
type"system"Discriminator.
labelstr | NoneOptional, max 255 chars.
FieldTypeDescription
type"agent"Discriminator.
labelstr | NoneOptional, max 255 chars.

The agent is resolved from the API-key signature server-side — there is no agent_id on the wire.


FieldType
session_tokenstr
connect_urlstr
expires_inint
expires_atstr

Same shape as ConnectSession. __repr__ redacts connect_url (it carries the session token in the URL fragment).

FieldType
grant_idstr
provider_idstr
account_identifierstr | None
scopeslist[str]
grant_policyGrantPolicy | None
FieldTypeDescription
user_tokenstrIDP JWT bearer token.
user_infodict[str, Any]User info from IDP (sub, email, name).

Returned by create_auth_session(). __repr__ redacts auth_url (it carries the session token as the OIDC state parameter).

FieldTypeDescription
session_tokenstrHandle to poll with poll_auth_session(). Persistable.
auth_urlstrIDP sign-in URL to hand to the end user. Never log it.
expires_inintSeconds until the session expires.
expires_atstrISO 8601 expiry timestamp.

Returned by oauth_providers.list().

MemberTypeDescription
providersdict[str, OAuthProviderCatalogItem]Connectable providers, keyed by id ("<provider_id>", …).
get_default_scopes(provider)tuple[str, ...]Default scopes for a provider, or () if unknown. Accepts a string or Provider member.
get_required_scopes(provider)tuple[str, ...]Required scopes for a provider, or () if unknown.
FieldTypeDescription
idstrProvider id.
namestrInternal provider name.
display_namestrHuman-readable name.
categorystr | NoneProvider category.
descriptionstr | NoneShort description.
logo_urlstr | NoneLogo URL.
supports_refreshboolProvider issues refresh tokens.
supports_pkceboolProvider supports PKCE.
available_scopesdict[str, OAuthProviderScopeInfo]All requestable scopes, keyed by scope string.
default_scopeslist[str]Scopes pre-selected in a Connect flow.
required_scopeslist[str]Scopes that are always requested.
statusstrAlways "active" (only connectable providers are returned).
FieldTypeDescription
descriptionstrWhat the scope grants.
requiredboolScope is always requested.
is_defaultboolScope is pre-selected by default.

The managed-agent record. PII (HITL approver list) is redacted server-side.

FieldTypeDescription
idUUID
namestr
display_namestr | None
type"agent" | "service"
status"active" | "inactive" | "revoked"
scopesdict[str, Any]Per-provider scope allowlist.
scopes_pendingdict[str, Any] | NonePending narrowing (Phase G).
scopes_applies_atdatetime | None
policydict[str, Any]Validated policy block.
metadatadict[str, Any]
rate_limit_per_minuteint | None
versionintMonotonic version counter.
created_atdatetime
last_used_atdatetime | None
parent_agent_idUUID | NoneReserved; not currently exposed.

Extends AgentInfo. Adds:

FieldTypeDescription
api_keystr | NonePlaintext API key. Shown ONCE. None on idempotency replay (branch on api_key is None).
key_idUUIDThe api_keys row id backing this agent.
FieldType
agentslist[AgentInfo]
totalint
limitint
offsetint
has_morebool
FieldTypeDescription
key_idUUID
key_prefixstrDisplay-only key prefix.
namestrAuto-generated {agent_name}-{N} at mint time.
created_atdatetime
deprecated_atdatetime | None
revoked_atdatetime | None
last_used_atdatetime | None

Derived property: status"active" \| "deprecated" \| "revoked".

Extends AgentKey. Adds:

FieldTypeDescription
api_keystr | NonePlaintext. Shown ONCE.
FieldType
itemslist[AgentKey]

Read-only view of a scoped API key.

FieldType
idUUID
namestr
key_prefixstr
key_type"rk" | "ak" | "dk" | "pk"
scopeslist[str]
scope_versionint
cidr_allowlistlist[str] | None
rate_limit_rpmint | None
expires_atdatetime | None
deprecated_atdatetime | None
revoked_atdatetime | None
parent_key_idUUID | None
created_atdatetime
last_used_atdatetime | None

Derived property: status"active" \| "rotated" \| "revoked".

Extends APIKeyInfo. Adds:

FieldTypeDescription
api_keystrPlaintext. Shown ONCE.
FieldType
scope_versionint
resourcesdict[str, ResourceScopes]
action_verbslist[str]
deprecatedlist[str]
FieldType
verbslist[str]

A one-off deny rule passed to with_constraints(rule=...) — cryptographically bound to every request the constrained client makes and enforced on credential-using calls.

FieldType
rule_typestr
rule_bodydict

Returned by proxy_request() when an HITL grant requires approval.

FieldTypeDescription
approval_idUUIDApproval row id.
status"pending"Always "pending" on creation.
expires_atdatetimeWhen the approval window closes.
expires_inintSeconds until expires_at.
approval_urlstrDeep link to the approver’s wallet UI. Primary delivery — surface this in the agent’s UI.

Snapshot of an approval row.

FieldTypeDescription
approval_idUUID
statusApprovalStatusValueOne of the seven status values (see Connect & Grants).
expires_atdatetime
decided_atdatetime | None
decision_reasonstr | None
executed_atdatetime | None
has_resultboolTrue when the proxied result is ready to fetch.

Derived property: is_terminalTrue for denied, expired, executed, failed.

ApprovalStatusValue = Literal[
"pending", "approved", "executing",
"denied", "expired", "executed", "failed",
]

Provider response captured during backend-proxy execution. The body is base64-encoded.

FieldTypeDescription
approval_idUUID | NoneNone for synchronous (non-HITL) proxy_request responses.
status_codeintHTTP status from the provider.
headersdict[str, str]Provider response headers.
body_b64strBase64-encoded response body. Validated at construction.
body_truncatedbool

Methods:

  • body_bytes() -> bytes — decode to raw bytes.
  • body_text(encoding: str = "utf-8") -> str — decode to text.
  • body_json() -> Any — decode and parse JSON.

Audit row built for a provider call.

FieldType
grant_idUUID
provider_idstr
methodstr
urlstr
request_headersdict[str, str] | None
request_bodyAny | None
response_statusint
response_headersdict[str, str] | None
response_bodyAny | None
latency_msint
reasonstr | None
contextdict[str, str] | None

Method sanitize() -> dict[str, Any] strips sensitive headers (Authorization, Cookie, x-api-key, x-amz-*, etc.).


Returned by App.resolve_identity() and Agent.resolve_identity(). The canonical identity set the platform resolved for the request — key external data (memory partitions, channel sessions, authorization tuples) on these IDs, never on email or a raw IDP sub.

FieldTypeDescription
app_idstrThe calling application (tenant).
app_user_idstr | NoneCanonical end-user key. None for headless calls.
external_subject_idstr | NoneStable external join key — the IDP subject identifier.
idp_idstr | NoneIdentity provider the subject belongs to.
user_statusstr | None"active" | "suspended". Deprovisioned users are rejected at resolution, never returned.
group_idslist[str]Stable external group IDs of the user’s unrevoked memberships.
agent_idstr | NoneCanonical agent key. None for plain app callers.
actor_idstr | NoneAudit correlation label only — NOT a partition key.
traceIdentityTrace | NoneEcho of the ambient run/thread trace context.
emailstr | NoneOnly with include_profile=True.
display_namestr | NoneOnly with include_profile=True.

Method memory_scope() -> MemoryScope derives the deterministic memory partition keys. See Propagate identity into memory layers.

FieldType
run_idstr | None
thread_idstr | None

Deterministic, prefixed partition keys derived from an IdentityContext.

FieldTypeDescription
user_keystr | None"alter:user:<app_user_id>"; None for headless contexts.
agent_keystr | None"alter:agent:<agent_id>"; None for app callers.
app_keystr"alter:app:<app_id>".
run_keystr | None"alter:run:<run_id>" from the trace context.
namespacetuple[str, ...]("alter", <app_id>, <app_user_id>); ("alter", <app_id>) headless.

Returned by App.assert_identity() and Agent.assert_identity().

FieldTypeDescription
tokenstrCompact ES256 JWS — verify against the published Alter identity JWKS. Redacted from repr().
expires_atdatetimeAbsolute expiry (short TTL by design — default 120s, bounds 10–300s).
identityIdentityContextThe identity the assertion encodes.

The assertion is identity-only: it carries no provider tokens, no credentials, no raw IDP claims, and grants nothing by itself — downstream systems map it to their own authorization.