TypeScript SDK
Coming Soon
The official TypeScript SDK is under active development. In the meantime, the REST API works with fetch or any HTTP client.
Planned Installation
npm install @inherent/sdk
# or
pnpm add @inherent/sdk
Using the API Today
No dependencies needed -- the wrapper below uses the built-in fetch API (Node 18+, Bun, Deno, browsers).
Wrapper Client
Drop this into your project as a lightweight SDK until the official one ships.
interface InherentConfig {
apiKey: string;
baseUrl?: string;
}
interface SearchResult {
chunks: Array<{
id: string;
content: string;
score: number;
document_id: string;
metadata: Record<string, unknown>;
}>;
query_id: string;
}
interface Document {
document_id: string;
title: string;
status: string;
created_at: string;
metadata: Record<string, unknown>;
}
interface DocumentUploadResponse {
document_id: string;
status: string;
}
interface DocumentListResponse {
documents: Document[];
total: number;
}
interface DocumentChunk {
id: string;
content: string;
chunk_index: number;
metadata: Record<string, unknown>;
}
interface DocumentContextResponse {
chunks: DocumentChunk[];
document_id: string;
}
class InherentClient {
private apiKey: string;
private baseUrl: string;
constructor(config: InherentConfig) {
this.apiKey = config.apiKey;
this.baseUrl = (config.baseUrl || "https://api.inherent.systems/api/v1").replace(/\/$/, "");
}
private async request<T>(method: string, path: string, body?: unknown): Promise<T> {
const res = await fetch(`${this.baseUrl}${path}`, {
method,
headers: {
"X-API-Key": this.apiKey,
"Content-Type": "application/json",
},
body: body ? JSON.stringify(body) : undefined,
});
if (!res.ok) {
const text = await res.text();
throw new Error(`Inherent API error ${res.status}: ${text}`);
}
return res.json() as Promise<T>;
}
// ── Documents ──────────────────────────────────────────────
async uploadDocument(file: File | Blob, metadata?: Record<string, unknown>): Promise<DocumentUploadResponse> {
const form = new FormData();
form.append("file", file);
if (metadata) {
form.append("metadata", JSON.stringify(metadata));
}
const res = await fetch(`${this.baseUrl}/documents`, {
method: "POST",
headers: { "X-API-Key": this.apiKey },
body: form,
});
if (!res.ok) {
const text = await res.text();
throw new Error(`Inherent API error ${res.status}: ${text}`);
}
return res.json() as Promise<DocumentUploadResponse>;
}
async listDocuments(limit = 20, offset = 0): Promise<DocumentListResponse> {
return this.request("GET", `/documents?limit=${limit}&offset=${offset}`);
}
async getDocument(documentId: string): Promise<Document> {
return this.request("GET", `/documents/${documentId}`);
}
// ── Search ─────────────────────────────────────────────────
async search(query: string, limit = 10): Promise<SearchResult> {
return this.request("POST", "/search", { query, limit });
}
// ── Chunks ─────────────────────────────────────────────────
async getChunks(documentId: string): Promise<DocumentChunk[]> {
return this.request("GET", `/chunks/${documentId}`);
}
async getContext(documentId: string): Promise<DocumentContextResponse> {
return this.request("GET", `/chunks/${documentId}/context`);
}
// ── Health ─────────────────────────────────────────────────
async health(): Promise<{ status: string }> {
return this.request("GET", "/health");
}
}
export { InherentClient, type InherentConfig, type SearchResult, type Document };
Complete Example
Upload a document, wait for processing, search, and retrieve context:
import { InherentClient } from "./inherent-client";
import { readFileSync } from "fs";
const client = new InherentClient({ apiKey: "ink_your_api_key_here" });
async function main() {
// 1. Upload a document
const fileBuffer = readFileSync("./knowledge-base/architecture.md");
const file = new File([fileBuffer], "architecture.md", { type: "text/markdown" });
const doc = await client.uploadDocument(file);
console.log(`Uploaded: ${doc.document_id} — status: ${doc.status}`);
// 2. Wait for ingestion to complete
let status = doc.status;
while (status !== "completed" && status !== "ready") {
if (status === "failed" || status === "error") {
throw new Error(`Ingestion failed for ${doc.document_id}`);
}
await new Promise((r) => setTimeout(r, 2000));
const info = await client.getDocument(doc.document_id);
status = info.status;
console.log(` Processing: ${status}`);
}
// 3. Search across the workspace
const results = await client.search("How does authentication work?", 5);
for (const chunk of results.chunks) {
console.log(`[${chunk.score.toFixed(3)}] ${chunk.content.slice(0, 120)}...`);
}
// 4. Get full context for the top result
const topDocId = results.chunks[0].document_id;
const context = await client.getContext(topDocId);
console.log(`\nContext window (${context.chunks.length} chunks):`);
for (const c of context.chunks) {
console.log(` - ${c.content.slice(0, 80)}...`);
}
}
main().catch(console.error);
Using with Vercel AI SDK
import { generateText } from "ai";
import { openai } from "@ai-sdk/openai";
import { InherentClient } from "./inherent-client";
const inherent = new InherentClient({ apiKey: "ink_your_api_key_here" });
async function answer(question: string): Promise<string> {
// Retrieve context from Inherent
const results = await inherent.search(question, 5);
const context = results.chunks.map((c) => c.content).join("\n\n---\n\n");
// Generate answer with context
const { text } = await generateText({
model: openai("gpt-4o"),
prompt: `Answer based on the following context:\n\n${context}\n\nQuestion: ${question}`,
});
return text;
}
Stay Updated
Star the GitHub repo to get notified when the official SDK launches.