thefaqapp

TypeScript SDK

Official TypeScript SDK for TheFAQApp

@faq/sdk

Universal TypeScript client for the TheFAQApp API. Works in Node.js, Deno, Bun, and the browser.

Install

npm install @faq/sdk

Setup

import { createFaqClient } from '@faq/sdk';

const client = createFaqClient({
  apiKey: process.env.FAQ_API_KEY!,
  organizationSlug: 'your-org',
});

Read Methods

getFaq(filters?)

List questions with filtering, sorting, and pagination.

const { questions, pagination } = await client.getFaq({
  limit: 10,
  category: 'billing',
  sortBy: 'views',
});

getQuestion(slug)

Get a single question with feedback stats.

const { question, stats, recentFeedback } = await client.getQuestion('how-to-cancel');

getCategories(includeEmpty?)

List categories with question counts.

const { categories } = await client.getCategories(true);

getCategoryQuestions(slug, filters?)

Get questions in a specific category.

const { category, questions, pagination } = await client.getCategoryQuestions('billing');

search(filters)

Full-text search. Requires q parameter.

const { results } = await client.search({ q: 'password reset', limit: 5 });

submitFeedback(questionSlug, feedback)

Submit helpful/not-helpful feedback.

await client.submitFeedback('how-to-cancel', {
  helpful: true,
  comment: 'This solved my issue!',
});

Write Methods

Requires an API key with write scope (STARTER+ plan).

createQuestion(input)

const { data } = await client.createQuestion({
  question: 'What are your business hours?',
  answer: '<p>Monday–Friday, 9am–5pm EST.</p>',
  categorySlug: 'general',
  published: true,
  tags: ['hours', 'contact'],
});

updateQuestion(slug, input)

Partial update — only provided fields are changed.

await client.updateQuestion('business-hours', {
  answer: '<p>Monday–Friday, 9am–6pm EST.</p>',
  featured: true,
});

deleteQuestion(slug)

Soft-deletes the question.

await client.deleteQuestion('old-question');

createCategory(input)

await client.createCategory({
  name: 'Billing',
  icon: '💳',
  description: 'Payment and subscription questions',
});

updateCategory(slug, input)

await client.updateCategory('billing', { description: 'Updated description' });

deleteCategory(slug, reassignTo?)

// Move questions to "general" before deleting
await client.deleteCategory('old-category', 'general');

// Uncategorize questions
await client.deleteCategory('old-category', 'none');

Configuration

createFaqClient({
  apiKey: 'faq_...',               // Required
  organizationSlug: 'my-org',      // Required
  baseUrl: 'https://www.thefaq.app',   // Default
  cache: {
    enabled: true,   // Default: true (in-memory)
    ttl: 300,        // Default: 300s (5 min)
  },
  timeout: 10000,    // Default: 10s
});

Error Handling

import { ApiError, ValidationError } from '@faq/sdk';

try {
  await client.createQuestion({ question: '', answer: '' });
} catch (error) {
  if (error instanceof ApiError) {
    console.error(`${error.status}: ${error.message}`);
    // error.data contains the full error response
  }
  if (error instanceof ValidationError) {
    console.error('Invalid input:', error.message);
  }
}

Caching

The SDK caches read responses in memory by default (5-minute TTL). Write methods automatically invalidate the cache.

// Clear cache manually
client.clearCache();

// Check cache stats
const { size, keys } = client.getCacheStats();

// Disable caching
const client = createFaqClient({
  ...config,
  cache: { enabled: false, ttl: 0 },
});

On this page