universal-mcp-applications 0.1.1__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (268) hide show
  1. universal_mcp/applications/ahrefs/README.md +51 -0
  2. universal_mcp/applications/ahrefs/__init__.py +1 -0
  3. universal_mcp/applications/ahrefs/app.py +2291 -0
  4. universal_mcp/applications/airtable/README.md +22 -0
  5. universal_mcp/applications/airtable/__init__.py +1 -0
  6. universal_mcp/applications/airtable/app.py +479 -0
  7. universal_mcp/applications/apollo/README.md +44 -0
  8. universal_mcp/applications/apollo/__init__.py +1 -0
  9. universal_mcp/applications/apollo/app.py +1847 -0
  10. universal_mcp/applications/asana/README.md +199 -0
  11. universal_mcp/applications/asana/__init__.py +1 -0
  12. universal_mcp/applications/asana/app.py +9509 -0
  13. universal_mcp/applications/aws-s3/README.md +0 -0
  14. universal_mcp/applications/aws-s3/__init__.py +1 -0
  15. universal_mcp/applications/aws-s3/app.py +552 -0
  16. universal_mcp/applications/bill/README.md +0 -0
  17. universal_mcp/applications/bill/__init__.py +1 -0
  18. universal_mcp/applications/bill/app.py +8705 -0
  19. universal_mcp/applications/box/README.md +307 -0
  20. universal_mcp/applications/box/__init__.py +1 -0
  21. universal_mcp/applications/box/app.py +15987 -0
  22. universal_mcp/applications/braze/README.md +106 -0
  23. universal_mcp/applications/braze/__init__.py +1 -0
  24. universal_mcp/applications/braze/app.py +4754 -0
  25. universal_mcp/applications/cal-com-v2/README.md +150 -0
  26. universal_mcp/applications/cal-com-v2/__init__.py +1 -0
  27. universal_mcp/applications/cal-com-v2/app.py +5541 -0
  28. universal_mcp/applications/calendly/README.md +53 -0
  29. universal_mcp/applications/calendly/__init__.py +1 -0
  30. universal_mcp/applications/calendly/app.py +1436 -0
  31. universal_mcp/applications/canva/README.md +43 -0
  32. universal_mcp/applications/canva/__init__.py +1 -0
  33. universal_mcp/applications/canva/app.py +941 -0
  34. universal_mcp/applications/clickup/README.md +135 -0
  35. universal_mcp/applications/clickup/__init__.py +1 -0
  36. universal_mcp/applications/clickup/app.py +5009 -0
  37. universal_mcp/applications/coda/README.md +108 -0
  38. universal_mcp/applications/coda/__init__.py +1 -0
  39. universal_mcp/applications/coda/app.py +3671 -0
  40. universal_mcp/applications/confluence/README.md +198 -0
  41. universal_mcp/applications/confluence/__init__.py +1 -0
  42. universal_mcp/applications/confluence/app.py +6273 -0
  43. universal_mcp/applications/contentful/README.md +17 -0
  44. universal_mcp/applications/contentful/__init__.py +1 -0
  45. universal_mcp/applications/contentful/app.py +364 -0
  46. universal_mcp/applications/crustdata/README.md +25 -0
  47. universal_mcp/applications/crustdata/__init__.py +1 -0
  48. universal_mcp/applications/crustdata/app.py +586 -0
  49. universal_mcp/applications/dialpad/README.md +202 -0
  50. universal_mcp/applications/dialpad/__init__.py +1 -0
  51. universal_mcp/applications/dialpad/app.py +5949 -0
  52. universal_mcp/applications/digitalocean/README.md +463 -0
  53. universal_mcp/applications/digitalocean/__init__.py +1 -0
  54. universal_mcp/applications/digitalocean/app.py +20835 -0
  55. universal_mcp/applications/domain-checker/README.md +13 -0
  56. universal_mcp/applications/domain-checker/__init__.py +1 -0
  57. universal_mcp/applications/domain-checker/app.py +265 -0
  58. universal_mcp/applications/e2b/README.md +12 -0
  59. universal_mcp/applications/e2b/__init__.py +1 -0
  60. universal_mcp/applications/e2b/app.py +187 -0
  61. universal_mcp/applications/elevenlabs/README.md +88 -0
  62. universal_mcp/applications/elevenlabs/__init__.py +1 -0
  63. universal_mcp/applications/elevenlabs/app.py +3235 -0
  64. universal_mcp/applications/exa/README.md +15 -0
  65. universal_mcp/applications/exa/__init__.py +1 -0
  66. universal_mcp/applications/exa/app.py +221 -0
  67. universal_mcp/applications/falai/README.md +17 -0
  68. universal_mcp/applications/falai/__init__.py +1 -0
  69. universal_mcp/applications/falai/app.py +331 -0
  70. universal_mcp/applications/figma/README.md +49 -0
  71. universal_mcp/applications/figma/__init__.py +1 -0
  72. universal_mcp/applications/figma/app.py +1090 -0
  73. universal_mcp/applications/firecrawl/README.md +20 -0
  74. universal_mcp/applications/firecrawl/__init__.py +1 -0
  75. universal_mcp/applications/firecrawl/app.py +514 -0
  76. universal_mcp/applications/fireflies/README.md +25 -0
  77. universal_mcp/applications/fireflies/__init__.py +1 -0
  78. universal_mcp/applications/fireflies/app.py +506 -0
  79. universal_mcp/applications/fpl/README.md +23 -0
  80. universal_mcp/applications/fpl/__init__.py +1 -0
  81. universal_mcp/applications/fpl/app.py +1327 -0
  82. universal_mcp/applications/fpl/utils/api.py +142 -0
  83. universal_mcp/applications/fpl/utils/fixtures.py +629 -0
  84. universal_mcp/applications/fpl/utils/helper.py +982 -0
  85. universal_mcp/applications/fpl/utils/league_utils.py +546 -0
  86. universal_mcp/applications/fpl/utils/position_utils.py +68 -0
  87. universal_mcp/applications/ghost-content/README.md +25 -0
  88. universal_mcp/applications/ghost-content/__init__.py +1 -0
  89. universal_mcp/applications/ghost-content/app.py +654 -0
  90. universal_mcp/applications/github/README.md +1049 -0
  91. universal_mcp/applications/github/__init__.py +1 -0
  92. universal_mcp/applications/github/app.py +50600 -0
  93. universal_mcp/applications/gong/README.md +63 -0
  94. universal_mcp/applications/gong/__init__.py +1 -0
  95. universal_mcp/applications/gong/app.py +2297 -0
  96. universal_mcp/applications/google-ads/README.md +0 -0
  97. universal_mcp/applications/google-ads/__init__.py +1 -0
  98. universal_mcp/applications/google-ads/app.py +23 -0
  99. universal_mcp/applications/google-calendar/README.md +21 -0
  100. universal_mcp/applications/google-calendar/__init__.py +1 -0
  101. universal_mcp/applications/google-calendar/app.py +574 -0
  102. universal_mcp/applications/google-docs/README.md +25 -0
  103. universal_mcp/applications/google-docs/__init__.py +1 -0
  104. universal_mcp/applications/google-docs/app.py +760 -0
  105. universal_mcp/applications/google-drive/README.md +68 -0
  106. universal_mcp/applications/google-drive/__init__.py +1 -0
  107. universal_mcp/applications/google-drive/app.py +4936 -0
  108. universal_mcp/applications/google-gemini/README.md +25 -0
  109. universal_mcp/applications/google-gemini/__init__.py +1 -0
  110. universal_mcp/applications/google-gemini/app.py +663 -0
  111. universal_mcp/applications/google-mail/README.md +31 -0
  112. universal_mcp/applications/google-mail/__init__.py +1 -0
  113. universal_mcp/applications/google-mail/app.py +1354 -0
  114. universal_mcp/applications/google-searchconsole/README.md +21 -0
  115. universal_mcp/applications/google-searchconsole/__init__.py +1 -0
  116. universal_mcp/applications/google-searchconsole/app.py +320 -0
  117. universal_mcp/applications/google-sheet/README.md +36 -0
  118. universal_mcp/applications/google-sheet/__init__.py +1 -0
  119. universal_mcp/applications/google-sheet/app.py +1941 -0
  120. universal_mcp/applications/hashnode/README.md +20 -0
  121. universal_mcp/applications/hashnode/__init__.py +1 -0
  122. universal_mcp/applications/hashnode/app.py +455 -0
  123. universal_mcp/applications/heygen/README.md +44 -0
  124. universal_mcp/applications/heygen/__init__.py +1 -0
  125. universal_mcp/applications/heygen/app.py +961 -0
  126. universal_mcp/applications/http-tools/README.md +16 -0
  127. universal_mcp/applications/http-tools/__init__.py +1 -0
  128. universal_mcp/applications/http-tools/app.py +153 -0
  129. universal_mcp/applications/hubspot/README.md +239 -0
  130. universal_mcp/applications/hubspot/__init__.py +1 -0
  131. universal_mcp/applications/hubspot/app.py +416 -0
  132. universal_mcp/applications/jira/README.md +600 -0
  133. universal_mcp/applications/jira/__init__.py +1 -0
  134. universal_mcp/applications/jira/app.py +28804 -0
  135. universal_mcp/applications/klaviyo/README.md +313 -0
  136. universal_mcp/applications/klaviyo/__init__.py +1 -0
  137. universal_mcp/applications/klaviyo/app.py +11236 -0
  138. universal_mcp/applications/linkedin/README.md +15 -0
  139. universal_mcp/applications/linkedin/__init__.py +1 -0
  140. universal_mcp/applications/linkedin/app.py +243 -0
  141. universal_mcp/applications/mailchimp/README.md +281 -0
  142. universal_mcp/applications/mailchimp/__init__.py +1 -0
  143. universal_mcp/applications/mailchimp/app.py +10937 -0
  144. universal_mcp/applications/markitdown/README.md +12 -0
  145. universal_mcp/applications/markitdown/__init__.py +1 -0
  146. universal_mcp/applications/markitdown/app.py +63 -0
  147. universal_mcp/applications/miro/README.md +151 -0
  148. universal_mcp/applications/miro/__init__.py +1 -0
  149. universal_mcp/applications/miro/app.py +5429 -0
  150. universal_mcp/applications/ms-teams/README.md +42 -0
  151. universal_mcp/applications/ms-teams/__init__.py +1 -0
  152. universal_mcp/applications/ms-teams/app.py +1823 -0
  153. universal_mcp/applications/neon/README.md +74 -0
  154. universal_mcp/applications/neon/__init__.py +1 -0
  155. universal_mcp/applications/neon/app.py +2018 -0
  156. universal_mcp/applications/notion/README.md +30 -0
  157. universal_mcp/applications/notion/__init__.py +1 -0
  158. universal_mcp/applications/notion/app.py +527 -0
  159. universal_mcp/applications/openai/README.md +22 -0
  160. universal_mcp/applications/openai/__init__.py +1 -0
  161. universal_mcp/applications/openai/app.py +759 -0
  162. universal_mcp/applications/outlook/README.md +20 -0
  163. universal_mcp/applications/outlook/__init__.py +1 -0
  164. universal_mcp/applications/outlook/app.py +444 -0
  165. universal_mcp/applications/perplexity/README.md +12 -0
  166. universal_mcp/applications/perplexity/__init__.py +1 -0
  167. universal_mcp/applications/perplexity/app.py +65 -0
  168. universal_mcp/applications/pipedrive/README.md +284 -0
  169. universal_mcp/applications/pipedrive/__init__.py +1 -0
  170. universal_mcp/applications/pipedrive/app.py +12924 -0
  171. universal_mcp/applications/posthog/README.md +132 -0
  172. universal_mcp/applications/posthog/__init__.py +1 -0
  173. universal_mcp/applications/posthog/app.py +7125 -0
  174. universal_mcp/applications/reddit/README.md +135 -0
  175. universal_mcp/applications/reddit/__init__.py +1 -0
  176. universal_mcp/applications/reddit/app.py +4652 -0
  177. universal_mcp/applications/replicate/README.md +18 -0
  178. universal_mcp/applications/replicate/__init__.py +1 -0
  179. universal_mcp/applications/replicate/app.py +495 -0
  180. universal_mcp/applications/resend/README.md +40 -0
  181. universal_mcp/applications/resend/__init__.py +1 -0
  182. universal_mcp/applications/resend/app.py +881 -0
  183. universal_mcp/applications/retell/README.md +21 -0
  184. universal_mcp/applications/retell/__init__.py +1 -0
  185. universal_mcp/applications/retell/app.py +333 -0
  186. universal_mcp/applications/rocketlane/README.md +70 -0
  187. universal_mcp/applications/rocketlane/__init__.py +1 -0
  188. universal_mcp/applications/rocketlane/app.py +4346 -0
  189. universal_mcp/applications/semanticscholar/README.md +25 -0
  190. universal_mcp/applications/semanticscholar/__init__.py +1 -0
  191. universal_mcp/applications/semanticscholar/app.py +482 -0
  192. universal_mcp/applications/semrush/README.md +44 -0
  193. universal_mcp/applications/semrush/__init__.py +1 -0
  194. universal_mcp/applications/semrush/app.py +2081 -0
  195. universal_mcp/applications/sendgrid/README.md +362 -0
  196. universal_mcp/applications/sendgrid/__init__.py +1 -0
  197. universal_mcp/applications/sendgrid/app.py +9752 -0
  198. universal_mcp/applications/sentry/README.md +186 -0
  199. universal_mcp/applications/sentry/__init__.py +1 -0
  200. universal_mcp/applications/sentry/app.py +7471 -0
  201. universal_mcp/applications/serpapi/README.md +14 -0
  202. universal_mcp/applications/serpapi/__init__.py +1 -0
  203. universal_mcp/applications/serpapi/app.py +293 -0
  204. universal_mcp/applications/sharepoint/README.md +0 -0
  205. universal_mcp/applications/sharepoint/__init__.py +1 -0
  206. universal_mcp/applications/sharepoint/app.py +215 -0
  207. universal_mcp/applications/shopify/README.md +321 -0
  208. universal_mcp/applications/shopify/__init__.py +1 -0
  209. universal_mcp/applications/shopify/app.py +15392 -0
  210. universal_mcp/applications/shortcut/README.md +128 -0
  211. universal_mcp/applications/shortcut/__init__.py +1 -0
  212. universal_mcp/applications/shortcut/app.py +4478 -0
  213. universal_mcp/applications/slack/README.md +0 -0
  214. universal_mcp/applications/slack/__init__.py +1 -0
  215. universal_mcp/applications/slack/app.py +570 -0
  216. universal_mcp/applications/spotify/README.md +91 -0
  217. universal_mcp/applications/spotify/__init__.py +1 -0
  218. universal_mcp/applications/spotify/app.py +2526 -0
  219. universal_mcp/applications/supabase/README.md +87 -0
  220. universal_mcp/applications/supabase/__init__.py +1 -0
  221. universal_mcp/applications/supabase/app.py +2970 -0
  222. universal_mcp/applications/tavily/README.md +12 -0
  223. universal_mcp/applications/tavily/__init__.py +1 -0
  224. universal_mcp/applications/tavily/app.py +51 -0
  225. universal_mcp/applications/trello/README.md +266 -0
  226. universal_mcp/applications/trello/__init__.py +1 -0
  227. universal_mcp/applications/trello/app.py +10875 -0
  228. universal_mcp/applications/twillo/README.md +0 -0
  229. universal_mcp/applications/twillo/__init__.py +1 -0
  230. universal_mcp/applications/twillo/app.py +269 -0
  231. universal_mcp/applications/twitter/README.md +100 -0
  232. universal_mcp/applications/twitter/__init__.py +1 -0
  233. universal_mcp/applications/twitter/api_segments/__init__.py +0 -0
  234. universal_mcp/applications/twitter/api_segments/api_segment_base.py +51 -0
  235. universal_mcp/applications/twitter/api_segments/compliance_api.py +122 -0
  236. universal_mcp/applications/twitter/api_segments/dm_conversations_api.py +255 -0
  237. universal_mcp/applications/twitter/api_segments/dm_events_api.py +140 -0
  238. universal_mcp/applications/twitter/api_segments/likes_api.py +159 -0
  239. universal_mcp/applications/twitter/api_segments/lists_api.py +395 -0
  240. universal_mcp/applications/twitter/api_segments/openapi_json_api.py +34 -0
  241. universal_mcp/applications/twitter/api_segments/spaces_api.py +309 -0
  242. universal_mcp/applications/twitter/api_segments/trends_api.py +40 -0
  243. universal_mcp/applications/twitter/api_segments/tweets_api.py +1403 -0
  244. universal_mcp/applications/twitter/api_segments/usage_api.py +40 -0
  245. universal_mcp/applications/twitter/api_segments/users_api.py +1498 -0
  246. universal_mcp/applications/twitter/app.py +46 -0
  247. universal_mcp/applications/unipile/README.md +28 -0
  248. universal_mcp/applications/unipile/__init__.py +1 -0
  249. universal_mcp/applications/unipile/app.py +829 -0
  250. universal_mcp/applications/whatsapp/README.md +23 -0
  251. universal_mcp/applications/whatsapp/__init__.py +1 -0
  252. universal_mcp/applications/whatsapp/app.py +595 -0
  253. universal_mcp/applications/whatsapp-business/README.md +34 -0
  254. universal_mcp/applications/whatsapp-business/__init__.py +1 -0
  255. universal_mcp/applications/whatsapp-business/app.py +1065 -0
  256. universal_mcp/applications/wrike/README.md +46 -0
  257. universal_mcp/applications/wrike/__init__.py +1 -0
  258. universal_mcp/applications/wrike/app.py +1583 -0
  259. universal_mcp/applications/youtube/README.md +57 -0
  260. universal_mcp/applications/youtube/__init__.py +1 -0
  261. universal_mcp/applications/youtube/app.py +1696 -0
  262. universal_mcp/applications/zenquotes/README.md +12 -0
  263. universal_mcp/applications/zenquotes/__init__.py +1 -0
  264. universal_mcp/applications/zenquotes/app.py +31 -0
  265. universal_mcp_applications-0.1.1.dist-info/METADATA +172 -0
  266. universal_mcp_applications-0.1.1.dist-info/RECORD +268 -0
  267. universal_mcp_applications-0.1.1.dist-info/WHEEL +4 -0
  268. universal_mcp_applications-0.1.1.dist-info/licenses/LICENSE +21 -0
