> ## Documentation Index
> Fetch the complete documentation index at: https://docs.valyu.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# DeepResearch API

> Comprehensive async research tasks with the Valyu Rust SDK

<Note>
  The Rust SDK is currently in **alpha**. The API is stable, but some features and interfaces may change based on user feedback.
</Note>

The DeepResearch API performs comprehensive async research tasks, generating detailed reports with citations from multiple sources. It's ideal for in-depth analysis that requires searching, synthesizing, and organizing information from various sources.

## Basic Usage

```rust theme={null}
use valyu::ValyuClient;

#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
    let client = ValyuClient::new("your-api-key");

    // Create a simple research task
    let task = client.research("What are the key differences between RAG and fine-tuning?").await?;

    println!("Task created: {:?}", task.deepresearch_id);
    println!("Status: {:?}", task.status);

    // Wait for completion
    let result = client.deepresearch_wait(
        task.deepresearch_id.as_ref().unwrap(),
        5,   // Poll every 5 seconds
        900, // Timeout after 15 minutes
    ).await?;

    if let Some(output) = &result.output {
        println!("Research output: {}", output);
    }

    Ok(())
}
```

## Advanced Usage with Builder Pattern

Use `DeepResearchCreateRequest` for full control over the research task:

```rust theme={null}
use valyu::{DeepResearchCreateRequest, DeepResearchMode, ValyuClient};

#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
    let client = ValyuClient::new("your-api-key");

    let request = DeepResearchCreateRequest::new(
        "What are the key differences between RAG and fine-tuning for LLMs?"
    )
    .with_mode(DeepResearchMode::Standard)
    .with_output_formats(vec!["markdown".to_string(), "pdf".to_string()])
    .with_strategy("Focus on peer-reviewed sources and recent publications");

    let task = client.deepresearch_create(&request).await?;
    println!("Task created: {:?}", task.deepresearch_id);

    // Wait for completion with custom timeout
    let result = client.deepresearch_wait(
        task.deepresearch_id.as_ref().unwrap(),
        5,    // Poll every 5 seconds
        900,  // Timeout after 15 minutes
    ).await?;

    // Access the research output
    if let Some(output) = &result.output {
        println!("Research completed!");
        println!("{}", output);
    }

    // Access sources used
    if let Some(sources) = &result.sources {
        println!("\nSources ({}):", sources.len());
        for source in sources.iter().take(5) {
            println!("  - {} ({})", source.title, source.url);
        }
    }

    // Access cost breakdown
    if let Some(cost) = &result.cost {
        println!("\nCost: ${:.4}", cost);
    }

    // PDF download URL (if requested)
    if let Some(pdf_url) = &result.pdf_url {
        println!("\nPDF Report: {}", pdf_url);
    }

    Ok(())
}
```

## Research Modes

| Mode       | Use Case                                                       | Typical Completion Time | Cost    |
| ---------- | -------------------------------------------------------------- | ----------------------- | ------- |
| `Fast`     | Quick answers, lightweight research, simple lookups            | \~5 minutes             | \$0.10  |
| `Standard` | Balanced research, deeper insights without long wait times     | \~10-20 minutes         | \$0.50  |
| `Heavy`    | In-depth, long-running research tasks, complex analysis        | Up to \~90 minutes      | \$2.50  |
| `Max`      | Exhaustive research with maximum quality and fact verification | Up to \~180 minutes     | \$15.00 |

<Note>
  In Rust, use the enum variants `DeepResearchMode::Fast`, `DeepResearchMode::Lite`, `DeepResearchMode::Heavy`, and `DeepResearchMode::Max`. The `Lite` variant corresponds to the `standard` mode in the API (backward compatible).
</Note>

```rust theme={null}
use valyu::DeepResearchMode;

// Fast mode for quick lookups
let request = DeepResearchCreateRequest::new("What is quantum computing?")
    .with_mode(DeepResearchMode::Fast);

// Standard mode for moderate research
let request = DeepResearchCreateRequest::new("Compare React and Vue frameworks")
    .with_mode(DeepResearchMode::Standard);

// Heavy mode for comprehensive analysis
let request = DeepResearchCreateRequest::new("Analyze the impact of AI on healthcare")
    .with_mode(DeepResearchMode::Heavy);
```

