Skip to content

Reference

Types

Public models, interfaces, and enums exported from @alter-ai/alter-sdk.

Every shape on this page is exported from the package root:

import type {
AlterResponse,
AlterLogger,
ApprovalResult,
ConnectSession,
RateLimitSnapshot,
IdentityContext,
IdentityAssertion,
MemoryScope,
// …
} from "@alter-ai/alter-sdk";

Wire format from the backend is snake_case. Exported model classes accept their documented wire shape in constructors and expose camelCase properties. Most model classes provide toJSON() in snake_case; exceptions are called out below.

Pluggable logger hook. Defaults to the global console.

interface AlterLogger {
warn: (message: string, ...args: unknown[]) => void;
info?: (message: string, ...args: unknown[]) => void;
error?: (message: string, ...args: unknown[]) => void;
debug?: (message: string, ...args: unknown[]) => void;
}

The SDK calls warn for non-fatal diagnostics and debug when optional token-refresh retry metadata is ignored or parsed. info and error are accepted for logger compatibility but are not currently called.

The return type of request().

interface AlterResponse extends Response {
readonly retryInfo: RetryInfo | null;
}

Standard Response plus retryInfo — populated when the backend retried a token refresh; null when the token was served from cache or refreshed on the first attempt.

OAuth token metadata. The plaintext access token is never exposed on this object; the SDK injects it into outgoing requests at call time.

FieldTypeDescription
tokenTypestringUsually "Bearer".
expiresInnumber | nullSeconds until expiry.
expiresAtDate | nullAbsolute 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.
tokenExpiresAtDate | nullThe provider token’s own expiry, independent of the grant’s TTL. The only clock a refresh can move.
grantExpiresAtDate | nullThe grant’s own TTL instant (the access duration chosen at consent); null when the grant has no TTL.
scopesstring[]Scopes granted.
grantIdstringGrant the token resolves to.
providerIdstring | nullProvider slug.
scopeMismatchbooleanThe grant’s scopes no longer cover the configured required set.
injectionHeaderstringHTTP header name used for credential injection.
injectionFormatstringFormat string with a {token} placeholder.
additionalCredentialsRecord<string, string> | nullNon-secret metadata for multi-part authentication. Credential-bearing entries used internally are stripped before this property is exposed; null means no safe entries remain.
additionalInjectionsReadonlyArray<{ target: string; key: string; valueSource: string }> | nullValidated multi-header or query-parameter injection rules. Runtime target values are "header" or "query_param"; the wire value_source field is exposed as valueSource.

Helpers:

  • isExpired(bufferSeconds?: number): boolean
  • needsRefresh(bufferSeconds?: number): boolean

The two answer different questions and read different fields. isExpired() reads expiresAt — whether the credential still works. needsRefresh() reads tokenExpiresAt — 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 grantExpiresAt to tell which clock is binding.

Frozen model exposed as lastRateLimit on App, Agent, and constrained clients.

FieldTypeDescription
limitnumberBinding requests-per-minute ceiling for the response.
remainingnumberRequests remaining against that binding ceiling.
resetAtDateInstant when the reported window resets.

toJSON() emits { limit, remaining, reset_at } with an ISO-8601 timestamp. The value is null 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.

Metadata about retry attempts during token refresh.

FieldType
totalAttemptsnumber
successfulAttemptnumber
errorsReadonlyArray<RetryErrorInfo>

One failed attempt.

FieldType
attemptnumber
errorstring
errorTypestring
delaySnumber
permanentboolean

A single-grant record.

FieldType
grantIdstring
providerIdstring
scopesstring[]
accountIdentifierstring | null
accountDisplayNamestring | null
statusstring
scopeMismatchboolean
expiresAtstring | null
createdAtstring
lastUsedAtstring | null
principalType"user" | "group" | "system" | "agent"
labelstring | null
credentialIdstring | null
grantPolicyRecord<string, unknown> | null

Returned by listGrants().

FieldType
grantsGrantListItem[]
totalnumber
limitnumber
offsetnumber
hasMoreboolean

Discriminated union over grantKind.

