Skip to main content
The Rust SDK is currently in alpha. The API is stable, but some features and interfaces may change based on user feedback.
The Answer API combines intelligent search with AI processing to generate comprehensive, factual answers to questions. It automatically searches relevant sources and uses advanced AI to synthesize accurate responses.

Basic Usage

use valyu::ValyuClient;

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

    // Simple answer with defaults
    let response = client.ask("What are the latest developments in quantum computing?").await?;

    if response.success {
        if let Some(contents) = &response.contents {
            println!("Answer: {}", contents);
        }
        if let Some(metadata) = &response.search_metadata {
            println!("Sources used: {:?}", metadata);
        }
    }

    Ok(())
}

Advanced Usage with Builder Pattern

Use AnswerRequest for full control over answer generation:
use valyu::{ValyuClient, AnswerRequest};

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

    let request = AnswerRequest::new("What are the latest developments in quantum computing?")
        .with_search_type("web")
        .with_system_instructions("Focus on breakthroughs from 2024")
        .with_fast_mode(true);

    let response = client.answer(&request).await?;

    if let Some(contents) = &response.contents {
        println!("Answer: {}", contents);
    }

    if let Some(sources) = &response.search_results {
        println!("\nSources ({}):", sources.len());
        for source in sources {
            println!("  - {}", source.title.as_deref().unwrap_or("Untitled"));
        }
    }

    Ok(())
}

Parameters

Query (Required)

ParameterTypeDescription
queryimpl Into<String>The question or query to answer

Builder Methods (Optional)

MethodTypeDescriptionDefault
with_structured_output()serde_json::ValueJSON schema for structured response formatNone
with_system_instructions()impl Into<String>Custom AI instructions (max 2000 chars)None
with_search_type()"web" | "proprietary" | "all"Search type before generating answer"all"
with_data_max_price()f64Maximum cost in USD for data retrieval1.0
with_country_code()impl Into<String>2-letter ISO country code to bias resultsNone
with_included_sources()Vec<String>Sources to search withinNone
with_excluded_sources()Vec<String>Sources to excludeNone
with_date_range()(start, end)Date range filter (YYYY-MM-DD)None
with_fast_mode()boolEnable fast mode for reduced latencyfalse

Response Format

pub struct AnswerResponse {
    pub success: bool,
    pub error: Option<String>,
    pub tx_id: Option<String>,
    pub original_query: Option<String>,
    pub contents: Option<serde_json::Value>,  // String or structured object
    pub data_type: Option<String>,            // "unstructured" | "structured"
    pub search_results: Option<Vec<AnswerSearchResult>>,
    pub search_metadata: Option<AnswerSearchMetadata>,
    pub ai_usage: Option<AiUsage>,
    pub cost: Option<AnswerCost>,
}

pub struct AnswerSearchResult {
    pub title: Option<String>,
    pub url: Option<String>,
    pub content: Option<String>,
    pub source: Option<String>,
    pub relevance_score: Option<f64>,
}

pub struct AiUsage {
    pub input_tokens: Option<i32>,
    pub output_tokens: Option<i32>,
}

pub struct AnswerCost {
    pub search_cost: Option<f64>,
    pub ai_cost: Option<f64>,
    pub total_deduction_dollars: Option<f64>,
}

Parameter Examples

Basic Question Answering

Get a comprehensive answer to any question:
let response = client.ask("How do neural networks learn?").await?;

if response.success {
    if let Some(contents) = &response.contents {
        println!("{}", contents);
    }
}

System Instructions

Customize the AI’s response style and focus:
let request = AnswerRequest::new("Explain quantum computing")
    .with_system_instructions(
        "You are a computer science professor. Explain concepts clearly \
         with practical examples and avoid overly technical jargon."
    );

let response = client.answer(&request).await?;

Structured Output Response

Get answers in a specific JSON format:
use serde_json::json;

let schema = json!({
    "type": "object",
    "properties": {
        "summary": {
            "type": "string",
            "description": "Brief summary of AI's impact"
        },
        "key_impacts": {
            "type": "array",
            "items": {"type": "string"},
            "description": "List of key impacts"
        },
        "benefits": {
            "type": "array",
            "items": {"type": "string"},
            "maxItems": 5
        },
        "challenges": {
            "type": "array",
            "items": {"type": "string"},
            "maxItems": 5
        },
        "future_outlook": {
            "type": "string",
            "description": "Future implications and trends"
        }
    },
    "required": ["summary", "key_impacts", "future_outlook"]
});