## Parameters

### Input (Required)

| Parameter | Type                | Description                        |
| --------- | ------------------- | ---------------------------------- |
| `input`   | `impl Into<String>` | Research query or task description |

### Builder Methods (Optional)

| Method                     | Type                               | Description                                           | Default        |
| -------------------------- | ---------------------------------- | ----------------------------------------------------- | -------------- |
| `with_mode()`              | `DeepResearchMode`                 | Research mode: `Fast`, `Standard`, or `Heavy`         | `Standard`     |
| `with_output_formats()`    | `Vec<String>`                      | Output formats: `["markdown"]`, `["markdown", "pdf"]` | `["markdown"]` |
| `with_structured_output()` | `serde_json::Value`                | JSON schema for structured output                     | None           |
| `with_strategy()`          | `impl Into<String>`                | Natural language research strategy                    | None           |
| `with_search()`            | `DeepResearchSearchConfig`         | Search configuration                                  | None           |
| `with_urls()`              | `Vec<String>`                      | URLs to extract content from (max 10)                 | None           |
| `with_files()`             | `Vec<DeepResearchFileAttachment>`  | File attachments (max 10)                             | None           |
| `with_deliverables()`      | `Vec<serde_json::Value>`           | Additional file outputs to generate (max 10)          | None           |
| `with_mcp_servers()`       | `Vec<DeepResearchMCPServerConfig>` | MCP server configs (max 5)                            | None           |
| `with_code_execution()`    | `bool`                             | Enable/disable code execution                         | `true`         |
| `with_previous_reports()`  | `Vec<String>`                      | Previous report IDs for context (max 3)               | None           |
| `with_webhook_url()`       | `impl Into<String>`                | Webhook URL for completion notification               | None           |
| `with_metadata()`          | `serde_json::Value`                | Custom metadata                                       | None           |

## Search Configuration

Search parameters control which data sources are queried, what content is included/excluded, and how results are filtered by date or category. These parameters are specified using `DeepResearchSearchConfig` and passed to the request via `with_search()`.

### Overview

Search parameters allow you to:

* Control which backend search systems are queried (`search_type`)
* Restrict or exclude specific source types (`included_sources`, `excluded_sources`)
* Filter results by publication date (`start_date`, `end_date`)
* Filter by category (`category`)

### Basic Example

```rust theme={null}
use valyu::{DeepResearchCreateRequest, DeepResearchMode, DeepResearchSearchConfig};

let request = DeepResearchCreateRequest::new(
    "Latest AI research in healthcare diagnostics"
)
.with_mode(DeepResearchMode::Heavy)
.with_search(DeepResearchSearchConfig {
    search_type: Some("all".to_string()),
    included_sources: Some(vec!["academic".to_string(), "web".to_string()]),
    start_date: Some("2024-01-01".to_string()),
    end_date: Some("2024-12-31".to_string()),
    excluded_sources: None,
    category: None,
});
```

### Search Type

Controls which backend search systems are queried:

* **`"all"`** (default): Searches both web and proprietary data sources
* **`"web"`**: Searches only web sources (general web search, news, articles)
* **`"proprietary"`**: Searches only proprietary data sources (academic papers, finance data, patents, etc.)

When set at the request level, this parameter **cannot be overridden** by the AI agent during research.

```rust theme={null}
let request = DeepResearchCreateRequest::new(
    "Recent advances in quantum computing"
)
.with_search(DeepResearchSearchConfig {
    search_type: Some("proprietary".to_string()),
    ..Default::default()
});
```

### Included Sources

Restricts search to only the specified source types. When specified, **only** these sources will be searched. If the AI agent attempts to use other sources, they will be ignored.

**Available source types:**