type GrantListItem = OAuthGrantItem | ManagedSecretGrantItem;
FieldType
grantKind"oauth"
grantIdstring
providerIdstring
scopesstring[]
accountIdentifierstring | null
accountDisplayNamestring | null
statusstring
scopeMismatchboolean
needsReconnectboolean
expiresAtstring | null
grantExpiresAtstring | null
createdAtstring
lastUsedAtstring | null
principalType"user" | "system" | "agent"
accessVia"ownership" | "oauth_delegation"
delegatedAtstring | null
delegatedAgentIdsstring[]
labelstring | null
credentialIdstring | null
grantPolicyRecord<string, unknown> | null
parentGrantIdstring | null
depthnumber
delegableboolean
scopeConstraintstring[] | null

The "agent" value on principalType marks a delegation child surfaced as its own row. parentGrantId names the grant this one was minted under (null = a root), and depth is its hop distance from the root — together they reconstruct the delegation tree from the flat list. delegable is whether the grant may be re-delegated onward; scopeConstraint is the narrowed provider-scope subset (null = inherits the parent/credential scope).

grantExpiresAt and expiresAt are two different axes: grantExpiresAt is the grant’s own TTL-policy expiry (the access duration chosen at consent; null = perpetual), while expiresAt is the underlying provider token’s expiry (auto-refreshed, never a grant terminal). status reads "expired" once grantExpiresAt has passed, even before the record is lazily flipped — so filtering on status never caches access that has actually lapsed.

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
grantKind"managed_secret"
grantIdstring
managedSecretIdstring
managedSecretSlugstring
managedSecretNamestring
agentIdstring | null
labelstring | null
statusstring
accountIdentifierstring | null
grantPolicyRecord<string, unknown> | null
expiresAtstring | null
grantExpiresAtstring | null
createdAtstring
lastUsedAtstring | null
principalType"user" | "group" | "system" | "agent"
accessVia"ownership" | "ms_delegation"
delegatedAtstring | null
parentGrantIdstring | null
depthnumber
delegableboolean
scopeConstraintstring[] | null

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

FieldTypeDescription
grantIdstringThe new child grant.
grantKind"oauth" | "managed_secret"Which credential family the child belongs to.
parentGrantIdstringThe held grant the child was minted under (always set — a delegation result is always a child).
depthnumberThe child’s hop distance from the root (always >= 1).
delegablebooleanWhether the recipient may re-delegate this child onward.
statusstringGrant status (e.g. "active").
expiresAtstring | nullChild expiry, clamped to the parent’s lifetime.

Discriminated union passed to createManagedSecretGrant().

type Principal = UserPrincipal | GroupPrincipal | SystemPrincipal | AgentPrincipal;

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

FieldType
type"user"
userTokenstring
labelstring
FieldType
type"group"
externalGroupIdstring
idpIdstring
labelstring
FieldType
type"system"
label?string | null
FieldType
type"agent"
label?string | null

Returned by createManagedSecretGrant().

FieldType
grantIdstring
principalType"user" | "group" | "system" | "agent"
labelstring | null
createdAtstring

Returned by revokeGrant().

FieldType
successboolean
messagestring
grantIdstring
revokedAtstring

Per-grant policy.

FieldType
expiresAt?string | null
createdBy?string | null
createdAt?string | null

Camel-case policy input accepted by createConnectSession(), createConnectSessionForError(), connect(), and createManagedSecretGrant(). Unknown keys throw AlterValueError; null values are omitted from the snake-case wire body.

FieldTypeDescription
expiresAt?string | nullNon-empty ISO 8601 absolute expiry.
maxTtlSeconds?number | nullPositive integer maximum TTL in seconds.
defaultTtlSeconds?number | nullPositive integer pre-selected TTL in seconds. The backend enforces that it does not exceed maxTtlSeconds.

One provider connection that was revoked after authorization because the selected usage limits could not be applied.

FieldType
providerIdstring
reasonstring
messagestring

Returned by createConnectSession().

FieldType
sessionTokenstring
connectUrlstring
expiresInnumber
expiresAtstring
scopeConstraintWarningsreadonly string[]

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

Returned by createManagedSecretConnectSession(). Same shape as ConnectSession minus scopeConstraintWarnings.

