@getunblocked/sdk
v0.1.5
Published
Lightweight TypeScript SDK for the Unblocked Public API.
Maintainers
Readme
Unblocked TypeScript SDK
Lightweight TypeScript wrapper for the Unblocked Public API.
The SDK uses the same API token authentication as the public API: pass a Personal Access Token or Team Access Token as a bearer token. You can pass the token explicitly or set UNBLOCKED_API_TOKEN.
Install
bun add @getunblocked/sdk
# or: npm install @getunblocked/sdkThe package is a public scoped package on npm. The compiled dist/ is committed
to the repo too, so a direct git install needs no build step and pulls in no
dependencies (the SDK has zero runtime dependencies):
bun add git+ssh://[email protected]/unblocked/unblocked-typescript-sdk.git#v0.1.0Always pin a tag (e.g. #v0.1.0) for git installs so they're reproducible —
omitting it tracks the default branch.
The
github:owner/reposhorthand and plainhttpsgit URLs go through GitHub's unauthenticated tarball API, which 404s on a private repo. Use thegit+ssh://URL above (or a tokenizedhttpsURL) so a git install authenticates.
Public template extraction: now that the SDK package is public,
examples/eve-pr-triagecan be extracted into its own repo (unblocked/eve-pr-triage-agent, configured as a GitHub template repo for the "Use this template" button — no-templatesuffix; keepevein the name for harness discoverability). Swap its@getunblocked/sdkdependency fromfile:../..to the published package and drop thepredeploy/postdeploytarball step. Leave a link-out here and indocs/agent-frameworks.md. The extraction's benefits (Vercel deploy button, public showcase, own issue tracker) switch on once the SDK is public.
When the GitHub repo goes public: enable npm provenance — add
id-token: writeto thepermissionsblock inpublish.ymland--provenanceto thenpm publishstep. Provenance is blocked while the source repo is private (the attestation publishes repo/workflow metadata to the public Sigstore log), even though the npm package itself is public.
Quickstart
import Unblocked from "@getunblocked/sdk";
const unblocked = new Unblocked({
apiKey: process.env.UNBLOCKED_API_TOKEN,
});
const research = await unblocked.context.research({
query: "How does the user authentication system work?",
});
console.log(research.summary);
for (const source of research.sources) {
console.log(source.content);
console.log(source.url);
}
const code = await unblocked.context.search.code({
query: "rate limiting",
});
const urls = await unblocked.context.get.urls({
urls: ["https://my.company.com/apollo/ticket/123456"],
});The same flow is available as a runnable script — from a clone of this repo (no install or build step needed):
UNBLOCKED_API_TOKEN=unb_... node examples/quickstart.mjs "How does auth work?"Documentation
Detailed guides live in docs/:
- Getting Started
- Authentication
- Configuration
- Context
- Pagination
- Errors and Retries
- Agent Frameworks
- Low-Level Requests
- Runtime and Packaging
- TypeScript Guide
Authentication
Unblocked supports Personal Access Tokens and Team Access Tokens. Both are sent as:
Authorization: Bearer <token>The client resolves tokens in this order:
new Unblocked({ apiKey })new Unblocked({ token })UNBLOCKED_API_TOKENUNBLOCKED_API_KEY
apiKey and token can also be async token providers:
const unblocked = new Unblocked({
apiKey: async () => getTokenFromSecretManager(),
});Client Options
const unblocked = new Unblocked({
apiKey: process.env.UNBLOCKED_API_TOKEN,
baseUrl: "https://getunblocked.com/api",
timeoutMs: 30_000,
maxRetries: 2,
retryDelayMs: 500,
fetch: globalThis.fetch,
});GET, PUT, and DELETE requests retry transient network failures and 408, 429, 500, 502, 503, and 504 responses. POST and PATCH are not retried by default because they are not generally safe to replay.
API Surface
const unblocked = new Unblocked();
await unblocked.context.research({ query, instruction, effort });
await unblocked.context.search.code({ query, instruction });
await unblocked.context.search.prs({ query, instruction });
await unblocked.context.search.issues({ query, instruction });
await unblocked.context.search.documentation({ query, instruction });
await unblocked.context.search.messages({ query, instruction });
await unblocked.context.query.issues({ query, projects, user_name });
await unblocked.context.query.prs({ query, projects, user_name });
await unblocked.context.get.urls({ urls });
await unblocked.context.get.rules({ repoName, ruleId, task, language, paths });Search, query, and get methods resolve to { sources: ContextSearchSource[] }. Research also returns a summary and the effort used:
const research = await unblocked.context.research({ query: "How does auth work?" });
research.summary; // string
research.sources; // [{ content, title?, url?, sourceType?, provider? }, ...]
research.effort; // "low" | "medium" | "high"
const code = await unblocked.context.search.code({ query: "rate limiting" });
code.sources; // [{ content, title?, url?, sourceType?, provider? }, ...]See docs/context.md for the full surface and effort levels.
Low-Level Requests
The resource methods cover the public API, but the client also exposes typed request helpers for new endpoints or advanced callers:
const result = await unblocked.request("POST", "/tools/context/research", {
body: { query: "How does auth work?" },
});Agent Frameworks
The SDK exports plain functions and JSON-schema-shaped descriptors so frameworks can adapt them without pulling in framework-specific dependencies.
import { createUnblockedTools, unblockedToolSchemas } from "@getunblocked/sdk";
const tools = createUnblockedTools({
apiKey: process.env.UNBLOCKED_API_TOKEN,
});
export const research = {
...unblockedToolSchemas.research,
execute: tools.research,
};For frameworks such as Flue or Eve, put the wrapper above in the framework's TypeScript tool file and let that framework handle its own tool registration conventions.
See examples/quickstart.mjs for a minimal runnable script, and examples/context-research-tool.ts for the tool-module pattern above.
For a full local programmable-harness demo, see examples/flue-bug-triage. For a deployable GitHub-App-webhook PR-triage agent that makes Unblocked context a required triage step, see examples/eve-pr-triage.
Runtime Support
- ESM package
- No runtime dependencies
- Uses the platform
fetch - Requires Node.js 18+ or any runtime with
fetch
Error Handling
Non-2xx API responses throw UnblockedApiError with status, statusText, response headers, parsed response body, and requestId (the X-Request-ID header). The thrown error is a status-specific subclass — UnblockedBadRequestError (400), UnblockedAuthenticationError (401), UnblockedPermissionDeniedError (403), UnblockedNotFoundError (404), UnblockedRateLimitError (429), and UnblockedServerError (5xx) — all extending UnblockedApiError. Request timeouts throw UnblockedTimeoutError.
import { UnblockedApiError, UnblockedTimeoutError } from "@getunblocked/sdk";
try {
await unblocked.context.research({ query: "How does auth work?" });
} catch (error) {
if (error instanceof UnblockedApiError) {
console.error(error.status, error.body, error.requestId);
} else if (error instanceof UnblockedTimeoutError) {
console.error(error.message);
}
}See docs/errors-and-retries.md for the full subclass table.