let request = AnswerRequest::new("What is the impact of AI on software development?")
    .with_structured_output(schema);

let response = client.answer(&request).await?;

if response.success {
    if let Some(data_type) = &response.data_type {
        if data_type == "structured" {
            if let Some(contents) = &response.contents {
                println!("Structured answer: {}", serde_json::to_string_pretty(contents)?);
            }
        }
    }
}

Source Filtering

Get answers from specific, authoritative sources:
let request = AnswerRequest::new("What are the best practices for React performance optimization?")
    .with_search_type("web")
    .with_included_sources(vec![
        "react.dev".to_string(),
        "developer.mozilla.org".to_string(),
        "web.dev".to_string(),
    ])
    .with_system_instructions("Focus on official recommendations and proven techniques");

let response = client.answer(&request).await?;

Geographic and Date Filtering

Get location-specific and recent information:
let request = AnswerRequest::new("What are the current renewable energy policies and incentives?")
    .with_country_code("US")
    .with_date_range("2024-01-01", "2024-12-31")
    .with_system_instructions("Focus on federal and state-level policies with specific program details");

let response = client.answer(&request).await?;

Fast Mode

For time-sensitive applications:
let request = AnswerRequest::new("What's the current status of the stock market?")
    .with_fast_mode(true);

let response = client.answer(&request).await?;

Use Case Examples

Financial Analysis

Build an AI-powered financial research assistant:
use serde_json::json;
use valyu::{ValyuClient, AnswerRequest};

async fn financial_analysis(
    client: &ValyuClient,
    query: &str,
) -> Result<(), Box<dyn std::error::Error>> {
    let schema = json!({
        "type": "object",
        "properties": {
            "company_analysis": {
                "type": "object",
                "properties": {
                    "performance_summary": {"type": "string"},
                    "key_metrics": {
                        "type": "array",
                        "items": {"type": "string"}
                    },
                    "key_events": {
                        "type": "array",
                        "items": {"type": "string"}
                    }
                }
            },
            "competitor_comparison": {
                "type": "array",
                "items": {
                    "type": "object",
                    "properties": {
                        "company": {"type": "string"},
                        "relative_performance": {"type": "string"}
                    }
                }
            },
            "market_analysis": {"type": "string"}
        }
    });

    let request = AnswerRequest::new(query)
        .with_search_type("proprietary")
        .with_included_sources(vec!["valyu/valyu-stocks".to_string()])
        .with_structured_output(schema)
        .with_system_instructions(
            "Provide detailed financial analysis with specific metrics, \
             key events, and market context."
        );

    let response = client.answer(&request).await?;

    if response.success {
        if let Some(contents) = &response.contents {
            println!("Financial Analysis:");
            println!("{}", serde_json::to_string_pretty(contents)?);
        }

        if let Some(cost) = &response.cost {
            println!("\nCost: ${:.4}", cost.total_deduction_dollars.unwrap_or(0.0));
        }
    }

    Ok(())
}

Technical Documentation Assistant

Create an AI assistant that provides comprehensive technical guidance:
use serde_json::json;

async fn get_technical_guide(
    client: &ValyuClient,
    topic: &str,
) -> Result<Option<serde_json::Value>, Box<dyn std::error::Error>> {
    let schema = json!({
        "type": "object",
        "properties": {
            "overview": {
                "type": "string",
                "description": "Brief overview of the implementation"
            },
            "prerequisites": {
                "type": "array",
                "items": {"type": "string"},
                "description": "Required dependencies and setup"
            },
            "implementation_steps": {
                "type": "array",
                "items": {
                    "type": "object",
                    "properties": {
                        "step": {"type": "string"},
                        "description": {"type": "string"},
                        "code_example": {"type": "string"}
                    }
                }
            },
            "security_considerations": {
                "type": "array",
                "items": {"type": "string"}
            },
            "common_pitfalls": {
                "type": "array",
                "items": {"type": "string"}
            }
        },
        "required": ["overview", "implementation_steps", "security_considerations"]
    });

    let request = AnswerRequest::new(format!(
        "How do I implement {} in a Rust application?",
        topic
    ))
    .with_system_instructions(
        "Provide step-by-step implementation guidance with code examples, \
         security best practices, and common pitfalls to avoid."
    )
    .with_included_sources(vec![
        "docs.rs".to_string(),
        "rust-lang.org".to_string(),
        "github.com".to_string(),
    ])
    .with_structured_output(schema);

    let response = client.answer(&request).await?;

    if response.success {
        if let Some(contents) = &response.contents {
            println!("=== Technical Implementation Guide ===");
            println!("{}", serde_json::to_string_pretty(contents)?);
            return Ok(Some(contents.clone()));
        }
    }

    Ok(None)
}