toString() redacts connectUrl — the URL fragment carries the session token, so logging would be a leak.

Returned per provider by connect() and pollConnectSession().

FieldType
grantIdstring
providerIdstring
accountIdentifierstring | null
scopesstring[]
grantPolicyGrantPolicy | null
failedGrantsConnectFailedGrant[]

failedGrants is empty on full success. Each successful result from a partially completed multi-provider session carries the same failure list.

Returned by authenticate() and pollAuthSession().

FieldType
userTokenstring
userInfoRecord<string, unknown>

Returned by createAuthSession(). toString() redacts authUrl (it carries the session token as the OIDC state parameter).

FieldTypeDescription
sessionTokenstringHandle to poll with pollAuthSession(). Persistable.
authUrlstringIDP sign-in URL to hand to the end user. Never log it.
expiresInnumberSeconds until the session expires.
expiresAtstringISO 8601 expiry timestamp.

Returned by oauthProviders.list().

MemberTypeDescription
providersReadonly<Record<string, OAuthProviderCatalogItem>>Connectable providers, keyed by id ("<providerId>", …).
getDefaultScopes(provider)readonly string[]Default scopes for a provider, or [] if unknown.
getRequiredScopes(provider)readonly string[]Required scopes for a provider, or [] if unknown.

Options accepted by oauthProviders.list().

interface OAuthProviderCatalogListOptions {
readonly forceRefresh?: boolean;
}

forceRefresh defaults to false. When true, the call bypasses the five-minute in-process cache.

FieldTypeDescription
idstringProvider id.
namestringInternal provider name.
displayNamestringHuman-readable name.
categorystring | nullProvider category.
descriptionstring | nullShort description.
logoUrlstring | nullLogo URL.
supportsRefreshbooleanProvider issues refresh tokens.
supportsPkcebooleanProvider supports PKCE.
availableScopesReadonly<Record<string, OAuthProviderScopeInfo>>All requestable scopes, keyed by scope string.
defaultScopesreadonly string[]Scopes pre-selected in a Connect flow.
requiredScopesreadonly string[]Scopes that are always requested.
statusstringAlways "active" (only connectable providers are returned).
FieldTypeDescription
descriptionstringWhat the scope grants.
requiredbooleanScope is always requested.
isDefaultbooleanScope is pre-selected by default.

One approver gate in an N-of-N approval group.

FieldType
approvalIdstring
expiresAtDate
expiresInnumber
approvalUrlstring

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

FieldType
approvalIdstring
approvalGroupIdstring
status"pending"
expiresAtDate
expiresInnumber
approvalUrlstring
gatesreadonly ApprovalGate[]

Discriminate from ApprovalResult with result instanceof PendingApproval or result.status === "pending".

Per-gate progress in an approval group.

FieldType
approvalIdstring
statusApprovalStatusValue
expiresAtDate
decidedAtDate | null

Snapshot returned by getApprovalStatus().

FieldType
approvalIdstring
approvalGroupIdstring
statusApprovalStatusValue
gatesreadonly ApprovalGateStatus[]
expiresAtDate
decidedAtDate | null
decisionReasonstring | null
executedAtDate | null
hasResultboolean
executionErrorstring | null

Helpers:

  • isTerminal: booleantrue when status is denied, expired, executed, or failed.
type ApprovalStatusValue =
| "pending"
| "approved"
| "executing"
| "denied"
| "expired"
| "executed"
| "failed";

Returned by awaitApproval() and the synchronous branch of proxyRequest().

FieldType
approvalIdstring | null
statusCodenumber
headersRecord<string, string>
bodyB64string
bodyTruncatedboolean
durationMsnumber | null
credentialHintstring | null

approvalId is null for the synchronous (non-HITL) branch of proxyRequest() — there was no approval row.

durationMs is the provider round-trip duration. It is null for responses produced by workers that predate this observation. ApprovalResult.toJSON() intentionally omits this observational field.

credentialHint 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, credentialHint says so.

It is null on success and on any rejection that does not match. It never changes statusCode or the body: the provider’s response is passed through unchanged and the hint accompanies it. Unlike durationMs it is serialized by toJSON() — it is part of the result’s meaning rather than a measurement of one attempt. A blank hint is normalized to null, so if (result.credentialHint) 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.