* **`"web"`**: General web search results (news, articles, websites)
* **`"academic"`**: Academic papers and research databases (ArXiv, PubMed, BioRxiv/MedRxiv, Clinical trials, FDA drug labels, WHO health data, NIH grants, Wikipedia)
* **`"finance"`**: Financial and economic data (Stock/crypto/FX prices, SEC filings, Company financial statements, Economic indicators, Prediction markets)
* **`"patent"`**: Patent and intellectual property data (USPTO patent database, Patent abstracts, claims, descriptions)
* **`"transportation"`**: Transit and transportation data (UK National Rail schedules, Maritime vessel tracking)
* **`"politics"`**: Government and parliamentary data (UK Parliament members, bills, votes)
* **`"legal"`**: Case law and legal data (UK court judgments, Legislation text)

```rust theme={null}
let request = DeepResearchCreateRequest::new(
    "Latest AI research"
)
.with_search(DeepResearchSearchConfig {
    search_type: Some("proprietary".to_string()),
    included_sources: Some(vec!["academic".to_string(), "web".to_string()]),
    ..Default::default()
});
```

### Excluded Sources

Excludes specific source types from search results. Uses the same source type values as `included_sources`. Cannot be used simultaneously with `included_sources` (use one or the other).

```rust theme={null}
let request = DeepResearchCreateRequest::new(
    "Clinical trial results"
)
.with_search(DeepResearchSearchConfig {
    search_type: Some("proprietary".to_string()),
    excluded_sources: Some(vec!["web".to_string(), "patent".to_string()]),
    ..Default::default()
});
```

### Start Date

**Format:** ISO date format (`YYYY-MM-DD`)

Filters search results to only include content published or dated on or after this date. Applied to both publication dates and event dates when available. Works across all source types.

```rust theme={null}
let request = DeepResearchCreateRequest::new(
    "Recent AI developments"
)
.with_search(DeepResearchSearchConfig {
    start_date: Some("2024-01-01".to_string()),
    ..Default::default()
});
```

### End Date

**Format:** ISO date format (`YYYY-MM-DD`)

Filters search results to only include content published or dated on or before this date. Applied to both publication dates and event dates when available. Works across all source types.

```rust theme={null}
let request = DeepResearchCreateRequest::new(
    "Historical market analysis"
)
.with_search(DeepResearchSearchConfig {
    end_date: Some("2020-12-31".to_string()),
    ..Default::default()
});
```

### Category

Filters results by a specific category. The exact categories available depend on the data source. Category values are source-dependent and may not be applicable to all source types.

```rust theme={null}
let request = DeepResearchCreateRequest::new(
    "Technology trends"
)
.with_search(DeepResearchSearchConfig {
    category: Some("technology".to_string()),
    ..Default::default()
});
```

### Important Notes

#### Parameter Enforcement

Request-level parameters are enforced and cannot be overridden by the AI agent during research. This ensures consistent search behavior throughout the research process. Tool-level source specifications are ignored if request-level sources are specified.

#### Date Filtering

Dates are applied to both publication dates and event dates when available. ISO format (`YYYY-MM-DD`) is required. Date filtering works across all source types. If only `start_date` is provided, results include all content from that date forward. If only `end_date` is provided, results include all content up to that date. Both dates can be combined for a specific date range.

## Response Types

### DeepResearchCreateResponse

```rust theme={null}
pub struct DeepResearchCreateResponse {
    pub success: bool,
    pub deepresearch_id: Option<String>,
    pub status: Option<DeepResearchStatus>,
    pub model: Option<DeepResearchMode>,
    pub created_at: Option<String>,
    pub metadata: Option<serde_json::Value>,
    pub public: Option<bool>,
    pub webhook_secret: Option<String>,  // Only returned once - store securely!
    pub message: Option<String>,
    pub error: Option<String>,
}
```

### DeepResearchStatusResponse

