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

@denserai/retriever-sdk

v0.1.0

Published

Official TypeScript SDK for Denser Retriever Platform

Readme

Denser Retriever SDK for TypeScript

The official TypeScript SDK for Denser Retriever Platform. Build powerful semantic search and retrieval applications with an intuitive API for knowledge base management, document ingestion, and intelligent querying.

Table of Contents

Installation

Install the SDK via npm:

npm install @denserai/retriever-sdk

Quick Start

import { DenserRetriever } from "@denserai/retriever-sdk";

const client = new DenserRetriever({
  apiKey: "your-api-key"
});

async function quickExample() {
  // Create a knowledge base
  const kb = await client.createKnowledgeBase("My First KB");
  const kbId = kb.data.id;

  // Import text content
  await client.importTextContentAndPoll(
    kbId,
    "Getting Started",
    "Denser Retriever enables semantic search across your documents."
  );

  // Search
  const results = await client.query("semantic search", {
    knowledgeBaseIds: [kbId],
    limit: 5
  });

  console.log(results.data);

  // Cleanup
  await client.deleteKnowledgeBase(kbId);
}

Configuration

Initialize the client with your API credentials:

import { DenserRetriever } from "@denserai/retriever-sdk";

const client = new DenserRetriever({
  apiKey: "YOUR_API_KEY",        // Required: Your API key
  timeout: 30000                  // Optional: Request timeout in ms (default: 10000)
});

API Reference

All methods return a Promise<ApiResponse<T>> where T is the response data type.

Account Methods

getUsage(): Promise<ApiResponse<UsageData>>

Retrieve current usage statistics for your organization.

const usage = await client.getUsage();
console.log(`Knowledge Bases: ${usage.data.knowledgeBaseCount}`);
console.log(`Storage Used: ${usage.data.storageUsed} bytes`);

Response:

{
  success: boolean;
  data: {
    knowledgeBaseCount: number;
    storageUsed: number; // bytes
  }
}

getBalance(): Promise<ApiResponse<BalanceData>>

Retrieve current credit balance for your account.

const balance = await client.getBalance();
console.log(`Balance: ${balance.data.balance} credits`);

Response:

{
  success: boolean;
  data: {
    balance: number;
  }
}

Knowledge Base Methods

createKnowledgeBase(name: string, description?: string): Promise<ApiResponse<KnowledgeBase>>

Create a new knowledge base.

Parameters:

  • name - Knowledge base name (required)
  • description - Optional description
const kb = await client.createKnowledgeBase(
  "Technical Documentation",
  "Product docs and API references"
);
const kbId = kb.data.id;

Response:

{
  success: boolean;
  data: {
    id: string;
    name: string;
    description: string | null;
    createdAt: string;
    updatedAt: string;
  }
}

listKnowledgeBases(): Promise<ApiResponse<KnowledgeBase[]>>

List all knowledge bases in your organization.

const kbs = await client.listKnowledgeBases();
kbs.data.forEach(kb => {
  console.log(`${kb.name} (ID: ${kb.id})`);
});

updateKnowledgeBase(id: string, data: UpdateKBData): Promise<ApiResponse<KnowledgeBase>>

Update knowledge base metadata.

Parameters:

  • id - Knowledge base ID (required)
  • data.name - New name (optional)
  • data.description - New description (optional)
await client.updateKnowledgeBase(kbId, {
  name: "Updated Name",
  description: "Updated description"
});

deleteKnowledgeBase(id: string): Promise<ApiResponse<{id: string}>>

Permanently delete a knowledge base and all its documents.

await client.deleteKnowledgeBase(kbId);

Document Methods

File Upload Workflow

Uploading files requires a three-step process:

Step 1: Get Presigned URL

presignUploadUrl(knowledgeBaseId: string, fileName: string, size: number): Promise<ApiResponse<PresignedUrlData>>

Generate a presigned S3 URL for file upload.

Parameters:

  • knowledgeBaseId - Target knowledge base ID
  • fileName - File name with extension
  • size - File size in bytes (max: 52,428,800)
const presign = await client.presignUploadUrl(kbId, "document.pdf", 1024000);
const { fileId, uploadUrl, expiresAt } = presign.data;
Step 2: Upload File to S3

Use any HTTP client (e.g., axios, fetch) to PUT the file to the presigned URL:

import axios from "axios";
import fs from "fs";

const fileStream = fs.createReadStream(filePath);
await axios.put(uploadUrl, fileStream, {
  headers: {
    "Content-Type": "application/octet-stream",
    "Content-Length": fileSize
  }
});
Step 3: Register and Process

importFile(fileId: string): Promise<ApiResponse<DocumentInfo>>

Register the uploaded file for processing.

const doc = await client.importFile(fileId);
console.log(`Document ID: ${doc.data.id}, Status: ${doc.data.status}`);

importFileAndPoll(fileId: string, options?: PollOptions): Promise<ApiResponse<DocumentInfo>>

Register file and automatically poll until processing completes.

Parameters:

  • fileId - File ID from presignUploadUrl
  • options.intervalMs - Polling interval in milliseconds (default: 2000)
  • options.timeoutMs - Maximum wait time in milliseconds (default: 600000)
const doc = await client.importFileAndPoll(fileId, {
  intervalMs: 2000,
  timeoutMs: 600000
});
// Returns when status is "processed" or throws on "failed"/"timeout"