Helpers:

  • bodyBytes(): Uint8Array
  • bodyText(encoding?: BufferEncoding | "utf-8"): string
  • bodyJson(): unknown

A managed agent record. Returned by app.agents.get, app.agents.update, agent.me, and others.

FieldType
idstring
namestring
displayNamestring | null
typeAgentType
statusAgentStatus
scopesRecord<string, unknown>
scopesPendingRecord<string, unknown> | null
scopesAppliesAtDate | null
policyRecord<string, unknown>
metadataRecord<string, unknown>
rateLimitPerMinutenumber | null
versionnumber
createdAtDate
lastUsedAtDate | null
parentAgentIdstring | null
type AgentType = "agent" | "service";
type AgentStatus = "active" | "inactive" | "revoked";

Extends AgentInfo with the freshly-minted plaintext API key.

FieldType
apiKeystring | null
keyIdstring

apiKey is null on an idempotency-replay — the plaintext is not server-side recoverable. Branch on result.apiKey === null rather than treating any returned value as a usable key.

FieldType
agentsAgentInfo[]
totalnumber
limitnumber
offsetnumber
hasMoreboolean

A single API key bound to a managed agent.

FieldType
keyIdstring
keyPrefixstring
namestring
createdAtDate
deprecatedAtDate | null
revokedAtDate | null
lastUsedAtDate | null

Computed property:

  • status: AgentKeyStatus"revoked" when revokedAt is set, "deprecated" when deprecatedAt is set, "active" otherwise.
type AgentKeyStatus = "active" | "deprecated" | "revoked";

Extends AgentKey with the plaintext apiKey (returned exactly once).

FieldType
apiKeystring | null
class AgentKeyList { readonly items: AgentKey[] }

A scoped API key (not bound to a managed agent).

FieldType
idstring
namestring
keyPrefixstring
keyType"rk" | "ak" | "dk" | "pk"
scopesreadonly string[]
scopeVersionnumber
cidrAllowlistreadonly string[] | null
rateLimitRpmnumber | null
effectiveRateLimitRpmnumber | null
rateLimitSource"key" | "organization" | "platform_default" | null
expiresAtstring | null
deprecatedAtstring | null
revokedAtstring | null
parentKeyIdstring | null
createdAtstring
lastUsedAtstring | null
status"active" | "rotated" | "revoked"

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

Extends APIKeyInfo with the plaintext.

FieldType
apiKeystring

Returned by scopes.list().

FieldType
scopeVersionnumber
resourcesReadonly<Record<string, ResourceScopes>>
actionVerbsreadonly string[]
deprecatedreadonly string[]
interface ResourceScopes {
readonly verbs: readonly string[];
}

A request rule passed to withConstraints({ rule }) — cryptographically bound to every request the constrained client makes and enforced on credential-using calls.

interface RequestRule {
ruleType: string;
ruleBody: Record<string, unknown>;
}

Inputs to contentMatchRule(options), which returns a RequestRule.

type ContentParamOp =
| "equals"
| "any_in"
| "not_subset_of"
| "gt"
| "gte"
| "lt"
| "lte";
type ContentMatchEffect = "deny" | "redact" | "step_up";
type ContentMatchFamily =
| "send"
| "read"
| "write"
| "delete"
| "admin"
| "payment";
interface ContentParamCondition {
name: string;
op: ContentParamOp;
value: string | number | readonly string[];
}
interface ContentMatchRuleOptions {
operations?: readonly string[];
families?: readonly ContentMatchFamily[];
params?: readonly ContentParamCondition[];
effect?: ContentMatchEffect;
redactFields?: readonly string[];
maxSessionAgeSeconds?: number;
}

At least one of operations or families is required. effect defaults to "deny". redactFields is required only for "redact"; maxSessionAgeSeconds is required only for "step_up" and must be an integer in [1, 86400].

Input to client.spans.emit().

FieldType
traceIdstring
namestring
startTimeDate | string
spanId?string
parentSpanId?string
endTime?Date | string
attributes?Readonly<Record<string, string>>