```rust theme={null}
pub struct DeepResearchStatusResponse {
    pub success: bool,
    pub deepresearch_id: Option<String>,
    pub status: Option<DeepResearchStatus>,        // Queued, Running, Completed, Failed, Cancelled
    pub query: Option<String>,
    pub mode: Option<DeepResearchMode>,
    pub output_formats: Option<Vec<serde_json::Value>>,
    pub created_at: Option<i64>,
    pub public: Option<bool>,
    pub progress: Option<DeepResearchProgress>,    // Current step / total steps
    pub messages: Option<Vec<serde_json::Value>>,
    pub completed_at: Option<i64>,
    pub output: Option<serde_json::Value>,         // Research output (markdown or JSON)
    pub output_type: Option<String>,               // "markdown" or "json"
    pub pdf_url: Option<String>,                   // PDF download URL
    pub images: Option<Vec<DeepResearchImage>>,    // Generated charts/images
    pub deliverables: Option<Vec<DeliverableResult>>,  // Generated deliverable files
    pub sources: Option<Vec<DeepResearchSource>>,  // Sources used
    pub cost: Option<f64>,                          // Fixed cost for the task
    pub error: Option<String>,
}

pub struct DeepResearchProgress {
    pub current_step: i32,
    pub total_steps: i32,
}

// Cost is a simple f64 value representing the fixed price:
// - Fast: $0.10
// - Standard: $0.50
// - Heavy: $2.00
```

## Client Methods

### Create Task

```rust theme={null}
let task = client.deepresearch_create(&request).await?;
```

### Get Status

```rust theme={null}
let status = client.deepresearch_status("task-id").await?;
println!("Current status: {:?}", status.status);

if let Some(progress) = &status.progress {
    println!("Progress: {}/{}", progress.current_step, progress.total_steps);
}
```

### Wait for Completion

```rust theme={null}
// Wait with custom polling interval and timeout
let result = client.deepresearch_wait(
    "task-id",
    5,    // Poll every 5 seconds
    900,  // Timeout after 15 minutes
).await?;
```

### List Tasks

```rust theme={null}
let tasks = client.deepresearch_list("api-key-id", Some(50)).await?;

if let Some(data) = &tasks.data {
    for task in data {
        println!("{}: {:?} - {}", task.deepresearch_id, task.status, task.query);
    }
}
```

### Cancel Task

```rust theme={null}
client.deepresearch_cancel("task-id").await?;
```

### Delete Task

```rust theme={null}
client.deepresearch_delete("task-id").await?;
```

## Use Case Examples

### Academic Research

```rust theme={null}
use valyu::{DeepResearchCreateRequest, DeepResearchMode, DeepResearchSearchConfig};

let request = DeepResearchCreateRequest::new(
    "What are the latest advances in quantum error correction?"
)
.with_mode(DeepResearchMode::Heavy)
.with_output_formats(vec!["markdown".to_string(), "pdf".to_string()])
.with_strategy("Focus on peer-reviewed papers from 2023-2024. Include citations.")
.with_search(DeepResearchSearchConfig {
    search_type: Some("proprietary".to_string()),
    included_sources: Some(vec!["valyu/valyu-arxiv".to_string()]),
});

let task = client.deepresearch_create(&request).await?;
let result = client.deepresearch_wait(
    task.deepresearch_id.as_ref().unwrap(),
    10,   // Poll every 10 seconds (heavy mode takes longer)
    5400, // 90 minute timeout for heavy mode
).await?;
```

### Market Analysis

```rust theme={null}
use serde_json::json;

let schema = json!({
    "type": "object",
    "properties": {
        "market_overview": {"type": "string"},
        "key_players": {
            "type": "array",
            "items": {
                "type": "object",
                "properties": {
                    "company": {"type": "string"},
                    "market_share": {"type": "string"},
                    "strengths": {"type": "array", "items": {"type": "string"}}
                }
            }
        },
        "trends": {"type": "array", "items": {"type": "string"}},
        "forecast": {"type": "string"}
    }
});

let request = DeepResearchCreateRequest::new(
    "Analyze the AI chip market landscape in 2024"
)
.with_mode(DeepResearchMode::Standard)
.with_structured_output(schema);

let task = client.deepresearch_create(&request).await?;
```

