Skip to main content

exa_async/types/
search.rs

1//! Types for the Exa `/search` endpoint
2
3use serde::{Deserialize, Serialize};
4
5use super::common::{ContentsOptions, LivecrawlOption, SearchResult, SearchType};
6
7// Backward-compatible re-exports (CostDollars previously lived in this module)
8pub use super::common::{CostDollars, CostDollarsContents, CostDollarsSearch};
9
10/// Request body for `POST /search`
11#[derive(Debug, Clone, Serialize, Deserialize)]
12#[serde(rename_all = "camelCase")]
13pub struct SearchRequest {
14    /// The search query (natural language)
15    pub query: String,
16
17    /// Number of results to return (default: 10)
18    #[serde(skip_serializing_if = "Option::is_none")]
19    pub num_results: Option<u32>,
20
21    /// Type of search
22    #[serde(rename = "type", skip_serializing_if = "Option::is_none")]
23    pub search_type: Option<SearchType>,
24
25    /// What content to include in results
26    #[serde(skip_serializing_if = "Option::is_none")]
27    pub contents: Option<ContentsOptions>,
28
29    /// Include domains filter
30    #[serde(skip_serializing_if = "Option::is_none")]
31    pub include_domains: Option<Vec<String>>,
32
33    /// Exclude domains filter
34    #[serde(skip_serializing_if = "Option::is_none")]
35    pub exclude_domains: Option<Vec<String>>,
36
37    /// Start date filter (ISO 8601)
38    #[serde(skip_serializing_if = "Option::is_none")]
39    pub start_published_date: Option<String>,
40
41    /// End date filter (ISO 8601)
42    #[serde(skip_serializing_if = "Option::is_none")]
43    pub end_published_date: Option<String>,
44
45    /// Livecrawl option
46    #[serde(skip_serializing_if = "Option::is_none")]
47    pub livecrawl: Option<LivecrawlOption>,
48
49    /// Category filter
50    #[serde(skip_serializing_if = "Option::is_none")]
51    pub category: Option<String>,
52}
53
54impl SearchRequest {
55    /// Create a new search request with the given query
56    #[must_use]
57    pub fn new(query: impl Into<String>) -> Self {
58        Self {
59            query: query.into(),
60            num_results: None,
61            search_type: None,
62            contents: None,
63            include_domains: None,
64            exclude_domains: None,
65            start_published_date: None,
66            end_published_date: None,
67            livecrawl: None,
68            category: None,
69        }
70    }
71
72    /// Set the number of results
73    #[must_use]
74    pub const fn with_num_results(mut self, n: u32) -> Self {
75        self.num_results = Some(n);
76        self
77    }
78
79    /// Set the search type
80    #[must_use]
81    pub const fn with_search_type(mut self, st: SearchType) -> Self {
82        self.search_type = Some(st);
83        self
84    }
85
86    /// Set the contents options
87    #[must_use]
88    pub fn with_contents(mut self, contents: ContentsOptions) -> Self {
89        self.contents = Some(contents);
90        self
91    }
92}
93
94/// Response from `POST /search`
95#[derive(Debug, Clone, Serialize, Deserialize)]
96#[serde(rename_all = "camelCase")]
97pub struct SearchResponse {
98    /// Search results
99    pub results: Vec<SearchResult>,
100
101    /// Autoprompt context (orientation text generated by Exa)
102    #[serde(default)]
103    pub autoprompt_string: Option<String>,
104
105    /// Cost in dollars for this request
106    #[serde(default)]
107    pub cost_dollars: Option<CostDollars>,
108
109    /// Resolved search type used
110    #[serde(default)]
111    pub resolved_search_type: Option<String>,
112}