// Usage
let guide = get_technical_guide(&client, "JWT authentication").await?;

Comparative Analysis Tool

Build a decision-making assistant:
use serde_json::json;

async fn compare_options(
    client: &ValyuClient,
    topic: &str,
    options: &[&str],
) -> Result<(), Box<dyn std::error::Error>> {
    let schema = json!({
        "type": "object",
        "properties": {
            "comparison_summary": {
                "type": "string",
                "description": "Brief overview of the comparison"
            },
            "options": {
                "type": "array",
                "items": {
                    "type": "object",
                    "properties": {
                        "name": {"type": "string"},
                        "pros": {
                            "type": "array",
                            "items": {"type": "string"}
                        },
                        "cons": {
                            "type": "array",
                            "items": {"type": "string"}
                        },
                        "best_for": {"type": "string"},
                        "learning_curve": {"type": "string"}
                    }
                }
            },
            "recommendation": {
                "type": "string",
                "description": "Final recommendation with reasoning"
            }
        },
        "required": ["comparison_summary", "options", "recommendation"]
    });

    let query = format!(
        "Compare the pros and cons of {} for {}",
        options.join(", "),
        topic
    );

    let request = AnswerRequest::new(query)
        .with_system_instructions(
            "Provide a comprehensive comparison with objective analysis. \
             Include specific examples and real-world considerations."
        )
        .with_structured_output(schema);

    let response = client.answer(&request).await?;

    if response.success {
        if let Some(contents) = &response.contents {
            println!("=== Comparative Analysis ===");
            println!("{}", serde_json::to_string_pretty(contents)?);
        }
    }

    Ok(())
}

// Usage
compare_options(
    &client,
    "web backend development",
    &["Actix Web", "Axum", "Rocket"]
).await?;

Error Handling

use valyu::{ValyuClient, AnswerRequest, ValyuError};

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

match client.answer(&request).await {
    Ok(response) => {
        if !response.success {
            eprintln!("Answer generation failed: {:?}", response.error);

            // Handle specific error cases
            if let Some(err) = &response.error {
                if err.contains("insufficient credits") {
                    eprintln!("Please add more credits to your account");
                } else if err.contains("invalid") {
                    eprintln!("Check your query and options");
                }
            }
            return;
        }

        // Process successful response
        println!("Transaction ID: {:?}", response.tx_id);
        println!("Data type: {:?}", response.data_type);

        if let Some(metadata) = &response.search_metadata {
            println!("Sources processed: {:?}", metadata);
        }

        if let Some(contents) = &response.contents {
            println!("Answer: {}", contents);
        }
    }
    Err(ValyuError::InvalidApiKey) => eprintln!("Invalid API key"),
    Err(ValyuError::RateLimitExceeded) => eprintln!("Rate limit exceeded"),
    Err(e) => eprintln!("Error: {}", e),
}

Best Practices

Improve Answer Quality

let request = AnswerRequest::new(query)
    .with_system_instructions("Provide detailed, evidence-based answers with specific examples")
    .with_search_type("proprietary")  // Use high-quality academic/professional sources
    .with_included_sources(vec!["authoritative-domain.com".to_string()])
    .with_date_range("2024-01-01", "2024-12-31");  // Focus on recent information

Handle Structured Responses

let request = AnswerRequest::new(query)
    .with_structured_output(schema);

let response = client.answer(&request).await?;

if response.success {
    match response.data_type.as_deref() {
        Some("structured") => {
            // Process as structured data
            if let Some(data) = &response.contents {
                let parsed: MyStruct = serde_json::from_value(data.clone())?;
                // Use parsed struct
            }
        }
        _ => {
            // Process as text
            if let Some(text) = &response.contents {
                println!("{}", text);
            }
        }
    }
}