
Security News
Ruby's Bundler 4.0.18 Extends Cooldown to bundle lock and bundle cache
The supply chain control that delays freshly published gems now covers lockfile generation and gem vendoring in Ruby projects.
@passband.ai/sdk
Advanced tools
Typed TypeScript client for the Passband /api/v1 REST API.
The client is a thin, dependency-free wrapper over fetch. All request and
response shapes are generated from the API's OpenAPI document, so the SDK
cannot drift from the server.
npm install @passband.ai/sdk
# or: pnpm add @passband.ai/sdk
Requires Node.js >= 18 (uses the global fetch). Ships ESM + CJS builds and types.
import { Passband } from '@passband.ai/sdk'
const pb = new Passband({ token: 'sf_...' })
// Run the content pipeline
await pb.pipeline.run()
// Review the ranked feed
const { drafts } = await pb.drafts.list({ status: 'pending_review' })
// Approve the first draft, if any
const first = drafts?.[0]
if (first) await pb.drafts.approve(first.id)
// Manage sources
await pb.sources.add({ name: 'HN', type: 'hackernews', url: 'https://news.ycombinator.com' })
With no options, the client reads PASSBAND_TOKEN (and PASSBAND_BASE_URL)
from the environment:
// reads PASSBAND_TOKEN from process.env
const pb = new Passband()
const summary = await pb.engagement.summary()
Constructing without a token is allowed, but the first request throws
PassbandAuthError — the SDK never sends an unauthenticated request.
Constructor options take precedence over environment variables:
| Option | Env var | Default |
|---|---|---|
token | PASSBAND_TOKEN | — |
baseUrl | PASSBAND_BASE_URL | https://passband.ai |
fetch | — | global fetch |
retry | — | disabled |
The token is sent as Authorization: Bearer <token>.
List endpoints are cursor-paginated. list() returns a single page (with a
nextCursor). For drafts, drafts.iterate() returns an async iterator that
transparently follows nextCursor:
for await (const draft of pb.drafts.iterate({ status: 'pending_review' })) {
console.log(draft.id)
}
Retries are opt-in. When enabled, the client retries 429 (honoring
Retry-After) and 5xx responses with exponential backoff and full jitter.
Other 4xx responses are never retried.
By default only idempotent methods are retried (GET/PUT/DELETE/PATCH).
POST is not retried, to avoid duplicating side effects. If your POST
endpoints are idempotent, opt in with retryNonIdempotent: true.
const pb = new Passband({
token: 'sf_...',
retry: { retries: 3, backoff: 250, retryNonIdempotent: false },
})
Cancellation via AbortSignal is never retried: the original AbortError
(or your signal.reason) is re-thrown unchanged.
Every non-2xx response throws a typed error: PassbandAuthError (401),
PassbandForbiddenError (403), PassbandNotFoundError (404),
PassbandRateLimitError (429, with retryAfter), and PassbandServerError
(5xx). Network and parse failures throw PassbandNetworkError. All extend
PassbandError with status, code, message, body, and requestId.
import {
Passband,
PassbandRateLimitError,
PassbandNotFoundError,
PassbandError,
} from '@passband.ai/sdk'
const pb = new Passband({ token: 'sf_...' })
try {
await pb.drafts.approve('draft_123')
} catch (err) {
if (err instanceof PassbandRateLimitError) {
console.warn(`Rate limited; retry after ${err.retryAfter}s`)
} else if (err instanceof PassbandNotFoundError) {
console.warn('Draft not found')
} else if (err instanceof PassbandError) {
console.error(err.status, err.code, err.message, err.requestId, err.body)
} else {
throw err
}
}
| Namespace | Methods |
|---|---|
pb.pipeline | run, status(runId), stats, runs.list |
pb.drafts | list, iterate, get, create, update, approve, post, bulk |
pb.sources | list, add, update, remove, test |
pb.voice | get, update |
pb.engagement | summary, upsert |
pb.experiments | list, create |
pipeline.status(runId)has no dedicated API route — it performs anO(n)linear scan ofpipeline.runs.list(capped at the most recent ~2000 runs) and throwsPassbandNotFoundErrorwhen the run isn't found. Prefer pagingpipeline.runs.listdirectly when you already know the run is recent.
Runnable end-to-end examples live in examples/ — including
agent-flow.ts, the canonical loop (run pipeline → ranked feed → approve drafts →
add sources). Each reads PASSBAND_TOKEN from the environment; see
examples/README.md.
Generate the static API + REST reference (typedoc + Redocly) into docs/:
pnpm --filter @passband.ai/sdk run docs # use `run docs` — bare `pnpm docs` is intercepted by pnpm
pnpm --filter @passband.ai/sdk generate # regenerate openapi.json + types
pnpm --filter @passband.ai/sdk build # tsup → ESM + CJS + d.ts
pnpm --filter @passband.ai/sdk test # vitest (unit + OpenAPI contract)
Types are generated from app/api/v1/docs/openapi.ts (the single source of
truth, also served at /api/v1/docs). Run generate after changing the API.
FAQs
Typed TypeScript client for the Passband /api/v1 REST API.
The npm package @passband.ai/sdk receives a total of 0 weekly downloads. As such, @passband.ai/sdk popularity was classified as not popular.
We found that @passband.ai/sdk demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago. It has 1 open source maintainer collaborating on the project.
Did you know?

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Security News
The supply chain control that delays freshly published gems now covers lockfile generation and gem vendoring in Ruby projects.

Security News
During a UK cyber test, a Mythos 5 agent used sockpuppets, social engineering, and prompt injection to try to get a maintainer to merge malware.

Company News
Socket is now in the AWS Security Hub Extended plan. Adopt it through AWS, apply committed spend, and block malicious open source packages.