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

@getunblocked/sdk

v0.2.1

Published

TypeScript SDK for the Unblocked Public API.

Readme

Unblocked TypeScript SDK

The official TypeScript SDK for the Unblocked Public API. Its request and response types mirror the public API contract.

Install

bun add @getunblocked/sdk

Create a client

Create a Personal Access Token or Team Access Token in Unblocked under Settings → API Tokens.

import { UnblockedClient } from "@getunblocked/sdk";

const token = process.env.UNBLOCKED_API_TOKEN;

if (!token) {
  throw new Error("UNBLOCKED_API_TOKEN is required");
}

const unblocked = new UnblockedClient({
  token,
  maxRetries: 0,
});

The client also accepts an asynchronous token provider:

const unblocked = new UnblockedClient({
  token: async () => getApiToken(),
  maxRetries: 0,
});

Use the SDK in a trusted server environment. Do not include an Unblocked API token in browser code.

Context

Context operations use one flat namespace:

const research = await unblocked.context.research({
  query: "How does authentication work?",
});

const code = await unblocked.context.searchCode({
  query: "rate limiting",
});

const issues = await unblocked.context.queryIssues({
  query: "Open authentication bugs",
});

const urls = await unblocked.context.getUrls({
  urls: ["https://example.com/document"],
});

The context client also provides:

  • searchDocumentation
  • searchIssues
  • searchMessages
  • searchPrs
  • queryPrs

Answers

Questions use caller-provided UUIDs and are processed asynchronously:

const questionId = crypto.randomUUID();

await unblocked.answers.ask({
  questionId,
  question: "What changed in authentication this week?",
});

const answer = await unblocked.answers.get({ questionId });

Use answers.list() to list questions. Use answers.delete({ questionId }) to delete one.

Collections

const collection = await unblocked.collections.create({
  name: "Support",
  description: "Customer support documents.",
  iconUrl: "https://example.com/support.png",
});

await unblocked.collections.update({
  collectionId: collection.id,
  body: {
    description: "Current customer support documents.",
  },
});

The collections client also provides list, get, and delete.

Documents

const document = await unblocked.documents.put({
  collectionId: collection.id,
  title: "Password reset guide",
  body: "To reset your password...",
  uri: "https://example.com/password-reset",
});

if (!document.id) {
  throw new Error("The API did not return a document ID");
}

await unblocked.documents.delete({ documentId: document.id });

The id guard is required because the current public OpenAPI contract marks the response field as optional.

Pagination

List methods return the response array. Pagination links are available through the raw response:

const request = unblocked.documents.list({ limit: 25 });
const { data: documents, rawResponse } = await request.withRawResponse();

const link = rawResponse.headers.get("link");

Do not assume that a short page is the final page. Follow the rel="next" link when it is present.

Request options

Each method accepts request options as its second argument:

const request = unblocked.context.research(
  { query: "How does authentication work?" },
  { timeoutInSeconds: 180, maxRetries: 0 },
);

const { data, rawResponse } = await request.withRawResponse();

Requests time out after 120 seconds by default. The SDK defaults to two retries for retryable failures, including operations that are not safe to replay. Set maxRetries: 0 on the client unless your application has an idempotency strategy. You can override the value for an individual request.

Error handling

Non-successful API responses throw status-specific errors generated from the public contract:

import { Unblocked, UnblockedClient } from "@getunblocked/sdk";

try {
  await unblocked.collections.get({ collectionId: crypto.randomUUID() });
} catch (error) {
  if (error instanceof Unblocked.NotFoundError) {
    console.error(error.statusCode, error.body);
  }
}

Network failures and unlisted status codes throw UnblockedError. Timeouts throw UnblockedTimeoutError. Both are root package exports.

Runtime support

  • ESM package
  • Node.js 18 or later
  • Native fetch
  • No runtime dependencies