The Rust SDK is in alpha. The API is stable, but some interfaces may change based on feedback.
Wire up Valyu Answer (search-grounded answers) with the Rust SDK (alpha).
Basic usage
use valyu::ValyuClient;
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
let client = ValyuClient::new("your-api-key");
let response = client.ask("What are the latest developments in quantum computing?").await?;
if response.success {
if let Some(contents) = &response.contents {
println!("{}", contents);
}
}
Ok(())
}
Common patterns
Use theAnswerRequest builder for anything beyond a plain question, then call client.answer(&request):
use serde_json::json;
use valyu::AnswerRequest;
// Steer tone and format
let req = AnswerRequest::new("Explain quantum computing")
.with_system_instructions("Explain clearly with practical examples, no jargon.");
// Restrict to authoritative sources
let req = AnswerRequest::new("React performance best practices")
.with_search_type("web")
.with_included_sources(vec!["react.dev".to_string(), "developer.mozilla.org".to_string()]);
// Recent, location-specific answers
let req = AnswerRequest::new("Current renewable energy incentives")
.with_country_code("US")
.with_date_range("2024-01-01", "2024-12-31");
// Structured output - pass a JSON schema, get back a structured object
let req = AnswerRequest::new("What is the impact of AI on software development?")
.with_structured_output(json!({
"type": "object",
"properties": {
"summary": {"type": "string"},
"key_impacts": {"type": "array", "items": {"type": "string"}}
},
"required": ["summary", "key_impacts"]
}));
let response = client.answer(&req).await?;
// With a schema, `contents` comes back as a JSON object instead of a string.
if let Some(contents) = &response.contents {
if contents.is_object() {
println!("{}", serde_json::to_string_pretty(contents)?);
}
}
For open-ended, multi-step work, reach for DeepResearch instead of Answer.
Reference
Builder methods
Builder methods
query (impl Into<String>, required) - the question to answer.| Method | Type | Description | Default |
|---|---|---|---|
with_structured_output() | serde_json::Value | JSON schema for structured response | None |
with_system_instructions() | impl Into<String> | Custom AI instructions (max 2000 chars) | None |
with_search_type() | "web" | "proprietary" | "all" | Search type before generating the answer | "all" |
with_data_max_price() | f64 | Max cost in USD for data retrieval | 1.0 |
with_country_code() | impl Into<String> | 2-letter ISO country code to bias results | None |
with_included_sources() / with_excluded_sources() | Vec<String> | Sources to search within / exclude | None |
with_date_range() | (start, end) | Date filter (YYYY-MM-DD) | None |
with_fast_mode() | bool | Reduced latency | false |
Response format
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 a JSON object when structured_output is set
pub search_results: Option<Vec<AnswerSearchResult>>,
pub search_metadata: Option<AnswerSearchMetadata>,
pub ai_usage: Option<AiUsage>,
pub cost: Option<AnswerCost>,
}
pub struct AnswerCost {
pub search_cost: Option<f64>,
pub ai_cost: Option<f64>,
pub total_deduction_dollars: Option<f64>,
}
Error handling
Error handling
use valyu::{AnswerRequest, ValyuError};
match client.answer(&AnswerRequest::new("test query")).await {
Ok(response) => {
if !response.success {
eprintln!("Answer failed: {:?}", response.error);
return;
}
if let Some(contents) = &response.contents {
println!("{}", contents);
}
}
Err(ValyuError::InvalidApiKey) => eprintln!("Invalid API key"),
Err(ValyuError::RateLimitExceeded) => eprintln!("Rate limit exceeded"),
Err(e) => eprintln!("Error: {}", e),
}

