New1 billion tokens free on sign-up — crawl, parse, chunk and embed on the houseClaim yours
SarvCrawl
Docs/Node SDK
SarvCrawl / Docs /Node SDK

Node SDK Reference

Complete method reference with request examples and responses.

npm install sarvcrawl

Installation & Initialization

Install the SDK and create a client instance. Pass your API key directly or via the KB_API_KEY environment variable.

new KBClient(options)

Creates a new client. Throws if no API key is provided.

import { KBClient } from 'sarvcrawl';

const kb = new KBClient({
  apiKey: 'YOUR_API_KEY',       // or set KB_API_KEY env var
  apiUrl: 'https://crawl.sarv.com', // the default; set your own host to self-host
});
kb.health()
GET/health

Returns server health status.

const status = await kb.health();
console.log(status);
kb.me()
GET/auth/me

Returns the authenticated user profile.

const user = await kb.me();
console.log(user.id, user.email);

Knowledge Bases

Create and manage knowledge bases that store your scraped and processed content.

kb.create(name, options?)KnowledgeBase
POST/api/kb

Creates a new knowledge base.

const newKb = await kb.create('Research KB', {
  description: 'My research knowledge base',
  settings: {},
});
console.log(newKb.id); // "kb_abc123"
kb.list()KnowledgeBase[]
GET/api/kb

Lists all knowledge bases owned by the authenticated user.

const kbs = await kb.list();
kbs.forEach(k => console.log(k.id, k.name));
kb.get(kbId)KnowledgeBase
GET/api/kb/:id

Fetches a single knowledge base with stats.

const myKb = await kb.get('kb_abc123');
console.log(myKb.total_pages, myKb.total_mb);
kb.stats(kbId)KBStats
GET/api/kb/:id/stats

Returns aggregated stats for a knowledge base.

const stats = await kb.stats('kb_abc123');
console.log(stats.total_pages, stats.total_mb);
kb.deleteKb(kbId)
DELETE/api/kb/:id

Permanently deletes a knowledge base and all its contents.

await kb.deleteKb('kb_abc123');

Scrape

Extract content from a single URL and store it in a knowledge base. Returns immediately with a job_id — poll kb.job() to track progress.

kb.scrape(kbId, url, options?)JobRef
POST/api/jobs/scrape
const job = await kb.scrape('kb_abc123', 'https://example.com/article', {
  formats: ['markdown', 'html'],  // default: ['markdown', 'json']
  include_docs: true,             // auto-download linked PDFs/DOCX
});
console.log(job.job_id, job.status); // "queued"

Crawl

Recursively crawl a website from a root URL and store every discovered page. The worker polls Sarvcrawl until complete (up to 15 min).

kb.crawl(kbId, url, options?)JobRef
POST/api/jobs/crawl
const job = await kb.crawl('kb_abc123', 'https://docs.example.com', {
  formats: ['markdown', 'json'],
  max_depth: 5,
  limit: 500,
  exclude_paths: ['/admin', '/api'],
  include_docs: true,
  allow_backward_links: false,
});
console.log(job.job_id);

Map

Discover all URLs on a site without extracting page content. Useful for auditing structure or planning crawls.

kb.map(kbId, url, options?)JobRef
POST/api/jobs/map
const job = await kb.map('kb_abc123', 'https://example.com', {
  limit: 5000,  // max URLs to discover, default: 5000
});
console.log(job.job_id);

Upload

Parse and index a local file — PDF, DOCX, XLSX, CSV, images, and more. OCR fallback is applied for scanned PDFs.

kb.upload(kbId, filePath, options?)JobRef
POST/api/jobs/upload
const job = await kb.upload('kb_abc123', '/path/to/report.pdf', {
  formats: ['markdown', 'json'],
  ocr_language: 'eng',  // default: 'eng'. Also supports 'hin'
});
console.log(job.job_id);

Monitor

Create a recurring check that re-scrapes a page (or re-crawls a site), diffs it against the last check, and POSTs a webhook when something is new, changed, or removed. Unlike other jobs, a monitor never "completes" — it stays "running" indefinitely by design. Output is always markdown, there's no formats/scrapeOptions field.

kb.monitor(kbId, monitorType, options)JobRef
POST/api/jobs/monitor

"page" mode watches one or more exact URLs (pass urls). "website" mode crawls a whole site and watches every discovered page (pass url, plus optional limit/include_paths/exclude_paths). schedule accepts natural language ("daily", "every 30 minutes") or a cron expression — a minimum interval is enforced server-side. notify_url is required.

const job = await kb.monitor('kb_abc123', 'page', {
  urls: ['https://example.com/pricing'],
  schedule: 'daily',
  notify_url: 'https://your-endpoint.example.com/webhook',
});
console.log(job.job_id, job.status); // "queued"

// Website mode — crawl and watch every discovered page:
await kb.monitor('kb_abc123', 'website', {
  url: 'https://docs.example.com',
  limit: 100,
  include_paths: ['/docs'],
  schedule: 'every 6 hours',
  notify_url: 'https://your-endpoint.example.com/webhook',
});

Job Management

Poll, list, cancel, and inspect jobs. Job status transitions: queued → running → completed / failed.

kb.job(jobId)Job
GET/api/jobs/:id

Fetches full details and current status for a job.

const job = await kb.job('dacf0540-f611-47eb-8e47-d5c72acea679');
console.log(job.status, job.urls_processed);
kb.jobs(options?)Job[]
GET/api/jobs

