TypeScript SDK

Official TypeScript/JavaScript client for Refyne

The official TypeScript SDK for Refyne with full type support.

Installation

npm install @refyne/sdk
# or
yarn add @refyne/sdk
# or
pnpm add @refyne/sdk

Quick Start

import { Refyne } from '@refyne/sdk';

// Using the builder pattern (recommended)
const refyne = new Refyne.Builder()
  .apiKey(process.env.REFYNE_API_KEY!)
  .build();

// Or using direct constructor
const refyne = new Refyne({
  apiKey: process.env.REFYNE_API_KEY!,
});

// Extract data from a page
const result = await refyne.extract({
  url: 'https://example.com/product',
  schema: {
    name: 'string',
    price: 'number',
    description: 'string',
  },
});

console.log(result.data);
// { name: "Product Name", price: 29.99, description: "..." }

Type-Safe Schemas

Define schemas with TypeScript types:

interface ProductSchema {
  name: string;
  price: number;
  inStock: boolean;
  tags: string[];
}

const result = await refyne.extract<ProductSchema>({
  url: 'https://example.com/product',
  schema: {
    name: 'string',
    price: 'number',
    inStock: 'boolean',
    tags: ['string'],
  },
});

// result.data is typed as ProductSchema
console.log(result.data.name);

Crawling

// Start a crawl job
const job = await refyne.crawl({
  url: 'https://example.com/products',
  schema: { name: 'string', price: 'number' },
  options: {
    followSelector: 'a.product-link',
    maxPages: 20,
  },
});

// Poll for completion
let status = await refyne.jobs.get(job.jobId);
while (status.status === 'running') {
  await new Promise(r => setTimeout(r, 2000));
  status = await refyne.jobs.get(job.jobId);
}

// Get results
const results = await refyne.jobs.getResults(job.jobId);

// Get merged results
const merged = await refyne.jobs.getResults(job.jobId, { merge: true });

Site Analysis

Use the analyze endpoint to discover the structure of a website before crawling:

const analysis = await refyne.analyze({
  url: 'https://example.com/products',
  depth: 1,
});

console.log(analysis.suggestedSchema);
// { "name": "string", "price": "number", "description": "string" }

console.log(analysis.followPatterns);
// ["a.product-link", ".pagination a", "a[href*='/product/']"]

// Use the suggested schema and follow patterns in a crawl
const job = await refyne.crawl({
  url: 'https://example.com/products',
  schema: analysis.suggestedSchema,
  options: {
    followSelector: analysis.followPatterns.join(', '),
    maxPages: 50,
  },
});

Error Handling

import { RefyneError, RateLimitError, ValidationError } from '@refyne/sdk';

try {
  const result = await refyne.extract({ ... });
} catch (error) {
  if (error instanceof RateLimitError) {
    // Wait and retry
    console.log(`Rate limited. Retry after ${error.retryAfter}s`);
  } else if (error instanceof ValidationError) {
    console.error('Invalid request:', error.errors);
  } else if (error instanceof RefyneError) {
    console.error(error.message, error.status);
  }
}

Configuration

// Using builder pattern
const refyne = new Refyne.Builder()
  .apiKey(process.env.REFYNE_API_KEY!)
  .baseUrl('https://api.refyne.uk')  // Optional
  .timeout(60000)                     // Optional, in ms
  .maxRetries(3)                      // Optional
  .cacheEnabled(true)                 // Optional
  .build();

// Or using config object
const refyne = new Refyne({
  apiKey: process.env.REFYNE_API_KEY!,
  baseUrl: 'https://api.refyne.uk',  // Optional
  timeout: 30000,                     // Optional, in ms
  maxRetries: 3,                      // Optional
  cacheEnabled: true,                 // Optional
});

API Reference

For detailed method documentation, see the TypeDoc reference.