TypeScript SDK
Use the Gazebo TypeScript SDK for server-side account automation and agent-scoped credential retrieval. The CLI uses the same SDK; MCP remains available for MCP-compatible clients.
Installation
The SDK is dependency-free, ESM-only and intended for server-side Node.js. Its current minimum is Node.js 20; use a maintained, security-patched Node.js 22 or 24 release for new applications. Do not put account or agent tokens in browser bundles.
npm install @gazebohq/sdk
Import Gazebo and, when needed, GazeboError from @gazebohq/sdk. The package includes compiled JavaScript and TypeScript declarations.
Authentication
Connect an application's users
The account-connection flow adds an explicit consent mode alongside the manual account/agent modes below. Your application supplies its own authenticated callback and encrypted per-user storage with shared locking.
Register an application public ES256 key, exact callback and gazebo.credentials.read scope in Agent Consent Flow. Your backend uses the server-only @gazebohq/sdk/consent helpers to start a signed request, retain session-bound state and PKCE, and complete the one-time callback. The user approves specific service/key pairs and chooses the existing agent expiry.
Follow the complete account-connection guide for application registration, startConnection, completeConnection, authenticated callback routes, per-user storage adapters, renewal, disconnect and error handling. The example below shows runtime use after that setup; it is not the entire onboarding flow.
import { Gazebo } from "@gazebohq/sdk";
import { createConnectionTokenProvider } from "@gazebohq/sdk/consent";
const agent = new Gazebo({
endpoint: "https://app.gazebohq.com",
auth: {
type: "consent",
tokenProvider: createConnectionTokenProvider({
endpoint: "https://app.gazebohq.com",
clientId,
privateKeyJwk,
store: encryptedPerUserConnectionStore,
}),
},
});
await agent.credentials.get("github", { keyName: "api_key" });
The application must supply encrypted persistent storage and a cross-worker lock for each authenticated user's connection. Helpers renew one-hour access tokens automatically; rotating renewal credentials expire after 30 inactive days. Both are capped by the user-selected approval expiry. Persisted operation IDs allow identical retries for 60 seconds; older lost-response recovery requires reconnecting. Use disconnectStoredConnection to block local use and retry remote revocation if Gazebo is unavailable.
Consent-mode operations are named-key retrieval and connection identity/disconnect—not account administration, bulk retrieval or MCP. Revoking the approval or agent, disabling the client, or reaching the expiry stops future retrieval and renewal.
The agent runtime and its host receive the selected provider key. This does not hide credentials from an untrusted host, invalidate keys already retrieved, or enforce provider operations after delivery. It is not an OAuth-compatibility claim. See Agent Consent Flow and the package's examples/connect-application.ts for the backend integration contract.
Manual token modes
Read the authentication guide for obtaining and protecting manual tokens. Account, agent and delegated consent tokens are not interchangeable.
- Account client: trusted administration, using an account API token supplied by your secret manager.
- Agent client: credential retrieval for one agent, using its agent token.
The SDK does not discover tokens from environment variables automatically. Your application supplies the token explicitly. Generating a replacement account token revokes the previous one; do not rotate a shared automation token just to try an example.
Account quickstart
This read-only example verifies authentication and reports counts without logging account details or credentials. Run it in a server-side ESM application with GAZEBO_ACCOUNT_TOKEN supplied through your environment or secret manager.
import { Gazebo } from "@gazebohq/sdk";
const token = process.env.GAZEBO_ACCOUNT_TOKEN;
if (!token) throw new Error("Set GAZEBO_ACCOUNT_TOKEN securely.");
const gazebo = new Gazebo({
endpoint: "https://app.gazebohq.com",
auth: { type: "account", token },
});
await gazebo.account.get();
const services = await gazebo.services.list();
const agents = await gazebo.agents.list();
console.log({
connectedServiceCount: services.length,
activeAgentCount: agents.length,
});
Agent credential quickstart
Connect a service in the dashboard, create an agent, and enable that service for the agent before retrieving its credential. This example assumes service stripe, a key named api_key, and a policy permitting credential release for the declared GET method.
import { Gazebo } from "@gazebohq/sdk";
export async function getStripeApiKey(): Promise<string> {
const token = process.env.GAZEBO_AGENT_TOKEN;
if (!token) throw new Error("Set GAZEBO_AGENT_TOKEN securely.");
const agent = new Gazebo({
endpoint: "https://app.gazebohq.com",
auth: { type: "agent", token },
});
const result = await agent.credentials.get("stripe", {
method: "GET",
keyName: "api_key",
});
// Pass directly to your server-side integration; never log this value.
return result.credentials.api_key;
}
The response contains one sensitive credential in credentials. Without keyName, the server selects the primary credential, preferring api_key. Without method, credential retrieval defaults to GET.
Method policies govern credential release, not subsequent provider calls. Once a credential is released, provider-side scopes and IAM must restrict what it can do. The SDK does not execute provider requests or automatically poll for approval.
Trust the runtime: the SDK returns the actual stored provider credential. If another developer hosts your agent, their infrastructure receives it. Use narrowly scoped provider credentials and keep each user's agent token separate; account administration tokens are not runtime tokens. Account connection and agent-token setup are manual—there is no integrated browser consent flow in this SDK.
Revocation and audit limits: revoking an agent blocks future retrieval, not use of provider keys already retrieved. If a key is compromised, revoke or rotate it at the provider. Gazebo logs credential access, not every subsequent provider action.
Supported operations
Account clients expose:
| Operation | Purpose |
|---|---|
account.get() | Read account identity and feature availability |
services.list() | List connected service metadata, not credential values |
agents.list() | List active agents without their tokens |
agents.create({ name, expiresAt? }) | Create an agent; return its token once |
agents.delete(agentId) | Revoke that agent |
access.get(agentId) | Read service access policies |
access.set(agentId, service, { enabled, methods }) | Replace a service policy with explicit methods |
auditEvents.list(filters?) | Read one page of credential-access events |
Agent clients expose only credentials.get(service, options?). The separation applies to TypeScript and runtime objects; server authorization remains the security boundary.
Consent clients expose credentials.get(service, { keyName }), connection.get() and connection.disconnect(). Named-key selection is required. Backend-managed connections should use disconnectStoredConnection to also block local renewal and token use while remote revocation is retried.
Service uploads, consent administration and arbitrary dashboard endpoints are not SDK operations. See the REST API for its separately documented capabilities.
Agent creation and policy changes
Creating an agent returns a sensitive token once. Store it in your secret manager without logging or serializing the entire response. Optional expiresAt is a UTC ISO timestamp; omitting it creates an agent without an expiration.
Using the account client from the quickstart:
const created = await gazebo.agents.create({
name: "GET credential retrieval",
expiresAt: new Date(Date.now() + 60 * 60 * 1000).toISOString(),
});
// Securely store created.token before proceeding. Do not console.log(created).
await gazebo.access.set(created.id, "stripe", {
enabled: true,
methods: ["GET"],
});
// Later, when this integration is no longer needed:
await gazebo.agents.delete(created.id);
Policy updates replace the existing policy. Always provide a nonempty methods list, including when setting enabled: false. Supported methods are GET, POST, PUT, PATCH and DELETE. Revocation blocks subsequent credential retrieval; it does not invalidate a provider credential already released.
Audit pagination
Each call returns { events, nextCursor, hasMore }. Pagination is explicit:
const filters = { service: "stripe", limit: 50 };
let page = await gazebo.auditEvents.list(filters);
let eventCount = page.events.length;
while (page.hasMore && page.nextCursor) {
page = await gazebo.auditEvents.list({
...filters,
cursor: page.nextCursor,
});
eventCount += page.events.length;
}
console.log({ eventCount });
Filters are limit (integer 1–200), cursor, agentId, service, outcome (success, denied or not_found), from and to. Date filters are timestamp strings. Keep filters unchanged when advancing opaque cursors. Returned timestamps remain strings, not JavaScript Date objects. Audit records may contain identifying information; do not publish raw responses.
Endpoint, timeout and cancellation
Set the origin, not an API resource URL. The SDK appends its supported paths and preserves an optional endpoint path prefix:
new Gazebo({ endpoint: "https://app.gazebohq.com", auth });
new Gazebo({ endpoint: "http://localhost:8787", auth });
Here auth is the same explicit { type, token } configuration shown above. Local targeting demonstrates interface configurability only: a local broker is not yet implemented and cloud/local parity is not yet verified.
The default timeout is 10 seconds, including response-body reads. Override it with constructor timeoutMs. Every operation accepts request options containing an AbortSignal; credential retrieval accepts signal alongside method and keyName.
const controller = new AbortController();
const pending = gazebo.agents.list({ signal: controller.signal });
controller.abort();
await pending; // Rejects with a cancelled GazeboError.
Use HTTPS remotely. Core API requests do not retry, automatically paginate, follow redirects, use cookie authentication or log responses. The server-side connection helper's bounded renewal retry is separate.
Errors and troubleshooting
import { GazeboError } from "@gazebohq/sdk";
try {
await gazebo.agents.list();
} catch (error) {
if (error instanceof GazeboError) {
console.error({ code: error.code, status: error.status });
} else {
throw error;
}
}
Error codes are http, network, timeout, cancelled, invalid_response and auth_mode. HTTP failures expose status and, when present, the raw retryAfter header. Input validation throws TypeError.
details contains the parsed server response, is non-enumerable and is omitted by JSON serialization. Direct access can still reveal sensitive fields: inspect deliberately, never log it blindly. Unknown additive response fields are preserved; missing or invalid required fields cause invalid_response.
- 401: check the token type, expiration and revocation.
- 403: inspect the agent's enabled service and declared-method policy; do not retry unchanged or invent approval polling.
- 404: check the service identifier and named key.
- 429: follow the API limits guidance; core API requests do not retry automatically.
Compatibility and support
SDK package versions and REST API versions are separate. Account operations use the supported /api/v1 resources; agent credential retrieval uses /api/agents. Do not assume every REST or dashboard capability exists in the SDK. Consult API errors and compatibility before depending on a response contract.
Local archive installation, TypeScript consumption and controlled cloud workflows have been verified. This does not certify every operating system, every example, real-provider credential usage, registry installation or a local broker.
For help, contact [email protected] with your runtime version, package version, error code and HTTP status. Do not send tokens, credential values or raw account/audit responses. Continue with the CLI guide for shell automation.