@@ -0,0 +1,2081 @@
1
+ from typing import Any
2
+
3
+ from universal_mcp.applications.application import APIApplication
4
+ from universal_mcp.integrations import Integration
5
+
6
+
7
+ class SemrushApp(APIApplication):
8
+ """
9
+ Base class for Universal MCP Applications.
10
+ """
11
+
12
+ def __init__(self, integration: Integration | None = None, **kwargs) -> None:
13
+ super().__init__(name="semrush", integration=integration, **kwargs)
14
+ self.base_url = "https://api.semrush.com"
15
+ self._api_key: str | None = None
16
+
17
+ def _get_headers(self):
18
+ if not self.integration:
19
+ raise ValueError("Integration not found")
20
+ credentials = self.integration.get_credentials()
21
+ if "api_key" in credentials:
22
+ self.api_key = credentials["api_key"]
23
+ # Always return empty headers
24
+ return {}
25
+
26
+ @property
27
+ def api_key(self):
28
+ """Gets the API key by calling _get_headers and caches it."""
29
+ if self._api_key:
30
+ return self._api_key
31
+ self._get_headers()
32
+ return self._api_key
33
+
34
+ @api_key.setter
35
+ def api_key(self, value: str) -> None:
36
+ """Sets the API key.
37
+
38
+ Args:
39
+ value (str): The API key to set.
40
+ """
41
+ self._api_key = value
42
+
43
+ def domain_ad_history(
44
+ self,
45
+ domain: str,
46
+ database: str = "us",
47
+ display_limit: int | None = None,
48
+ display_offset: int | None = None,
49
+ display_date: str | None = None,
50
+ export_columns: str | None = None,
51
+ display_sort: str | None = None,
52
+ display_filter: str | None = None,
53
+ export_escape: int | None = None,
54
+ export_decode: int | None = None,
55
+ ) -> dict[str, Any]:
56
+ """
57
+ Get domain ad history data showing past ad copies, landing pages, and performance metrics over time.
58
+
59
+ Args:
60
+ domain (str): Unique name of the website to investigate
61
+ database (str): Regional database (default: "us")
62
+ display_limit (int, optional): Number of results to return (max 100,000)
63
+ display_offset (int, optional): Number of results to skip
64
+ display_date (str, optional): Date in format "YYYYMM15" for historical data
65
+ export_columns (str, optional): Comma-separated list of columns to include
66
+ display_sort (str, optional): Sorting order (e.g., "tr_desc", "pc_asc")
67
+ display_filter (str, optional): Filter criteria for columns
68
+ export_escape (int, optional): Set to 1 to wrap columns in quotes
69
+ export_decode (int, optional): Set to 0 for URL-encoded response
70
+
71
+ Returns:
72
+ Dict[str, Any]: API response data
73
+
74
+ Raises:
75
+ ValueError: If required parameters are missing
76
+ httpx.HTTPStatusError: If the API request fails
77
+
78
+ Tags:
79
+ domain-search, important
80
+ """
81
+ if not domain:
82
+ raise ValueError("Domain parameter is required")
83
+
84
+ # Build parameters dictionary
85
+ params = {
86
+ "type": "domain_ad_history",
87
+ "key": self.api_key,
88
+ "domain": domain,
89
+ "database": database,
90
+ }
91
+
92
+ if display_limit is not None:
93
+ params["display_limit"] = display_limit
94
+ if display_offset is not None:
95
+ params["display_offset"] = display_offset
96
+ if display_date is not None:
97
+ params["display_date"] = display_date
98
+ if export_columns is not None:
99
+ params["export_columns"] = export_columns
100
+ if display_sort is not None:
101
+ params["display_sort"] = display_sort
102
+ if display_filter is not None:
103
+ params["display_filter"] = display_filter
104
+ if export_escape is not None:
105
+ params["export_escape"] = export_escape
106
+ if export_decode is not None:
107
+ params["export_decode"] = export_decode
108
+
109
+ response = self._get(self.base_url, params=params)
110
+
111
+ return self._handle_response(response)
112
+
113
+ def domain_organic_pages(
114
+ self,
115
+ domain: str,
116
+ database: str = "us",
117
+ display_limit: int | None = None,
118
+ display_offset: int | None = None,
119
+ display_date: str | None = None,
120
+ export_columns: str | None = None,
121
+ display_sort: str | None = None,
122
+ display_filter: str | None = None,
123
+ export_escape: int | None = None,
124
+ export_decode: int | None = None,
125
+ ) -> dict[str, Any]:
126
+ """
127
+ Get unique pages of a domain that rank in Google's top 100 organic search results.
128
+
129
+ Args:
130
+ domain (str): Unique name of the website to investigate
131
+ database (str): Regional database (default: "us")
132
+ display_limit (int, optional): Number of results to return (max 100,000)
133
+ display_offset (int, optional): Number of results to skip
134
+ display_date (str, optional): Date in format "YYYYMM15" for historical data
135
+ export_columns (str, optional): Comma-separated list of columns to include
136
+ display_sort (str, optional): Sorting order (e.g., "tr_desc", "pc_asc")
137
+ display_filter (str, optional): Filter criteria for columns
138
+ export_escape (int, optional): Set to 1 to wrap columns in quotes
139
+ export_decode (int, optional): Set to 0 for URL-encoded response
140
+
141
+ Returns:
142
+ dict[str, Any]: API response data
143
+
144
+ Raises:
145
+ ValueError: If required parameters are missing
146
+ httpx.HTTPStatusError: If the API request fails
147
+
148
+ Tags:
149
+ domain-search
150
+ """
151
+ if not domain:
152
+ raise ValueError("Domain parameter is required")
153
+
154
+ # Build parameters dictionary
155
+ params = {
156
+ "type": "domain_organic_unique",
157
+ "key": self.api_key,
158
+ "domain": domain,
159
+ "database": database,
160
+ }
161
+
162
+ if display_limit is not None:
163
+ params["display_limit"] = display_limit
164
+ if display_offset is not None:
165
+ params["display_offset"] = display_offset
166
+ if display_date is not None:
167
+ params["display_date"] = display_date
168
+ if export_columns is not None:
169
+ params["export_columns"] = export_columns
170
+ if display_sort is not None:
171
+ params["display_sort"] = display_sort
172
+ if display_filter is not None:
173
+ params["display_filter"] = display_filter
174
+ if export_escape is not None:
175
+ params["export_escape"] = export_escape
176
+ if export_decode is not None:
177
+ params["export_decode"] = export_decode
178
+
179
+ response = self._get(self.base_url, params=params)
180
+
181
+ return self._handle_response(response)
182
+
183
+ def domain_organic_search_keywords(
184
+ self,
185
+ domain: str,
186
+ database: str = "us",
187
+ display_limit: int | None = None,
188
+ display_offset: int | None = None,
189
+ display_date: str | None = None,
190
+ display_daily: int | None = None,
191
+ export_columns: str | None = None,
192
+ display_sort: str | None = None,
193
+ display_positions: str | None = None,
194
+ display_positions_type: str | None = None,
195
+ display_filter: str | None = None,
196
+ export_escape: int | None = None,
197
+ ) -> dict[str, Any]:
198
+ """
199
+ Get keywords that bring organic traffic to a domain via Google's top 100 search results.
200
+
201
+ Args:
202
+ domain (str): Unique name of a website to investigate
203
+ database (str): Regional database (default: "us")
204
+ display_limit (int, optional): Number of results to return (max 100,000)
205
+ display_offset (int, optional): Number of results to skip
206
+ display_date (str, optional): Date in format "YYYYMM15" or "YYYYMMDD"
207
+ display_daily (int, optional): Set to 1 for daily updates in last 31 days
208
+ export_columns (str, optional): Comma-separated list of columns to include
209
+ display_sort (str, optional): Sorting order (e.g., "po_asc", "tg_desc")
210
+ display_positions (str, optional): Filter by position changes ("new", "lost", "rise", "fall")
211
+ display_positions_type (str, optional): Position type ("organic", "all", "serp_features")
212
+ display_filter (str, optional): Filter criteria for columns
213
+ export_escape (int, optional): Set to 1 to wrap columns in quotes
214
+
215
+ Returns:
216
+ dict[str, Any]: API response data
217
+
218
+ Raises:
219
+ ValueError: If required parameters are missing
220
+ httpx.HTTPStatusError: If the API request fails
221
+
222
+ Tags:
223
+ domain-search
224
+ """
225
+ if not domain:
226
+ raise ValueError("Domain parameter is required")
227
+
228
+ # Build parameters dictionary
229
+ params = {
230
+ "type": "domain_organic",
231
+ "key": self.api_key,
232
+ "domain": domain,
233
+ "database": database,
234
+ }
235
+
236
+ if display_limit is not None:
237
+ params["display_limit"] = display_limit
238
+ if display_offset is not None:
239
+ params["display_offset"] = display_offset
240
+ if display_date is not None:
241
+ params["display_date"] = display_date
242
+ if display_daily is not None:
243
+ params["display_daily"] = display_daily
244
+ if export_columns is not None:
245
+ params["export_columns"] = export_columns
246
+ if display_sort is not None:
247
+ params["display_sort"] = display_sort
248
+ if display_positions is not None:
249
+ params["display_positions"] = display_positions
250
+ if display_positions_type is not None:
251
+ params["display_positions_type"] = display_positions_type
252
+ if display_filter is not None:
253
+ params["display_filter"] = display_filter
254
+ if export_escape is not None:
255
+ params["export_escape"] = export_escape
256
+
257
+ response = self._get(self.base_url, params=params)
258
+
259
+ return self._handle_response(response)
260
+
261
+ def domain_organic_subdomains(
262
+ self,
263
+ domain: str,
264
+ database: str = "us",
265
+ display_limit: int | None = None,
266
+ display_offset: int | None = None,
267
+ display_date: str | None = None,
268
+ export_columns: str | None = None,
269
+ display_sort: str | None = None,
270
+ export_escape: int | None = None,
271
+ export_decode: int | None = None,
272
+ ) -> dict[str, Any]:
273
+ """
274
+ Get subdomains of a domain that rank in Google's top 100 organic search results.
275
+
276
+ Args:
277
+ domain (str): Unique name of the website to investigate
278
+ database (str): Regional database (default: "us")
279
+ display_limit (int, optional): Number of results to return (max 100,000)
280
+ display_offset (int, optional): Number of results to skip
281
+ display_date (str, optional): Date in format "YYYYMM15" for historical data
282
+ export_columns (str, optional): Comma-separated list of columns to include
283
+ display_sort (str, optional): Sorting order (e.g., "pc_asc", "tg_desc")
284
+ export_escape (int, optional): Set to 1 to wrap columns in quotes
285
+ export_decode (int, optional): Set to 0 for URL-encoded response
286
+
287
+ Returns:
288
+ dict[str, Any]: API response data
289
+
290
+ Raises:
291
+ ValueError: If required parameters are missing
292
+ httpx.HTTPStatusError: If the API request fails
293
+
294
+ Tags:
295
+ domain-search
296
+ """
297
+ if not domain:
298
+ raise ValueError("Domain parameter is required")
299
+
300
+ # Build parameters dictionary
301
+ params = {
302
+ "type": "domain_organic_subdomains",
303
+ "key": self.api_key,
304
+ "domain": domain,
305
+ "database": database,
306
+ }
307
+
308
+ if display_limit is not None:
309
+ params["display_limit"] = display_limit
310
+ if display_offset is not None:
311
+ params["display_offset"] = display_offset
312
+ if display_date is not None:
313
+ params["display_date"] = display_date
314
+ if export_columns is not None:
315
+ params["export_columns"] = export_columns
316
+ if display_sort is not None:
317
+ params["display_sort"] = display_sort
318
+ if export_escape is not None:
319
+ params["export_escape"] = export_escape
320
+ if export_decode is not None:
321
+ params["export_decode"] = export_decode
322
+
323
+ response = self._get(self.base_url, params=params)
324
+
325
+ return self._handle_response(response)
326
+
327
+ def domain_paid_search_keywords(
328
+ self,
329
+ domain: str,
330
+ database: str = "us",
331
+ display_limit: int | None = None,
332
+ display_offset: int | None = None,
333
+ display_date: str | None = None,
334
+ export_columns: str | None = None,
335
+ display_sort: str | None = None,
336
+ display_positions: str | None = None,
337
+ display_filter: str | None = None,
338
+ export_escape: int | None = None,
339
+ export_decode: int | None = None,
340
+ ) -> dict[str, Any]:
341
+ """
342
+ Get keywords that bring paid traffic to a domain via Google's paid search results.
343
+
344
+ Args:
345
+ domain (str): Unique name of a website to investigate
346
+ database (str): Regional database (default: "us")
347
+ display_limit (int, optional): Number of results to return (max 100,000)
348
+ display_offset (int, optional): Number of results to skip
349
+ display_date (str, optional): Date in format "YYYYMM15" for historical data
350
+ export_columns (str, optional): Comma-separated list of columns to include
351
+ display_sort (str, optional): Sorting order (e.g., "po_asc", "tg_desc")
352
+ display_positions (str, optional): Filter by position changes ("new", "lost", "rise", "fall")
353
+ display_filter (str, optional): Filter criteria for columns
354
+ export_escape (int, optional): Set to 1 to wrap columns in quotes
355
+ export_decode (int, optional): Set to 0 for URL-encoded response
356
+
357
+ Returns:
358
+ dict[str, Any]: API response data
359
+
360
+ Raises:
361
+ ValueError: If required parameters are missing
362
+ httpx.HTTPStatusError: If the API request fails
363
+
364
+ Tags:
365
+ domain-search
366
+ """
367
+ if not domain:
368
+ raise ValueError("Domain parameter is required")
369
+
370
+ # Build parameters dictionary
371
+ params = {
372
+ "type": "domain_adwords",
373
+ "key": self.api_key,
374
+ "domain": domain,
375
+ "database": database,
376
+ }
377
+
378
+ if display_limit is not None:
379
+ params["display_limit"] = display_limit
380
+ if display_offset is not None:
381
+ params["display_offset"] = display_offset
382
+ if display_date is not None:
383
+ params["display_date"] = display_date
384
+ if export_columns is not None:
385
+ params["export_columns"] = export_columns
386
+ if display_sort is not None:
387
+ params["display_sort"] = display_sort
388
+ if display_positions is not None:
389
+ params["display_positions"] = display_positions
390
+ if display_filter is not None:
391
+ params["display_filter"] = display_filter
392
+ if export_escape is not None:
393
+ params["export_escape"] = export_escape
394
+ if export_decode is not None:
395
+ params["export_decode"] = export_decode
396
+
397
+ response = self._get(self.base_url, params=params)
398
+
399
+ return self._handle_response(response)
400
+
401
+ def domain_pla_search_keywords(
402
+ self,
403
+ domain: str,
404
+ database: str = "us",
405
+ display_limit: int | None = None,
406
+ display_offset: int | None = None,
407
+ export_columns: str | None = None,
408
+ display_sort: str | None = None,
409
+ display_filter: str | None = None,
410
+ export_escape: int | None = None,
411
+ export_decode: int | None = None,
412
+ ) -> dict[str, Any]:
413
+ """
414
+ Get keywords that trigger a domain's product listing ads (PLA) in Google's paid search results.
415
+
416
+ Args:
417
+ domain (str): Unique name of a website to investigate
418
+ database (str): Regional database (default: "us")
419
+ display_limit (int, optional): Number of results to return (max 100,000)
420
+ display_offset (int, optional): Number of results to skip
421
+ export_columns (str, optional): Comma-separated list of columns to include
422
+ display_sort (str, optional): Sorting order (e.g., "po_asc", "nq_desc")
423
+ display_filter (str, optional): Filter criteria for columns
424
+ export_escape (int, optional): Set to 1 to wrap columns in quotes
425
+ export_decode (int, optional): Set to 0 for URL-encoded response
426
+
427
+ Returns:
428
+ dict[str, Any]: API response data
429
+
430
+ Raises:
431
+ ValueError: If required parameters are missing
432
+ httpx.HTTPStatusError: If the API request fails
433
+
434
+ Tags:
435
+ domain-search
436
+ """
437
+ if not domain:
438
+ raise ValueError("Domain parameter is required")
439
+
440
+ # Build parameters dictionary
441
+ params = {
442
+ "type": "domain_shopping",
443
+ "key": self.api_key,
444
+ "domain": domain,
445
+ "database": database,
446
+ }
447
+
448
+ if display_limit is not None:
449
+ params["display_limit"] = display_limit
450
+ if display_offset is not None:
451
+ params["display_offset"] = display_offset
452
+ if export_columns is not None:
453
+ params["export_columns"] = export_columns
454
+ if display_sort is not None:
455
+ params["display_sort"] = display_sort
456
+ if display_filter is not None:
457
+ params["display_filter"] = display_filter
458
+ if export_escape is not None:
459
+ params["export_escape"] = export_escape
460
+ if export_decode is not None:
461
+ params["export_decode"] = export_decode
462
+
463
+ response = self._get(self.base_url, params=params)
464
+
465
+ return self._handle_response(response)
466
+
467
+ def domain_vs_domain(
468
+ self,
469
+ domains: str,
470
+ database: str = "us",
471
+ display_limit: int | None = None,
472
+ display_offset: int | None = None,
473
+ display_date: str | None = None,
474
+ export_columns: str | None = None,
475
+ display_sort: str | None = None,
476
+ display_filter: str | None = None,
477
+ export_escape: int | None = None,
478
+ export_decode: int | None = None,
479
+ ) -> dict[str, Any]:
480
+ """
481
+ Compare up to five domains by common keywords, unique keywords, or search terms unique to the first domain.
482
+
483
+ Args:
484
+ domains (str): URL-encoded string containing domains in format: <sign>|<type>|<domain>
485
+ Examples:
486
+ - Shared keywords: "*|or|domain1|*|or|domain2|*|or|domain3"
487
+ - All keywords: "*|or|domain1|+|or|domain2|+|or|domain3"
488
+ - Unique keywords: "*|or|domain1|-|or|domain2|-|or|domain3"
489
+ - Untapped keywords: "*|or|domain2|+|or|domain3|-|or|domain1"
490
+ database (str): Regional database (default: "us")
491
+ display_limit (int, optional): Number of results to return (max 100,000)
492
+ display_offset (int, optional): Number of results to skip
493
+ display_date (str, optional): Date in format "YYYYMM15" for historical data
494
+ export_columns (str, optional): Comma-separated list of columns to include
495
+ display_sort (str, optional): Sorting order (e.g., "p0_asc", "p1_desc")
496
+ display_filter (str, optional): Filter criteria for columns
497
+ export_escape (int, optional): Set to 1 to wrap columns in quotes
498
+ export_decode (int, optional): Set to 0 for URL-encoded response
499
+
500
+ Returns:
501
+ dict[str, Any]: API response data
502
+
503
+ Raises:
504
+ ValueError: If required parameters are missing
505
+ httpx.HTTPStatusError: If the API request fails
506
+
507
+ Tags:
508
+ domain-search
509
+ """
510
+ if not domains:
511
+ raise ValueError("Domains parameter is required")
512
+
513
+ # Build parameters dictionary
514
+ params = {
515
+ "type": "domain_domains",
516
+ "key": self.api_key,
517
+ "domains": domains,
518
+ "database": database,
519
+ }
520
+
521
+ if display_limit is not None:
522
+ params["display_limit"] = display_limit
523
+ if display_offset is not None:
524
+ params["display_offset"] = display_offset
525
+ if display_date is not None:
526
+ params["display_date"] = display_date
527
+ if export_columns is not None:
528
+ params["export_columns"] = export_columns
529
+ if display_sort is not None:
530
+ params["display_sort"] = display_sort
531
+ if display_filter is not None:
532
+ params["display_filter"] = display_filter
533
+ if export_escape is not None:
534
+ params["export_escape"] = export_escape
535
+ if export_decode is not None:
536
+ params["export_decode"] = export_decode
537
+
538
+ response = self._get(self.base_url, params=params)
539
+
540
+ return self._handle_response(response)
541
+
542
+ def backlinks(
543
+ self,
544
+ target: str,
545
+ target_type: str,
546
+ export_columns: str | None = None,
547
+ display_sort: str | None = None,
548
+ display_limit: int | None = None,
549
+ display_offset: int | None = None,
550
+ display_filter: str | None = None,
551
+ ) -> dict[str, Any]:
552
+ """
553
+ Get backlinks data for a domain, root domain, or URL.
554
+
555
+ Args:
556
+ target (str): Root domain, subdomain, or URL of the website to investigate
557
+ target_type (str): Type of requested target (root_domain, domain, or url)
558
+ export_columns (str, optional): Comma-separated list of columns to include
559
+ display_sort (str, optional): Sorting order (e.g., "page_ascore_desc", "last_seen_asc")
560
+ display_limit (int, optional): Number of results to return (max 1,000,000)
561
+ display_offset (int, optional): Number of results to skip
562
+ display_filter (str, optional): Filter criteria for columns
563
+
564
+ Returns:
565
+ dict[str, Any]: API response data
566
+
567
+ Raises:
568
+ ValueError: If required parameters are missing
569
+ httpx.HTTPStatusError: If the API request fails
570
+
571
+ Tags:
572
+ backlinks
573
+ """
574
+ if not target:
575
+ raise ValueError("Target parameter is required")
576
+ if not target_type:
577
+ raise ValueError("Target_type parameter is required")
578
+
579
+ # Build parameters dictionary
580
+ params = {
581
+ "type": "backlinks",
582
+ "key": self.api_key,
583
+ "target": target,
584
+ "target_type": target_type,
585
+ }
586
+
587
+ if export_columns is not None:
588
+ params["export_columns"] = export_columns
589
+ if display_sort is not None:
590
+ params["display_sort"] = display_sort
591
+ if display_limit is not None:
592
+ params["display_limit"] = display_limit
593
+ if display_offset is not None:
594
+ params["display_offset"] = display_offset
595
+ if display_filter is not None:
596
+ params["display_filter"] = display_filter
597
+
598
+ url = f"{self.base_url}/analytics/v1"
599
+ response = self._get(url, params=params)
600
+
601
+ return self._handle_response(response)
602
+
603
+ def backlinks_overview(
604
+ self,
605
+ target: str,
606
+ target_type: str,
607
+ export_columns: str | None = None,
608
+ display_sort: str | None = None,
609
+ display_limit: int | None = None,
610
+ display_offset: int | None = None,
611
+ display_filter: str | None = None,
612
+ ) -> dict[str, Any]:
613
+ """
614
+ Get backlinks overview summary including type, referring domains, and IP addresses.
615
+
616
+ Args:
617
+ target (str): Root domain, subdomain, or URL of the website to investigate
618
+ target_type (str): Type of requested target (root_domain, domain, or url)
619
+ export_columns (str, optional): Comma-separated list of columns to include
620
+ display_sort (str, optional): Sorting order for results
621
+ display_limit (int, optional): Number of results to return
622
+ display_offset (int, optional): Number of results to skip
623
+ display_filter (str, optional): Filter criteria for columns
624
+
625
+ Returns:
626
+ dict[str, Any]: API response data
627
+
628
+ Raises:
629
+ ValueError: If required parameters are missing
630
+ httpx.HTTPStatusError: If the API request fails
631
+
632
+ Tags:
633
+ backlinks
634
+ """
635
+ if not target:
636
+ raise ValueError("Target parameter is required")
637
+ if not target_type:
638
+ raise ValueError("Target_type parameter is required")
639
+
640
+ # Build parameters dictionary
641
+ params = {
642
+ "type": "backlinks_overview",
643
+ "key": self.api_key,
644
+ "target": target,
645
+ "target_type": target_type,
646
+ }
647
+
648
+ if export_columns is not None:
649
+ params["export_columns"] = export_columns
650
+ if display_sort is not None:
651
+ params["display_sort"] = display_sort
652
+ if display_limit is not None:
653
+ params["display_limit"] = display_limit
654
+ if display_offset is not None:
655
+ params["display_offset"] = display_offset
656
+ if display_filter is not None:
657
+ params["display_filter"] = display_filter
658
+
659
+ url = f"{self.base_url}/analytics/v1"
660
+ response = self._get(url, params=params)
661
+
662
+ return self._handle_response(response)
663
+
664
+ def keyword_difficulty(
665
+ self,
666
+ phrase: str,
667
+ database: str = "us",
668
+ export_columns: str | None = None,
669
+ export_escape: int | None = None,
670
+ ) -> dict[str, Any]:
671
+ """
672
+ Get keyword difficulty data to estimate ranking difficulty for organic search terms.
673
+
674
+ Args:
675
+ phrase (str): Phrase (from 1 to 100 keywords separated by semicolons)
676
+ database (str): Regional database (default: "us")
677
+ export_columns (str, optional): Comma-separated list of columns to include
678
+ export_escape (int, optional): Set to 1 to wrap columns in quotes
679
+
680
+ Returns:
681
+ dict[str, Any]: API response data
682
+
683
+ Raises:
684
+ ValueError: If required parameters are missing
685
+ httpx.HTTPStatusError: If the API request fails
686
+
687
+ Tags:
688
+ keyword-analysis, important
689
+ """
690
+ if not phrase:
691
+ raise ValueError("Phrase parameter is required")
692
+
693
+ # Build parameters dictionary
694
+ params = {
695
+ "type": "phrase_kdi",
696
+ "key": self.api_key,
697
+ "phrase": phrase,
698
+ "database": database,
699
+ }
700
+
701
+ if export_columns is not None:
702
+ params["export_columns"] = export_columns
703
+ if export_escape is not None:
704
+ params["export_escape"] = export_escape
705
+
706
+ response = self._get(self.base_url, params=params)
707
+
708
+ return self._handle_response(response)
709
+
710
+ def ads_copies(
711
+ self,
712
+ domain: str,
713
+ database: str = "us",
714
+ display_limit: int | None = None,
715
+ display_offset: int | None = None,
716
+ export_columns: str | None = None,
717
+ display_sort: str | None = None,
718
+ display_filter: str | None = None,
719
+ export_escape: int | None = None,
720
+ export_decode: int | None = None,
721
+ ) -> dict[str, Any]:
722
+ """
723
+ Get unique ad copies that appeared when a domain ranked in Google's paid search results.
724
+
725
+ Args:
726
+ domain (str): Unique name of a website to investigate
727
+ database (str): Regional database (default: "us")
728
+ display_limit (int, optional): Number of results to return (max 100,000)
729
+ display_offset (int, optional): Number of results to skip
730
+ export_columns (str, optional): Comma-separated list of columns to include
731
+ display_sort (str, optional): Sorting order (e.g., "pc_asc", "pc_desc")
732
+ display_filter (str, optional): Filter criteria for columns
733
+ export_escape (int, optional): Set to 1 to wrap columns in quotes
734
+ export_decode (int, optional): Set to 0 for URL-encoded response
735
+
736
+ Returns:
737
+ dict[str, Any]: API response data
738
+
739
+ Raises:
740
+ ValueError: If required parameters are missing
741
+ httpx.HTTPStatusError: If the API request fails
742
+
743
+ Tags:
744
+ domain-search
745
+ """
746
+ if not domain:
747
+ raise ValueError("Domain parameter is required")
748
+
749
+ # Build parameters dictionary
750
+ params = {
751
+ "type": "domain_adwords_unique",
752
+ "key": self.api_key,
753
+ "domain": domain,
754
+ "database": database,
755
+ }
756
+
757
+ if display_limit is not None:
758
+ params["display_limit"] = display_limit
759
+ if display_offset is not None:
760
+ params["display_offset"] = display_offset
761
+ if export_columns is not None:
762
+ params["export_columns"] = export_columns
763
+ if display_sort is not None:
764
+ params["display_sort"] = display_sort
765
+ if display_filter is not None:
766
+ params["display_filter"] = display_filter
767
+ if export_escape is not None:
768
+ params["export_escape"] = export_escape
769
+ if export_decode is not None:
770
+ params["export_decode"] = export_decode
771
+
772
+ response = self._get(self.base_url, params=params)
773
+
774
+ return self._handle_response(response)
775
+
776
+ def anchors(
777
+ self,
778
+ target: str,
779
+ target_type: str,
780
+ export_columns: str | None = None,
781
+ display_sort: str | None = None,
782
+ display_limit: int | None = None,
783
+ display_offset: int | None = None,
784
+ ) -> dict[str, Any]:
785
+ """
786
+ Get anchor texts used in backlinks leading to a domain, root domain, or URL.
787
+
788
+ Args:
789
+ target (str): Root domain, subdomain, or URL of the website to investigate
790
+ target_type (str): Type of requested target (root_domain, domain, or url)
791
+ export_columns (str, optional): Comma-separated list of columns to include
792
+ display_sort (str, optional): Sorting order (e.g., "domains_num_desc", "backlinks_num_asc")
793
+ display_limit (int, optional): Number of results to return (default: 10,000)
794
+ display_offset (int, optional): Number of results to skip
795
+
796
+ Returns:
797
+ dict[str, Any]: API response data
798
+
799
+ Raises:
800
+ ValueError: If required parameters are missing
801
+ httpx.HTTPStatusError: If the API request fails
802
+
803
+ Tags:
804
+ backlinks
805
+ """
806
+ if not target:
807
+ raise ValueError("Target parameter is required")
808
+ if not target_type:
809
+ raise ValueError("Target_type parameter is required")
810
+
811
+ # Build parameters dictionary
812
+ params = {
813
+ "type": "backlinks_anchors",
814
+ "key": self.api_key,
815
+ "target": target,
816
+ "target_type": target_type,
817
+ }
818
+
819
+ if export_columns is not None:
820
+ params["export_columns"] = export_columns
821
+ if display_sort is not None:
822
+ params["display_sort"] = display_sort
823
+ if display_limit is not None:
824
+ params["display_limit"] = display_limit
825
+ if display_offset is not None:
826
+ params["display_offset"] = display_offset
827
+
828
+ url = f"{self.base_url}/analytics/v1"
829
+ response = self._get(url, params=params)
830
+
831
+ return self._handle_response(response)
832
+
833
+ def authority_score_profile(self, target: str, target_type: str) -> dict[str, Any]:
834
+ """
835
+ Get distribution of referring domains by Authority Score from 0 to 100.
836
+
837
+ Args:
838
+ target (str): Root domain, subdomain, or URL of the website to investigate
839
+ target_type (str): Type of requested target (root_domain, domain, or url)
840
+
841
+ Returns:
842
+ dict[str, Any]: API response data
843
+
844
+ Raises:
845
+ ValueError: If required parameters are missing
846
+ httpx.HTTPStatusError: If the API request fails
847
+
848
+ Tags:
849
+ backlinks
850
+ """
851
+ if not target:
852
+ raise ValueError("Target parameter is required")
853
+ if not target_type:
854
+ raise ValueError("Target_type parameter is required")
855
+
856
+ # Build parameters dictionary
857
+ params = {
858
+ "type": "backlinks_ascore_profile",
859
+ "key": self.api_key,
860
+ "target": target,
861
+ "target_type": target_type,
862
+ }
863
+
864
+ url = f"{self.base_url}/analytics/v1"
865
+ response = self._get(url, params=params)
866
+
867
+ return self._handle_response(response)
868
+
869
+ def batch_comparison(
870
+ self,
871
+ targets: list[str],
872
+ target_types: list[str],
873
+ export_columns: str | None = None,
874
+ ) -> dict[str, Any]:
875
+ """
876
+ Compare backlink profiles and link-building progress across multiple competitors.
877
+
878
+ Args:
879
+ targets (list[str]): Array of root domains, subdomains, or URLs to investigate (max 200)
880
+ target_types (list[str]): Array of target types corresponding to targets (root_domain, domain, or url)
881
+ export_columns (str, optional): Comma-separated list of columns to include
882
+
883
+ Returns:
884
+ dict[str, Any]: API response data
885
+
886
+ Raises:
887
+ ValueError: If required parameters are missing or invalid
888
+ httpx.HTTPStatusError: If the API request fails
889
+
890
+ Tags:
891
+ backlinks
892
+ """
893
+ if not targets:
894
+ raise ValueError("Targets parameter is required")
895
+ if not target_types:
896
+ raise ValueError("Target_types parameter is required")
897
+ if len(targets) > 200:
898
+ raise ValueError("Maximum 200 targets allowed")
899
+ if len(targets) != len(target_types):
900
+ raise ValueError(
901
+ "Targets and target_types arrays must have the same length"
902
+ )
903
+
904
+ # Build parameters dictionary
905
+ params = {"type": "backlinks_comparison", "key": self.api_key}
906
+
907
+ # Add targets and target_types as arrays
908
+ for target in targets:
909
+ params["targets[]"] = target
910
+ for target_type in target_types:
911
+ params["target_types[]"] = target_type
912
+
913
+ if export_columns is not None:
914
+ params["export_columns"] = export_columns
915
+
916
+ url = f"{self.base_url}/analytics/v1"
917
+ response = self._get(url, params=params)
918
+
919
+ return self._handle_response(response)
920
+
921
+ def batch_keyword_overview(
922
+ self,
923
+ phrase: str,
924
+ database: str = "us",
925
+ export_escape: int | None = None,
926
+ export_decode: int | None = None,
927
+ display_date: str | None = None,
928
+ export_columns: str | None = None,
929
+ ) -> dict[str, Any]:
930
+ """
931
+ Get summary of up to 100 keywords including volume, CPC, competition level, and results count.
932
+
933
+ Args:
934
+ phrase (str): Keyword or keyword expression to investigate (up to 100 keywords separated by semicolons)
935
+ database (str): Regional database (default: "us")
936
+ export_escape (int, optional): Set to 1 to wrap columns in quotes
937
+ export_decode (int, optional): Set to 0 for URL-encoded response, 1 for normal response
938
+ display_date (str, optional): Date in format "YYYYMM15" for historical data
939
+ export_columns (str, optional): Comma-separated list of columns to include
940
+
941
+ Returns:
942
+ dict[str, Any]: API response data
943
+
944
+ Raises:
945
+ ValueError: If required parameters are missing
946
+ httpx.HTTPStatusError: If the API request fails
947
+
948
+ Tags:
949
+ keyword-analysis
950
+ """
951
+ if not phrase:
952
+ raise ValueError("Phrase parameter is required")
953
+
954
+ # Build parameters dictionary
955
+ params = {
956
+ "type": "phrase_these",
957
+ "key": self.api_key,
958
+ "phrase": phrase,
959
+ "database": database,
960
+ }
961
+
962
+ if export_escape is not None:
963
+ params["export_escape"] = export_escape
964
+ if export_decode is not None:
965
+ params["export_decode"] = export_decode
966
+ if display_date is not None:
967
+ params["display_date"] = display_date
968
+ if export_columns is not None:
969
+ params["export_columns"] = export_columns
970
+
971
+ response = self._get(self.base_url, params=params)
972
+
973
+ return self._handle_response(response)
974
+
975
+ def broad_match_keyword(
976
+ self,
977
+ phrase: str,
978
+ database: str = "us",
979
+ display_limit: int | None = None,
980
+ display_offset: int | None = None,
981
+ export_escape: int | None = None,
982
+ export_decode: int | None = None,
983
+ export_columns: str | None = None,
984
+ display_sort: str | None = None,
985
+ display_filter: str | None = None,
986
+ ) -> dict[str, Any]:
987
+ """
988
+ Get broad matches and alternate search queries for a keyword or keyword expression.
989
+
990
+ Args:
991
+ phrase (str): Keyword or keyword expression to investigate
992
+ database (str): Regional database (default: "us")
993
+ display_limit (int, optional): Number of results to return (max 100,000)
994
+ display_offset (int, optional): Number of results to skip
995
+ export_escape (int, optional): Set to 1 to wrap columns in quotes
996
+ export_decode (int, optional): Set to 0 for URL-encoded response, 1 for normal response
997
+ export_columns (str, optional): Comma-separated list of columns to include
998
+ display_sort (str, optional): Sorting order (e.g., "nq_desc", "cp_asc")
999
+ display_filter (str, optional): Filter criteria for columns
1000
+
1001
+ Returns:
1002
+ dict[str, Any]: API response data
1003
+
1004
+ Raises:
1005
+ ValueError: If required parameters are missing
1006
+ httpx.HTTPStatusError: If the API request fails
1007
+
1008
+ Tags:
1009
+ keyword-analysis
1010
+ """
1011
+ if not phrase:
1012
+ raise ValueError("Phrase parameter is required")
1013
+
1014
+ # Build parameters dictionary
1015
+ params = {
1016
+ "type": "phrase_fullsearch",
1017
+ "key": self.api_key,
1018
+ "phrase": phrase,
1019
+ "database": database,
1020
+ }
1021
+
1022
+ if display_limit is not None:
1023
+ params["display_limit"] = display_limit
1024
+ if display_offset is not None:
1025
+ params["display_offset"] = display_offset
1026
+ if export_escape is not None:
1027
+ params["export_escape"] = export_escape
1028
+ if export_decode is not None:
1029
+ params["export_decode"] = export_decode
1030
+ if export_columns is not None:
1031
+ params["export_columns"] = export_columns
1032
+ if display_sort is not None:
1033
+ params["display_sort"] = display_sort
1034
+ if display_filter is not None:
1035
+ params["display_filter"] = display_filter
1036
+
1037
+ response = self._get(self.base_url, params=params)
1038
+
1039
+ return self._handle_response(response)
1040
+
1041
+ def categories(
1042
+ self, target: str, target_type: str, export_columns: str | None = None
1043
+ ) -> dict[str, Any]:
1044
+ """
1045
+ Get list of categories that the queried domain belongs to with confidence ratings.
1046
+
1047
+ Args:
1048
+ target (str): Root domain, subdomain, or URL of the website to investigate
1049
+ target_type (str): Type of requested target (root_domain, subdomain, or url)
1050
+ export_columns (str, optional): Comma-separated list of columns to include
1051
+
1052
+ Returns:
1053
+ dict[str, Any]: API response data
1054
+
1055
+ Raises:
1056
+ ValueError: If required parameters are missing
1057
+ httpx.HTTPStatusError: If the API request fails
1058
+
1059
+ Tags:
1060
+ backlinks
1061
+ """
1062
+ if not target:
1063
+ raise ValueError("Target parameter is required")
1064
+ if not target_type:
1065
+ raise ValueError("Target_type parameter is required")
1066
+
1067
+ # Build parameters dictionary
1068
+ params = {
1069
+ "type": "backlinks_categories",
1070
+ "key": self.api_key,
1071
+ "target": target,
1072
+ "target_type": target_type,
1073
+ }
1074
+
1075
+ if export_columns is not None:
1076
+ params["export_columns"] = export_columns
1077
+
1078
+ url = f"{self.base_url}/analytics/v1"
1079
+ response = self._get(url, params=params)
1080
+
1081
+ return self._handle_response(response)
1082
+
1083
+ def categories_profile(
1084
+ self,
1085
+ target: str,
1086
+ target_type: str,
1087
+ export_columns: str | None = None,
1088
+ display_limit: int | None = None,
1089
+ display_offset: int | None = None,
1090
+ ) -> dict[str, Any]:
1091
+ """
1092
+ Get categories that referring domains belong to with domain counts for the queried domain.
1093
+
1094
+ Args:
1095
+ target (str): Root domain, subdomain, or URL of the website to investigate
1096
+ target_type (str): Type of requested target (root_domain, domain, or url)
1097
+ export_columns (str, optional): Comma-separated list of columns to include
1098
+ display_limit (int, optional): Number of results to return (default: 10,000)
1099
+ display_offset (int, optional): Number of results to skip
1100
+
1101
+ Returns:
1102
+ dict[str, Any]: API response data
1103
+
1104
+ Raises:
1105
+ ValueError: If required parameters are missing
1106
+ httpx.HTTPStatusError: If the API request fails
1107
+
1108
+ Tags:
1109
+ backlinks
1110
+ """
1111
+ if not target:
1112
+ raise ValueError("Target parameter is required")
1113
+ if not target_type:
1114
+ raise ValueError("Target_type parameter is required")
1115
+
1116
+ # Build parameters dictionary
1117
+ params = {
1118
+ "type": "backlinks_categories_profile",
1119
+ "key": self.api_key,
1120
+ "target": target,
1121
+ "target_type": target_type,
1122
+ }
1123
+
1124
+ if export_columns is not None:
1125
+ params["export_columns"] = export_columns
1126
+ if display_limit is not None:
1127
+ params["display_limit"] = display_limit
1128
+ if display_offset is not None:
1129
+ params["display_offset"] = display_offset
1130
+
1131
+ url = f"{self.base_url}/analytics/v1"
1132
+ response = self._get(url, params=params)
1133
+
1134
+ return self._handle_response(response)
1135
+
1136
+ def competitors(
1137
+ self,
1138
+ target: str,
1139
+ target_type: str,
1140
+ export_columns: str | None = None,
1141
+ display_limit: int | None = None,
1142
+ display_offset: int | None = None,
1143
+ ) -> dict[str, Any]:
1144
+ """
1145
+ Get domains that share a similar backlink profile with the analyzed domain.
1146
+
1147
+ Args:
1148
+ target (str): Root domain, subdomain, or URL of the website to investigate
1149
+ target_type (str): Type of requested target (root_domain, domain, or url)
1150
+ export_columns (str, optional): Comma-separated list of columns to include
1151
+ display_limit (int, optional): Number of results to return (default: 10,000)
1152
+ display_offset (int, optional): Number of results to skip
1153
+
1154
+ Returns:
1155
+ dict[str, Any]: API response data
1156
+
1157
+ Raises:
1158
+ ValueError: If required parameters are missing
1159
+ httpx.HTTPStatusError: If the API request fails
1160
+
1161
+ Tags:
1162
+ backlinks
1163
+ """
1164
+ if not target:
1165
+ raise ValueError("Target parameter is required")
1166
+ if not target_type:
1167
+ raise ValueError("Target_type parameter is required")
1168
+
1169
+ # Build parameters dictionary
1170
+ params = {
1171
+ "type": "backlinks_competitors",
1172
+ "key": self.api_key,
1173
+ "target": target,
1174
+ "target_type": target_type,
1175
+ }
1176
+
1177
+ if export_columns is not None:
1178
+ params["export_columns"] = export_columns
1179
+ if display_limit is not None:
1180
+ params["display_limit"] = display_limit
1181
+ if display_offset is not None:
1182
+ params["display_offset"] = display_offset
1183
+
1184
+ url = f"{self.base_url}/analytics/v1"
1185
+ response = self._get(url, params=params)
1186
+
1187
+ return self._handle_response(response)
1188
+
1189
+ def competitors_organic_search(
1190
+ self,
1191
+ domain: str,
1192
+ database: str = "us",
1193
+ display_limit: int | None = None,
1194
+ display_offset: int | None = None,
1195
+ export_escape: int | None = None,
1196
+ export_decode: int | None = None,
1197
+ display_date: str | None = None,
1198
+ export_columns: str | None = None,
1199
+ display_sort: str | None = None,
1200
+ ) -> dict[str, Any]:
1201
+ """
1202
+ Get domain's competitors in organic search results with common keywords analysis.
1203
+
1204
+ Args:
1205
+ domain (str): Unique name of the website to investigate
1206
+ database (str): Regional database (default: "us")
1207
+ display_limit (int, optional): Number of results to return (max 100,000)
1208
+ display_offset (int, optional): Number of results to skip
1209
+ export_escape (int, optional): Set to 1 to wrap columns in quotes
1210
+ export_decode (int, optional): Set to 0 for URL-encoded response, 1 for normal response
1211
+ display_date (str, optional): Date in format "YYYYMM15" for historical data
1212
+ export_columns (str, optional): Comma-separated list of columns to include
1213
+ display_sort (str, optional): Sorting order (e.g., "np_desc", "cr_asc")
1214
+
1215
+ Returns:
1216
+ dict[str, Any]: API response data
1217
+
1218
+ Raises:
1219
+ ValueError: If required parameters are missing
1220
+ httpx.HTTPStatusError: If the API request fails
1221
+
1222
+ Tags:
1223
+ domain-search
1224
+ """
1225
+ if not domain:
1226
+ raise ValueError("Domain parameter is required")
1227
+
1228
+ # Build parameters dictionary
1229
+ params = {
1230
+ "type": "domain_organic_organic",
1231
+ "key": self.api_key,
1232
+ "domain": domain,
1233
+ "database": database,
1234
+ }
1235
+
1236
+ if display_limit is not None:
1237
+ params["display_limit"] = display_limit
1238
+ if display_offset is not None:
1239
+ params["display_offset"] = display_offset
1240
+ if export_escape is not None:
1241
+ params["export_escape"] = export_escape
1242
+ if export_decode is not None:
1243
+ params["export_decode"] = export_decode
1244
+ if display_date is not None:
1245
+ params["display_date"] = display_date
1246
+ if export_columns is not None:
1247
+ params["export_columns"] = export_columns
1248
+ if display_sort is not None:
1249
+ params["display_sort"] = display_sort
1250
+
1251
+ response = self._get(self.base_url, params=params)
1252
+
1253
+ return self._handle_response(response)
1254
+
1255
+ def competitors_paid_search(
1256
+ self,
1257
+ domain: str,
1258
+ database: str = "us",
1259
+ display_limit: int | None = None,
1260
+ display_offset: int | None = None,
1261
+ export_escape: int | None = None,
1262
+ export_decode: int | None = None,
1263
+ display_date: str | None = None,
1264
+ export_columns: str | None = None,
1265
+ display_sort: str | None = None,
1266
+ ) -> dict[str, Any]:
1267
+ """
1268
+ Get domain's competitors in paid search results with common keywords analysis.
1269
+
1270
+ Args:
1271
+ domain (str): Unique name of a website to investigate
1272
+ database (str): Regional database (default: "us")
1273
+ display_limit (int, optional): Number of results to return (max 100,000)
1274
+ display_offset (int, optional): Number of results to skip
1275
+ export_escape (int, optional): Set to 1 to wrap columns in quotes
1276
+ export_decode (int, optional): Set to 0 for URL-encoded response, 1 for normal response
1277
+ display_date (str, optional): Date in format "YYYYMM15" for historical data
1278
+ export_columns (str, optional): Comma-separated list of columns to include
1279
+ display_sort (str, optional): Sorting order (e.g., "np_desc", "cr_asc")
1280
+
1281
+ Returns:
1282
+ dict[str, Any]: API response data
1283
+
1284
+ Raises:
1285
+ ValueError: If required parameters are missing
1286
+ httpx.HTTPStatusError: If the API request fails
1287
+
1288
+ Tags:
1289
+ domain-search
1290
+ """
1291
+ if not domain:
1292
+ raise ValueError("Domain parameter is required")
1293
+
1294
+ # Build parameters dictionary
1295
+ params = {
1296
+ "type": "domain_adwords_adwords",
1297
+ "key": self.api_key,
1298
+ "domain": domain,
1299
+ "database": database,
1300
+ }
1301
+
1302
+ if display_limit is not None:
1303
+ params["display_limit"] = display_limit
1304
+ if display_offset is not None:
1305
+ params["display_offset"] = display_offset
1306
+ if export_escape is not None:
1307
+ params["export_escape"] = export_escape
1308
+ if export_decode is not None:
1309
+ params["export_decode"] = export_decode
1310
+ if display_date is not None:
1311
+ params["display_date"] = display_date
1312
+ if export_columns is not None:
1313
+ params["export_columns"] = export_columns
1314
+ if display_sort is not None:
1315
+ params["display_sort"] = display_sort
1316
+
1317
+ response = self._get(self.base_url, params=params)
1318
+
1319
+ return self._handle_response(response)
1320
+
1321
+ def indexed_pages(
1322
+ self,
1323
+ target: str,
1324
+ target_type: str,
1325
+ export_columns: str | None = None,
1326
+ display_sort: str | None = None,
1327
+ display_limit: int | None = None,
1328
+ display_offset: int | None = None,
1329
+ ) -> dict[str, Any]:
1330
+ """
1331
+ Get indexed pages of the queried domain with backlink and response data.
1332
+
1333
+ Args:
1334
+ target (str): Root domain, subdomain, or URL of the website to investigate
1335
+ target_type (str): Type of requested target (root_domain, domain, or url)
1336
+ export_columns (str, optional): Comma-separated list of columns to include
1337
+ display_sort (str, optional): Sorting order (e.g., "backlinks_num_desc", "backlinks_num_asc")
1338
+ display_limit (int, optional): Number of results to return (default: 10,000)
1339
+ display_offset (int, optional): Number of results to skip
1340
+
1341
+ Returns:
1342
+ dict[str, Any]: API response data
1343
+
1344
+ Raises:
1345
+ ValueError: If required parameters are missing
1346
+ httpx.HTTPStatusError: If the API request fails
1347
+
1348
+ Tags:
1349
+ backlinks
1350
+ """
1351
+ if not target:
1352
+ raise ValueError("Target parameter is required")
1353
+ if not target_type:
1354
+ raise ValueError("Target_type parameter is required")
1355
+
1356
+ # Build parameters dictionary
1357
+ params = {
1358
+ "type": "backlinks_pages",
1359
+ "key": self.api_key,
1360
+ "target": target,
1361
+ "target_type": target_type,
1362
+ }
1363
+
1364
+ if export_columns is not None:
1365
+ params["export_columns"] = export_columns
1366
+ if display_sort is not None:
1367
+ params["display_sort"] = display_sort
1368
+ if display_limit is not None:
1369
+ params["display_limit"] = display_limit
1370
+ if display_offset is not None:
1371
+ params["display_offset"] = display_offset
1372
+
1373
+ url = f"{self.base_url}/analytics/v1"
1374
+ response = self._get(url, params=params)
1375
+
1376
+ return self._handle_response(response)
1377
+
1378
+ def keyword_ads_history(
1379
+ self,
1380
+ phrase: str,
1381
+ database: str = "us",
1382
+ display_limit: int | None = None,
1383
+ display_offset: int | None = None,
1384
+ export_escape: int | None = None,
1385
+ export_decode: int | None = None,
1386
+ export_columns: str | None = None,
1387
+ ) -> dict[str, Any]:
1388
+ """
1389
+ Get domains that have bid on a keyword in the last 12 months with their paid search positions.
1390
+
1391
+ Args:
1392
+ phrase (str): Keyword or keyword expression to investigate
1393
+ database (str): Regional database (default: "us")
1394
+ display_limit (int, optional): Number of results to return (max 100,000)
1395
+ display_offset (int, optional): Number of results to skip
1396
+ export_escape (int, optional): Set to 1 to wrap columns in quotes
1397
+ export_decode (int, optional): Set to 0 for URL-encoded response, 1 for normal response
1398
+ export_columns (str, optional): Comma-separated list of columns to include
1399
+
1400
+ Returns:
1401
+ dict[str, Any]: API response data
1402
+
1403
+ Raises:
1404
+ ValueError: If required parameters are missing
1405
+ httpx.HTTPStatusError: If the API request fails
1406
+
1407
+ Tags:
1408
+ keyword-analysis
1409
+ """
1410
+ if not phrase:
1411
+ raise ValueError("Phrase parameter is required")
1412
+
1413
+ # Build parameters dictionary
1414
+ params = {
1415
+ "type": "phrase_adwords_historical",
1416
+ "key": self.api_key,
1417
+ "phrase": phrase,
1418
+ "database": database,
1419
+ }
1420
+
1421
+ if display_limit is not None:
1422
+ params["display_limit"] = display_limit
1423
+ if display_offset is not None:
1424
+ params["display_offset"] = display_offset
1425
+ if export_escape is not None:
1426
+ params["export_escape"] = export_escape
1427
+ if export_decode is not None:
1428
+ params["export_decode"] = export_decode
1429
+ if export_columns is not None:
1430
+ params["export_columns"] = export_columns
1431
+
1432
+ response = self._get(self.base_url, params=params)
1433
+
1434
+ return self._handle_response(response)
1435
+
1436
+ def keyword_overview_all_databases(
1437
+ self,
1438
+ phrase: str,
1439
+ database: str | None = None,
1440
+ export_escape: int | None = None,
1441
+ export_decode: int | None = None,
1442
+ export_columns: str | None = None,
1443
+ ) -> dict[str, Any]:
1444
+ """
1445
+ Get keyword summary including volume, CPC, competition level, and results across all regional databases.
1446
+
1447
+ Args:
1448
+ phrase (str): Keyword or keyword expression to investigate
1449
+ database (str, optional): Regional database (if not specified, uses all databases)
1450
+ export_escape (int, optional): Set to 1 to wrap columns in quotes
1451
+ export_decode (int, optional): Set to 0 for URL-encoded response, 1 for normal response
1452
+ export_columns (str, optional): Comma-separated list of columns to include
1453
+
1454
+ Returns:
1455
+ dict[str, Any]: API response data
1456
+
1457
+ Raises:
1458
+ ValueError: If required parameters are missing
1459
+ httpx.HTTPStatusError: If the API request fails
1460
+
1461
+ Tags:
1462
+ keyword-analysis
1463
+ """
1464
+ if not phrase:
1465
+ raise ValueError("Phrase parameter is required")
1466
+
1467
+ # Build parameters dictionary
1468
+ params = {"type": "phrase_all", "key": self.api_key, "phrase": phrase}
1469
+
1470
+ if database is not None:
1471
+ params["database"] = database
1472
+ if export_escape is not None:
1473
+ params["export_escape"] = export_escape
1474
+ if export_decode is not None:
1475
+ params["export_decode"] = export_decode
1476
+ if export_columns is not None:
1477
+ params["export_columns"] = export_columns
1478
+
1479
+ response = self._get(self.base_url, params=params)
1480
+
1481
+ return self._handle_response(response)
1482
+
1483
+ def keyword_overview_one_database(
1484
+ self,
1485
+ phrase: str,
1486
+ database: str = "us",
1487
+ export_escape: int | None = None,
1488
+ export_decode: int | None = None,
1489
+ display_date: str | None = None,
1490
+ export_columns: str | None = None,
1491
+ ) -> dict[str, Any]:
1492
+ """
1493
+ Get keyword summary including volume, CPC, competition level, and results for a specific database.
1494
+
1495
+ Args:
1496
+ phrase (str): Keyword or keyword expression to investigate
1497
+ database (str): Regional database (default: "us")
1498
+ export_escape (int, optional): Set to 1 to wrap columns in quotes
1499
+ export_decode (int, optional): Set to 0 for URL-encoded response, 1 for normal response
1500
+ display_date (str, optional): Date in format "YYYYMM15" for historical data
1501
+ export_columns (str, optional): Comma-separated list of columns to include
1502
+
1503
+ Returns:
1504
+ dict[str, Any]: API response data
1505
+
1506
+ Raises:
1507
+ ValueError: If required parameters are missing
1508
+ httpx.HTTPStatusError: If the API request fails
1509
+
1510
+ Tags:
1511
+ keyword-analysis
1512
+ """
1513
+ if not phrase:
1514
+ raise ValueError("Phrase parameter is required")
1515
+
1516
+ # Build parameters dictionary
1517
+ params = {
1518
+ "type": "phrase_this",
1519
+ "key": self.api_key,
1520
+ "phrase": phrase,
1521
+ "database": database,
1522
+ }
1523
+
1524
+ if export_escape is not None:
1525
+ params["export_escape"] = export_escape
1526
+ if export_decode is not None:
1527
+ params["export_decode"] = export_decode
1528
+ if display_date is not None:
1529
+ params["display_date"] = display_date
1530
+ if export_columns is not None:
1531
+ params["export_columns"] = export_columns
1532
+
1533
+ response = self._get(self.base_url, params=params)
1534
+
1535
+ return self._handle_response(response)
1536
+
1537
+ def organic_results(
1538
+ self,
1539
+ phrase: str,
1540
+ database: str = "us",
1541
+ display_limit: int | None = None,
1542
+ display_offset: int | None = None,
1543
+ export_escape: int | None = None,
1544
+ export_decode: int | None = None,
1545
+ display_date: str | None = None,
1546
+ export_columns: str | None = None,
1547
+ positions_type: str | None = None,
1548
+ ) -> dict[str, Any]:
1549
+ """
1550
+ Get domains ranking in Google's top 100 organic search results for a keyword.
1551
+
1552
+ Args:
1553
+ phrase (str): Keyword or keyword expression to investigate
1554
+ database (str): Regional database (default: "us")
1555
+ display_limit (int, optional): Number of results to return (max 100,000)
1556
+ display_offset (int, optional): Number of results to skip
1557
+ export_escape (int, optional): Set to 1 to wrap columns in quotes
1558
+ export_decode (int, optional): Set to 0 for URL-encoded response, 1 for normal response
1559
+ display_date (str, optional): Date in format "YYYYMM15" for historical data
1560
+ export_columns (str, optional): Comma-separated list of columns to include
1561
+ positions_type (str, optional): Position type ("organic" or "all")
1562
+
1563
+ Returns:
1564
+ dict[str, Any]: API response data
1565
+
1566
+ Raises:
1567
+ ValueError: If required parameters are missing
1568
+ httpx.HTTPStatusError: If the API request fails
1569
+
1570
+ Tags:
1571
+ keyword-analysis
1572
+ """
1573
+ if not phrase:
1574
+ raise ValueError("Phrase parameter is required")
1575
+
1576
+ # Build parameters dictionary
1577
+ params = {
1578
+ "type": "phrase_organic",
1579
+ "key": self.api_key,
1580
+ "phrase": phrase,
1581
+ "database": database,
1582
+ }
1583
+
1584
+ if display_limit is not None:
1585
+ params["display_limit"] = display_limit
1586
+ if display_offset is not None:
1587
+ params["display_offset"] = display_offset
1588
+ if export_escape is not None:
1589
+ params["export_escape"] = export_escape
1590
+ if export_decode is not None:
1591
+ params["export_decode"] = export_decode
1592
+ if display_date is not None:
1593
+ params["display_date"] = display_date
1594
+ if export_columns is not None:
1595
+ params["export_columns"] = export_columns
1596
+ if positions_type is not None:
1597
+ params["positions_type"] = positions_type
1598
+
1599
+ response = self._get(self.base_url, params=params)
1600
+
1601
+ return self._handle_response(response)
1602
+
1603
+ def paid_results(
1604
+ self,
1605
+ phrase: str,
1606
+ database: str = "us",
1607
+ display_limit: int | None = None,
1608
+ display_offset: int | None = None,
1609
+ export_escape: int | None = None,
1610
+ export_decode: int | None = None,
1611
+ display_date: str | None = None,
1612
+ export_columns: str | None = None,
1613
+ ) -> dict[str, Any]:
1614
+ """
1615
+ Get domains ranking in Google's paid search results for a keyword.
1616
+
1617
+ Args:
1618
+ phrase (str): Keyword or keyword expression to investigate
1619
+ database (str): Regional database (default: "us")
1620
+ display_limit (int, optional): Number of results to return (max 100,000)
1621
+ display_offset (int, optional): Number of results to skip
1622
+ export_escape (int, optional): Set to 1 to wrap columns in quotes
1623
+ export_decode (int, optional): Set to 0 for URL-encoded response, 1 for normal response
1624
+ display_date (str, optional): Date in format "YYYYMM15" for historical data
1625
+ export_columns (str, optional): Comma-separated list of columns to include
1626
+
1627
+ Returns:
1628
+ dict[str, Any]: API response data
1629
+
1630
+ Raises:
1631
+ ValueError: If required parameters are missing
1632
+ httpx.HTTPStatusError: If the API request fails
1633
+
1634
+ Tags:
1635
+ keyword-analysis
1636
+ """
1637
+ if not phrase:
1638
+ raise ValueError("Phrase parameter is required")
1639
+
1640
+ # Build parameters dictionary
1641
+ params = {
1642
+ "type": "phrase_adwords",
1643
+ "key": self.api_key,
1644
+ "phrase": phrase,
1645
+ "database": database,
1646
+ }
1647
+
1648
+ if display_limit is not None:
1649
+ params["display_limit"] = display_limit
1650
+ if display_offset is not None:
1651
+ params["display_offset"] = display_offset
1652
+ if export_escape is not None:
1653
+ params["export_escape"] = export_escape
1654
+ if export_decode is not None:
1655
+ params["export_decode"] = export_decode
1656
+ if display_date is not None:
1657
+ params["display_date"] = display_date
1658
+ if export_columns is not None:
1659
+ params["export_columns"] = export_columns
1660
+
1661
+ response = self._get(self.base_url, params=params)
1662
+
1663
+ return self._handle_response(response)
1664
+
1665
+ def phrase_questions(
1666
+ self,
1667
+ phrase: str,
1668
+ database: str = "us",
1669
+ display_limit: int | None = None,
1670
+ display_offset: int | None = None,
1671
+ export_escape: int | None = None,
1672
+ export_decode: int | None = None,
1673
+ export_columns: str | None = None,
1674
+ display_sort: str | None = None,
1675
+ display_filter: str | None = None,
1676
+ ) -> dict[str, Any]:
1677
+ """
1678
+ Get phrase questions relevant to a queried term in a chosen database.
1679
+
1680
+ Args:
1681
+ phrase (str): Keyword or keyword expression to investigate
1682
+ database (str): Regional database (default: "us")
1683
+ display_limit (int, optional): Number of results to return (max 100,000)
1684
+ display_offset (int, optional): Number of results to skip
1685
+ export_escape (int, optional): Set to 1 to wrap columns in quotes
1686
+ export_decode (int, optional): Set to 0 for URL-encoded response, 1 for normal response
1687
+ export_columns (str, optional): Comma-separated list of columns to include
1688
+ display_sort (str, optional): Sorting order (e.g., "nq_desc", "cp_asc")
1689
+ display_filter (str, optional): Filter criteria for columns
1690
+
1691
+ Returns:
1692
+ dict[str, Any]: API response data
1693
+
1694
+ Raises:
1695
+ ValueError: If required parameters are missing
1696
+ httpx.HTTPStatusError: If the API request fails
1697
+
1698
+ Tags:
1699
+ keyword-analysis
1700
+ """
1701
+ if not phrase:
1702
+ raise ValueError("Phrase parameter is required")
1703
+
1704
+ # Build parameters dictionary
1705
+ params = {
1706
+ "type": "phrase_questions",
1707
+ "key": self.api_key,
1708
+ "phrase": phrase,
1709
+ "database": database,
1710
+ }
1711
+
1712
+ if display_limit is not None:
1713
+ params["display_limit"] = display_limit
1714
+ if display_offset is not None:
1715
+ params["display_offset"] = display_offset
1716
+ if export_escape is not None:
1717
+ params["export_escape"] = export_escape
1718
+ if export_decode is not None:
1719
+ params["export_decode"] = export_decode
1720
+ if export_columns is not None:
1721
+ params["export_columns"] = export_columns
1722
+ if display_sort is not None:
1723
+ params["display_sort"] = display_sort
1724
+ if display_filter is not None:
1725
+ params["display_filter"] = display_filter
1726
+
1727
+ response = self._get(self.base_url, params=params)
1728
+
1729
+ return self._handle_response(response)
1730
+
1731
+ def pla_competitors(
1732
+ self,
1733
+ domain: str,
1734
+ database: str = "us",
1735
+ display_limit: int | None = None,
1736
+ display_offset: int | None = None,
1737
+ export_escape: int | None = None,
1738
+ export_decode: int | None = None,
1739
+ export_columns: str | None = None,
1740
+ display_sort: str | None = None,
1741
+ ) -> dict[str, Any]:
1742
+ """
1743
+ Get domains competing against the requested domain in Google's Product Listing Ads (PLA).
1744
+
1745
+ Args:
1746
+ domain (str): Unique name of a website to investigate
1747
+ database (str): Regional database (default: "us")
1748
+ display_limit (int, optional): Number of results to return (max 100,000)
1749
+ display_offset (int, optional): Number of results to skip
1750
+ export_escape (int, optional): Set to 1 to wrap columns in quotes
1751
+ export_decode (int, optional): Set to 0 for URL-encoded response, 1 for normal response
1752
+ export_columns (str, optional): Comma-separated list of columns to include
1753
+ display_sort (str, optional): Sorting order (e.g., "np_desc", "cr_asc")
1754
+
1755
+ Returns:
1756
+ dict[str, Any]: API response data
1757
+
1758
+ Raises:
1759
+ ValueError: If required parameters are missing
1760
+ httpx.HTTPStatusError: If the API request fails
1761
+
1762
+ Tags:
1763
+ domain-search
1764
+ """
1765
+ if not domain:
1766
+ raise ValueError("Domain parameter is required")
1767
+
1768
+ # Build parameters dictionary
1769
+ params = {
1770
+ "type": "domain_shopping_shopping",
1771
+ "key": self.api_key,
1772
+ "domain": domain,
1773
+ "database": database,
1774
+ }
1775
+
1776
+ if display_limit is not None:
1777
+ params["display_limit"] = display_limit
1778
+ if display_offset is not None:
1779
+ params["display_offset"] = display_offset
1780
+ if export_escape is not None:
1781
+ params["export_escape"] = export_escape
1782
+ if export_decode is not None:
1783
+ params["export_decode"] = export_decode
1784
+ if export_columns is not None:
1785
+ params["export_columns"] = export_columns
1786
+ if display_sort is not None:
1787
+ params["display_sort"] = display_sort
1788
+
1789
+ response = self._get(self.base_url, params=params)
1790
+
1791
+ return self._handle_response(response)
1792
+
1793
+ def pla_copies(
1794
+ self,
1795
+ domain: str,
1796
+ database: str = "us",
1797
+ display_limit: int | None = None,
1798
+ display_offset: int | None = None,
1799
+ export_escape: int | None = None,
1800
+ export_decode: int | None = None,
1801
+ export_columns: str | None = None,
1802
+ display_sort: str | None = None,
1803
+ display_filter: str | None = None,
1804
+ ) -> dict[str, Any]:
1805
+ """
1806
+ Get product listing ad (PLA) copies that appeared when a domain ranked in Google's paid search results.
1807
+
1808
+ Args:
1809
+ domain (str): Unique name of a website to investigate
1810
+ database (str): Regional database (default: "us")
1811
+ display_limit (int, optional): Number of results to return (max 100,000)
1812
+ display_offset (int, optional): Number of results to skip
1813
+ export_escape (int, optional): Set to 1 to wrap columns in quotes
1814
+ export_decode (int, optional): Set to 0 for URL-encoded response, 1 for normal response
1815
+ export_columns (str, optional): Comma-separated list of columns to include
1816
+ display_sort (str, optional): Sorting order (e.g., "pr_desc", "pc_asc")
1817
+ display_filter (str, optional): Filter criteria for columns
1818
+
1819
+ Returns:
1820
+ dict[str, Any]: API response data
1821
+
1822
+ Raises:
1823
+ ValueError: If required parameters are missing
1824
+ httpx.HTTPStatusError: If the API request fails
1825
+
1826
+ Tags:
1827
+ domain-search
1828
+ """
1829
+ if not domain:
1830
+ raise ValueError("Domain parameter is required")
1831
+
1832
+ # Build parameters dictionary
1833
+ params = {
1834
+ "type": "domain_shopping_unique",
1835
+ "key": self.api_key,
1836
+ "domain": domain,
1837
+ "database": database,
1838
+ }
1839
+
1840
+ if display_limit is not None:
1841
+ params["display_limit"] = display_limit
1842
+ if display_offset is not None:
1843
+ params["display_offset"] = display_offset
1844
+ if export_escape is not None:
1845
+ params["export_escape"] = export_escape
1846
+ if export_decode is not None:
1847
+ params["export_decode"] = export_decode
1848
+ if export_columns is not None:
1849
+ params["export_columns"] = export_columns
1850
+ if display_sort is not None:
1851
+ params["display_sort"] = display_sort
1852
+ if display_filter is not None:
1853
+ params["display_filter"] = display_filter
1854
+
1855
+ response = self._get(self.base_url, params=params)
1856
+
1857
+ return self._handle_response(response)
1858
+
1859
+ def referring_domains(
1860
+ self,
1861
+ target: str,
1862
+ target_type: str,
1863
+ export_columns: str | None = None,
1864
+ display_sort: str | None = None,
1865
+ display_limit: int | None = None,
1866
+ display_offset: int | None = None,
1867
+ display_filter: str | None = None,
1868
+ ) -> dict[str, Any]:
1869
+ """
1870
+ Get domains pointing to the queried domain, root domain, or URL.
1871
+
1872
+ Args:
1873
+ target (str): Root domain, subdomain, or URL of the website to investigate
1874
+ target_type (str): Type of requested target (root_domain, domain, or url)
1875
+ export_columns (str, optional): Comma-separated list of columns to include
1876
+ display_sort (str, optional): Sorting order (e.g., "domain_ascore_desc", "backlinks_num_asc")
1877
+ display_limit (int, optional): Number of results to return (default: 10,000)
1878
+ display_offset (int, optional): Number of results to skip
1879
+ display_filter (str, optional): Filter criteria for columns
1880
+
1881
+ Returns:
1882
+ dict[str, Any]: API response data
1883
+
1884
+ Raises:
1885
+ ValueError: If required parameters are missing
1886
+ httpx.HTTPStatusError: If the API request fails
1887
+
1888
+ Tags:
1889
+ backlinks
1890
+ """
1891
+ if not target:
1892
+ raise ValueError("Target parameter is required")
1893
+ if not target_type:
1894
+ raise ValueError("Target_type parameter is required")
1895
+
1896
+ # Build parameters dictionary
1897
+ params = {
1898
+ "type": "backlinks_refdomains",
1899
+ "key": self.api_key,
1900
+ "target": target,
1901
+ "target_type": target_type,
1902
+ }
1903
+
1904
+ if export_columns is not None:
1905
+ params["export_columns"] = export_columns
1906
+ if display_sort is not None:
1907
+ params["display_sort"] = display_sort
1908
+ if display_limit is not None:
1909
+ params["display_limit"] = display_limit
1910
+ if display_offset is not None:
1911
+ params["display_offset"] = display_offset
1912
+ if display_filter is not None:
1913
+ params["display_filter"] = display_filter
1914
+
1915
+ url = f"{self.base_url}/analytics/v1"
1916
+ response = self._get(url, params=params)
1917
+
1918
+ return self._handle_response(response)
1919
+
1920
+ def referring_domains_by_country(
1921
+ self,
1922
+ target: str,
1923
+ target_type: str,
1924
+ export_columns: str | None = None,
1925
+ display_sort: str | None = None,
1926
+ display_limit: int | None = None,
1927
+ display_offset: int | None = None,
1928
+ ) -> dict[str, Any]:
1929
+ """
1930
+ Get referring domain distribution by country based on IP addresses.
1931
+
1932
+ Args:
1933
+ target (str): Root domain, subdomain, or URL of the website to investigate
1934
+ target_type (str): Type of requested target (root_domain, domain, or url)
1935
+ export_columns (str, optional): Comma-separated list of columns to include
1936
+ display_sort (str, optional): Sorting order (e.g., "domains_num_desc", "backlinks_num_asc")
1937
+ display_limit (int, optional): Number of results to return (default: 10,000)
1938
+ display_offset (int, optional): Number of results to skip
1939
+
1940
+ Returns:
1941
+ dict[str, Any]: API response data
1942
+
1943
+ Raises:
1944
+ ValueError: If required parameters are missing
1945
+ httpx.HTTPStatusError: If the API request fails
1946
+
1947
+ Tags:
1948
+ backlinks
1949
+ """
1950
+ if not target:
1951
+ raise ValueError("Target parameter is required")
1952
+ if not target_type:
1953
+ raise ValueError("Target_type parameter is required")
1954
+
1955
+ # Build parameters dictionary
1956
+ params = {
1957
+ "type": "backlinks_geo",
1958
+ "key": self.api_key,
1959
+ "target": target,
1960
+ "target_type": target_type,
1961
+ }
1962
+
1963
+ if export_columns is not None:
1964
+ params["export_columns"] = export_columns
1965
+ if display_sort is not None:
1966
+ params["display_sort"] = display_sort
1967
+ if display_limit is not None:
1968
+ params["display_limit"] = display_limit
1969
+ if display_offset is not None:
1970
+ params["display_offset"] = display_offset
1971
+
1972
+ url = f"{self.base_url}/analytics/v1"
1973
+ response = self._get(url, params=params)
1974
+
1975
+ return self._handle_response(response)
1976
+
1977
+ def related_keywords(
1978
+ self,
1979
+ phrase: str,
1980
+ database: str = "us",
1981
+ display_limit: int | None = None,
1982
+ display_offset: int | None = None,
1983
+ export_escape: int | None = None,
1984
+ export_decode: int | None = None,
1985
+ export_columns: str | None = None,
1986
+ display_sort: str | None = None,
1987
+ display_filter: str | None = None,
1988
+ ) -> dict[str, Any]:
1989
+ """
1990
+ Get extended list of related keywords, synonyms, and variations relevant to a queried term.
1991
+
1992
+ Args:
1993
+ phrase (str): Keyword or keyword expression to investigate
1994
+ database (str): Regional database (default: "us")
1995
+ display_limit (int, optional): Number of results to return (max 100,000)
1996
+ display_offset (int, optional): Number of results to skip
1997
+ export_escape (int, optional): Set to 1 to wrap columns in quotes
1998
+ export_decode (int, optional): Set to 0 for URL-encoded response, 1 for normal response
1999
+ export_columns (str, optional): Comma-separated list of columns to include
2000
+ display_sort (str, optional): Sorting order (e.g., "nq_desc", "cp_asc")
2001
+ display_filter (str, optional): Filter criteria for columns
2002
+
2003
+ Returns:
2004
+ dict[str, Any]: API response data
2005
+
2006
+ Raises:
2007
+ ValueError: If required parameters are missing
2008
+ httpx.HTTPStatusError: If the API request fails
2009
+
2010
+ Tags:
2011
+ keyword-analysis
2012
+ """
2013
+ if not phrase:
2014
+ raise ValueError("Phrase parameter is required")
2015
+
2016
+ # Build parameters dictionary
2017
+ params = {
2018
+ "type": "phrase_related",
2019
+ "key": self.api_key,
2020
+ "phrase": phrase,
2021
+ "database": database,
2022
+ }
2023
+
2024
+ if display_limit is not None:
2025
+ params["display_limit"] = display_limit
2026
+ if display_offset is not None:
2027
+ params["display_offset"] = display_offset
2028
+ if export_escape is not None:
2029
+ params["export_escape"] = export_escape
2030
+ if export_decode is not None:
2031
+ params["export_decode"] = export_decode
2032
+ if export_columns is not None:
2033
+ params["export_columns"] = export_columns
2034
+ if display_sort is not None:
2035
+ params["display_sort"] = display_sort
2036
+ if display_filter is not None:
2037
+ params["display_filter"] = display_filter
2038
+
2039
+ response = self._get(self.base_url, params=params)
2040
+
2041
+ return self._handle_response(response)
2042
+
2043
+ def list_tools(self):
2044
+ """
2045
+ Lists the available tools (methods) for this application.
2046
+ """
2047
+ return [
2048
+ self.domain_ad_history,
2049
+ self.domain_organic_pages,
2050
+ self.domain_organic_search_keywords,
2051
+ self.domain_organic_subdomains,
2052
+ self.domain_paid_search_keywords,
2053
+ self.domain_pla_search_keywords,
2054
+ self.domain_vs_domain,
2055
+ self.backlinks,
2056
+ self.backlinks_overview,
2057
+ self.keyword_difficulty,
2058
+ self.ads_copies,
2059
+ self.anchors,
2060
+ self.authority_score_profile,
2061
+ self.batch_comparison,
2062
+ self.batch_keyword_overview,
2063
+ self.broad_match_keyword,
2064
+ self.categories,
2065
+ self.categories_profile,
2066
+ self.competitors,
2067
+ self.competitors_organic_search,
2068
+ self.competitors_paid_search,
2069
+ self.indexed_pages,
2070
+ self.keyword_ads_history,
2071
+ self.keyword_overview_all_databases,
2072
+ self.keyword_overview_one_database,
2073
+ self.organic_results,
2074
+ self.paid_results,
2075
+ self.phrase_questions,
2076
+ self.pla_competitors,
2077
+ self.pla_copies,
2078
+ self.referring_domains,
2079
+ self.referring_domains_by_country,
2080
+ self.related_keywords,
2081
+ ]