Skip to main content
The DeepResearch API performs comprehensive research by searching multiple sources, analyzing content, and generating detailed reports. Tasks run in the background, enabling thorough multi-step research.
For conceptual overview, search configuration details, and best practices, see the DeepResearch Guide. This page focuses on TypeScript SDK method reference.

Basic Usage

import { Valyu } from "valyu-js";

const valyu = new Valyu();

// Create a research task
const task = await valyu.deepresearch.create({
  query: "What are the key differences between RAG and fine-tuning for LLMs?",
  mode: "standard"
});

if (task.success) {
  console.log(`Task created: ${task.deepresearch_id}`);
  
  // Wait for completion with progress updates
  const result = await valyu.deepresearch.wait(task.deepresearch_id, {
    onProgress: (s) => console.log(`Status: ${s.status}`)
  });
  
  if (result.status === "completed") {
    console.log(result.output);
    console.log(`Cost: $${result.cost}`);
  }
}

Research Modes

DeepResearch offers three modes optimized for different use cases:
ModeBest ForTypical Completion Time
fastQuick answers, lightweight research, simple lookups~5 minutes
standardBalanced research, deeper insights without long wait times~10-20 minutes
heavyIn-depth, long-running research tasks, complex analysisUp to ~90 minutes
The lite mode has been replaced by fast.
// Use fast mode for quick lookups
const task = await valyu.deepresearch.create({
  query: "What is quantum computing?",
  mode: "fast"
});

// Use heavy mode for complex research
const task = await valyu.deepresearch.create({
  query: "Analyze the competitive landscape of cloud computing in 2024",
  mode: "heavy"
});

Parameters

Query (Required)

ParameterTypeDescription
querystringResearch query or task description

Options (Optional)

ParameterTypeDescriptionDefault
mode"fast" | "standard" | "heavy"Research mode. For lite mode, use fast instead."standard"
outputFormatsarrayOutput formats (see below)["markdown"]
strategystringNatural language strategy instructionsundefined
searchobjectSearch configuration (filters, date range)undefined
urlsstring[]URLs to analyze (max 10)undefined
filesFileAttachment[]File attachments (max 10)undefined
deliverables(string | Deliverable)[]Additional file outputs to generate (max 10)undefined
mcpServersMCPServerConfig[]MCP server configurations (max 5)undefined
codeExecutionbooleanEnable code executiontrue
previousReportsstring[]Previous task IDs for context (max 3)undefined
webhookUrlstringHTTPS URL for completion notificationundefined
metadataobjectCustom metadata for trackingundefined

Output Formats

Markdown (Default)

const task = await valyu.deepresearch.create({
  query: "Explain quantum computing advancements in 2024",
  outputFormats: ["markdown"]
});

Markdown + PDF

Request both markdown and a downloadable PDF report:
const task = await valyu.deepresearch.create({
  query: "Write a report on renewable energy trends",
  outputFormats: ["markdown", "pdf"]
});

const result = await valyu.deepresearch.wait(task.deepresearch_id!);

if (result.pdf_url) {
  console.log(`PDF available at: ${result.pdf_url}`);
}

Structured JSON

Get research results in a custom schema using JSON Schema specification:
const task = await valyu.deepresearch.create({
  query: "Research competitor pricing in the SaaS market",
  outputFormats: [{
    type: "object",
    properties: {
      competitors: {
        type: "array",
        items: {
          type: "object",
          properties: {
            name: { type: "string" },
            pricing_model: { type: "string" },
            price_range: { type: "string" },
            key_features: {
              type: "array",
              items: { type: "string" }
            }
          },
          required: ["name", "pricing_model"]
        }
      },
      market_summary: { type: "string" },
      recommendations: {
        type: "array",
        items: { type: "string" }
      }
    },
    required: ["competitors", "market_summary"]
  }]
});

const result = await valyu.deepresearch.wait(task.deepresearch_id!);

if (result.output_type === "json") {
  const data = result.output as any;
  data.competitors.forEach((competitor: any) => {
    console.log(`${competitor.name}: ${competitor.pricing_model}`);
  });
}

