---
title: TypeScript SDK
description: Install and use the PostGrad TypeScript SDK.
---

Typed client for Node.js, Deno, and the browser. Wraps the REST API with automatic retries on 429, typed errors, and a `defaultFeed` option so you rarely have to pass the feed header manually.

## Installation

```bash
npm install postgrad
```

## Quick Start

```typescript
import { PostGrad } from 'postgrad';

// defaultFeed: 'all' makes every search query fan out across every feed
// the user is subscribed to. Alternatively pass a specific feed UUID,
// or omit defaultFeed to have PostGrad auto-select your biggest feed.
const client = new PostGrad({
  apiKey: 'pg_live_YOUR_API_KEY',
  defaultFeed: 'all',
});

// Search across all subscribed feeds and merge results by relevance.
// Each hit's metadata includes feed_id + feed_name.
const results = await client.search('pricing strategy');
for (const entry of results.data) {
  console.log(`${entry.title} (from ${entry.feed_name}, ${entry.confidence})`);
}

// Override defaultFeed per-call when you want to scope to one feed.
const scoped = await client.search('pricing strategy', {
  feedId: 'b1a2c3d4-e5f6-7890-abcd-ef0123456789',
});

// List + get endpoints still require an explicit feed id.
const entries = await client.knowledge.list({
  feedId: 'b1a2c3d4-e5f6-7890-abcd-ef0123456789',
  category: 'deal_evaluation',
  limit: 10,
});

const entry = await client.knowledge.get('entry-uuid-here', {
  feedId: 'b1a2c3d4-e5f6-7890-abcd-ef0123456789',
});
```

## Client Options

```typescript
const client = new PostGrad({
  apiKey: 'pg_live_YOUR_API_KEY',
  baseUrl: 'https://postgrad.io', // default
  timeout: 30_000, // request timeout in ms (default: 30s)
  // defaultFeed applies to every request unless overridden via `feedId`.
  //   'all'         — fan out across every subscribed feed (search only)
  //   '<uuid>'      — scope every request to this one feed
  //   undefined     — auto-select your most-populated feed (search only)
  defaultFeed: 'all',
});
```

## Methods

### `client.search(query, options?)`

Search the knowledge base with natural language.

```typescript
const results = await client.search('AI agent architecture', {
  categories: ['ai_architecture', 'tech_stack'],
  confidenceMin: 0.7,
  limit: 20,
});

for (const entry of results.data) {
  console.log(`${entry.title} (${entry.confidence})`);
}
```

### `client.knowledge.list(options?)`

List knowledge entries with optional filters.

```typescript
const entries = await client.knowledge.list({
  category: 'sales_process',
  limit: 25,
  offset: 0,
});
```

### `client.knowledge.get(id)`

Retrieve a single knowledge entry by ID.

```typescript
const entry = await client.knowledge.get('550e8400-e29b-41d4-a716-446655440000');
console.log(entry.data.title);
console.log(entry.data.content);
```

### `client.categories.list()`

List all available knowledge categories with entry counts.

```typescript
const categories = await client.categories.list();
for (const cat of categories.data) {
  console.log(`${cat.name}: ${cat.count} entries`);
}
```

### `client.usage.get()`

Check your current billing period usage.

```typescript
const usage = await client.usage.get();
console.log(`${usage.data.queries_used} / ${usage.data.queries_limit} queries used`);
```

## Error Handling

The SDK throws typed errors for common failure scenarios.

```typescript
import { PostGrad, PostGradError, RateLimitError, AuthError } from 'postgrad';

const client = new PostGrad({ apiKey: 'pg_live_YOUR_API_KEY' });

try {
  const results = await client.search('pricing');
} catch (error) {
  if (error instanceof AuthError) {
    console.error('Invalid or expired API key');
  } else if (error instanceof RateLimitError) {
    console.error(`Rate limited. Retry after ${error.retryAfter}s`);
  } else if (error instanceof PostGradError) {
    console.error(`API error: ${error.message} (${error.status})`);
  }
}
```

## TypeScript Types

The SDK exports types for all response objects.

```typescript
import type { KnowledgeEntry, Category, UsageInfo } from 'postgrad';

// KnowledgeEntry
interface KnowledgeEntry {
  id: string;
  title: string;
  category: string;
  content: string;
  tags: string[];
  confidence: number;
  reinforcement_count: number;
  created_at: string;
  updated_at: string;
}

// Category
interface Category {
  name: string;
  count: number;
}

// UsageInfo
interface UsageInfo {
  period_start: string;
  period_end: string;
  queries_used: number;
  queries_limit: number;
  queries_remaining: number;
  tier: string;
}
```
