Denser Retriever

TypeScript

Official TypeScript SDK for Denser Retriever Platform

Installation

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");

  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)
});

You can find your API key in the Denser Retriever Dashboard.

API Reference

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

Knowledge Base Management

createKnowledgeBase

Create a new knowledge base.

Parameters:

ParameterTypeRequiredDescription
namestringYesKnowledge base name
descriptionstringNoOptional description
const kb = await client.createKnowledgeBase(
  "Technical Documentation",
  "Product docs and API references"
);
const kbId = kb.data.id;

Returns:

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

listKnowledgeBases

List all knowledge bases in your organization.

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

updateKnowledgeBase

Update knowledge base metadata.

Parameters:

ParameterTypeRequiredDescription
idstringYesKnowledge base ID
data.namestringNoNew name
data.descriptionstringNoNew description
await client.updateKnowledgeBase(kbId, {
  name: "Updated Name",
  description: "Updated description"
});

deleteKnowledgeBase

Permanently delete a knowledge base and all its documents.

await client.deleteKnowledgeBase(kbId);

File Import Workflow

Uploading files requires a three-step process:

Step 1: Get Presigned URL

presignUploadUrl

Generate a presigned URL for file upload.

Parameters:

ParameterTypeRequiredDescription
knowledgeBaseIdstringYesTarget knowledge base ID
fileNamestringYesFile name with extension
sizenumberYesFile size in bytes (max: 52,428,800)
const presign = await client.presignUploadUrl(kbId, "document.pdf", 1024000);
const fileId = presign.data.fileId;
const uploadUrl = presign.data.uploadUrl;
const expiresAt = presign.data.expiresAt;

Step 2: Upload File

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
  }
});
const fileStream = await Bun.file(filePath).arrayBuffer();
await fetch(uploadUrl, {
  method: "PUT",
  body: fileStream,
  headers: {
    "Content-Type": "application/octet-stream",
    "Content-Length": fileStream.byteLength.toString()
  }
});

The presigned URL expires after a certain time. Make sure to upload the file before expiration.

Step 3: Register and Process

importFile

Register the uploaded file for processing.

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

importFileAndPoll

Register file and automatically poll until processing completes.

Parameters:

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

Text Content Import

importTextContent

Import text content directly as a document.

Parameters:

ParameterTypeRequiredDescription
knowledgeBaseIdstringYesTarget knowledge base ID
titlestringYesDocument title (max: 256 chars)
contentstringYesText content (max: 1,000,000 chars)
const doc = await client.importTextContent(
  kbId,
  "API Documentation",
  "Complete API reference and usage examples..."
);

importTextContentAndPoll

Import text content and poll until processing completes.

Parameters:

ParameterTypeDefaultDescription
knowledgeBaseIdstring-Target knowledge base ID
titlestring-Document title
contentstring-Text content
options.intervalMsnumber2000Polling interval in milliseconds
options.timeoutMsnumber600000Maximum wait time in milliseconds
const doc = await client.importTextContentAndPoll(
  kbId,
  "Release Notes",
  "Version 2.0 includes...",
  { intervalMs: 1000, timeoutMs: 300000 }
);

Document Management

listDocuments

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)`);
});

Returns:

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

getDocumentStatus

Check document processing status.

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

Status Values:

StatusDescription
pendingQueued for processing
processingCurrently being processed
processedSuccessfully processed and searchable
failedProcessing failed
timeoutProcessing timed out

deleteDocument

Permanently delete a document.

await client.deleteDocument(docId);

Query Method

query

Perform semantic search across knowledge bases.

Parameters:

ParameterTypeRequiredDescription
contentstringYesSearch query (1-8192 chars)
options.knowledgeBaseIdsstring[]NoFilter by specific knowledge bases
options.limitnumberNoMaximum results (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("---");
});

Returns:

{
  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;
    }
  }>
}

Account Management

getUsage

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`);

Returns:

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

getBalance

Retrieve current credit balance for your account.

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

Returns:

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

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";

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

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
    if (error.code === "INSUFFICIENT_CREDITS") {
      console.error("Please top up your account to continue.");
    } else if (error.code === "NOT_FOUND") {
      console.error("The requested resource does not exist.");
    } else if (error.code === "STORAGE_LIMIT_EXCEEDED") {
      console.error("Storage quota exceeded:", error.data);
    } else if (error.code === "KNOWLEDGE_BASE_LIMIT_EXCEEDED") {
      console.error("Maximum knowledge bases reached.");
    } else {
      console.error("An error occurred:", error.message);
    }
  } else {
    console.error("Unexpected error:", error);
  }
}

Common Error Codes

Error CodeHTTP StatusDescription
INPUT_VALIDATION_FAILED422Request parameters failed validation
UNAUTHORIZED401Invalid or missing API key
FORBIDDEN403Access to resource is denied
NOT_FOUND404Requested resource does not exist
INSUFFICIENT_CREDITS403Account has insufficient credits
STORAGE_LIMIT_EXCEEDED403Storage quota exceeded
KNOWLEDGE_BASE_LIMIT_EXCEEDED403Maximum knowledge bases reached
INTERNAL_SERVER_ERROR500Server encountered an error

Always implement proper error handling in your application to gracefully handle these error cases.

Next Steps

On this page