Skip to content

Reference

Types

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

Fields are snake_case and match the wire format. Most Pydantic models are frozen. APICallAuditLog, UserSpan, and EmitSpansResult are mutable Pydantic models; RequestRule and ContentParamCondition are TypedDict shapes.

from alter_sdk import (
TokenResponse, GrantInfo, ConnectSession, ConnectResult,
UnifiedGrantListResult, OAuthGrantItem, ManagedSecretGrantItem,
GrantListItem, GrantPolicy, GrantPolicyInput, ConnectFailedGrant,
CreateGrantResult, RevokeGrantResult, DelegationResult,
Principal, PrincipalType, NonGroupPrincipalType,
UserPrincipal, GroupPrincipal, SystemPrincipal, AgentPrincipal,
AgentInfo, AgentCreateResult, AgentListResult,
AgentKey, AgentKeyList, AgentKeyMintResult,
APIKeyInfo, MintedKey, ScopeCatalog, ResourceScopes,
ApprovalGate, ApprovalGateStatus,
ApprovalResult, ApprovalStatus, ApprovalStatusValue, PendingApproval,
AuthResult, AuthSession, APICallAuditLog,
OAuthProviderCatalog, OAuthProviderCatalogItem, OAuthProviderScopeInfo,
ProviderSpec, ProviderSpecKind,
SpecOperation, SpecOperationsPage, SpecOperationDetail,
RetryInfo, RetryErrorInfo, RateLimitSnapshot,
RequestRule, ContentMatchEffect, ContentMatchFamily,
ContentParamCondition, ContentParamOp, content_match_rule,
UserSpan, EmitSpansResult,
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. It contains the provider ids available when the SDK version was published. Methods also accept plain strings for forward compatibility with provider ids added after that release.


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 instant this credential stops working — the binding value: the earlier of the provider token’s own expiry and the grant’s TTL. Caching past it produces an authorization failure, not a refresh.
token_expires_atdatetime | NoneThe provider token’s own expiry, independent of the grant’s TTL. The only clock a refresh can move.
grant_expires_atdatetime | NoneThe grant’s own TTL instant (the access duration chosen at consent); None when the grant has no TTL.
scopeslist[str]OAuth scopes granted.
provider_idstr | NoneProvider id.
scope_mismatchboolTrue when the backend has flagged this grant as requiring re-authorization.
injection_headerstrCredential-injection header name. Excluded from model_dump().
injection_formatstrCredential-injection value format. Excluded from model_dump().
additional_credentialsdict[str, str] | NoneAdditional non-exposed credential metadata for multipart authentication. Excluded from model_dump().
additional_injectionslist[dict[str, str]] | NoneAdditional header or query injection rules. Excluded from model_dump().

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

The two answer different questions and read different fields. is_expired() reads expires_at — whether the credential still works. needs_refresh() reads token_expires_at — whether refreshing would help.

They diverge whenever the grant’s TTL is the earlier of the two clocks: the credential is about to stop working, but a refresh cannot extend permission and the correct response is re-consent. Compare grant_expires_at to tell which clock is binding.

Frozen snapshot exposed as last_rate_limit on App, Agent, and constrained clients.

FieldTypeDescription
limitintBinding requests-per-minute ceiling for the response.
remainingintRequests remaining against that binding ceiling.
reset_atdatetimeAware UTC instant when the reported window resets.

The value is None until a metered response supplies the standard RateLimit-Policy / RateLimit pair or the compatibility X-RateLimit-* triple. A later unmetered response does not erase the last reading. Provider response headers are not captured because they describe the provider’s budget, not Alter’s.

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.

Metadata shape returned by App.mint_grant(), and retained for legacy grant responses. App.list_grants() and Agent.list_grants() return OAuthGrantItem / ManagedSecretGrantItem through the unified list instead.

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"
labelstr | None
credential_idstr | None
grant_policydict[str, Any] | None

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
needs_reconnectboolConnection health (a separate axis from status): True when the grant is active but its provider token broke and needs re-auth. A call against it may raise ReAuthRequiredError (a recoverable break self-heals transparently on the next call); the flag clears on a successful refresh or a reconnect.
expires_atstr | NoneThe provider token’s expiry (auto-refreshed — never a grant terminal).
grant_expires_atstr | NoneThe grant’s own TTL-policy expiry (the access duration chosen at consent). A different axis from expires_at; None = perpetual. status reads "expired" once this instant passes, even before the record is lazily flipped.
created_atstr
last_used_atstr | None
principal_type"user" | "system" | "agent"The "agent" value marks a delegation child surfaced as its own row in the operator list.
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.
labelstr | NoneStable sibling-grant address within the credential.
credential_idstr | NoneShared credential id used to group sibling grants.
grant_policydict[str, Any] | NonePer-grant policy.
parent_grant_idstr | NoneThe grant this one was minted under. None marks a root (a directly-consented grant).
depthintHop distance from the root (0 at the root). With parent_grant_id, lets a caller reconstruct the delegation tree from the flat list.
delegableboolWhether this grant may be re-delegated onward to another agent. Always present (defaults False).
scope_constraintlist[str] | NoneThe narrowed provider-scope subset this delegated grant is clamped to. None = inherits the parent/credential scope.

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
grant_expires_atstr | None
created_atstr
last_used_atstr | None
principal_type"user" | "group" | "system" | "agent"
access_via"ownership" | "ms_delegation"
delegated_atstr | None
parent_grant_idstr | None
depthint
delegablebool
scope_constraintlist[str] | None
FieldType
successbool
messagestr
grant_idstr
revoked_atstr
FieldType
grant_idstr
principal_type"user" | "group" | "system" | "agent"
labelstr | None
created_atstr

Returned by agent.delegate() — the child grant minted onto another agent.

FieldTypeDescription
grant_idstrThe new child grant.
grant_kind"oauth" | "managed_secret"Which credential family the child belongs to.
parent_grant_idstrThe held grant the child was minted under (always set — a delegation result is always a child).
depthintThe child’s hop distance from the root (always >= 1).
delegableboolWhether the recipient may re-delegate this child onward.
statusstrGrant status (e.g. "active").
expires_atstr | NoneChild expiry, clamped to the parent’s lifetime.
FieldTypeDescription
expires_atstr | NoneHard expiry timestamp (ISO 8601 UTC).
created_bystr | None"developer" or "end_user".
created_atstr | None

Input model accepted by Connect and sibling-grant minting methods.

FieldTypeDescription
expires_atstr | NoneHard expiry timestamp (ISO 8601 UTC).
max_ttl_secondsint | NonePositive maximum TTL in seconds.
default_ttl_secondsint | NonePositive pre-selected TTL; must not exceed max_ttl_seconds.

Principal = UserPrincipal | GroupPrincipal | SystemPrincipal | AgentPrincipal

The discriminator is type.

PrincipalType is Literal["user", "group", "system", "agent"]. NonGroupPrincipalType is Literal["user", "system", "agent"] and is used by OAuth grant models, where group principals are not supported.

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
scope_constraint_warningslist[str]

scope_constraint_warnings (default []) carries one diagnostic per provider whose required scopes the requested scope_constraint admits nothing against — the session still succeeds, but a grant minted from it would deny every call until the constraint is widened.

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

FieldType
session_tokenstr
connect_urlstr
expires_inint
expires_atstr
FieldType
grant_idstr
provider_idstr
account_identifierstr | None
scopeslist[str]
grant_policyGrantPolicy | None
failed_grantslist[ConnectFailedGrant]

One provider whose newly authorized grant was revoked because the selected usage limits could not be applied.

FieldTypeDescription
provider_idstrProvider id.
reasonstrMachine-readable failure reason. Unknown values are retained.
messagestrOperator-safe failure message.
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.

ProviderSpecKind = Literal["oauth", "managed"]
FieldTypeDescription
provider_kindstrProvider family ("oauth" or "managed").
provider_idstrProvider identifier.
versionintMonotonic stored-spec version.
provenancestrIngestion source.
source_urlstr | NoneUpstream spec URL when known.
content_hashstrHash of the ingested content.
operation_countintNumber of operations in the spec.
fetched_atdatetimeMost recent ingestion time.
changed_atdatetimeTime the active content version last changed.
titlestr | NoneSpec title when present.
spec_versionstr | NoneUpstream spec version when present.
FieldType
operation_idstr
methodstr
path_templatestr
summarystr | None
FieldTypeDescription
itemslist[SpecOperation]Operations on this page.
totalintTotal matching operations.
limitintPage size.
offsetintPage offset.
has_moreboolWhether another page exists.
specProviderSpecMetadata for the active spec that served the page.
FieldType
operation_idstr
methodstr
path_templatestr
summarystr | None
params_schemalist[dict[str, Any]] | None
request_schemadict[str, Any] | None
response_schemadict[str, Any] | None
specProviderSpec

See Provider discovery for the namespace methods.


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
effective_rate_limit_rpmint | None
rate_limit_source"key" | "organization" | "platform_default" | 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".

rate_limit_rpm is the per-key override chosen at mint time; None means no override, not unlimited. effective_rate_limit_rpm is the requests-per-minute ceiling actually enforced for the key once the organization ceiling and the platform default are applied, and rate_limit_source names which of those produced it. Throttling decisions should read effective_rate_limit_rpm. Both are optional on parse: a backend that does not report them leaves each None, which means not reported — never unlimited. A live backend always sends both.

Extends APIKeyInfo. Adds:

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

A TypedDict 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

content_match_rule() uses these exported type aliases:

ContentMatchEffect = Literal["deny", "redact", "step_up"]
ContentMatchFamily = Literal["send", "read", "write", "delete", "admin", "payment"]
ContentParamOp = Literal[
"equals", "any_in", "not_subset_of",
"gt", "gte", "lt", "lte",
]

ContentParamCondition is a TypedDict:

FieldType
namestr
opContentParamOp
valuestr | int | float | list[str]

Numeric operands must be finite. any_in and not_subset_of take a non-empty list of pattern strings. See content_match_rule() for authoring and validation behavior.


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

FieldTypeDescription
approval_idUUIDApproval row id.
approval_group_idUUIDShared execution unit for all gates.
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.
gateslist[ApprovalGate]Every approver gate; each must approve before execution.

One approver gate in a pending N-of-N approval group.

FieldType
approval_idUUID
expires_atdatetime
expires_inint
approval_urlstr

Snapshot of an approval row.

FieldTypeDescription
approval_idUUID
statusApprovalStatusValueOne of the seven status values (see Connect & Grants).
approval_group_idUUIDShared execution unit for the gate group.
gateslist[ApprovalGateStatus]Per-gate status breakdown.
expires_atdatetime
decided_atdatetime | None
decision_reasonstr | None
executed_atdatetime | None
execution_errorstr | NoneOperator-safe execution failure when status="failed".
has_resultboolTrue when the proxied result is ready to fetch.

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

FieldType
approval_idUUID
statusApprovalStatusValue
expires_atdatetime
decided_atdatetime | None
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
duration_msint | NoneProvider round-trip duration when available.
credential_hintstr | NoneWhy the provider rejected the credential, when the cause is the API surface rather than the credential. Only ever set on 401/403.

credential_hint addresses a specific dead end. Some providers run several APIs that accept the same credential but expect it in different headers, so a perfectly valid key is rejected with 401 purely because the request went to the other API. The provider’s own error blames the key, and the natural response — rotating it — changes nothing. When the rejection matches that pattern, credential_hint says so.

It is None on success and on any rejection that does not match, and it never changes status_code or the body: the provider’s response is passed through unchanged and the hint accompanies it. A blank hint is normalized to None, so if result.credential_hint: is the correct test for “is there an explanation”. The SDK does not reject a hint that arrives on an unexpected status — the status rule is the backend’s to enforce, and re-checking it client-side would turn a future backend addition into a hard failure in already-installed SDKs.

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
timestampdatetime
reasonstr | None
contextdict[str, str] | None

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


FieldTypeDescription
trace_idstrRequired trace identifier.
namestrRequired span name.
start_timedatetimeRequired start time.
span_idstr | NoneStable id for idempotent retries.
parent_span_idstr | NoneParent span id.
end_timedatetime | NoneEnd time.
attributesdict[str, str]Caller-defined string attributes.
FieldTypeDescription
acceptedintNumber of newly stored spans; idempotent duplicates are not recounted.

See spans.emit() for batch limits.


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.

Report an issue with this page

Necessary

Required for sign-in, security, authorization, and remembering your choices.

Always active

Analytics

Helps us understand which product and documentation features are useful.

Performance diagnostics

Uses performance tracing and privacy-masked session replay to diagnose problems.

You can change these choices at any time from Cookie settings.