TOON Format

Get research results in TOON format for structured, machine-readable deliverables. TOON format requires a JSON schema and cannot be mixed with markdown/pdf.
const task = await valyu.deepresearch.create({
  query: "Research competitor pricing in the SaaS market",
  outputFormats: [{
    type: "object",
    properties: {
      competitors: {
        type: "array",
        items: {
          type: "object",
          properties: {
            name: { type: "string" },
            pricing_model: { type: "string" }
          }
        }
      }
    },
    required: ["competitors"]
  }]
});
You cannot mix JSON Schema with markdown/pdf formats. Use one or the other. TOON format requires a JSON schema.
The schema must be a valid JSON Schema. Use type, properties, required, items, and other standard JSON Schema keywords.

Search Configuration

The search parameter controls which data sources are queried. See the DeepResearch Guide for complete documentation of all search options.
const task = await valyu.deepresearch.create({
  query: "Research AI trends",
  search: {
    searchType: "proprietary",
    includedSources: ["academic", "finance"],
    startDate: "2024-01-01",
    endDate: "2024-12-31",
    countryCode: "US"  // Filter web results by country
  }
});

Search Parameters

ParameterTypeDescription
searchType"all" | "web" | "proprietary"Which search systems to query
includedSourcesstring[]Only search these source types
excludedSourcesstring[]Exclude these source types
startDatestringISO date (YYYY-MM-DD) for minimum date
endDatestringISO date (YYYY-MM-DD) for maximum date
categorystringFilter by category (source-dependent)
countryCodestringISO 3166-1 alpha-2 code (e.g., "US", "GB") for location-filtered web searches
Available source types: web, academic, finance, patent, transportation, politics, legal

File Attachments

Analyze documents as part of research:
import * as fs from "fs";

// Read and encode a PDF
const pdfBuffer = fs.readFileSync("report.pdf");
const pdfData = pdfBuffer.toString("base64");

const task = await valyu.deepresearch.create({
  query: "Summarize the key findings and compare with market trends",
  model: "heavy",
  files: [{
    data: `data:application/pdf;base64,${pdfData}`,
    filename: "report.pdf",
    mediaType: "application/pdf",
    context: "Q4 2024 financial report"  // Optional context
  }]
});
Supported file types: PDFs, images (PNG, JPEG, WebP), and documents.

Deliverables

Generate additional file outputs alongside the research report. Deliverables allow you to extract structured data or create formatted documents (CSV, Excel, PowerPoint, Word, PDF) from the research.

Simple Deliverables

Use simple strings to describe what you need:
const task = await valyu.deepresearch.create({
  query: "Research the top 20 AI companies in 2024",
  deliverables: [
    "CSV file with company names, founding year, and funding",
    "PowerPoint presentation with 5 slides summarizing key findings"
  ]
});

const result = await valyu.deepresearch.wait(task.deepresearch_id);

if (result.deliverables) {
  for (const deliverable of result.deliverables) {
    if (deliverable.status === "completed") {
      console.log(`✅ ${deliverable.title}`);
      console.log(`   Download: ${deliverable.url}`);
      if (deliverable.row_count) {
        console.log(`   Rows: ${deliverable.row_count}`);
      }
    }
  }
}

Structured Deliverables

Use the Deliverable type for precise control:
const task = await valyu.deepresearch.create({
  query: "Analyze startup funding trends in 2024",
  deliverables: [
    {
      type: "xlsx",
      description: "Startup funding data with company details",
      columns: ["Company", "Funding Amount", "Date", "Investors", "Stage"],
      includeHeaders: true,
      sheetName: "Funding Data"
    },
    {
      type: "pptx",
      description: "Executive summary presentation",
      slides: 10,
      template: "modern"
    },
    {
      type: "pdf",
      description: "Detailed analysis report with charts and insights"
    }
  ]
});

const result = await valyu.deepresearch.wait(task.deepresearch_id);