Text Content Import

importTextContent(knowledgeBaseId: string, title: string, content: string): Promise<ApiResponse<DocumentInfo>>

Import text content directly as a document.

Parameters:

  • knowledgeBaseId - Target knowledge base ID
  • title - Document title (max: 256 chars)
  • content - Text content (max: 1,000,000 chars)
const doc = await client.importTextContent(
  kbId,
  "API Documentation",
  "Complete API reference and usage examples..."
);

importTextContentAndPoll(knowledgeBaseId: string, title: string, content: string, options?: PollOptions): Promise<ApiResponse<DocumentInfo>>

Import text content and poll until processing completes.

const doc = await client.importTextContentAndPoll(
  kbId,
  "Release Notes",
  "Version 2.0 includes...",
  { intervalMs: 1000, timeoutMs: 300000 }
);

Document Management

listDocuments(knowledgeBaseId: string): Promise<ApiResponse<DocumentInfo[]>>

List all documents in a knowledge base.

const docs = await client.listDocuments(kbId);
docs.data.forEach(doc => {
  console.log(`${doc.title} - ${doc.status} (${doc.size} bytes)`);
});

Response:

{
  success: boolean;
  data: Array<{
    id: string;
    title: string;
    type: string;
    size: number;
    status: "pending" | "processing" | "processed" | "failed" | "timeout";
    createdAt: string;
  }>
}

getDocumentStatus(documentId: string): Promise<ApiResponse<DocumentStatusData>>

Check document processing status.

const status = await client.getDocumentStatus(docId);
console.log(`Status: ${status.data.status}`);

Status Values:

  • pending - Queued for processing
  • processing - Currently being processed
  • processed - Successfully processed and searchable
  • failed - Processing failed
  • timeout - Processing timed out

deleteDocument(documentId: string): Promise<ApiResponse<{id: string}>>

Permanently delete a document.

await client.deleteDocument(docId);

Query Methods

query(content: string, options?: QueryOptions): Promise<ApiResponse<QueryResultItem[]>>

Perform semantic search across knowledge bases.

Parameters:

  • content - Search query (required, 1-8192 chars)
  • options.knowledgeBaseIds - Filter by specific knowledge bases (optional)
  • options.limit - Maximum results (optional, default: 10, max: 50)
// Search across all knowledge bases
const results = await client.query("machine learning algorithms");

// Search within specific knowledge bases
const results = await client.query("deployment guide", {
  knowledgeBaseIds: [kbId1, kbId2],
  limit: 20
});

// Process results
results.data.forEach(item => {
  console.log(`Score: ${item.score.toFixed(3)}`);
  console.log(`Title: ${item.title}`);
  console.log(`Content: ${item.content}`);
  console.log(`Document: ${item.document_id}`);
  console.log(`KB: ${item.knowledge_base_id}`);
  console.log(`Metadata:`, item.metadata);
  console.log("---");
});

Response:

{
  success: boolean;
  data: Array<{
    id: string;
    score: number;
    document_id: string;
    knowledge_base_id: string;
    title: string;
    type: string;
    content: string;
    metadata?: {
      source?: string | null;
      annotations?: string;
    }
  }>
}

Error Handling

The SDK throws APIError for all API-related errors, providing structured error information for robust error handling.

APIError Class

class APIError extends Error {
  code: string;           // Machine-readable error code
  message: string;        // Human-readable error message
  httpStatus: number;     // HTTP status code
  data?: object;          // Additional error context
}

Error Handling Pattern

import { DenserRetriever, APIError } from "@denserai/retriever-sdk";

try {
  const results = await client.query("search term", {
    knowledgeBaseIds: ["invalid-kb-id"],
    limit: 5
  });
  console.log(results.data);
} catch (error) {
  if (error instanceof APIError) {
    console.error(`[${error.code}] ${error.message}`);
    console.error(`HTTP Status: ${error.httpStatus}`);
    
    // Handle specific error codes
    switch (error.code) {
      case "INSUFFICIENT_CREDITS":
        console.error("Please top up your account to continue.");
        break;
      case "NOT_FOUND":
        console.error("The requested resource does not exist.");
        break;
      case "STORAGE_LIMIT_EXCEEDED":
        console.error("Storage quota exceeded:", error.data);
        break;
      case "KNOWLEDGE_BASE_LIMIT_EXCEEDED":
        console.error("Maximum knowledge bases reached.");
        break;
      default:
        console.error("An error occurred:", error.message);
    }
  } else {
    console.error("Unexpected error:", error);
  }
}

Common Error Codes

| Error Code | HTTP Status | Description | | --------- | ----------- | ----------- | | INPUT_VALIDATION_FAILED | 422 | Request parameters failed validation | | UNAUTHORIZED | 401 | Invalid or missing API key | | FORBIDDEN | 403 | Access to resource is denied | | NOT_FOUND | 404 | Requested resource does not exist | | INSUFFICIENT_CREDITS | 403 | Account has insufficient credits | | STORAGE_LIMIT_EXCEEDED | 403 | Storage quota exceeded | | KNOWLEDGE_BASE_LIMIT_EXCEEDED | 403 | Maximum knowledge bases reached | | INTERNAL_SERVER_ERROR | 500 | Server encountered an error |