### Research with File Attachments

```rust theme={null}
use valyu::DeepResearchFileAttachment;
use base64;
use std::fs;

// Read and encode a PDF file
let pdf_bytes = fs::read("research_paper.pdf")?;
let pdf_base64 = base64::encode(&pdf_bytes);

let request = DeepResearchCreateRequest::new(
    "Summarize the key findings from this research paper and compare with recent literature"
)
.with_files(vec![DeepResearchFileAttachment {
    data: format!("data:application/pdf;base64,{}", pdf_base64),
    filename: "research_paper.pdf".to_string(),
    media_type: "application/pdf".to_string(),
    context: Some("Primary research paper to analyze".to_string()),
}]);

let task = client.deepresearch_create(&request).await?;
```

### Research with Deliverables

Generate additional file outputs alongside the research report:

```rust theme={null}
use valyu::{Deliverable, DeliverableType};
use serde_json::json;

// Simple deliverables using strings
let request = DeepResearchCreateRequest::new(
    "Research the top 20 AI companies in 2024"
)
.with_deliverables(vec![
    json!("CSV file with company names, founding year, and funding"),
    json!("PowerPoint presentation with 5 slides summarizing key findings")
]);

let task = client.deepresearch_create(&request).await?;
let result = client.deepresearch_wait(&task.deepresearch_id.unwrap()).await?;

// Access deliverables
if let Some(deliverables) = &result.deliverables {
    for deliverable in deliverables {
        if deliverable.status == DeliverableStatus::Completed {
            println!("✅ {}", deliverable.title);
            println!("   Download: {}", deliverable.url);
            if let Some(rows) = deliverable.row_count {
                println!("   Rows: {}", rows);
            }
        }
    }
}
```

### Structured Deliverables

Use the `Deliverable` type for precise control:

```rust theme={null}
use valyu::{Deliverable, DeliverableType};
use serde_json::json;

let request = DeepResearchCreateRequest::new(
    "Analyze startup funding trends in 2024"
)
.with_deliverables(vec![
    json!(Deliverable {
        deliverable_type: DeliverableType::Xlsx,
        description: "Startup funding data with company details".to_string(),
        columns: Some(vec![
            "Company".to_string(),
            "Funding Amount".to_string(),
            "Date".to_string(),
            "Investors".to_string(),
            "Stage".to_string()
        ]),
        include_headers: Some(true),
        sheet_name: Some("Funding Data".to_string()),
        slides: None,
        template: None,
    }),
    json!(Deliverable {
        deliverable_type: DeliverableType::Pptx,
        description: "Executive summary presentation".to_string(),
        columns: None,
        include_headers: None,
        sheet_name: None,
        slides: Some(10),
        template: Some("modern".to_string()),
    }),
    json!(Deliverable {
        deliverable_type: DeliverableType::Pdf,
        description: "Detailed analysis report with charts and insights".to_string(),
        columns: None,
        include_headers: None,
        sheet_name: None,
        slides: None,
        template: None,
    })
]);

let task = client.deepresearch_create(&request).await?;
let result = client.deepresearch_wait(&task.deepresearch_id.unwrap()).await?;

// Process deliverables
if let Some(deliverables) = &result.deliverables {
    for deliverable in deliverables {
        println!("{}: {}", deliverable.deliverable_type.to_uppercase(), deliverable.title);
        println!("Status: {:?}", deliverable.status);

        match deliverable.status {
            DeliverableStatus::Completed => {
                println!("Download: {}", deliverable.url);
            }
            DeliverableStatus::Failed => {
                if let Some(error) = &deliverable.error {
                    println!("Error: {}", error);
                }
            }
        }
    }
}
```

<Note>
  You can request up to 10 deliverables per research task. Deliverables are generated after the research completes.
</Note>

### Webhook Integration