// Access deliverables
for (const deliverable of result.deliverables) {
  console.log(`${deliverable.type.toUpperCase()}: ${deliverable.title}`);
  console.log(`Status: ${deliverable.status}`);
  if (deliverable.status === "completed") {
    console.log(`Download: ${deliverable.url}`);
  } else if (deliverable.status === "failed") {
    console.log(`Error: ${deliverable.error}`);
  }
}

Deliverable Types

TypeDescriptionOptional Fields
csvComma-separated valuescolumns, includeHeaders
xlsxExcel spreadsheetcolumns, includeHeaders, sheetName
pptxPowerPoint presentationslides, template
docxWord documenttemplate
pdfPDF documenttemplate

Deliverable Response

interface DeliverableResult {
  id: string;
  request: string;  // Original description
  type: "csv" | "xlsx" | "pptx" | "docx" | "pdf" | "unknown";
  status: "completed" | "failed";
  title: string;  // Generated filename
  url: string;  // Download URL (token-signed, expires)
  s3_key: string;
  row_count?: number;  // For CSV/Excel
  column_count?: number;  // For CSV/Excel
  error?: string;  // If failed
  created_at: string;  // ISO 8601 timestamp string
}
You can request up to 10 deliverables per research task. Deliverables are generated after the research completes.

URL Extraction

Include specific URLs to analyze alongside web research:
const task = await valyu.deepresearch.create({
  query: "Compare the approaches described in these articles",
  urls: [
    "https://example.com/article-1",
    "https://example.com/article-2"
  ]
});

Waiting for Completion

Basic Wait

const result = await valyu.deepresearch.wait(task.deepresearch_id!);

if (result.status === "completed") {
  console.log(result.output);
}

With Progress Callback

Track research progress in real-time:
const result = await valyu.deepresearch.wait(task.deepresearch_id!, {
  pollInterval: 5000,      // Check every 5 seconds
  maxWaitTime: 900000,     // Timeout after 15 minutes (standard mode)
  onProgress: (status) => {
    if (status.progress) {
      const pct = (status.progress.current_step / status.progress.total_steps) * 100;
      console.log(`Progress: ${pct.toFixed(0)}% - Step ${status.progress.current_step}/${status.progress.total_steps}`);
    }
    console.log(`Status: ${status.status}`);
  }
});

Polling Options

OptionTypeDescriptionDefault
pollIntervalnumberMilliseconds between status checks5000
maxWaitTimenumberMaximum wait time in milliseconds3600000
onProgressfunctionCallback for progress updatesundefined

Response Format

interface DeepResearchStatusResponse {
  success: boolean;
  deepresearch_id?: string;
  status?: "queued" | "running" | "completed" | "failed" | "cancelled";
  query?: string;
  mode?: "fast" | "standard" | "heavy";
  output_type?: "markdown" | "json" | "toon";
  output?: string | Record<string, any>;  // Research output
  sources?: DeepResearchSource[];  // Sources used
  cost?: number;  // Fixed cost for the task
  created_at?: string;  // ISO 8601 timestamp string
  completed_at?: string;  // ISO 8601 timestamp string
  pdf_url?: string;  // PDF download URL
  images?: ImageMetadata[];  // Generated images
  deliverables?: DeliverableResult[];  // Generated deliverable files
  batch_id?: string;  // Batch ID if task belongs to a batch
  batch_task_id?: string;  // Batch task identifier if task belongs to a batch
  error?: string;  // Error message if failed
}

Source Object

interface DeepResearchSource {
  title: string;
  url: string;
  snippet?: string;
  source?: string;  // web, pubmed, arxiv, etc.
  word_count?: number;
  doi?: string;  // For academic papers
}

Cost

The cost field contains the fixed price for the research task based on the mode:
  • fast: $0.10
  • standard: $0.50
  • heavy: $1.50

Task Management

Check Status

const status = await valyu.deepresearch.status(taskId);

console.log(`Status: ${status.status}`);
if (status.progress) {
  console.log(`Step ${status.progress.current_step}/${status.progress.total_steps}`);
}

