npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@alter-ai/alter-sdk

v0.22.0

Published

Official TypeScript SDK for Alter Vault — OAuth token management with policy enforcement

Readme

Alter SDK for TypeScript / Node.js

Official TypeScript SDK for Alter Vault — credential and authorization layer for apps and AI agents that call third-party APIs.

Credentials are never returned as application-visible values. In retrieve mode, the SDK process obtains the credential long enough to inject it into the provider request; in proxy mode, the credential stays in the Alter backend. Application code calls app.request() or app.proxyRequest() and receives only the provider result.

Install

npm install @alter-ai/alter-sdk

Runs on Node.js 20+ and is intended for server-side environments. For browser-side OAuth popup flows, see @alter-ai/connect.

Quick example

Make an authenticated API call — no token ever touches application code.

import { App, HttpMethod } from "@alter-ai/alter-sdk";

const app = new App({ apiKey: "<api-key>" });
try {
  const response = await app.request(
    HttpMethod.POST,
    "https://api.example.com/resource",
    {
      grantId: "<grant-id>",
      json: { example: "payload" },
    },
  );
  console.log(response.status, await response.json());
} finally {
  await app.close();
}

For a full walkthrough — sign-up, key minting, OAuth — see the Quickstart.

Two runtime modes

The SDK exposes two ways to reach a third-party API:

  • app.request(...)retrieve mode. The SDK fetches the token from the backend and makes the outgoing call itself. Returns the third-party response.
  • app.proxyRequest(...)proxy mode. The backend holds the token, makes the outgoing call, and returns the result. Application code and the SDK never observe the token. Required for any grant configured with human-in-the-loop approval; available for any other grant when wire-level audit, strong token isolation, or backend-side policy enforcement matter.

Proxy mode returns an ApprovalResult with statusCode, response headers/body, bodyTruncated, and durationMs (provider round-trip milliseconds; null for results created by older workers). Managed-secret secondary header/query injections and AWS SigV4—including query parameters, raw/JSON bodies, and temporary session tokens—behave the same in retrieve and proxy modes.

See runtime modes for the tradeoffs and when to pick each.

Policy rule helpers

contentMatchRule(...) builds operation-aware request rules for withConstraints({ rule }) with local validation before the first API call. It accepts attested operation ids and/or operation families, optional parameter conditions, and one of three effects: deny, redact, or step_up. Redaction strips named outbound request-body fields; step-up requires maxSessionAgeSeconds as an integer from 1 through 86400.

Recovering from missing-grant errors

When a request fails because the user hasn't authorized the provider yet, the SDK exposes recovery context on the typed error so you can drive a re-consent flow without re-deriving anything from the call site:

import { Agent, HttpMethod, NoDelegatedGrantError } from "@alter-ai/alter-sdk";

const agent = new Agent({ apiKey: "<agent-api-key>" });
try {
  try {
    await agent.request(HttpMethod.GET, "https://api.example.com/v1/resources", {
      provider: "<provider-id>",
      userToken: jwt,
    });
  } catch (e) {
    if (e instanceof NoDelegatedGrantError) {
      const session = await agent.createConnectSessionForError(e, {
        allowedOrigin: "https://app.example.com",
      });
      // Surface session.connectUrl to the user, then wait for consent.
      const results = await agent.pollConnectSession(session.sessionToken);
      const response = await agent.request(
        HttpMethod.GET,
        "https://api.example.com/v1/resources",
        { grantId: results[0].grantId, userToken: jwt },
      );
      console.log(response.status);
    } else {
      // Re-throw every other error class so network errors and
      // programming bugs aren't silently swallowed.
      throw e;
    }
  }
} finally {
  await agent.close();
}

createConnectSessionForError and pollConnectSession are available on both App and Agent so the catch block can recover from whichever client raised.

NoDelegatedGrantError and GrantNotFoundError carry providerId / agentId / appUserId recovery context when the original lookup was identity-mode; CredentialRevokedError carries providerId / appUserId. See the error reference for the full surface.