MAX_SPANS_PER_BATCH is the exported batch cap (50). spans.emit() accepts from 1 through MAX_SPANS_PER_BATCH items.

Returned by client.spans.emit().

FieldType
acceptednumber

Audit payload model used by retrieve-mode provider-call reporting.

FieldType
grantIdstring
providerIdstring
methodstring
urlstring
requestHeadersRecord<string, string> | null
requestBodyunknown
responseStatusnumber
responseHeadersRecord<string, string> | null
responseBodyunknown
latencyMsnumber
timestampDate
reasonstring | null
contextRecord<string, string> | null

sanitize() returns the snake_case submission shape after filtering sensitive headers. This class exposes sanitize() rather than toJSON().

Returned by app.resolveIdentity() and agent.resolveIdentity(). 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
appIdstringThe calling application (tenant).
appUserIdstring | nullCanonical end-user key. null for headless calls.
externalSubjectIdstring | nullStable external join key — the IDP subject identifier.
idpIdstring | nullIdentity provider the subject belongs to.
userStatusstring | null"active" | "suspended". Deprovisioned users are rejected at resolution, never returned.
groupIdsreadonly string[]Stable external group IDs of the user’s unrevoked memberships.
agentIdstring | nullCanonical agent key. null for plain app callers.
actorIdstring | nullAudit correlation label only — NOT a partition key.
traceIdentityTrace | nullEcho of the ambient run/thread trace context.
emailstring | nullOnly with includeProfile: true.
displayNamestring | nullOnly with includeProfile: true.

Method memoryScope(): MemoryScope derives the deterministic memory partition keys. See Propagate identity into memory layers.

FieldType
runIdstring | null
threadIdstring | null

Deterministic, prefixed partition keys derived from an IdentityContext.

FieldTypeDescription
userKeystring | null"alter:user:<app_user_id>"; null for headless contexts.
agentKeystring | null"alter:agent:<agent_id>"; null for app callers.
appKeystring"alter:app:<app_id>".
runKeystring | null"alter:run:<run_id>" from the trace context.
namespacereadonly string[]["alter", <app_id>, <app_user_id>]; ["alter", <app_id>] headless.

Returned by app.assertIdentity() and agent.assertIdentity().

FieldTypeDescription
tokenstringCompact ES256 JWS — verify against the published Alter identity JWKS. Redacted from toString() / inspect output.
expiresAtDateAbsolute 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.

type ProviderSpecKind = "oauth" | "managed";

This union validates and types the kind argument on providerSpecs methods. ProviderSpec.providerKind remains a broader string to match the Python SDK’s wire model, so a newly introduced backend value does not fail in TypeScript while the Python model accepts it.

FieldType
providerKindstring
providerIdstring
versionnumber
provenancestring
sourceUrlstring | null
contentHashstring
operationCountnumber
fetchedAtDate
changedAtDate
titlestring | null
specVersionstring | null

Options accepted by providerSpecs.listOperations().

FieldTypeDefaultDescription
search?stringCase-insensitive substring filter over operation id, path, and summary. Non-empty and at most 200 characters when supplied.
limit?number100Page size from 1 through 500.
offset?number0Non-negative page offset.
FieldType
operationIdstring
methodstring
pathTemplatestring
summarystring | null
FieldType
itemsreadonly SpecOperation[]
totalnumber
limitnumber
offsetnumber
hasMoreboolean
specProviderSpec
FieldType
operationIdstring
methodstring
pathTemplatestring
summarystring | null
paramsSchemaRecord<string, unknown>[] | null
requestSchemaRecord<string, unknown> | null
responseSchemaRecord<string, unknown> | null
specProviderSpec
enum HttpMethod {
GET = "GET",
POST = "POST",
PUT = "PUT",
PATCH = "PATCH",
DELETE = "DELETE",
HEAD = "HEAD",
OPTIONS = "OPTIONS",
}
enum CallerType {
SERVICE = "service",
AGENT = "agent",
}

Distinguishes backend services from AI agents at the audit layer. Set via the callerType constructor option.

Slug enum for the OAuth provider catalog. Plain provider-ID strings are also accepted by request() and createConnectSession(); the enum provides IDE autocomplete.

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.