Skip to main content

data_for_seo/entity/dataforseo_labs/
element.rs

1//! Shared building blocks for DataForSEO Labs response models.
2//!
3//! These structs are reused across many Labs endpoints (ranked_keywords,
4//! keyword_ideas, competitors_domain, ...).
5//! See <https://docs.dataforseo.com/v3/dataforseo_labs/overview/>.
6
7use serde::{Deserialize, Serialize};
8use serde_json::Value;
9use std::collections::HashMap;
10
11/// Google Ads keyword metrics attached to a keyword.
12/// See <https://docs.dataforseo.com/v3/dataforseo_labs/google/keyword_ideas/live/>.
13#[derive(Debug, Default, Serialize, Deserialize, Clone)]
14pub struct DataForSeoLabsKeywordInfo {
15    /// Search engine type (e.g. `"google"`).
16    pub se_type: Option<String>,
17    /// Timestamp when this data was last updated (UTC).
18    pub last_updated_time: Option<String>,
19    /// Google Ads competition level, from 0 to 1.
20    pub competition: Option<f64>,
21    /// Competition category: `"LOW"`, `"MEDIUM"`, or `"HIGH"`.
22    pub competition_level: Option<String>,
23    /// Average cost per click (USD).
24    pub cpc: Option<f64>,
25    /// Average monthly search volume.
26    pub search_volume: Option<i64>,
27    /// Low range of the top-of-page bid (USD).
28    pub low_top_of_page_bid: Option<f64>,
29    /// High range of the top-of-page bid (USD).
30    pub high_top_of_page_bid: Option<f64>,
31    /// Product and service category codes for the keyword.
32    pub categories: Option<Vec<i64>>,
33    /// Search volume for each of the preceding months.
34    pub monthly_searches: Option<Vec<DataForSeoLabsMonthlySearch>>,
35    /// Percentage change of search volume across recent periods.
36    pub search_volume_trend: Option<DataForSeoLabsSearchVolumeTrend>,
37}
38
39/// A single month of historical search volume.
40#[derive(Debug, Default, Serialize, Deserialize, Clone)]
41pub struct DataForSeoLabsMonthlySearch {
42    /// Year the data point refers to.
43    pub year: Option<i64>,
44    /// Month the data point refers to (1-12).
45    pub month: Option<i64>,
46    /// Average monthly search volume.
47    pub search_volume: Option<i64>,
48}
49
50/// Percentage change of search volume across recent periods.
51#[derive(Debug, Default, Serialize, Deserialize, Clone)]
52pub struct DataForSeoLabsSearchVolumeTrend {
53    /// Percentage change compared with the previous month.
54    pub monthly: Option<i64>,
55    /// Percentage change compared with the previous quarter.
56    pub quarterly: Option<i64>,
57    /// Percentage change compared with the previous year.
58    pub yearly: Option<i64>,
59}
60
61/// Search volume normalized with a secondary data source (Bing or clickstream).
62/// See <https://docs.dataforseo.com/v3/dataforseo_labs/google/keyword_ideas/live/>.
63#[derive(Debug, Default, Serialize, Deserialize, Clone)]
64pub struct DataForSeoLabsKeywordInfoNormalized {
65    /// Search engine type (e.g. `"google"`).
66    pub se_type: Option<String>,
67    /// Timestamp when this data was last updated (UTC).
68    pub last_updated_time: Option<String>,
69    /// Whether the search volume was normalized with the secondary source.
70    pub is_normalized: Option<bool>,
71    /// Average monthly search volume.
72    pub search_volume: Option<i64>,
73    /// Search volume for each of the preceding months.
74    pub monthly_searches: Option<Vec<DataForSeoLabsMonthlySearch>>,
75}
76
77/// Clickstream-based keyword metrics.
78/// See <https://docs.dataforseo.com/v3/dataforseo_labs/google/keyword_ideas/live/>.
79#[derive(Debug, Default, Serialize, Deserialize, Clone)]
80pub struct DataForSeoLabsClickstreamKeywordInfo {
81    /// Search engine type (e.g. `"google"`).
82    pub se_type: Option<String>,
83    /// Timestamp when this data was last updated (UTC).
84    pub last_updated_time: Option<String>,
85    /// Average monthly search volume.
86    pub search_volume: Option<i64>,
87    /// Clickstream traffic split by gender.
88    pub gender_distribution: Option<DataForSeoLabsGenderDistribution>,
89    /// Clickstream traffic split by age bracket.
90    pub age_distribution: Option<DataForSeoLabsAgeDistribution>,
91    /// Search volume for each of the preceding months.
92    pub monthly_searches: Option<Vec<DataForSeoLabsMonthlySearch>>,
93}
94
95/// Structural properties of a keyword (difficulty, language, clustering).
96/// See <https://docs.dataforseo.com/v3/dataforseo_labs/google/keyword_ideas/live/>.
97#[derive(Debug, Default, Serialize, Deserialize, Clone)]
98pub struct DataForSeoLabsKeywordProperties {
99    /// Search engine type (e.g. `"google"`).
100    pub se_type: Option<String>,
101    /// Canonical keyword this keyword was clustered under.
102    pub core_keyword: Option<String>,
103    /// Algorithm used to cluster synonymous keywords.
104    pub synonym_clustering_algorithm: Option<String>,
105    /// Difficulty of ranking in the top 10, from 0 to 100.
106    pub keyword_difficulty: Option<i64>,
107    /// Language detected for the keyword.
108    pub detected_language: Option<String>,
109    /// Whether the keyword is in a language other than requested.
110    pub is_another_language: Option<bool>,
111    /// Number of words in the keyword.
112    pub words_count: Option<i64>,
113}
114
115/// Estimated Google Ads impression/click metrics for a keyword.
116/// See <https://docs.dataforseo.com/v3/dataforseo_labs/google/ranked_keywords/live/>.
117#[derive(Debug, Default, Serialize, Deserialize, Clone)]
118pub struct DataForSeoLabsImpressionsInfo {
119    /// Search engine type (e.g. `"google"`).
120    pub se_type: Option<String>,
121    /// Timestamp when this data was last updated (UTC).
122    pub last_updated_time: Option<String>,
123    /// Bid value the impression estimates are based on (USD).
124    pub bid: Option<f64>,
125    /// Keyword match type the estimates are based on.
126    pub match_type: Option<String>,
127    /// Minimum estimated ad position.
128    pub ad_position_min: Option<f64>,
129    /// Maximum estimated ad position.
130    pub ad_position_max: Option<f64>,
131    /// Average estimated ad position.
132    pub ad_position_average: Option<f64>,
133    /// Minimum estimated cost per click (USD).
134    pub cpc_min: Option<f64>,
135    /// Maximum estimated cost per click (USD).
136    pub cpc_max: Option<f64>,
137    /// Average estimated cost per click (USD).
138    pub cpc_average: Option<f64>,
139    /// Minimum estimated daily impressions.
140    pub daily_impressions_min: Option<f64>,
141    /// Maximum estimated daily impressions.
142    pub daily_impressions_max: Option<f64>,
143    /// Average estimated daily impressions.
144    pub daily_impressions_average: Option<f64>,
145    /// Minimum estimated daily clicks.
146    pub daily_clicks_min: Option<f64>,
147    /// Maximum estimated daily clicks.
148    pub daily_clicks_max: Option<f64>,
149    /// Average estimated daily clicks.
150    pub daily_clicks_average: Option<f64>,
151    /// Minimum estimated daily ad cost (USD).
152    pub daily_cost_min: Option<f64>,
153    /// Maximum estimated daily ad cost (USD).
154    pub daily_cost_max: Option<f64>,
155    /// Average estimated daily ad cost (USD).
156    pub daily_cost_average: Option<f64>,
157}
158
159/// Metadata about the SERP a keyword was last checked against.
160/// See <https://docs.dataforseo.com/v3/dataforseo_labs/google/keyword_ideas/live/>.
161#[derive(Debug, Default, Serialize, Deserialize, Clone)]
162pub struct DataForSeoLabsSerpInfo {
163    /// Search engine type (e.g. `"google"`).
164    pub se_type: Option<String>,
165    /// URL used to check the SERP.
166    pub check_url: Option<String>,
167    /// Types of SERP elements present in the results.
168    pub serp_item_types: Option<Vec<String>>,
169    /// Total number of results the search engine reported.
170    pub se_results_count: Option<i64>,
171    /// Timestamp when this data was last updated (UTC).
172    pub last_updated_time: Option<String>,
173    /// Timestamp of the previous data update (UTC).
174    pub previous_updated_time: Option<String>,
175}
176
177/// Average backlink metrics of the pages ranking for a keyword.
178/// See <https://docs.dataforseo.com/v3/dataforseo_labs/google/keyword_ideas/live/>.
179#[derive(Debug, Default, Serialize, Deserialize, Clone)]
180pub struct DataForSeoLabsAvgBacklinksInfo {
181    /// Search engine type (e.g. `"google"`).
182    pub se_type: Option<String>,
183    /// Average backlinks of the ranking pages.
184    pub backlinks: Option<f64>,
185    /// Average dofollow backlinks of the ranking pages.
186    pub dofollow: Option<f64>,
187    /// Average referring pages of the ranking pages.
188    pub referring_pages: Option<f64>,
189    /// Average referring domains of the ranking pages.
190    pub referring_domains: Option<f64>,
191    /// Average referring main domains of the ranking pages.
192    pub referring_main_domains: Option<f64>,
193    /// Average rank of the ranking pages.
194    pub rank: Option<f64>,
195    /// Average main-domain rank of the ranking pages.
196    pub main_domain_rank: Option<f64>,
197    /// Timestamp when this data was last updated (UTC).
198    pub last_updated_time: Option<String>,
199}
200
201/// Search intent classification attached to a keyword.
202/// See <https://docs.dataforseo.com/v3/dataforseo_labs/google/keyword_ideas/live/>.
203#[derive(Debug, Default, Serialize, Deserialize, Clone)]
204pub struct DataForSeoLabsSearchIntentInfo {
205    /// Search engine type (e.g. `"google"`).
206    pub se_type: Option<String>,
207    /// Dominant search intent of the keyword.
208    pub main_intent: Option<String>,
209    /// Additional detected search intents.
210    pub foreign_intent: Option<Vec<String>>,
211    /// Timestamp when this data was last updated (UTC).
212    pub last_updated_time: Option<String>,
213}
214
215/// Full set of metrics DataForSEO stores for a single keyword.
216///
217/// Used both as a standalone item (keyword_ideas, keyword_suggestions,
218/// keywords_for_site, keyword_overview, top_searches) and nested inside
219/// ranked/related keyword items.
220/// See <https://docs.dataforseo.com/v3/dataforseo_labs/google/keyword_ideas/live/>.
221#[derive(Debug, Default, Serialize, Deserialize, Clone)]
222pub struct DataForSeoLabsKeywordData {
223    /// Search engine type (e.g. `"google"`).
224    pub se_type: Option<String>,
225    /// Keyword the data relates to.
226    pub keyword: Option<String>,
227    /// Location code (e.g. `2840`); alternative to `location_name`.
228    pub location_code: Option<i32>,
229    /// Language code (e.g. `"en"`); alternative to `language_name`.
230    pub language_code: Option<String>,
231    /// Google Ads keyword metrics.
232    pub keyword_info: Option<DataForSeoLabsKeywordInfo>,
233    /// Search volume normalized with Bing data.
234    pub keyword_info_normalized_with_bing: Option<DataForSeoLabsKeywordInfoNormalized>,
235    /// Search volume normalized with clickstream data.
236    pub keyword_info_normalized_with_clickstream: Option<DataForSeoLabsKeywordInfoNormalized>,
237    /// Clickstream-based keyword metrics.
238    pub clickstream_keyword_info: Option<DataForSeoLabsClickstreamKeywordInfo>,
239    /// Structural properties of the keyword.
240    pub keyword_properties: Option<DataForSeoLabsKeywordProperties>,
241    /// Estimated Google Ads impression and click metrics.
242    pub impressions_info: Option<DataForSeoLabsImpressionsInfo>,
243    /// Metadata about the SERP the keyword was last checked against.
244    pub serp_info: Option<DataForSeoLabsSerpInfo>,
245    /// Average backlink metrics of the ranking pages.
246    pub avg_backlinks_info: Option<DataForSeoLabsAvgBacklinksInfo>,
247    /// Search-intent classification of the keyword.
248    pub search_intent_info: Option<DataForSeoLabsSearchIntentInfo>,
249}
250
251/// Clickstream gender split.
252#[derive(Debug, Default, Serialize, Deserialize, Clone)]
253pub struct DataForSeoLabsGenderDistribution {
254    /// Estimated share of female users.
255    pub female: Option<i64>,
256    /// Estimated share of male users.
257    pub male: Option<i64>,
258}
259
260/// Clickstream age split.
261#[derive(Debug, Default, Serialize, Deserialize, Clone)]
262pub struct DataForSeoLabsAgeDistribution {
263    /// Estimated traffic share for the 18-24 age bracket.
264    #[serde(rename = "18-24")]
265    pub age_18_24: Option<i64>,
266    /// Estimated traffic share for the 25-34 age bracket.
267    #[serde(rename = "25-34")]
268    pub age_25_34: Option<i64>,
269    /// Estimated traffic share for the 35-44 age bracket.
270    #[serde(rename = "35-44")]
271    pub age_35_44: Option<i64>,
272    /// Estimated traffic share for the 45-54 age bracket.
273    #[serde(rename = "45-54")]
274    pub age_45_54: Option<i64>,
275    /// Estimated traffic share for the 55-64 age bracket.
276    #[serde(rename = "55-64")]
277    pub age_55_64: Option<i64>,
278}
279
280/// Aggregated ranking metrics grouped by SERP feature type.
281/// See <https://docs.dataforseo.com/v3/dataforseo_labs/google/domain_rank_overview/live/>.
282#[derive(Debug, Default, Serialize, Deserialize, Clone)]
283pub struct DataForSeoLabsMetrics {
284    /// Metrics for organic search results.
285    pub organic: Option<DataForSeoLabsMetricsInfo>,
286    /// Metrics for paid search results.
287    pub paid: Option<DataForSeoLabsMetricsInfo>,
288    /// Metrics for featured snippet results.
289    pub featured_snippet: Option<DataForSeoLabsMetricsInfo>,
290    /// Metrics for local pack results.
291    pub local_pack: Option<DataForSeoLabsMetricsInfo>,
292}
293
294/// Ranking metrics for one SERP feature type (organic, paid, ...).
295/// See <https://docs.dataforseo.com/v3/dataforseo_labs/google/domain_rank_overview/live/>.
296#[derive(Debug, Default, Serialize, Deserialize, Clone)]
297pub struct DataForSeoLabsMetricsInfo {
298    /// Number of SERPs where the target ranks #1.
299    pub pos_1: Option<i64>,
300    /// Number of SERPs where the target ranks #2-3.
301    pub pos_2_3: Option<i64>,
302    /// Number of SERPs where the target ranks #4-10.
303    pub pos_4_10: Option<i64>,
304    /// Number of SERPs where the target ranks #11-20.
305    pub pos_11_20: Option<i64>,
306    /// Number of SERPs where the target ranks #21-30.
307    pub pos_21_30: Option<i64>,
308    /// Number of SERPs where the target ranks #31-40.
309    pub pos_31_40: Option<i64>,
310    /// Number of SERPs where the target ranks #41-50.
311    pub pos_41_50: Option<i64>,
312    /// Number of SERPs where the target ranks #51-60.
313    pub pos_51_60: Option<i64>,
314    /// Number of SERPs where the target ranks #61-70.
315    pub pos_61_70: Option<i64>,
316    /// Number of SERPs where the target ranks #71-80.
317    pub pos_71_80: Option<i64>,
318    /// Number of SERPs where the target ranks #81-90.
319    pub pos_81_90: Option<i64>,
320    /// Number of SERPs where the target ranks #91-100.
321    pub pos_91_100: Option<i64>,
322    /// Estimated monthly traffic volume (CTR times search volume across ranking keywords).
323    pub etv: Option<f64>,
324    /// Estimated traffic volume based on impressions.
325    pub impressions_etv: Option<f64>,
326    /// Number of SERPs containing the target for this feature type.
327    pub count: Option<i64>,
328    /// Estimated monthly cost (USD) to obtain this traffic via paid search.
329    pub estimated_paid_traffic_cost: Option<f64>,
330    /// Number of newly ranked elements.
331    pub is_new: Option<i64>,
332    /// Number of elements that improved in rank.
333    pub is_up: Option<i64>,
334    /// Number of elements that declined in rank.
335    pub is_down: Option<i64>,
336    /// Number of previously ranked elements no longer found.
337    pub is_lost: Option<i64>,
338    /// Estimated traffic volume derived from clickstream data.
339    pub clickstream_etv: Option<f64>,
340    /// Clickstream traffic split by gender.
341    pub clickstream_gender_distribution: Option<DataForSeoLabsGenderDistribution>,
342    /// Clickstream traffic split by age bracket.
343    pub clickstream_age_distribution: Option<DataForSeoLabsAgeDistribution>,
344}
345
346/// A ranked SERP position held by a target, wrapping the SERP item.
347/// See <https://docs.dataforseo.com/v3/dataforseo_labs/google/ranked_keywords/live/>.
348#[derive(Debug, Default, Serialize, Deserialize, Clone)]
349pub struct DataForSeoLabsRankedSerpElement {
350    /// Search engine type (e.g. `"google"`).
351    pub se_type: Option<String>,
352    /// The SERP element occupying this ranked position.
353    pub serp_item: Option<DataForSeoLabsSerpItem>,
354    /// URL used to check the SERP.
355    pub check_url: Option<String>,
356    /// Types of SERP elements present in the results.
357    pub serp_item_types: Option<Vec<String>>,
358    /// Total number of results the search engine reported.
359    pub se_results_count: Option<i64>,
360    /// Timestamp when this data was last updated (UTC).
361    pub last_updated_time: Option<String>,
362    /// Timestamp of the previous data update (UTC).
363    pub previous_updated_time: Option<String>,
364}
365
366/// A single SERP element (organic result, paid result, featured snippet, ...).
367/// See <https://docs.dataforseo.com/v3/dataforseo_labs/google/ranked_keywords/live/>.
368#[derive(Debug, Default, Serialize, Deserialize, Clone)]
369pub struct DataForSeoLabsSerpItem {
370    /// Search engine type (e.g. `"google"`).
371    pub se_type: Option<String>,
372    /// Type of SERP element (serialized as `type`).
373    #[serde(rename = "type")]
374    pub item_type: Option<String>,
375    /// Rank within elements of the same type.
376    pub rank_group: Option<i64>,
377    /// Absolute rank among all SERP elements.
378    pub rank_absolute: Option<i64>,
379    /// Placement within the SERP (e.g. `"left"` or `"right"`).
380    pub position: Option<String>,
381    /// XPath of the element in the SERP HTML.
382    pub xpath: Option<String>,
383    /// Domain of the result.
384    pub domain: Option<String>,
385    /// Title of the result.
386    pub title: Option<String>,
387    /// URL of the result (for an id-list entry, the endpoint the task was posted to).
388    pub url: Option<String>,
389    /// URL path relative to the domain.
390    pub relative_url: Option<String>,
391    /// Text snippet of the result.
392    pub description: Option<String>,
393    /// Estimated monthly traffic volume (CTR times search volume across ranking keywords).
394    pub etv: Option<f64>,
395    /// Estimated traffic volume based on impressions.
396    pub impressions_etv: Option<f64>,
397    /// Estimated monthly cost (USD) to obtain this traffic via paid search.
398    pub estimated_paid_traffic_cost: Option<f64>,
399    /// Estimated traffic volume derived from clickstream data.
400    pub clickstream_etv: Option<f64>,
401    /// How the element's rank changed since the previous check.
402    pub rank_changes: Option<DataForSeoLabsRankChanges>,
403    /// Backlink counters of the ranking page.
404    pub backlinks_info: Option<DataForSeoLabsSerpBacklinksInfo>,
405    /// Page and domain rank of the ranking page.
406    pub rank_info: Option<DataForSeoLabsRankInfo>,
407}
408
409/// Position movement of a SERP element between the last two checks.
410/// See <https://docs.dataforseo.com/v3/dataforseo_labs/google/ranked_keywords/live/>.
411#[derive(Debug, Default, Serialize, Deserialize, Clone)]
412pub struct DataForSeoLabsRankChanges {
413    /// Absolute rank at the previous check.
414    pub previous_rank_absolute: Option<i64>,
415    /// Whether the element is newly ranked.
416    pub is_new: Option<bool>,
417    /// Whether the element moved up in rank.
418    pub is_up: Option<bool>,
419    /// Whether the element moved down in rank.
420    pub is_down: Option<bool>,
421}
422
423/// Backlink counters of a ranking page.
424/// See <https://docs.dataforseo.com/v3/dataforseo_labs/google/ranked_keywords/live/>.
425#[derive(Debug, Default, Serialize, Deserialize, Clone)]
426pub struct DataForSeoLabsSerpBacklinksInfo {
427    /// Search engine type (e.g. `"google"`).
428    pub se_type: Option<String>,
429    /// Number of referring domains pointing to the page.
430    pub referring_domains: Option<i64>,
431    /// Number of referring main domains pointing to the page.
432    pub referring_main_domains: Option<i64>,
433    /// Number of referring pages pointing to the page.
434    pub referring_pages: Option<i64>,
435    /// Number of dofollow backlinks pointing to the page.
436    pub dofollow: Option<i64>,
437    /// Number of backlinks pointing to the page.
438    pub backlinks: Option<i64>,
439    /// Timestamp when the backlink data was updated (UTC).
440    pub time_update: Option<String>,
441}
442
443/// Page/domain rank of a ranking page.
444/// See <https://docs.dataforseo.com/v3/dataforseo_labs/google/ranked_keywords/live/>.
445#[derive(Debug, Default, Serialize, Deserialize, Clone)]
446pub struct DataForSeoLabsRankInfo {
447    /// Rank of the page, from 0 to 1000.
448    pub page_rank: Option<i64>,
449    /// Rank of the page's main domain, from 0 to 1000.
450    pub main_domain_rank: Option<i64>,
451}
452
453/// Common result wrapper shared by DataForSEO Labs endpoints.
454///
455/// Individual endpoints populate the relevant metadata fields (a target, a
456/// keyword, a seed keyword, ...) plus their `items` array. Fields that a
457/// given endpoint does not return stay `None`.
458/// See <https://docs.dataforseo.com/v3/dataforseo_labs/overview/>.
459#[derive(Debug, Default, Serialize, Deserialize, Clone)]
460pub struct DataForSeoLabsResult<T> {
461    /// Search engine type (e.g. `"google"`).
462    pub se_type: Option<String>,
463    /// Domain, subdomain, or webpage the request targets.
464    pub target: Option<String>,
465    /// First domain to compare.
466    pub target1: Option<String>,
467    /// Second domain to compare.
468    pub target2: Option<String>,
469    /// Store identifier of the app.
470    pub app_id: Option<String>,
471    /// App identifiers, keyed by an index string.
472    pub app_ids: Option<HashMap<String, String>>,
473    /// Keyword the data relates to.
474    pub keyword: Option<String>,
475    /// Seed keyword the results were expanded from.
476    pub seed_keyword: Option<String>,
477    /// Seed keywords the results were expanded from.
478    pub seed_keywords: Option<Vec<String>>,
479    /// Location code (e.g. `2840`); alternative to `location_name`.
480    pub location_code: Option<i32>,
481    /// Language code (e.g. `"en"`); alternative to `language_name`.
482    pub language_code: Option<String>,
483    /// Total number of matching results in the database.
484    pub total_count: Option<i64>,
485    /// Number of items returned in `items`.
486    pub items_count: Option<i64>,
487    /// Offset into the result set, for pagination.
488    pub offset: Option<i32>,
489    /// Token used to page beyond the standard offset limit.
490    pub offset_token: Option<String>,
491    /// Ranking and traffic metrics, grouped by SERP feature type.
492    pub metrics: Option<DataForSeoLabsMetrics>,
493    /// Absolute ranking and traffic metrics, grouped by SERP feature type.
494    pub metrics_absolute: Option<DataForSeoLabsMetrics>,
495    /// Result items.
496    pub items: Option<Vec<T>>,
497}
498
499impl<T> DataForSeoLabsResult<T> {
500    /// Items of this result (empty slice when the API returned none).
501    pub fn items(&self) -> &[T] {
502        self.items.as_deref().unwrap_or_default()
503    }
504}
505
506/// Raw JSON alias for endpoints whose item schema is not modeled in detail.
507pub type DataForSeoLabsRawItem = Value;