```rust theme={null}
let request = DeepResearchCreateRequest::new("Comprehensive AI safety research")
    .with_mode(DeepResearchMode::Heavy)
    .with_webhook_url("https://your-app.com/webhooks/deepresearch");

let task = client.deepresearch_create(&request).await?;

// Store the webhook secret securely for signature verification
if let Some(secret) = &task.webhook_secret {
    println!("Webhook secret (store securely): {}", secret);
}
```

## Error Handling

```rust theme={null}
use valyu::{ValyuClient, DeepResearchCreateRequest, ValyuError};

let request = DeepResearchCreateRequest::new("test query");

match client.deepresearch_create(&request).await {
    Ok(task) => {
        if !task.success {
            eprintln!("Task creation failed: {:?}", task.error);
            return Ok(());
        }
        println!("Task created: {:?}", task.deepresearch_id);
    }
    Err(ValyuError::InvalidApiKey) => eprintln!("Invalid API key"),
    Err(ValyuError::ApiError(msg)) if msg.contains("Insufficient credits") => {
        eprintln!("Not enough credits - please top up your account");
    }
    Err(ValyuError::RateLimitExceeded) => eprintln!("Rate limit exceeded"),
    Err(e) => eprintln!("Error: {}", e),
}

// Handle wait errors
match client.deepresearch_wait("task-id", 5, 900).await {
    Ok(result) => {
        println!("Research completed: {:?}", result.status);
    }
    Err(ValyuError::ApiError(msg)) if msg.contains("Task was cancelled") => {
        eprintln!("Task was cancelled");
    }
    Err(ValyuError::ApiError(msg)) if msg.contains("exceeded") => {
        eprintln!("Task timed out - consider using a longer timeout for heavy mode");
    }
    Err(e) => eprintln!("Error: {}", e),
}
```

## Best Practices

### Choose the Right Mode

```rust theme={null}
// Fast mode: Quick factual lookups
let request = DeepResearchCreateRequest::new("What year was Python released?")
    .with_mode(DeepResearchMode::Fast);

// Standard mode: Standard research questions
let request = DeepResearchCreateRequest::new("Compare Python vs Rust for systems programming")
    .with_mode(DeepResearchMode::Standard);

// Heavy mode: Complex multi-faceted analysis
let request = DeepResearchCreateRequest::new(
    "Comprehensive analysis of renewable energy adoption across OECD countries"
)
.with_mode(DeepResearchMode::Heavy);
```

### Set Appropriate Timeouts

```rust theme={null}
// Fast mode: 5 minutes
let result = client.deepresearch_wait(task_id, 3, 300).await?;

// Standard mode: 15 minutes
let result = client.deepresearch_wait(task_id, 5, 900).await?;

// Heavy mode: 90 minutes
let result = client.deepresearch_wait(task_id, 10, 5400).await?;
```

### Use Webhooks for Long-Running Tasks

For heavy mode tasks, consider using webhooks instead of polling:

```rust theme={null}
let request = DeepResearchCreateRequest::new("Complex research task")
    .with_mode(DeepResearchMode::Heavy)
    .with_webhook_url("https://your-app.com/webhooks/research-complete");

let task = client.deepresearch_create(&request).await?;

// Task ID for later reference
println!("Task submitted: {:?}", task.deepresearch_id);

// Handle the webhook callback in your web server
// The webhook will include the task ID and completion status
```

### Handle Progress Updates

```rust theme={null}
let task_id = task.deepresearch_id.as_ref().unwrap();

loop {
    let status = client.deepresearch_status(task_id).await?;

    match &status.status {
        Some(DeepResearchStatus::Running) => {
            if let Some(progress) = &status.progress {
                println!(
                    "Progress: Step {}/{}",
                    progress.current_step, progress.total_steps
                );
            }
            tokio::time::sleep(std::time::Duration::from_secs(5)).await;
        }
        Some(DeepResearchStatus::Completed) => {
            println!("Research completed!");
            break;
        }
        Some(DeepResearchStatus::Failed) => {
            eprintln!("Research failed: {:?}", status.error);
            break;
        }
        _ => {
            tokio::time::sleep(std::time::Duration::from_secs(5)).await;
        }
    }
}
```