Lists jobs with optional filters.

const jobs = await kb.jobs({
  kb_id: 'kb_abc123',   // filter by KB
  status: 'completed',  // queued | running | completed | failed | cancelled
  type: 'scrape',       // scrape | crawl | search | map | upload
  limit: 20,
  offset: 0,
});
kb.cancelJob(jobId)
DELETE/api/jobs/:id/cancel

Cancels a running or queued job. For a monitor job (which stays "running" indefinitely by design), this is the correct way to stop the recurring check — required before deleteJob() will succeed.

await kb.cancelJob('dacf0540-f611-47eb-8e47-d5c72acea679');
kb.deleteJob(jobId)
DELETE/api/jobs/:id

Permanently deletes a job and its stored pages. Refuses jobs in "running"/"queued" status — monitor jobs must be cancelled with cancelJob() first.

await kb.deleteJob('dacf0540-f611-47eb-8e47-d5c72acea679');
kb.jobLogs(jobId)JobLog[]
GET/api/jobs/:id/logs

Returns processing logs for a job.

const logs = await kb.jobLogs('dacf0540-f611-47eb-8e47-d5c72acea679');
logs.forEach(l => console.log(l.level, l.message));
kb.jobAudit(jobId)AuditReport
GET/api/jobs/:id/audit

Returns a diff-audit comparing the source PDF against the extracted markdown.

const audit = await kb.jobAudit('dacf0540-f611-47eb-8e47-d5c72acea679');
console.log(audit.similarity_score);

Pages & Search

Browse pages stored in a knowledge base, retrieve their content, and run full-text search.

kb.pages(kbId, options?)PageSummary[]
GET/api/kb/:id/pages

Lists all pages stored in a knowledge base.

const pages = await kb.pages('kb_abc123', {
  limit: 50,
  offset: 0,
});
pages.forEach(p => console.log(p.url, p.title));
kb.page(kbId, pageId, format?)PageContent
GET/api/kb/:id/pages/:pageId

Fetches the stored content of a page in the requested format.

const page = await kb.page('kb_abc123', 'page_abc', 'markdown');
console.log(page.content);
kb.searchKb(kbId, q, options?)SearchResponse
GET/api/kb/:id/search

Full-text Elasticsearch search over all pages in a knowledge base.

const results = await kb.searchKb('kb_abc123', 'knowledge infrastructure', {
  page: 1,
  size: 10,
  type: 'scrape',    // optional: filter by job type
  job_id: 'job_xyz', // optional: filter by specific job
});
results.hits.forEach(h => console.log(h.title, h.score));
kb.embedSearchKb(kbId, q, options?)EmbedSearchResponse
GET/api/kb/:id/search/embed

Semantic (hybrid) search over chunk embeddings — dense KNN + BM25 fused with RRF. Returns chunk-level hits ideal for RAG. Not paginated (no page param).

const results = await kb.embedSearchKb('kb_abc123', 'how do refunds work?', {
  size: 10,
  type: 'crawl',     // optional: filter by job type
  job_id: 'job_xyz', // optional: filter by specific job
});
results.hits.forEach(h => console.log(h.rrf_score, h.title, h.text));

Files & Exports

Browse stored files, download individual files, and export jobs or entire knowledge bases as ZIP archives.

kb.kbJobs(kbId, options?)Job[]
GET/api/kb/:id/jobs

Lists all jobs belonging to a specific knowledge base.

const jobs = await kb.kbJobs('kb_abc123', { limit: 20, offset: 0 });
kb.jobFiles(kbId, jobId)FileEntry[]
GET/api/kb/:id/jobs/:jobId/files

Lists all files stored by a job (markdown, JSON, HTML, etc.).

const files = await kb.jobFiles('kb_abc123', 'dacf0540-f611-47eb-8e47-d5c72acea679');
files.forEach(f => console.log(f.path, f.size));
kb.downloadFile(kbId, jobId, filePath)Buffer
GET/api/kb/:id/jobs/:jobId/files/:fp

Downloads a single file by its storage path.

const buffer = await kb.downloadFile(
  'kb_abc123',
  'dacf0540-f611-47eb-8e47-d5c72acea679',
  'pages/page_abc/content.md',
);
fs.writeFileSync('content.md', buffer);
kb.exportJobZip(kbId, jobId)Buffer
GET/api/kb/:id/jobs/:jobId/export.zip

Downloads all files from a single job as a ZIP archive.

const zip = await kb.exportJobZip('kb_abc123', 'dacf0540-f611-47eb-8e47-d5c72acea679');
fs.writeFileSync('job-export.zip', zip);
kb.exportKbZip(kbId)Buffer
GET/api/kb/:id/export.zip

Downloads all pages across every job in a knowledge base as a single ZIP archive.

const zip = await kb.exportKbZip('kb_abc123');
fs.writeFileSync('kb-export.zip', zip);
kb.exportKb(kbId, format?)AsyncIterable<Buffer>
GET/api/kb/:id/export

Streams a full KB export in JSONL or CSV format. Ideal for large exports that should not be buffered in memory.

import { createWriteStream } from 'fs';

const stream = kb.exportKb('kb_abc123', 'jsonl'); // 'jsonl' (default) or 'csv'
const out = createWriteStream('kb-export.jsonl');
for await (const chunk of stream) {
  out.write(chunk);
}
out.end();