Get Assets

Retrieve authenticated assets (images, charts, deliverables, PDFs) from completed tasks. Supports both API key authentication (default) and token-based authentication.
// Using API key (default)
const asset = await valyu.deepresearch.getAssets(taskId, assetId);

if (asset.success && asset.data) {
  // asset.data is a Buffer containing the binary data
  // asset.contentType contains the MIME type (e.g., "image/png", "application/pdf")
  fs.writeFileSync("output.png", asset.data);
}

// Using token
const asset = await valyu.deepresearch.getAssets(taskId, assetId, {
  token: "asset-access-token"
});
Response:
interface DeepResearchGetAssetsResponse {
  success: boolean;
  data?: Buffer;  // Binary asset data
  contentType?: string;  // MIME type (e.g., "image/png", "application/pdf")
  error?: string;
}

Add Follow-up Instructions

Add instructions to refine or adjust the scope of a running task. Instructions are collected during the research phase and incorporated when report generation begins.
Follow-up instructions can only be added before the writing phase starts. Once research completes and the writing phase begins, new instructions are rejected.
// Add first instruction
const response = await valyu.deepresearch.update(
  taskId,
  "Focus more on peer-reviewed sources from 2024"
);

if (response.success) {
  console.log("Instruction added");
}

// Add another instruction
await valyu.deepresearch.update(
  taskId,
  "Include a comparison table of major providers"
);

Cancel a Task

const response = await valyu.deepresearch.cancel(taskId);

if (response.success) {
  console.log("Task cancelled");
}

Delete a Task

const response = await valyu.deepresearch.delete(taskId);

if (response.success) {
  console.log("Task deleted");
}

List All Tasks

const tasks = await valyu.deepresearch.list({
  apiKeyId: "your-api-key-id",
  limit: 50
});

tasks.data?.forEach(task => {
  console.log(`${task.query?.substring(0, 50)}... - ${task.status}`);
});

Webhooks

Get notified when research completes instead of polling. See the DeepResearch Guide for complete webhook documentation including signature verification and retry behavior.
const task = await valyu.deepresearch.create({
  query: "Research market trends in AI",
  webhookUrl: "https://your-app.com/webhooks/deepresearch"
});

// IMPORTANT: Save the secret immediately - it's only returned once
const webhookSecret = task.webhook_secret;
The webhook_secret is only returned once. Store it securely—you cannot retrieve it later.

Error Handling

const task = await valyu.deepresearch.create({
  query: "Research query"
});

if (!task.success) {
  console.error(`Failed to create task: ${task.error}`);
  return;
}

try {
  const result = await valyu.deepresearch.wait(task.deepresearch_id!, {
    maxWaitTime: 1800000  // 30 minutes for standard, use 7200000 for heavy
  });
  
  if (result.status === "completed") {
    console.log(result.output);
  } else if (result.status === "failed") {
    console.error(`Research failed: ${result.error}`);
  }
  
} catch (error: any) {
  if (error.message.includes("Maximum wait time")) {
    console.log("Task timed out - cancelling");
    await valyu.deepresearch.cancel(task.deepresearch_id!);
  } else {
    console.error(`Task error: ${error.message}`);
  }
}

Best Practices

See the DeepResearch Guide for comprehensive best practices including polling strategies, timeouts, and research quality tips.
ModeRecommended Poll IntervalRecommended Timeout
fast2-5 seconds10 minutes
standard5-10 seconds30 minutes
heavy10-30 seconds120 minutes
// Production: use webhooks instead of polling
const task = await valyu.deepresearch.create({
  query: "Research query",
  webhookUrl: "https://your-app.com/webhooks"
});

Type-Safe Structured Output

interface ResearchOutput {
  summary: string;
  key_findings: string[];
  recommendations: string[];
}

const result = await valyu.deepresearch.wait(taskId);

if (result.output_type === "json" && result.output) {
  const data = result.output as ResearchOutput;
  console.log(data.summary);
  data.key_findings.forEach(finding => console.log(`- ${finding}`));
}

See Also