On the agent path, a grant_not_found for an explicit grantId surfaces as AgentDelegationMissingError — a subclass of GrantNotFoundError, so a catch on the base class still fires. It means the grant is not delegated to this agent, or a user/base grant id was passed where the agent's own delegation id is required (get it from agent.listGrants). Recover by delegating the agent through Connect (agent.createConnectSession), or resolve by provider instead of passing a grantId.

Onward delegation (agent to agent)

An agent that holds a grant can hand a scoped-down copy to another agent — without asking the credential owner to consent again. Use agent.delegate() to mint a child grant for the second agent:

import { Agent, GrantNotDelegableError } from "@alter-ai/alter-sdk";

const agent = new Agent({ apiKey: "<agent-api-key>" });

try {
  const result = await agent.delegate(
    "<grant-id>",                // a grant this agent already holds
    "<other-agent-id>",          // the agent that should receive access
    {
      scopeConstraint: ["resource:write"], // optional: narrow to fewer scopes
      ttlSeconds: 3600,                // optional: shorten the lifetime
      delegable: false,                // may the recipient delegate onward? (default no)
    },
  );
  console.log(result.grantId, result.depth, result.expiresAt);
} catch (e) {
  if (e instanceof GrantNotDelegableError) {
    // The held grant was not marked delegable when it was created,
    // so it cannot be passed on. Ask the owner for a delegable grant.
  } else {
    throw e;
  }
} finally {
  await agent.close();
}

The held grant must have been created as delegable (chosen at connect time). The child can only narrow — fewer scopes, a shorter lifetime — never widen. A grant narrowed with scopeConstraint is proxy-only: call it with agent.proxyRequest(...). Onward delegation is opt-in at every hop: pass delegable: true only when the recipient should be allowed to delegate further.

agent.listGrants() returns each grant with parentGrantId (the grant it was minted under, or null for a root) and depth (its distance from the root), so the full delegation chain can be reconstructed from the flat list.

OpenTelemetry trace propagation

When the application runs an OpenTelemetry SDK, Alter requests automatically carry the active span's W3C traceparent, so the audit trail — and any spans the organization streams to its own OTLP collector — join the application's traces. No configuration is required: @opentelemetry/api is an optional peer dependency that the SDK never installs or requires — when the application has it, the SDK uses it (including under pnpm's isolated mode and Yarn PnP); without it (or without an active span) the SDK behaves exactly as before.

import { trace } from "@opentelemetry/api";
import { App, HttpMethod } from "@alter-ai/alter-sdk";

const tracer = trace.getTracer("the-application");

const tracedApp = new App({ apiKey: "<api-key>" });
try {
  await tracer.startActiveSpan("handle-user-request", async (span) => {
    try {
      // This call's audit events share the surrounding trace's ids.
      const response = await tracedApp.request(
        HttpMethod.GET,
        "https://api.example.com/v1/resources",
        { grantId: "<grant-id>" },
      );
      console.log(response.status);
    } finally {
      span.end();
    }
  });
} finally {
  await tracedApp.close();
}

Documentation

Full docs are at https://docs.alterauth.com.

| Topic | Page | |---|---| | Getting started end-to-end | Quickstart | | The mental model | How Alter works | | Calling APIs on behalf of users (OAuth + JWT) | Guide | | Identity provider setup | Guide | | Provisioning backend secrets | Guide | | Scoped credentials for AI agents | Guide | | Embedding the Connect widget | Guide | | Human-in-the-loop approvals | Guide | | OpenTelemetry trace propagation | Calling APIs | | Runtime modes (retrieve vs proxy) | Concept | | Per-method API reference | TypeScript SDK reference | | Browser popup SDK | @alter-ai/connect | | Errors | Error reference |

License

MIT. See LICENSE.

Support

Email [email protected] or open an issue at https://github.com/alter-ai/alter-vault.