From 6001ecbc6504d11d83fbebe0a3cffd83713e71bd Mon Sep 17 00:00:00 2001
From: "stainless-app[bot]"
<142633134+stainless-app[bot]@users.noreply.github.com>
Date: Tue, 11 Aug 2026 21:01:29 +0000
Subject: [PATCH 1/3] feat(api): api update
---
.stats.yml | 8 +-
README.md | 9 +-
api.md | 23 +-
src/x_twitter_scraper/resources/draws.py | 20 +-
src/x_twitter_scraper/resources/events.py | 16 +-
.../resources/extractions.py | 1286 +++++++++++-
.../resources/support/__init__.py | 14 +
.../resources/support/attachments.py | 185 ++
.../resources/support/support.py | 38 +
.../resources/x/communities/communities.py | 234 ++-
src/x_twitter_scraper/resources/x/lists.py | 238 ++-
.../resources/x/tweets/tweets.py | 1079 ++++++++--
.../resources/x/users/users.py | 1747 +++++++++++++++--
.../types/draw_export_params.py | 6 +-
.../types/draw_list_params.py | 2 +-
.../types/event_list_params.py | 7 +-
.../types/extraction_estimate_cost_params.py | 296 ++-
.../extraction_estimate_cost_response.py | 1 +
.../types/extraction_export_results_params.py | 60 +-
.../types/extraction_list_params.py | 2 +-
.../types/extraction_retrieve_params.py | 18 +-
.../types/extraction_run_params.py | 219 ++-
.../types/extraction_run_response.py | 43 +-
src/x_twitter_scraper/types/monitor.py | 9 +-
src/x_twitter_scraper/types/shared/error.py | 8 +
.../types/shared/paginated_tweets.py | 5 +-
.../types/shared/paginated_users.py | 2 +-
src/x_twitter_scraper/types/x/__init__.py | 6 +
.../x/community_retrieve_members_params.py | 42 +
.../x/community_retrieve_moderators_params.py | 46 +-
.../types/x/list_retrieve_followers_params.py | 47 +-
.../types/x/list_retrieve_members_params.py | 42 +
.../types/x/tweet_get_favoriters_params.py | 47 +-
.../types/x/tweet_get_quotes_params.py | 57 +
.../types/x/tweet_get_replies_params.py | 104 +-
.../types/x/tweet_get_replies_response.py | 4 +-
.../types/x/tweet_get_retweeters_params.py | 47 +-
.../types/x/tweet_search_params.py | 84 +-
.../types/x/tweet_search_response.py | 102 +
.../types/x/user_retrieve_followers_params.py | 68 +-
.../x/user_retrieve_followers_response.py | 81 +
...user_retrieve_followers_you_know_params.py | 47 +-
.../types/x/user_retrieve_following_params.py | 68 +-
.../x/user_retrieve_following_response.py | 81 +
.../types/x/user_retrieve_likes_params.py | 57 +
.../types/x/user_retrieve_media_params.py | 57 +
.../types/x/user_retrieve_mentions_params.py | 57 +
.../types/x/user_retrieve_replies_params.py | 69 +-
.../types/x/user_retrieve_search_params.py | 46 +-
.../types/x/user_retrieve_tweets_params.py | 69 +-
...user_retrieve_verified_followers_params.py | 72 +-
...er_retrieve_verified_followers_response.py | 81 +
src/x_twitter_scraper/types/x/x_account.py | 10 +-
.../api_resources/support/test_attachments.py | 176 ++
tests/api_resources/test_events.py | 2 +
tests/api_resources/test_extractions.py | 324 ++-
tests/api_resources/x/test_communities.py | 56 +
tests/api_resources/x/test_lists.py | 56 +
tests/api_resources/x/test_tweets.py | 209 +-
tests/api_resources/x/test_users.py | 399 +++-
60 files changed, 7620 insertions(+), 668 deletions(-)
create mode 100644 src/x_twitter_scraper/resources/support/attachments.py
create mode 100644 src/x_twitter_scraper/types/x/tweet_search_response.py
create mode 100644 src/x_twitter_scraper/types/x/user_retrieve_followers_response.py
create mode 100644 src/x_twitter_scraper/types/x/user_retrieve_following_response.py
create mode 100644 src/x_twitter_scraper/types/x/user_retrieve_verified_followers_response.py
create mode 100644 tests/api_resources/support/test_attachments.py
diff --git a/.stats.yml b/.stats.yml
index ec9dedf..f192b6e 100644
--- a/.stats.yml
+++ b/.stats.yml
@@ -1,4 +1,4 @@
-configured_endpoints: 123
-openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/xquik/x-twitter-scraper-5f26f3694399b4ac5a4431c66f7d27c4024f9d0dcd899702de5fde1150e28330.yml
-openapi_spec_hash: 362e24e622f9a74ded8b38018e50460c
-config_hash: dab26921eb273c16e5570c0485c9ac2c
+configured_endpoints: 124
+openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/xquik/x-twitter-scraper-7bcac1557175956021a62532c55ce29b8822b5a41d0d59ae67787a6326c0ef8a.yml
+openapi_spec_hash: 04e28f19097d9b59119101492100c4ab
+config_hash: 217d68ca6999ad03cfc4922e9658297e
diff --git a/README.md b/README.md
index d54f1ce..f84f867 100644
--- a/README.md
+++ b/README.md
@@ -123,11 +123,10 @@ client = XTwitterScraper(
api_key=os.environ.get("X_TWITTER_SCRAPER_API_KEY"), # This is the default and can be omitted
)
-paginated_tweets = client.x.tweets.search(
+response = client.x.tweets.search(
q="from:elonmusk",
limit=10,
)
-print(paginated_tweets.has_next_page)
```
While you can provide an `api_key` keyword argument,
@@ -150,11 +149,10 @@ client = AsyncXTwitterScraper(
async def main() -> None:
- paginated_tweets = await client.x.tweets.search(
+ response = await client.x.tweets.search(
q="from:elonmusk",
limit=10,
)
- print(paginated_tweets.has_next_page)
asyncio.run(main())
@@ -189,11 +187,10 @@ async def main() -> None:
), # This is the default and can be omitted
http_client=DefaultAioHttpClient(),
) as client:
- paginated_tweets = await client.x.tweets.search(
+ response = await client.x.tweets.search(
q="from:elonmusk",
limit=10,
)
- print(paginated_tweets.has_next_page)
asyncio.run(main())
diff --git a/api.md b/api.md
index b652b9b..ff10877 100644
--- a/api.md
+++ b/api.md
@@ -277,6 +277,7 @@ from x_twitter_scraper.types.x import (
TweetRetrieveResponse,
TweetDeleteResponse,
TweetGetRepliesResponse,
+ TweetSearchResponse,
)
```
@@ -291,7 +292,7 @@ Methods:
- client.x.tweets.get_replies(id, \*\*params) -> TweetGetRepliesResponse
- client.x.tweets.get_retweeters(id, \*\*params) -> PaginatedUsers
- client.x.tweets.get_thread(id, \*\*params) -> PaginatedTweets
-- client.x.tweets.search(\*\*params) -> PaginatedTweets
+- client.x.tweets.search(\*\*params) -> TweetSearchResponse
### Like
@@ -324,7 +325,13 @@ Methods:
Types:
```python
-from x_twitter_scraper.types.x import UserRemoveFollowerResponse, UserRetrieveBatchResponse
+from x_twitter_scraper.types.x import (
+ UserRemoveFollowerResponse,
+ UserRetrieveBatchResponse,
+ UserRetrieveFollowersResponse,
+ UserRetrieveFollowingResponse,
+ UserRetrieveVerifiedFollowersResponse,
+)
```
Methods:
@@ -332,16 +339,16 @@ Methods:
- client.x.users.retrieve(id) -> UserProfile
- client.x.users.remove_follower(id, \*\*params) -> UserRemoveFollowerResponse
- client.x.users.retrieve_batch(\*\*params) -> UserRetrieveBatchResponse
-- client.x.users.retrieve_followers(id, \*\*params) -> PaginatedUsers
+- client.x.users.retrieve_followers(id, \*\*params) -> UserRetrieveFollowersResponse
- client.x.users.retrieve_followers_you_know(id, \*\*params) -> PaginatedUsers
-- client.x.users.retrieve_following(id, \*\*params) -> PaginatedUsers
+- client.x.users.retrieve_following(id, \*\*params) -> UserRetrieveFollowingResponse
- client.x.users.retrieve_likes(id, \*\*params) -> PaginatedTweets
- client.x.users.retrieve_media(id, \*\*params) -> PaginatedTweets
- client.x.users.retrieve_mentions(id, \*\*params) -> PaginatedTweets
- client.x.users.retrieve_replies(id, \*\*params) -> PaginatedTweets
- client.x.users.retrieve_search(\*\*params) -> PaginatedUsers
- client.x.users.retrieve_tweets(id, \*\*params) -> PaginatedTweets
-- client.x.users.retrieve_verified_followers(id, \*\*params) -> PaginatedUsers
+- client.x.users.retrieve_verified_followers(id, \*\*params) -> UserRetrieveVerifiedFollowersResponse
### Follow
@@ -537,6 +544,12 @@ Methods:
# Support
+## Attachments
+
+Methods:
+
+- client.support.attachments.download(id) -> BinaryAPIResponse
+
## Tickets
Types:
diff --git a/src/x_twitter_scraper/resources/draws.py b/src/x_twitter_scraper/resources/draws.py
index cad659f..42bc4a7 100644
--- a/src/x_twitter_scraper/resources/draws.py
+++ b/src/x_twitter_scraper/resources/draws.py
@@ -108,7 +108,7 @@ def list(
List draws
Args:
- cursor: Cursor for keyset pagination from prior response next_cursor
+ cursor: Previous nextCursor.
limit: Maximum number of items to return (1-100, default 50). For paid per-result
endpoints, the returned count may be lower when remaining credits cannot cover
@@ -154,11 +154,13 @@ def export(
extra_body: Body | None = None,
timeout: float | httpx.Timeout | None | NotGiven = not_given,
) -> BinaryAPIResponse:
- """
- Export draw data
+ """Export draw data
Args:
- format: Export output format
+ format: Export output format.
+
+ PDF entry exports include up to 10,000 rows. Other entry
+ formats include up to 100,000 rows.
type: Export winners or all entries
@@ -326,7 +328,7 @@ async def list(
List draws
Args:
- cursor: Cursor for keyset pagination from prior response next_cursor
+ cursor: Previous nextCursor.
limit: Maximum number of items to return (1-100, default 50). For paid per-result
endpoints, the returned count may be lower when remaining credits cannot cover
@@ -372,11 +374,13 @@ async def export(
extra_body: Body | None = None,
timeout: float | httpx.Timeout | None | NotGiven = not_given,
) -> AsyncBinaryAPIResponse:
- """
- Export draw data
+ """Export draw data
Args:
- format: Export output format
+ format: Export output format.
+
+ PDF entry exports include up to 10,000 rows. Other entry
+ formats include up to 100,000 rows.
type: Export winners or all entries
diff --git a/src/x_twitter_scraper/resources/events.py b/src/x_twitter_scraper/resources/events.py
index 3b1ff17..3d7ae5a 100644
--- a/src/x_twitter_scraper/resources/events.py
+++ b/src/x_twitter_scraper/resources/events.py
@@ -87,6 +87,7 @@ def list(
*,
cursor: str | Omit = omit,
event_type: EventType | Omit = omit,
+ keyword_monitor_id: str | Omit = omit,
limit: int | Omit = omit,
monitor_id: str | Omit = omit,
# Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
@@ -100,16 +101,18 @@ def list(
List events
Args:
- cursor: Cursor for keyset pagination from prior response next_cursor
+ cursor: Previous nextCursor.
event_type: Filter events by type
+ keyword_monitor_id: Keyword monitor ID.
+
limit: Maximum number of items to return (1-100, default 50). For paid per-result
endpoints, the returned count may be lower when remaining credits cannot cover
the requested page. If zero paid results are affordable, the endpoint returns
402 insufficient_credits.
- monitor_id: Filter events by monitor ID
+ monitor_id: Account monitor ID.
extra_headers: Send extra headers
@@ -130,6 +133,7 @@ def list(
{
"cursor": cursor,
"event_type": event_type,
+ "keyword_monitor_id": keyword_monitor_id,
"limit": limit,
"monitor_id": monitor_id,
},
@@ -200,6 +204,7 @@ async def list(
*,
cursor: str | Omit = omit,
event_type: EventType | Omit = omit,
+ keyword_monitor_id: str | Omit = omit,
limit: int | Omit = omit,
monitor_id: str | Omit = omit,
# Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
@@ -213,16 +218,18 @@ async def list(
List events
Args:
- cursor: Cursor for keyset pagination from prior response next_cursor
+ cursor: Previous nextCursor.
event_type: Filter events by type
+ keyword_monitor_id: Keyword monitor ID.
+
limit: Maximum number of items to return (1-100, default 50). For paid per-result
endpoints, the returned count may be lower when remaining credits cannot cover
the requested page. If zero paid results are affordable, the endpoint returns
402 insufficient_credits.
- monitor_id: Filter events by monitor ID
+ monitor_id: Account monitor ID.
extra_headers: Send extra headers
@@ -243,6 +250,7 @@ async def list(
{
"cursor": cursor,
"event_type": event_type,
+ "keyword_monitor_id": keyword_monitor_id,
"limit": limit,
"monitor_id": monitor_id,
},
diff --git a/src/x_twitter_scraper/resources/extractions.py b/src/x_twitter_scraper/resources/extractions.py
index 324bcf0..d7481b0 100644
--- a/src/x_twitter_scraper/resources/extractions.py
+++ b/src/x_twitter_scraper/resources/extractions.py
@@ -6,8 +6,8 @@
from __future__ import annotations
-from typing import Union
-from datetime import date
+from typing import Union, Iterable
+from datetime import date, datetime
from typing_extensions import Literal
import httpx
@@ -19,7 +19,7 @@
extraction_estimate_cost_params,
extraction_export_results_params,
)
-from .._types import Body, Omit, Query, Headers, NotGiven, omit, not_given
+from .._types import Body, Omit, Query, Headers, NotGiven, SequenceNotStr, omit, not_given
from .._utils import path_template, maybe_transform, async_maybe_transform
from .._compat import cached_property
from .._resource import SyncAPIResource, AsyncAPIResource
@@ -73,7 +73,11 @@ def retrieve(
id: str,
*,
cursor: str | Omit = omit,
+ field_style: Literal["source", "camelCase", "snake_case"] | Omit = omit,
+ include_raw: bool | Omit = omit,
limit: int | Omit = omit,
+ output_mode: Literal["compact", "full", "raw"] | Omit = omit,
+ output_preset: Literal["nested", "flat"] | Omit = omit,
# Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
# The extra values given here take precedence over values defined on the client or passed to this method.
extra_headers: Headers | None = None,
@@ -85,10 +89,18 @@ def retrieve(
Get extraction results
Args:
- cursor: Cursor for keyset pagination from prior response next_cursor
+ cursor: Previous nextCursor.
+
+ field_style: Preserve source keys or convert result field names.
+
+ include_raw: Use outputMode=raw instead.
limit: Maximum number of results to return (1-1000, default 100)
+ output_mode: Select compact, full, or raw-compatible result fields.
+
+ output_preset: Keep enrichment nested or merge it into each result.
+
extra_headers: Send extra headers
extra_query: Add additional query parameters to the request
@@ -109,7 +121,11 @@ def retrieve(
query=maybe_transform(
{
"cursor": cursor,
+ "field_style": field_style,
+ "include_raw": include_raw,
"limit": limit,
+ "output_mode": output_mode,
+ "output_preset": output_preset,
},
extraction_retrieve_params.ExtractionRetrieveParams,
),
@@ -160,7 +176,7 @@ def list(
List extraction jobs
Args:
- cursor: Cursor for keyset pagination from prior response next_cursor
+ cursor: Previous nextCursor.
limit: Maximum number of items to return (1-100, default 50). For paid per-result
endpoints, the returned count may be lower when remaining credits cannot cover
@@ -229,42 +245,99 @@ def estimate_cost(
],
advanced_query: str | Omit = omit,
any_words: str | Omit = omit,
+ bio_contains: str | Omit = omit,
+ blue_verified_only: bool | Omit = omit,
bounding_box: str | Omit = omit,
+ card_name: str | Omit = omit,
cashtags: str | Omit = omit,
+ collection_strategy: Literal["auto", "complete", "direct", "search", "thread"] | Omit = omit,
conversation_id: str | Omit = omit,
+ dedupe_across_targets: bool | Omit = omit,
+ dedupe_mode: Literal["none", "first", "merge"] | Omit = omit,
exact_phrase: str | Omit = omit,
+ exclude_original_author: bool | Omit = omit,
+ exclude_source: str | Omit = omit,
exclude_words: str | Omit = omit,
from_user: str | Omit = omit,
+ geocode: str | Omit = omit,
hashtags: str | Omit = omit,
+ has_location: bool | Omit = omit,
+ has_media_only: bool | Omit = omit,
+ has_website: bool | Omit = omit,
+ include_original_post: bool | Omit = omit,
+ include_search_terms: bool | Omit = omit,
+ include_target_metadata: bool | Omit = omit,
in_reply_to_tweet_id: str | Omit = omit,
language: str | Omit = omit,
list_id: str | Omit = omit,
+ location_contains: str | Omit = omit,
+ max_depth: int | Omit = omit,
+ max_followers: int | Omit = omit,
+ max_following: int | Omit = omit,
+ max_id: str | Omit = omit,
+ max_items_per_target: int | Omit = omit,
+ max_likes: int | Omit = omit,
+ max_pages_per_target: int | Omit = omit,
+ max_posts: int | Omit = omit,
+ max_quotes: int | Omit = omit,
+ max_replies: int | Omit = omit,
+ max_retweets: int | Omit = omit,
media_type: Literal["images", "videos", "gifs", "media", "links", "none"] | Omit = omit,
mentioning: str | Omit = omit,
+ min_account_age_days: int | Omit = omit,
+ min_bookmarks: int | Omit = omit,
min_faves: int | Omit = omit,
+ min_followers: int | Omit = omit,
+ min_following: int | Omit = omit,
+ min_posts: int | Omit = omit,
min_quotes: int | Omit = omit,
min_replies: int | Omit = omit,
min_retweets: int | Omit = omit,
+ min_views: int | Omit = omit,
+ native_retweets: bool | Omit = omit,
+ near: str | Omit = omit,
+ news: bool | Omit = omit,
+ overlap_mode: bool | Omit = omit,
place: str | Omit = omit,
place_country: str | Omit = omit,
point_radius: str | Omit = omit,
+ query_type: Literal["Latest", "Top", "Both"] | Omit = omit,
quotes: Literal["include", "exclude", "only"] | Omit = omit,
quotes_of_tweet_id: str | Omit = omit,
+ relation_targets: Iterable[extraction_estimate_cost_params.RelationTarget] | Omit = omit,
replies: Literal["include", "exclude", "only"] | Omit = omit,
results_limit: int | Omit = omit,
retweets: Literal["include", "exclude", "only"] | Omit = omit,
retweets_of_tweet_id: str | Omit = omit,
+ safe: bool | Omit = omit,
+ scope: Literal["all", "direct", "nested"] | Omit = omit,
+ search_queries: SequenceNotStr[str] | Omit = omit,
search_query: str | Omit = omit,
since_date: Union[str, date] | Omit = omit,
+ since_id: str | Omit = omit,
+ since_time: Union[Union[str, datetime], int] | Omit = omit,
+ sort: Literal["relevance", "latest", "oldest", "likes"] | Omit = omit,
+ source: str | Omit = omit,
+ start_cursor: str | Omit = omit,
target_community_id: str | Omit = omit,
+ target_community_ids: SequenceNotStr[str] | Omit = omit,
target_list_id: str | Omit = omit,
+ target_list_ids: SequenceNotStr[str] | Omit = omit,
+ targets: SequenceNotStr[extraction_estimate_cost_params.Target] | Omit = omit,
target_space_id: str | Omit = omit,
target_tweet_id: str | Omit = omit,
+ target_tweet_ids: SequenceNotStr[str] | Omit = omit,
target_username: str | Omit = omit,
+ target_usernames: SequenceNotStr[str] | Omit = omit,
to_user: str | Omit = omit,
until_date: Union[str, date] | Omit = omit,
+ until_time: Union[Union[str, datetime], int] | Omit = omit,
url: str | Omit = omit,
+ username_contains: str | Omit = omit,
verified_only: bool | Omit = omit,
+ verified_type: str | Omit = omit,
+ within: str | Omit = omit,
+ within_time: str | Omit = omit,
# Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
# The extra values given here take precedence over values defined on the client or passed to this method.
extra_headers: Headers | None = None,
@@ -278,83 +351,195 @@ def estimate_cost(
Args:
tool_type: Identifier for the extraction tool used to run a job.
- advanced_query: Raw advanced query string appended to the estimate (tweet_search_extractor)
+ advanced_query: Raw advanced search query appended as-is (tweet_search_extractor)
+
+ any_words: Words or quoted phrases where any one can match. Separate with spaces, commas,
+ or lines. (tweet_search_extractor)
+
+ bio_contains: Bio terms separated by commas or lines.
+
+ blue_verified_only: Return only Blue-verified Tweet authors.
+
+ bounding_box: Geo bounding box, e.g. -74.1 40.6 -73.9 40.8 (tweet_search_extractor)
+
+ card_name: Match the Tweet card name.
+
+ cashtags: Cashtags separated by spaces, commas, or lines. (tweet_search_extractor)
+
+ collection_strategy: Reply collection strategy.
+
+ conversation_id: Conversation ID filter (tweet_search_extractor)
+
+ dedupe_across_targets: Merge duplicate results across collection targets.
+
+ dedupe_mode: Keep target duplicates, first rows, or merged overlap.
+
+ exact_phrase: Exact phrase to match (tweet_search_extractor)
+
+ exclude_original_author: Exclude replies from the source author.
- any_words: Alternative words or quoted phrases for estimated results. Separate with spaces,
- commas, or lines.
+ exclude_source: Exclude a source application.
- bounding_box: Geo bounding box used for estimation, e.g. -74.1 40.6 -73.9 40.8
+ exclude_words: Words or quoted phrases to exclude. Separate with spaces, commas, or lines.
(tweet_search_extractor)
- cashtags: Cashtags applied to the estimate, separated by spaces, commas, or lines.
+ from_user: Filter by author username (tweet_search_extractor)
- conversation_id: Conversation ID filter used for estimation (tweet_search_extractor)
+ geocode: Match latitude, longitude, and radius.
- exact_phrase: Exact phrase filter for search estimation
+ hashtags: Hashtags separated by spaces, commas, or lines. (tweet_search_extractor)
- exclude_words: Words or quoted phrases excluded from estimated results. Separate with spaces,
- commas, or lines.
+ has_location: Require a profile location.
- from_user: Estimate only tweets from this author username (tweet_search_extractor)
+ has_media_only: Return only replies with media.
- hashtags: Hashtags applied to the estimate, separated by spaces, commas, or lines.
+ has_website: Require a profile website.
- in_reply_to_tweet_id: Estimate only replies to this tweet ID (tweet_search_extractor)
+ include_original_post: Include the source post in reply results.
- language: Language code used for estimate filtering (tweet_search_extractor)
+ include_search_terms: Add matching search terms to collection metadata.
- list_id: Estimate search results within this list ID (tweet_search_extractor)
+ include_target_metadata: Add source target metadata to each result.
- media_type: Media type used for estimate filtering (tweet_search_extractor)
+ in_reply_to_tweet_id: Only replies to this tweet ID (tweet_search_extractor)
- mentioning: Estimate tweets mentioning this username (tweet_search_extractor)
+ language: Language code filter (tweet_search_extractor)
- min_faves: Minimum likes threshold for estimated results (tweet_search_extractor)
+ list_id: Search within a list ID (tweet_search_extractor)
- min_quotes: Minimum quote count threshold for estimated results (tweet_search_extractor)
+ location_contains: Required profile location text.
- min_replies: Minimum replies threshold for estimated results (tweet_search_extractor)
+ max_depth: Maximum nested reply depth.
- min_retweets: Minimum retweets threshold for estimated results (tweet_search_extractor)
+ max_followers: Maximum follower count for profile results.
- place: Estimate search results within this place ID (tweet_search_extractor)
+ max_following: Maximum following count for profile results.
- place_country: Estimate search results within this country code (tweet_search_extractor)
+ max_id: Return Tweets older than this Tweet ID.
- point_radius: Geo point radius used for estimation, e.g. -73.99 40.73 25mi
- (tweet_search_extractor)
+ max_items_per_target: Maximum results collected for each target.
+
+ max_likes: Maximum Tweet like count.
+
+ max_pages_per_target: Reply pages collected for each target.
+
+ max_posts: Maximum post count for profile results.
+
+ max_quotes: Maximum Tweet quote count.
+
+ max_replies: Maximum Tweet reply count.
+
+ max_retweets: Maximum Tweet repost count.
+
+ media_type: Media type filter (tweet_search_extractor)
+
+ mentioning: Filter tweets mentioning a username (tweet_search_extractor)
+
+ min_account_age_days: Minimum profile age in days.
+
+ min_bookmarks: Minimum Tweet bookmark count.
+
+ min_faves: Minimum likes threshold (tweet_search_extractor)
+
+ min_followers: Minimum follower count for profile results.
+
+ min_following: Minimum following count for profile results.
+
+ min_posts: Minimum post count for profile results.
- quotes: Quote mode used for estimation (tweet_search_extractor)
+ min_quotes: Minimum quote count threshold (tweet_search_extractor)
+
+ min_replies: Minimum replies threshold (tweet_search_extractor)
+
+ min_retweets: Minimum retweets threshold (tweet_search_extractor)
+
+ min_views: Minimum Tweet view count.
+
+ native_retweets: Only return native reposts.
+
+ near: Match a place name.
+
+ news: Only return news results.
+
+ overlap_mode: Shortcut for dedupeMode=merge.
+
+ place: Search within a place ID (tweet_search_extractor)
- quotes_of_tweet_id: Estimate only quotes of this tweet ID (tweet_search_extractor)
+ place_country: Search within a country code (tweet_search_extractor)
+
+ point_radius: Geo point radius, e.g. -73.99 40.73 25mi (tweet_search_extractor)
+
+ query_type: Search ranking applied to every query.
+
+ quotes: Quote mode (tweet_search_extractor)
- replies: Reply mode used for estimation (tweet_search_extractor)
+ quotes_of_tweet_id: Only quotes of this tweet ID (tweet_search_extractor)
- results_limit: Maximum number of results to estimate. When set, the estimate caps projected
- results to this value.
+ relation_targets: Profile relations processed within one job.
- retweets: Retweet mode used for estimation (tweet_search_extractor)
+ replies: Reply mode (tweet_search_extractor)
- retweets_of_tweet_id: Estimate only retweets of this tweet ID (tweet_search_extractor)
+ results_limit: Maximum number of results to extract. When set, the extraction stops after
+ reaching this limit.
- search_query: Query used to price tweet_search_extractor or community_search.
+ retweets: Retweet mode (tweet_search_extractor)
- since_date: Estimate start date in YYYY-MM-DD format (tweet_search_extractor)
+ retweets_of_tweet_id: Only retweets of this tweet ID (tweet_search_extractor)
- target_community_id: Community ID used to price community_post_extractor or community_search.
+ safe: Enable the safe-search filter.
- target_list_id: List ID used to price list_follower_explorer, list_member_extractor, or
+ scope: Reply depth scope.
+
+ search_queries: Search queries processed as one collection job.
+
+ search_query: Required for tweet_search_extractor & community_search.
+
+ since_date: Start date YYYY-MM-DD (tweet_search_extractor)
+
+ since_id: Return Tweets newer than this Tweet ID.
+
+ since_time: Reply start time as ISO 8601 or Unix seconds.
+
+ sort: Reply result order.
+
+ source: Match the source application.
+
+ start_cursor: Resume one reply target from this cursor.
+
+ target_community_id: Required for community_post_extractor & community_search.
+
+ target_community_ids: Community IDs processed as one collection job.
+
+ target_list_id: Required for list_follower_explorer, list_member_extractor &
list_post_extractor.
- target_space_id: Space ID used to price space_explorer.
+ target_list_ids: List IDs processed as one collection job.
- to_user: Estimate replies sent to this username (tweet_search_extractor)
+ targets: Mixed targets auto-routed within one job.
- until_date: Estimate end date in YYYY-MM-DD format (tweet_search_extractor)
+ target_space_id: Required for space_explorer.
+
+ target_tweet_ids: Tweet IDs processed as one collection job.
- url: URL substring or domain filter used for estimation (tweet_search_extractor)
+ target_usernames: Usernames processed as one collection job.
- verified_only: Estimate only verified authors (tweet_search_extractor)
+ to_user: Filter replies sent to a username (tweet_search_extractor)
+
+ until_date: End date YYYY-MM-DD (tweet_search_extractor)
+
+ until_time: Reply end time as ISO 8601 or Unix seconds.
+
+ url: URL substring or domain filter (tweet_search_extractor)
+
+ username_contains: Required username text.
+
+ verified_only: Only verified authors (tweet_search_extractor)
+
+ verified_type: Exact profile verification type.
+
+ within: Set the radius for the near filter.
+
+ within_time: Match Tweets inside a recent time window.
extra_headers: Send extra headers
@@ -371,42 +556,99 @@ def estimate_cost(
"tool_type": tool_type,
"advanced_query": advanced_query,
"any_words": any_words,
+ "bio_contains": bio_contains,
+ "blue_verified_only": blue_verified_only,
"bounding_box": bounding_box,
+ "card_name": card_name,
"cashtags": cashtags,
+ "collection_strategy": collection_strategy,
"conversation_id": conversation_id,
+ "dedupe_across_targets": dedupe_across_targets,
+ "dedupe_mode": dedupe_mode,
"exact_phrase": exact_phrase,
+ "exclude_original_author": exclude_original_author,
+ "exclude_source": exclude_source,
"exclude_words": exclude_words,
"from_user": from_user,
+ "geocode": geocode,
"hashtags": hashtags,
+ "has_location": has_location,
+ "has_media_only": has_media_only,
+ "has_website": has_website,
+ "include_original_post": include_original_post,
+ "include_search_terms": include_search_terms,
+ "include_target_metadata": include_target_metadata,
"in_reply_to_tweet_id": in_reply_to_tweet_id,
"language": language,
"list_id": list_id,
+ "location_contains": location_contains,
+ "max_depth": max_depth,
+ "max_followers": max_followers,
+ "max_following": max_following,
+ "max_id": max_id,
+ "max_items_per_target": max_items_per_target,
+ "max_likes": max_likes,
+ "max_pages_per_target": max_pages_per_target,
+ "max_posts": max_posts,
+ "max_quotes": max_quotes,
+ "max_replies": max_replies,
+ "max_retweets": max_retweets,
"media_type": media_type,
"mentioning": mentioning,
+ "min_account_age_days": min_account_age_days,
+ "min_bookmarks": min_bookmarks,
"min_faves": min_faves,
+ "min_followers": min_followers,
+ "min_following": min_following,
+ "min_posts": min_posts,
"min_quotes": min_quotes,
"min_replies": min_replies,
"min_retweets": min_retweets,
+ "min_views": min_views,
+ "native_retweets": native_retweets,
+ "near": near,
+ "news": news,
+ "overlap_mode": overlap_mode,
"place": place,
"place_country": place_country,
"point_radius": point_radius,
+ "query_type": query_type,
"quotes": quotes,
"quotes_of_tweet_id": quotes_of_tweet_id,
+ "relation_targets": relation_targets,
"replies": replies,
"results_limit": results_limit,
"retweets": retweets,
"retweets_of_tweet_id": retweets_of_tweet_id,
+ "safe": safe,
+ "scope": scope,
+ "search_queries": search_queries,
"search_query": search_query,
"since_date": since_date,
+ "since_id": since_id,
+ "since_time": since_time,
+ "sort": sort,
+ "source": source,
+ "start_cursor": start_cursor,
"target_community_id": target_community_id,
+ "target_community_ids": target_community_ids,
"target_list_id": target_list_id,
+ "target_list_ids": target_list_ids,
+ "targets": targets,
"target_space_id": target_space_id,
"target_tweet_id": target_tweet_id,
+ "target_tweet_ids": target_tweet_ids,
"target_username": target_username,
+ "target_usernames": target_usernames,
"to_user": to_user,
"until_date": until_date,
+ "until_time": until_time,
"url": url,
+ "username_contains": username_contains,
"verified_only": verified_only,
+ "verified_type": verified_type,
+ "within": within,
+ "within_time": within_time,
},
extraction_estimate_cost_params.ExtractionEstimateCostParams,
),
@@ -421,6 +663,24 @@ def export_results(
id: str,
*,
format: Literal["csv", "json", "md", "md-document", "pdf", "txt", "xlsx"],
+ has_description: bool | Omit = omit,
+ has_location: bool | Omit = omit,
+ has_media: bool | Omit = omit,
+ lang: str | Omit = omit,
+ max_followers: int | Omit = omit,
+ max_following: int | Omit = omit,
+ max_posts: int | Omit = omit,
+ min_followers: int | Omit = omit,
+ min_following: int | Omit = omit,
+ min_likes: int | Omit = omit,
+ min_posts: int | Omit = omit,
+ min_replies: int | Omit = omit,
+ min_retweets: int | Omit = omit,
+ min_views: int | Omit = omit,
+ search: str | Omit = omit,
+ since_date: Union[str, date] | Omit = omit,
+ until_date: Union[str, date] | Omit = omit,
+ verified: bool | Omit = omit,
# Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
# The extra values given here take precedence over values defined on the client or passed to this method.
extra_headers: Headers | None = None,
@@ -434,6 +694,42 @@ def export_results(
Args:
format: Export file format
+ has_description: Require a non-empty description.
+
+ has_location: Require a non-empty location.
+
+ has_media: Require media.
+
+ lang: Filter by language code.
+
+ max_followers: Maximum follower count.
+
+ max_following: Maximum following count.
+
+ max_posts: Maximum post count.
+
+ min_followers: Minimum follower count.
+
+ min_following: Minimum following count.
+
+ min_likes: Minimum like count.
+
+ min_posts: Minimum post count.
+
+ min_replies: Minimum reply count.
+
+ min_retweets: Minimum repost count.
+
+ min_views: Minimum view count.
+
+ search: Search exported result text.
+
+ since_date: Include results on or after this date.
+
+ until_date: Include results on or before this date.
+
+ verified: Filter by verified status.
+
extra_headers: Send extra headers
extra_query: Add additional query parameters to the request
@@ -453,7 +749,28 @@ def export_results(
extra_body=extra_body,
timeout=timeout,
query=maybe_transform(
- {"format": format}, extraction_export_results_params.ExtractionExportResultsParams
+ {
+ "format": format,
+ "has_description": has_description,
+ "has_location": has_location,
+ "has_media": has_media,
+ "lang": lang,
+ "max_followers": max_followers,
+ "max_following": max_following,
+ "max_posts": max_posts,
+ "min_followers": min_followers,
+ "min_following": min_following,
+ "min_likes": min_likes,
+ "min_posts": min_posts,
+ "min_replies": min_replies,
+ "min_retweets": min_retweets,
+ "min_views": min_views,
+ "search": search,
+ "since_date": since_date,
+ "until_date": until_date,
+ "verified": verified,
+ },
+ extraction_export_results_params.ExtractionExportResultsParams,
),
),
cast_to=BinaryAPIResponse,
@@ -487,44 +804,102 @@ def run(
"user_media",
"verified_follower_explorer",
],
+ dry_run: bool | Omit = omit,
advanced_query: str | Omit = omit,
any_words: str | Omit = omit,
+ bio_contains: str | Omit = omit,
+ blue_verified_only: bool | Omit = omit,
bounding_box: str | Omit = omit,
+ card_name: str | Omit = omit,
cashtags: str | Omit = omit,
+ collection_strategy: Literal["auto", "complete", "direct", "search", "thread"] | Omit = omit,
conversation_id: str | Omit = omit,
+ dedupe_across_targets: bool | Omit = omit,
+ dedupe_mode: Literal["none", "first", "merge"] | Omit = omit,
exact_phrase: str | Omit = omit,
+ exclude_original_author: bool | Omit = omit,
+ exclude_source: str | Omit = omit,
exclude_words: str | Omit = omit,
from_user: str | Omit = omit,
+ geocode: str | Omit = omit,
hashtags: str | Omit = omit,
+ has_location: bool | Omit = omit,
+ has_media_only: bool | Omit = omit,
+ has_website: bool | Omit = omit,
+ include_original_post: bool | Omit = omit,
+ include_search_terms: bool | Omit = omit,
+ include_target_metadata: bool | Omit = omit,
in_reply_to_tweet_id: str | Omit = omit,
language: str | Omit = omit,
list_id: str | Omit = omit,
+ location_contains: str | Omit = omit,
+ max_depth: int | Omit = omit,
+ max_followers: int | Omit = omit,
+ max_following: int | Omit = omit,
+ max_id: str | Omit = omit,
+ max_items_per_target: int | Omit = omit,
+ max_likes: int | Omit = omit,
+ max_pages_per_target: int | Omit = omit,
+ max_posts: int | Omit = omit,
+ max_quotes: int | Omit = omit,
+ max_replies: int | Omit = omit,
+ max_retweets: int | Omit = omit,
media_type: Literal["images", "videos", "gifs", "media", "links", "none"] | Omit = omit,
mentioning: str | Omit = omit,
+ min_account_age_days: int | Omit = omit,
+ min_bookmarks: int | Omit = omit,
min_faves: int | Omit = omit,
+ min_followers: int | Omit = omit,
+ min_following: int | Omit = omit,
+ min_posts: int | Omit = omit,
min_quotes: int | Omit = omit,
min_replies: int | Omit = omit,
min_retweets: int | Omit = omit,
+ min_views: int | Omit = omit,
+ native_retweets: bool | Omit = omit,
+ near: str | Omit = omit,
+ news: bool | Omit = omit,
+ overlap_mode: bool | Omit = omit,
place: str | Omit = omit,
place_country: str | Omit = omit,
point_radius: str | Omit = omit,
+ query_type: Literal["Latest", "Top", "Both"] | Omit = omit,
quotes: Literal["include", "exclude", "only"] | Omit = omit,
quotes_of_tweet_id: str | Omit = omit,
+ relation_targets: Iterable[extraction_run_params.RelationTarget] | Omit = omit,
replies: Literal["include", "exclude", "only"] | Omit = omit,
results_limit: int | Omit = omit,
retweets: Literal["include", "exclude", "only"] | Omit = omit,
retweets_of_tweet_id: str | Omit = omit,
+ safe: bool | Omit = omit,
+ scope: Literal["all", "direct", "nested"] | Omit = omit,
+ search_queries: SequenceNotStr[str] | Omit = omit,
search_query: str | Omit = omit,
since_date: Union[str, date] | Omit = omit,
+ since_id: str | Omit = omit,
+ since_time: Union[Union[str, datetime], int] | Omit = omit,
+ sort: Literal["relevance", "latest", "oldest", "likes"] | Omit = omit,
+ source: str | Omit = omit,
+ start_cursor: str | Omit = omit,
target_community_id: str | Omit = omit,
+ target_community_ids: SequenceNotStr[str] | Omit = omit,
target_list_id: str | Omit = omit,
+ target_list_ids: SequenceNotStr[str] | Omit = omit,
+ targets: SequenceNotStr[extraction_run_params.Target] | Omit = omit,
target_space_id: str | Omit = omit,
target_tweet_id: str | Omit = omit,
+ target_tweet_ids: SequenceNotStr[str] | Omit = omit,
target_username: str | Omit = omit,
+ target_usernames: SequenceNotStr[str] | Omit = omit,
to_user: str | Omit = omit,
until_date: Union[str, date] | Omit = omit,
+ until_time: Union[Union[str, datetime], int] | Omit = omit,
url: str | Omit = omit,
+ username_contains: str | Omit = omit,
verified_only: bool | Omit = omit,
+ verified_type: str | Omit = omit,
+ within: str | Omit = omit,
+ within_time: str | Omit = omit,
# Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
# The extra values given here take precedence over values defined on the client or passed to this method.
extra_headers: Headers | None = None,
@@ -538,54 +913,134 @@ def run(
Args:
tool_type: Identifier for the extraction tool used to run a job.
+ dry_run: Estimate cost without creating an extraction.
+
advanced_query: Raw advanced search query appended as-is (tweet_search_extractor)
any_words: Words or quoted phrases where any one can match. Separate with spaces, commas,
or lines. (tweet_search_extractor)
+ bio_contains: Bio terms separated by commas or lines.
+
+ blue_verified_only: Return only Blue-verified Tweet authors.
+
bounding_box: Geo bounding box, e.g. -74.1 40.6 -73.9 40.8 (tweet_search_extractor)
+ card_name: Match the Tweet card name.
+
cashtags: Cashtags separated by spaces, commas, or lines. (tweet_search_extractor)
+ collection_strategy: Reply collection strategy.
+
conversation_id: Conversation ID filter (tweet_search_extractor)
+ dedupe_across_targets: Merge duplicate results across collection targets.
+
+ dedupe_mode: Keep target duplicates, first rows, or merged overlap.
+
exact_phrase: Exact phrase to match (tweet_search_extractor)
+ exclude_original_author: Exclude replies from the source author.
+
+ exclude_source: Exclude a source application.
+
exclude_words: Words or quoted phrases to exclude. Separate with spaces, commas, or lines.
(tweet_search_extractor)
from_user: Filter by author username (tweet_search_extractor)
+ geocode: Match latitude, longitude, and radius.
+
hashtags: Hashtags separated by spaces, commas, or lines. (tweet_search_extractor)
+ has_location: Require a profile location.
+
+ has_media_only: Return only replies with media.
+
+ has_website: Require a profile website.
+
+ include_original_post: Include the source post in reply results.
+
+ include_search_terms: Add matching search terms to collection metadata.
+
+ include_target_metadata: Add source target metadata to each result.
+
in_reply_to_tweet_id: Only replies to this tweet ID (tweet_search_extractor)
language: Language code filter (tweet_search_extractor)
list_id: Search within a list ID (tweet_search_extractor)
+ location_contains: Required profile location text.
+
+ max_depth: Maximum nested reply depth.
+
+ max_followers: Maximum follower count for profile results.
+
+ max_following: Maximum following count for profile results.
+
+ max_id: Return Tweets older than this Tweet ID.
+
+ max_items_per_target: Maximum results collected for each target.
+
+ max_likes: Maximum Tweet like count.
+
+ max_pages_per_target: Reply pages collected for each target.
+
+ max_posts: Maximum post count for profile results.
+
+ max_quotes: Maximum Tweet quote count.
+
+ max_replies: Maximum Tweet reply count.
+
+ max_retweets: Maximum Tweet repost count.
+
media_type: Media type filter (tweet_search_extractor)
mentioning: Filter tweets mentioning a username (tweet_search_extractor)
+ min_account_age_days: Minimum profile age in days.
+
+ min_bookmarks: Minimum Tweet bookmark count.
+
min_faves: Minimum likes threshold (tweet_search_extractor)
+ min_followers: Minimum follower count for profile results.
+
+ min_following: Minimum following count for profile results.
+
+ min_posts: Minimum post count for profile results.
+
min_quotes: Minimum quote count threshold (tweet_search_extractor)
min_replies: Minimum replies threshold (tweet_search_extractor)
min_retweets: Minimum retweets threshold (tweet_search_extractor)
+ min_views: Minimum Tweet view count.
+
+ native_retweets: Only return native reposts.
+
+ near: Match a place name.
+
+ news: Only return news results.
+
+ overlap_mode: Shortcut for dedupeMode=merge.
+
place: Search within a place ID (tweet_search_extractor)
place_country: Search within a country code (tweet_search_extractor)
point_radius: Geo point radius, e.g. -73.99 40.73 25mi (tweet_search_extractor)
+ query_type: Search ranking applied to every query.
+
quotes: Quote mode (tweet_search_extractor)
quotes_of_tweet_id: Only quotes of this tweet ID (tweet_search_extractor)
+ relation_targets: Profile relations processed within one job.
+
replies: Reply mode (tweet_search_extractor)
results_limit: Maximum number of results to extract. When set, the extraction stops after
@@ -595,25 +1050,61 @@ def run(
retweets_of_tweet_id: Only retweets of this tweet ID (tweet_search_extractor)
+ safe: Enable the safe-search filter.
+
+ scope: Reply depth scope.
+
+ search_queries: Search queries processed as one collection job.
+
search_query: Required for tweet_search_extractor & community_search.
since_date: Start date YYYY-MM-DD (tweet_search_extractor)
+ since_id: Return Tweets newer than this Tweet ID.
+
+ since_time: Reply start time as ISO 8601 or Unix seconds.
+
+ sort: Reply result order.
+
+ source: Match the source application.
+
+ start_cursor: Resume one reply target from this cursor.
+
target_community_id: Required for community_post_extractor & community_search.
+ target_community_ids: Community IDs processed as one collection job.
+
target_list_id: Required for list_follower_explorer, list_member_extractor &
list_post_extractor.
+ target_list_ids: List IDs processed as one collection job.
+
+ targets: Mixed targets auto-routed within one job.
+
target_space_id: Required for space_explorer.
+ target_tweet_ids: Tweet IDs processed as one collection job.
+
+ target_usernames: Usernames processed as one collection job.
+
to_user: Filter replies sent to a username (tweet_search_extractor)
until_date: End date YYYY-MM-DD (tweet_search_extractor)
+ until_time: Reply end time as ISO 8601 or Unix seconds.
+
url: URL substring or domain filter (tweet_search_extractor)
+ username_contains: Required username text.
+
verified_only: Only verified authors (tweet_search_extractor)
+ verified_type: Exact profile verification type.
+
+ within: Set the radius for the near filter.
+
+ within_time: Match Tweets inside a recent time window.
+
extra_headers: Send extra headers
extra_query: Add additional query parameters to the request
@@ -629,47 +1120,108 @@ def run(
"tool_type": tool_type,
"advanced_query": advanced_query,
"any_words": any_words,
+ "bio_contains": bio_contains,
+ "blue_verified_only": blue_verified_only,
"bounding_box": bounding_box,
+ "card_name": card_name,
"cashtags": cashtags,
+ "collection_strategy": collection_strategy,
"conversation_id": conversation_id,
+ "dedupe_across_targets": dedupe_across_targets,
+ "dedupe_mode": dedupe_mode,
"exact_phrase": exact_phrase,
+ "exclude_original_author": exclude_original_author,
+ "exclude_source": exclude_source,
"exclude_words": exclude_words,
"from_user": from_user,
+ "geocode": geocode,
"hashtags": hashtags,
+ "has_location": has_location,
+ "has_media_only": has_media_only,
+ "has_website": has_website,
+ "include_original_post": include_original_post,
+ "include_search_terms": include_search_terms,
+ "include_target_metadata": include_target_metadata,
"in_reply_to_tweet_id": in_reply_to_tweet_id,
"language": language,
"list_id": list_id,
+ "location_contains": location_contains,
+ "max_depth": max_depth,
+ "max_followers": max_followers,
+ "max_following": max_following,
+ "max_id": max_id,
+ "max_items_per_target": max_items_per_target,
+ "max_likes": max_likes,
+ "max_pages_per_target": max_pages_per_target,
+ "max_posts": max_posts,
+ "max_quotes": max_quotes,
+ "max_replies": max_replies,
+ "max_retweets": max_retweets,
"media_type": media_type,
"mentioning": mentioning,
+ "min_account_age_days": min_account_age_days,
+ "min_bookmarks": min_bookmarks,
"min_faves": min_faves,
+ "min_followers": min_followers,
+ "min_following": min_following,
+ "min_posts": min_posts,
"min_quotes": min_quotes,
"min_replies": min_replies,
"min_retweets": min_retweets,
+ "min_views": min_views,
+ "native_retweets": native_retweets,
+ "near": near,
+ "news": news,
+ "overlap_mode": overlap_mode,
"place": place,
"place_country": place_country,
"point_radius": point_radius,
+ "query_type": query_type,
"quotes": quotes,
"quotes_of_tweet_id": quotes_of_tweet_id,
+ "relation_targets": relation_targets,
"replies": replies,
"results_limit": results_limit,
"retweets": retweets,
"retweets_of_tweet_id": retweets_of_tweet_id,
+ "safe": safe,
+ "scope": scope,
+ "search_queries": search_queries,
"search_query": search_query,
"since_date": since_date,
+ "since_id": since_id,
+ "since_time": since_time,
+ "sort": sort,
+ "source": source,
+ "start_cursor": start_cursor,
"target_community_id": target_community_id,
+ "target_community_ids": target_community_ids,
"target_list_id": target_list_id,
+ "target_list_ids": target_list_ids,
+ "targets": targets,
"target_space_id": target_space_id,
"target_tweet_id": target_tweet_id,
+ "target_tweet_ids": target_tweet_ids,
"target_username": target_username,
+ "target_usernames": target_usernames,
"to_user": to_user,
"until_date": until_date,
+ "until_time": until_time,
"url": url,
+ "username_contains": username_contains,
"verified_only": verified_only,
+ "verified_type": verified_type,
+ "within": within,
+ "within_time": within_time,
},
extraction_run_params.ExtractionRunParams,
),
options=make_request_options(
- extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
+ extra_headers=extra_headers,
+ extra_query=extra_query,
+ extra_body=extra_body,
+ timeout=timeout,
+ query=maybe_transform({"dry_run": dry_run}, extraction_run_params.ExtractionRunParams),
),
cast_to=ExtractionRunResponse,
)
@@ -702,7 +1254,11 @@ async def retrieve(
id: str,
*,
cursor: str | Omit = omit,
+ field_style: Literal["source", "camelCase", "snake_case"] | Omit = omit,
+ include_raw: bool | Omit = omit,
limit: int | Omit = omit,
+ output_mode: Literal["compact", "full", "raw"] | Omit = omit,
+ output_preset: Literal["nested", "flat"] | Omit = omit,
# Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
# The extra values given here take precedence over values defined on the client or passed to this method.
extra_headers: Headers | None = None,
@@ -714,10 +1270,18 @@ async def retrieve(
Get extraction results
Args:
- cursor: Cursor for keyset pagination from prior response next_cursor
+ cursor: Previous nextCursor.
+
+ field_style: Preserve source keys or convert result field names.
+
+ include_raw: Use outputMode=raw instead.
limit: Maximum number of results to return (1-1000, default 100)
+ output_mode: Select compact, full, or raw-compatible result fields.
+
+ output_preset: Keep enrichment nested or merge it into each result.
+
extra_headers: Send extra headers
extra_query: Add additional query parameters to the request
@@ -738,7 +1302,11 @@ async def retrieve(
query=await async_maybe_transform(
{
"cursor": cursor,
+ "field_style": field_style,
+ "include_raw": include_raw,
"limit": limit,
+ "output_mode": output_mode,
+ "output_preset": output_preset,
},
extraction_retrieve_params.ExtractionRetrieveParams,
),
@@ -789,7 +1357,7 @@ async def list(
List extraction jobs
Args:
- cursor: Cursor for keyset pagination from prior response next_cursor
+ cursor: Previous nextCursor.
limit: Maximum number of items to return (1-100, default 50). For paid per-result
endpoints, the returned count may be lower when remaining credits cannot cover
@@ -858,42 +1426,99 @@ async def estimate_cost(
],
advanced_query: str | Omit = omit,
any_words: str | Omit = omit,
+ bio_contains: str | Omit = omit,
+ blue_verified_only: bool | Omit = omit,
bounding_box: str | Omit = omit,
+ card_name: str | Omit = omit,
cashtags: str | Omit = omit,
+ collection_strategy: Literal["auto", "complete", "direct", "search", "thread"] | Omit = omit,
conversation_id: str | Omit = omit,
+ dedupe_across_targets: bool | Omit = omit,
+ dedupe_mode: Literal["none", "first", "merge"] | Omit = omit,
exact_phrase: str | Omit = omit,
+ exclude_original_author: bool | Omit = omit,
+ exclude_source: str | Omit = omit,
exclude_words: str | Omit = omit,
from_user: str | Omit = omit,
+ geocode: str | Omit = omit,
hashtags: str | Omit = omit,
+ has_location: bool | Omit = omit,
+ has_media_only: bool | Omit = omit,
+ has_website: bool | Omit = omit,
+ include_original_post: bool | Omit = omit,
+ include_search_terms: bool | Omit = omit,
+ include_target_metadata: bool | Omit = omit,
in_reply_to_tweet_id: str | Omit = omit,
language: str | Omit = omit,
list_id: str | Omit = omit,
+ location_contains: str | Omit = omit,
+ max_depth: int | Omit = omit,
+ max_followers: int | Omit = omit,
+ max_following: int | Omit = omit,
+ max_id: str | Omit = omit,
+ max_items_per_target: int | Omit = omit,
+ max_likes: int | Omit = omit,
+ max_pages_per_target: int | Omit = omit,
+ max_posts: int | Omit = omit,
+ max_quotes: int | Omit = omit,
+ max_replies: int | Omit = omit,
+ max_retweets: int | Omit = omit,
media_type: Literal["images", "videos", "gifs", "media", "links", "none"] | Omit = omit,
mentioning: str | Omit = omit,
+ min_account_age_days: int | Omit = omit,
+ min_bookmarks: int | Omit = omit,
min_faves: int | Omit = omit,
+ min_followers: int | Omit = omit,
+ min_following: int | Omit = omit,
+ min_posts: int | Omit = omit,
min_quotes: int | Omit = omit,
min_replies: int | Omit = omit,
min_retweets: int | Omit = omit,
+ min_views: int | Omit = omit,
+ native_retweets: bool | Omit = omit,
+ near: str | Omit = omit,
+ news: bool | Omit = omit,
+ overlap_mode: bool | Omit = omit,
place: str | Omit = omit,
place_country: str | Omit = omit,
point_radius: str | Omit = omit,
+ query_type: Literal["Latest", "Top", "Both"] | Omit = omit,
quotes: Literal["include", "exclude", "only"] | Omit = omit,
quotes_of_tweet_id: str | Omit = omit,
+ relation_targets: Iterable[extraction_estimate_cost_params.RelationTarget] | Omit = omit,
replies: Literal["include", "exclude", "only"] | Omit = omit,
results_limit: int | Omit = omit,
retweets: Literal["include", "exclude", "only"] | Omit = omit,
retweets_of_tweet_id: str | Omit = omit,
+ safe: bool | Omit = omit,
+ scope: Literal["all", "direct", "nested"] | Omit = omit,
+ search_queries: SequenceNotStr[str] | Omit = omit,
search_query: str | Omit = omit,
since_date: Union[str, date] | Omit = omit,
+ since_id: str | Omit = omit,
+ since_time: Union[Union[str, datetime], int] | Omit = omit,
+ sort: Literal["relevance", "latest", "oldest", "likes"] | Omit = omit,
+ source: str | Omit = omit,
+ start_cursor: str | Omit = omit,
target_community_id: str | Omit = omit,
+ target_community_ids: SequenceNotStr[str] | Omit = omit,
target_list_id: str | Omit = omit,
+ target_list_ids: SequenceNotStr[str] | Omit = omit,
+ targets: SequenceNotStr[extraction_estimate_cost_params.Target] | Omit = omit,
target_space_id: str | Omit = omit,
target_tweet_id: str | Omit = omit,
+ target_tweet_ids: SequenceNotStr[str] | Omit = omit,
target_username: str | Omit = omit,
+ target_usernames: SequenceNotStr[str] | Omit = omit,
to_user: str | Omit = omit,
until_date: Union[str, date] | Omit = omit,
+ until_time: Union[Union[str, datetime], int] | Omit = omit,
url: str | Omit = omit,
+ username_contains: str | Omit = omit,
verified_only: bool | Omit = omit,
+ verified_type: str | Omit = omit,
+ within: str | Omit = omit,
+ within_time: str | Omit = omit,
# Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
# The extra values given here take precedence over values defined on the client or passed to this method.
extra_headers: Headers | None = None,
@@ -907,83 +1532,195 @@ async def estimate_cost(
Args:
tool_type: Identifier for the extraction tool used to run a job.
- advanced_query: Raw advanced query string appended to the estimate (tweet_search_extractor)
+ advanced_query: Raw advanced search query appended as-is (tweet_search_extractor)
+
+ any_words: Words or quoted phrases where any one can match. Separate with spaces, commas,
+ or lines. (tweet_search_extractor)
+
+ bio_contains: Bio terms separated by commas or lines.
+
+ blue_verified_only: Return only Blue-verified Tweet authors.
+
+ bounding_box: Geo bounding box, e.g. -74.1 40.6 -73.9 40.8 (tweet_search_extractor)
+
+ card_name: Match the Tweet card name.
+
+ cashtags: Cashtags separated by spaces, commas, or lines. (tweet_search_extractor)
+
+ collection_strategy: Reply collection strategy.
+
+ conversation_id: Conversation ID filter (tweet_search_extractor)
+
+ dedupe_across_targets: Merge duplicate results across collection targets.
+
+ dedupe_mode: Keep target duplicates, first rows, or merged overlap.
+
+ exact_phrase: Exact phrase to match (tweet_search_extractor)
+
+ exclude_original_author: Exclude replies from the source author.
- any_words: Alternative words or quoted phrases for estimated results. Separate with spaces,
- commas, or lines.
+ exclude_source: Exclude a source application.
- bounding_box: Geo bounding box used for estimation, e.g. -74.1 40.6 -73.9 40.8
+ exclude_words: Words or quoted phrases to exclude. Separate with spaces, commas, or lines.
(tweet_search_extractor)
- cashtags: Cashtags applied to the estimate, separated by spaces, commas, or lines.
+ from_user: Filter by author username (tweet_search_extractor)
- conversation_id: Conversation ID filter used for estimation (tweet_search_extractor)
+ geocode: Match latitude, longitude, and radius.
- exact_phrase: Exact phrase filter for search estimation
+ hashtags: Hashtags separated by spaces, commas, or lines. (tweet_search_extractor)
- exclude_words: Words or quoted phrases excluded from estimated results. Separate with spaces,
- commas, or lines.
+ has_location: Require a profile location.
- from_user: Estimate only tweets from this author username (tweet_search_extractor)
+ has_media_only: Return only replies with media.
- hashtags: Hashtags applied to the estimate, separated by spaces, commas, or lines.
+ has_website: Require a profile website.
- in_reply_to_tweet_id: Estimate only replies to this tweet ID (tweet_search_extractor)
+ include_original_post: Include the source post in reply results.
- language: Language code used for estimate filtering (tweet_search_extractor)
+ include_search_terms: Add matching search terms to collection metadata.
- list_id: Estimate search results within this list ID (tweet_search_extractor)
+ include_target_metadata: Add source target metadata to each result.
- media_type: Media type used for estimate filtering (tweet_search_extractor)
+ in_reply_to_tweet_id: Only replies to this tweet ID (tweet_search_extractor)
- mentioning: Estimate tweets mentioning this username (tweet_search_extractor)
+ language: Language code filter (tweet_search_extractor)
- min_faves: Minimum likes threshold for estimated results (tweet_search_extractor)
+ list_id: Search within a list ID (tweet_search_extractor)
- min_quotes: Minimum quote count threshold for estimated results (tweet_search_extractor)
+ location_contains: Required profile location text.
- min_replies: Minimum replies threshold for estimated results (tweet_search_extractor)
+ max_depth: Maximum nested reply depth.
- min_retweets: Minimum retweets threshold for estimated results (tweet_search_extractor)
+ max_followers: Maximum follower count for profile results.
- place: Estimate search results within this place ID (tweet_search_extractor)
+ max_following: Maximum following count for profile results.
- place_country: Estimate search results within this country code (tweet_search_extractor)
+ max_id: Return Tweets older than this Tweet ID.
- point_radius: Geo point radius used for estimation, e.g. -73.99 40.73 25mi
- (tweet_search_extractor)
+ max_items_per_target: Maximum results collected for each target.
+
+ max_likes: Maximum Tweet like count.
+
+ max_pages_per_target: Reply pages collected for each target.
+
+ max_posts: Maximum post count for profile results.
+
+ max_quotes: Maximum Tweet quote count.
+
+ max_replies: Maximum Tweet reply count.
+
+ max_retweets: Maximum Tweet repost count.
+
+ media_type: Media type filter (tweet_search_extractor)
+
+ mentioning: Filter tweets mentioning a username (tweet_search_extractor)
+
+ min_account_age_days: Minimum profile age in days.
+
+ min_bookmarks: Minimum Tweet bookmark count.
+
+ min_faves: Minimum likes threshold (tweet_search_extractor)
+
+ min_followers: Minimum follower count for profile results.
+
+ min_following: Minimum following count for profile results.
+
+ min_posts: Minimum post count for profile results.
- quotes: Quote mode used for estimation (tweet_search_extractor)
+ min_quotes: Minimum quote count threshold (tweet_search_extractor)
+
+ min_replies: Minimum replies threshold (tweet_search_extractor)
+
+ min_retweets: Minimum retweets threshold (tweet_search_extractor)
+
+ min_views: Minimum Tweet view count.
+
+ native_retweets: Only return native reposts.
+
+ near: Match a place name.
+
+ news: Only return news results.
+
+ overlap_mode: Shortcut for dedupeMode=merge.
+
+ place: Search within a place ID (tweet_search_extractor)
- quotes_of_tweet_id: Estimate only quotes of this tweet ID (tweet_search_extractor)
+ place_country: Search within a country code (tweet_search_extractor)
+
+ point_radius: Geo point radius, e.g. -73.99 40.73 25mi (tweet_search_extractor)
+
+ query_type: Search ranking applied to every query.
+
+ quotes: Quote mode (tweet_search_extractor)
- replies: Reply mode used for estimation (tweet_search_extractor)
+ quotes_of_tweet_id: Only quotes of this tweet ID (tweet_search_extractor)
- results_limit: Maximum number of results to estimate. When set, the estimate caps projected
- results to this value.
+ relation_targets: Profile relations processed within one job.
- retweets: Retweet mode used for estimation (tweet_search_extractor)
+ replies: Reply mode (tweet_search_extractor)
- retweets_of_tweet_id: Estimate only retweets of this tweet ID (tweet_search_extractor)
+ results_limit: Maximum number of results to extract. When set, the extraction stops after
+ reaching this limit.
- search_query: Query used to price tweet_search_extractor or community_search.
+ retweets: Retweet mode (tweet_search_extractor)
- since_date: Estimate start date in YYYY-MM-DD format (tweet_search_extractor)
+ retweets_of_tweet_id: Only retweets of this tweet ID (tweet_search_extractor)
- target_community_id: Community ID used to price community_post_extractor or community_search.
+ safe: Enable the safe-search filter.
- target_list_id: List ID used to price list_follower_explorer, list_member_extractor, or
+ scope: Reply depth scope.
+
+ search_queries: Search queries processed as one collection job.
+
+ search_query: Required for tweet_search_extractor & community_search.
+
+ since_date: Start date YYYY-MM-DD (tweet_search_extractor)
+
+ since_id: Return Tweets newer than this Tweet ID.
+
+ since_time: Reply start time as ISO 8601 or Unix seconds.
+
+ sort: Reply result order.
+
+ source: Match the source application.
+
+ start_cursor: Resume one reply target from this cursor.
+
+ target_community_id: Required for community_post_extractor & community_search.
+
+ target_community_ids: Community IDs processed as one collection job.
+
+ target_list_id: Required for list_follower_explorer, list_member_extractor &
list_post_extractor.
- target_space_id: Space ID used to price space_explorer.
+ target_list_ids: List IDs processed as one collection job.
- to_user: Estimate replies sent to this username (tweet_search_extractor)
+ targets: Mixed targets auto-routed within one job.
- until_date: Estimate end date in YYYY-MM-DD format (tweet_search_extractor)
+ target_space_id: Required for space_explorer.
+
+ target_tweet_ids: Tweet IDs processed as one collection job.
- url: URL substring or domain filter used for estimation (tweet_search_extractor)
+ target_usernames: Usernames processed as one collection job.
- verified_only: Estimate only verified authors (tweet_search_extractor)
+ to_user: Filter replies sent to a username (tweet_search_extractor)
+
+ until_date: End date YYYY-MM-DD (tweet_search_extractor)
+
+ until_time: Reply end time as ISO 8601 or Unix seconds.
+
+ url: URL substring or domain filter (tweet_search_extractor)
+
+ username_contains: Required username text.
+
+ verified_only: Only verified authors (tweet_search_extractor)
+
+ verified_type: Exact profile verification type.
+
+ within: Set the radius for the near filter.
+
+ within_time: Match Tweets inside a recent time window.
extra_headers: Send extra headers
@@ -1000,42 +1737,99 @@ async def estimate_cost(
"tool_type": tool_type,
"advanced_query": advanced_query,
"any_words": any_words,
+ "bio_contains": bio_contains,
+ "blue_verified_only": blue_verified_only,
"bounding_box": bounding_box,
+ "card_name": card_name,
"cashtags": cashtags,
+ "collection_strategy": collection_strategy,
"conversation_id": conversation_id,
+ "dedupe_across_targets": dedupe_across_targets,
+ "dedupe_mode": dedupe_mode,
"exact_phrase": exact_phrase,
+ "exclude_original_author": exclude_original_author,
+ "exclude_source": exclude_source,
"exclude_words": exclude_words,
"from_user": from_user,
+ "geocode": geocode,
"hashtags": hashtags,
+ "has_location": has_location,
+ "has_media_only": has_media_only,
+ "has_website": has_website,
+ "include_original_post": include_original_post,
+ "include_search_terms": include_search_terms,
+ "include_target_metadata": include_target_metadata,
"in_reply_to_tweet_id": in_reply_to_tweet_id,
"language": language,
"list_id": list_id,
+ "location_contains": location_contains,
+ "max_depth": max_depth,
+ "max_followers": max_followers,
+ "max_following": max_following,
+ "max_id": max_id,
+ "max_items_per_target": max_items_per_target,
+ "max_likes": max_likes,
+ "max_pages_per_target": max_pages_per_target,
+ "max_posts": max_posts,
+ "max_quotes": max_quotes,
+ "max_replies": max_replies,
+ "max_retweets": max_retweets,
"media_type": media_type,
"mentioning": mentioning,
+ "min_account_age_days": min_account_age_days,
+ "min_bookmarks": min_bookmarks,
"min_faves": min_faves,
+ "min_followers": min_followers,
+ "min_following": min_following,
+ "min_posts": min_posts,
"min_quotes": min_quotes,
"min_replies": min_replies,
"min_retweets": min_retweets,
+ "min_views": min_views,
+ "native_retweets": native_retweets,
+ "near": near,
+ "news": news,
+ "overlap_mode": overlap_mode,
"place": place,
"place_country": place_country,
"point_radius": point_radius,
+ "query_type": query_type,
"quotes": quotes,
"quotes_of_tweet_id": quotes_of_tweet_id,
+ "relation_targets": relation_targets,
"replies": replies,
"results_limit": results_limit,
"retweets": retweets,
"retweets_of_tweet_id": retweets_of_tweet_id,
+ "safe": safe,
+ "scope": scope,
+ "search_queries": search_queries,
"search_query": search_query,
"since_date": since_date,
+ "since_id": since_id,
+ "since_time": since_time,
+ "sort": sort,
+ "source": source,
+ "start_cursor": start_cursor,
"target_community_id": target_community_id,
+ "target_community_ids": target_community_ids,
"target_list_id": target_list_id,
+ "target_list_ids": target_list_ids,
+ "targets": targets,
"target_space_id": target_space_id,
"target_tweet_id": target_tweet_id,
+ "target_tweet_ids": target_tweet_ids,
"target_username": target_username,
+ "target_usernames": target_usernames,
"to_user": to_user,
"until_date": until_date,
+ "until_time": until_time,
"url": url,
+ "username_contains": username_contains,
"verified_only": verified_only,
+ "verified_type": verified_type,
+ "within": within,
+ "within_time": within_time,
},
extraction_estimate_cost_params.ExtractionEstimateCostParams,
),
@@ -1050,6 +1844,24 @@ async def export_results(
id: str,
*,
format: Literal["csv", "json", "md", "md-document", "pdf", "txt", "xlsx"],
+ has_description: bool | Omit = omit,
+ has_location: bool | Omit = omit,
+ has_media: bool | Omit = omit,
+ lang: str | Omit = omit,
+ max_followers: int | Omit = omit,
+ max_following: int | Omit = omit,
+ max_posts: int | Omit = omit,
+ min_followers: int | Omit = omit,
+ min_following: int | Omit = omit,
+ min_likes: int | Omit = omit,
+ min_posts: int | Omit = omit,
+ min_replies: int | Omit = omit,
+ min_retweets: int | Omit = omit,
+ min_views: int | Omit = omit,
+ search: str | Omit = omit,
+ since_date: Union[str, date] | Omit = omit,
+ until_date: Union[str, date] | Omit = omit,
+ verified: bool | Omit = omit,
# Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
# The extra values given here take precedence over values defined on the client or passed to this method.
extra_headers: Headers | None = None,
@@ -1063,6 +1875,42 @@ async def export_results(
Args:
format: Export file format
+ has_description: Require a non-empty description.
+
+ has_location: Require a non-empty location.
+
+ has_media: Require media.
+
+ lang: Filter by language code.
+
+ max_followers: Maximum follower count.
+
+ max_following: Maximum following count.
+
+ max_posts: Maximum post count.
+
+ min_followers: Minimum follower count.
+
+ min_following: Minimum following count.
+
+ min_likes: Minimum like count.
+
+ min_posts: Minimum post count.
+
+ min_replies: Minimum reply count.
+
+ min_retweets: Minimum repost count.
+
+ min_views: Minimum view count.
+
+ search: Search exported result text.
+
+ since_date: Include results on or after this date.
+
+ until_date: Include results on or before this date.
+
+ verified: Filter by verified status.
+
extra_headers: Send extra headers
extra_query: Add additional query parameters to the request
@@ -1082,7 +1930,28 @@ async def export_results(
extra_body=extra_body,
timeout=timeout,
query=await async_maybe_transform(
- {"format": format}, extraction_export_results_params.ExtractionExportResultsParams
+ {
+ "format": format,
+ "has_description": has_description,
+ "has_location": has_location,
+ "has_media": has_media,
+ "lang": lang,
+ "max_followers": max_followers,
+ "max_following": max_following,
+ "max_posts": max_posts,
+ "min_followers": min_followers,
+ "min_following": min_following,
+ "min_likes": min_likes,
+ "min_posts": min_posts,
+ "min_replies": min_replies,
+ "min_retweets": min_retweets,
+ "min_views": min_views,
+ "search": search,
+ "since_date": since_date,
+ "until_date": until_date,
+ "verified": verified,
+ },
+ extraction_export_results_params.ExtractionExportResultsParams,
),
),
cast_to=AsyncBinaryAPIResponse,
@@ -1116,44 +1985,102 @@ async def run(
"user_media",
"verified_follower_explorer",
],
+ dry_run: bool | Omit = omit,
advanced_query: str | Omit = omit,
any_words: str | Omit = omit,
+ bio_contains: str | Omit = omit,
+ blue_verified_only: bool | Omit = omit,
bounding_box: str | Omit = omit,
+ card_name: str | Omit = omit,
cashtags: str | Omit = omit,
+ collection_strategy: Literal["auto", "complete", "direct", "search", "thread"] | Omit = omit,
conversation_id: str | Omit = omit,
+ dedupe_across_targets: bool | Omit = omit,
+ dedupe_mode: Literal["none", "first", "merge"] | Omit = omit,
exact_phrase: str | Omit = omit,
+ exclude_original_author: bool | Omit = omit,
+ exclude_source: str | Omit = omit,
exclude_words: str | Omit = omit,
from_user: str | Omit = omit,
+ geocode: str | Omit = omit,
hashtags: str | Omit = omit,
+ has_location: bool | Omit = omit,
+ has_media_only: bool | Omit = omit,
+ has_website: bool | Omit = omit,
+ include_original_post: bool | Omit = omit,
+ include_search_terms: bool | Omit = omit,
+ include_target_metadata: bool | Omit = omit,
in_reply_to_tweet_id: str | Omit = omit,
language: str | Omit = omit,
list_id: str | Omit = omit,
+ location_contains: str | Omit = omit,
+ max_depth: int | Omit = omit,
+ max_followers: int | Omit = omit,
+ max_following: int | Omit = omit,
+ max_id: str | Omit = omit,
+ max_items_per_target: int | Omit = omit,
+ max_likes: int | Omit = omit,
+ max_pages_per_target: int | Omit = omit,
+ max_posts: int | Omit = omit,
+ max_quotes: int | Omit = omit,
+ max_replies: int | Omit = omit,
+ max_retweets: int | Omit = omit,
media_type: Literal["images", "videos", "gifs", "media", "links", "none"] | Omit = omit,
mentioning: str | Omit = omit,
+ min_account_age_days: int | Omit = omit,
+ min_bookmarks: int | Omit = omit,
min_faves: int | Omit = omit,
+ min_followers: int | Omit = omit,
+ min_following: int | Omit = omit,
+ min_posts: int | Omit = omit,
min_quotes: int | Omit = omit,
min_replies: int | Omit = omit,
min_retweets: int | Omit = omit,
+ min_views: int | Omit = omit,
+ native_retweets: bool | Omit = omit,
+ near: str | Omit = omit,
+ news: bool | Omit = omit,
+ overlap_mode: bool | Omit = omit,
place: str | Omit = omit,
place_country: str | Omit = omit,
point_radius: str | Omit = omit,
+ query_type: Literal["Latest", "Top", "Both"] | Omit = omit,
quotes: Literal["include", "exclude", "only"] | Omit = omit,
quotes_of_tweet_id: str | Omit = omit,
+ relation_targets: Iterable[extraction_run_params.RelationTarget] | Omit = omit,
replies: Literal["include", "exclude", "only"] | Omit = omit,
results_limit: int | Omit = omit,
retweets: Literal["include", "exclude", "only"] | Omit = omit,
retweets_of_tweet_id: str | Omit = omit,
+ safe: bool | Omit = omit,
+ scope: Literal["all", "direct", "nested"] | Omit = omit,
+ search_queries: SequenceNotStr[str] | Omit = omit,
search_query: str | Omit = omit,
since_date: Union[str, date] | Omit = omit,
+ since_id: str | Omit = omit,
+ since_time: Union[Union[str, datetime], int] | Omit = omit,
+ sort: Literal["relevance", "latest", "oldest", "likes"] | Omit = omit,
+ source: str | Omit = omit,
+ start_cursor: str | Omit = omit,
target_community_id: str | Omit = omit,
+ target_community_ids: SequenceNotStr[str] | Omit = omit,
target_list_id: str | Omit = omit,
+ target_list_ids: SequenceNotStr[str] | Omit = omit,
+ targets: SequenceNotStr[extraction_run_params.Target] | Omit = omit,
target_space_id: str | Omit = omit,
target_tweet_id: str | Omit = omit,
+ target_tweet_ids: SequenceNotStr[str] | Omit = omit,
target_username: str | Omit = omit,
+ target_usernames: SequenceNotStr[str] | Omit = omit,
to_user: str | Omit = omit,
until_date: Union[str, date] | Omit = omit,
+ until_time: Union[Union[str, datetime], int] | Omit = omit,
url: str | Omit = omit,
+ username_contains: str | Omit = omit,
verified_only: bool | Omit = omit,
+ verified_type: str | Omit = omit,
+ within: str | Omit = omit,
+ within_time: str | Omit = omit,
# Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
# The extra values given here take precedence over values defined on the client or passed to this method.
extra_headers: Headers | None = None,
@@ -1167,54 +2094,134 @@ async def run(
Args:
tool_type: Identifier for the extraction tool used to run a job.
+ dry_run: Estimate cost without creating an extraction.
+
advanced_query: Raw advanced search query appended as-is (tweet_search_extractor)
any_words: Words or quoted phrases where any one can match. Separate with spaces, commas,
or lines. (tweet_search_extractor)
+ bio_contains: Bio terms separated by commas or lines.
+
+ blue_verified_only: Return only Blue-verified Tweet authors.
+
bounding_box: Geo bounding box, e.g. -74.1 40.6 -73.9 40.8 (tweet_search_extractor)
+ card_name: Match the Tweet card name.
+
cashtags: Cashtags separated by spaces, commas, or lines. (tweet_search_extractor)
+ collection_strategy: Reply collection strategy.
+
conversation_id: Conversation ID filter (tweet_search_extractor)
+ dedupe_across_targets: Merge duplicate results across collection targets.
+
+ dedupe_mode: Keep target duplicates, first rows, or merged overlap.
+
exact_phrase: Exact phrase to match (tweet_search_extractor)
+ exclude_original_author: Exclude replies from the source author.
+
+ exclude_source: Exclude a source application.
+
exclude_words: Words or quoted phrases to exclude. Separate with spaces, commas, or lines.
(tweet_search_extractor)
from_user: Filter by author username (tweet_search_extractor)
+ geocode: Match latitude, longitude, and radius.
+
hashtags: Hashtags separated by spaces, commas, or lines. (tweet_search_extractor)
+ has_location: Require a profile location.
+
+ has_media_only: Return only replies with media.
+
+ has_website: Require a profile website.
+
+ include_original_post: Include the source post in reply results.
+
+ include_search_terms: Add matching search terms to collection metadata.
+
+ include_target_metadata: Add source target metadata to each result.
+
in_reply_to_tweet_id: Only replies to this tweet ID (tweet_search_extractor)
language: Language code filter (tweet_search_extractor)
list_id: Search within a list ID (tweet_search_extractor)
+ location_contains: Required profile location text.
+
+ max_depth: Maximum nested reply depth.
+
+ max_followers: Maximum follower count for profile results.
+
+ max_following: Maximum following count for profile results.
+
+ max_id: Return Tweets older than this Tweet ID.
+
+ max_items_per_target: Maximum results collected for each target.
+
+ max_likes: Maximum Tweet like count.
+
+ max_pages_per_target: Reply pages collected for each target.
+
+ max_posts: Maximum post count for profile results.
+
+ max_quotes: Maximum Tweet quote count.
+
+ max_replies: Maximum Tweet reply count.
+
+ max_retweets: Maximum Tweet repost count.
+
media_type: Media type filter (tweet_search_extractor)
mentioning: Filter tweets mentioning a username (tweet_search_extractor)
+ min_account_age_days: Minimum profile age in days.
+
+ min_bookmarks: Minimum Tweet bookmark count.
+
min_faves: Minimum likes threshold (tweet_search_extractor)
+ min_followers: Minimum follower count for profile results.
+
+ min_following: Minimum following count for profile results.
+
+ min_posts: Minimum post count for profile results.
+
min_quotes: Minimum quote count threshold (tweet_search_extractor)
min_replies: Minimum replies threshold (tweet_search_extractor)
min_retweets: Minimum retweets threshold (tweet_search_extractor)
+ min_views: Minimum Tweet view count.
+
+ native_retweets: Only return native reposts.
+
+ near: Match a place name.
+
+ news: Only return news results.
+
+ overlap_mode: Shortcut for dedupeMode=merge.
+
place: Search within a place ID (tweet_search_extractor)
place_country: Search within a country code (tweet_search_extractor)
point_radius: Geo point radius, e.g. -73.99 40.73 25mi (tweet_search_extractor)
+ query_type: Search ranking applied to every query.
+
quotes: Quote mode (tweet_search_extractor)
quotes_of_tweet_id: Only quotes of this tweet ID (tweet_search_extractor)
+ relation_targets: Profile relations processed within one job.
+
replies: Reply mode (tweet_search_extractor)
results_limit: Maximum number of results to extract. When set, the extraction stops after
@@ -1224,25 +2231,61 @@ async def run(
retweets_of_tweet_id: Only retweets of this tweet ID (tweet_search_extractor)
+ safe: Enable the safe-search filter.
+
+ scope: Reply depth scope.
+
+ search_queries: Search queries processed as one collection job.
+
search_query: Required for tweet_search_extractor & community_search.
since_date: Start date YYYY-MM-DD (tweet_search_extractor)
+ since_id: Return Tweets newer than this Tweet ID.
+
+ since_time: Reply start time as ISO 8601 or Unix seconds.
+
+ sort: Reply result order.
+
+ source: Match the source application.
+
+ start_cursor: Resume one reply target from this cursor.
+
target_community_id: Required for community_post_extractor & community_search.
+ target_community_ids: Community IDs processed as one collection job.
+
target_list_id: Required for list_follower_explorer, list_member_extractor &
list_post_extractor.
+ target_list_ids: List IDs processed as one collection job.
+
+ targets: Mixed targets auto-routed within one job.
+
target_space_id: Required for space_explorer.
+ target_tweet_ids: Tweet IDs processed as one collection job.
+
+ target_usernames: Usernames processed as one collection job.
+
to_user: Filter replies sent to a username (tweet_search_extractor)
until_date: End date YYYY-MM-DD (tweet_search_extractor)
+ until_time: Reply end time as ISO 8601 or Unix seconds.
+
url: URL substring or domain filter (tweet_search_extractor)
+ username_contains: Required username text.
+
verified_only: Only verified authors (tweet_search_extractor)
+ verified_type: Exact profile verification type.
+
+ within: Set the radius for the near filter.
+
+ within_time: Match Tweets inside a recent time window.
+
extra_headers: Send extra headers
extra_query: Add additional query parameters to the request
@@ -1258,47 +2301,108 @@ async def run(
"tool_type": tool_type,
"advanced_query": advanced_query,
"any_words": any_words,
+ "bio_contains": bio_contains,
+ "blue_verified_only": blue_verified_only,
"bounding_box": bounding_box,
+ "card_name": card_name,
"cashtags": cashtags,
+ "collection_strategy": collection_strategy,
"conversation_id": conversation_id,
+ "dedupe_across_targets": dedupe_across_targets,
+ "dedupe_mode": dedupe_mode,
"exact_phrase": exact_phrase,
+ "exclude_original_author": exclude_original_author,
+ "exclude_source": exclude_source,
"exclude_words": exclude_words,
"from_user": from_user,
+ "geocode": geocode,
"hashtags": hashtags,
+ "has_location": has_location,
+ "has_media_only": has_media_only,
+ "has_website": has_website,
+ "include_original_post": include_original_post,
+ "include_search_terms": include_search_terms,
+ "include_target_metadata": include_target_metadata,
"in_reply_to_tweet_id": in_reply_to_tweet_id,
"language": language,
"list_id": list_id,
+ "location_contains": location_contains,
+ "max_depth": max_depth,
+ "max_followers": max_followers,
+ "max_following": max_following,
+ "max_id": max_id,
+ "max_items_per_target": max_items_per_target,
+ "max_likes": max_likes,
+ "max_pages_per_target": max_pages_per_target,
+ "max_posts": max_posts,
+ "max_quotes": max_quotes,
+ "max_replies": max_replies,
+ "max_retweets": max_retweets,
"media_type": media_type,
"mentioning": mentioning,
+ "min_account_age_days": min_account_age_days,
+ "min_bookmarks": min_bookmarks,
"min_faves": min_faves,
+ "min_followers": min_followers,
+ "min_following": min_following,
+ "min_posts": min_posts,
"min_quotes": min_quotes,
"min_replies": min_replies,
"min_retweets": min_retweets,
+ "min_views": min_views,
+ "native_retweets": native_retweets,
+ "near": near,
+ "news": news,
+ "overlap_mode": overlap_mode,
"place": place,
"place_country": place_country,
"point_radius": point_radius,
+ "query_type": query_type,
"quotes": quotes,
"quotes_of_tweet_id": quotes_of_tweet_id,
+ "relation_targets": relation_targets,
"replies": replies,
"results_limit": results_limit,
"retweets": retweets,
"retweets_of_tweet_id": retweets_of_tweet_id,
+ "safe": safe,
+ "scope": scope,
+ "search_queries": search_queries,
"search_query": search_query,
"since_date": since_date,
+ "since_id": since_id,
+ "since_time": since_time,
+ "sort": sort,
+ "source": source,
+ "start_cursor": start_cursor,
"target_community_id": target_community_id,
+ "target_community_ids": target_community_ids,
"target_list_id": target_list_id,
+ "target_list_ids": target_list_ids,
+ "targets": targets,
"target_space_id": target_space_id,
"target_tweet_id": target_tweet_id,
+ "target_tweet_ids": target_tweet_ids,
"target_username": target_username,
+ "target_usernames": target_usernames,
"to_user": to_user,
"until_date": until_date,
+ "until_time": until_time,
"url": url,
+ "username_contains": username_contains,
"verified_only": verified_only,
+ "verified_type": verified_type,
+ "within": within,
+ "within_time": within_time,
},
extraction_run_params.ExtractionRunParams,
),
options=make_request_options(
- extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
+ extra_headers=extra_headers,
+ extra_query=extra_query,
+ extra_body=extra_body,
+ timeout=timeout,
+ query=await async_maybe_transform({"dry_run": dry_run}, extraction_run_params.ExtractionRunParams),
),
cast_to=ExtractionRunResponse,
)
diff --git a/src/x_twitter_scraper/resources/support/__init__.py b/src/x_twitter_scraper/resources/support/__init__.py
index 9846ab2..32241fc 100644
--- a/src/x_twitter_scraper/resources/support/__init__.py
+++ b/src/x_twitter_scraper/resources/support/__init__.py
@@ -20,8 +20,22 @@
TicketsResourceWithStreamingResponse,
AsyncTicketsResourceWithStreamingResponse,
)
+from .attachments import (
+ AttachmentsResource,
+ AsyncAttachmentsResource,
+ AttachmentsResourceWithRawResponse,
+ AsyncAttachmentsResourceWithRawResponse,
+ AttachmentsResourceWithStreamingResponse,
+ AsyncAttachmentsResourceWithStreamingResponse,
+)
__all__ = [
+ "AttachmentsResource",
+ "AsyncAttachmentsResource",
+ "AttachmentsResourceWithRawResponse",
+ "AsyncAttachmentsResourceWithRawResponse",
+ "AttachmentsResourceWithStreamingResponse",
+ "AsyncAttachmentsResourceWithStreamingResponse",
"TicketsResource",
"AsyncTicketsResource",
"TicketsResourceWithRawResponse",
diff --git a/src/x_twitter_scraper/resources/support/attachments.py b/src/x_twitter_scraper/resources/support/attachments.py
new file mode 100644
index 0000000..5289638
--- /dev/null
+++ b/src/x_twitter_scraper/resources/support/attachments.py
@@ -0,0 +1,185 @@
+# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+from __future__ import annotations
+
+import httpx
+
+from ..._types import Body, Omit, Query, Headers, NotGiven, omit, not_given
+from ..._utils import path_template, strip_not_given
+from ..._compat import cached_property
+from ..._resource import SyncAPIResource, AsyncAPIResource
+from ..._response import (
+ BinaryAPIResponse,
+ AsyncBinaryAPIResponse,
+ StreamedBinaryAPIResponse,
+ AsyncStreamedBinaryAPIResponse,
+ to_custom_raw_response_wrapper,
+ to_custom_streamed_response_wrapper,
+ async_to_custom_raw_response_wrapper,
+ async_to_custom_streamed_response_wrapper,
+)
+from ..._base_client import make_request_options
+
+__all__ = ["AttachmentsResource", "AsyncAttachmentsResource"]
+
+
+class AttachmentsResource(SyncAPIResource):
+ """Support ticket management"""
+
+ @cached_property
+ def with_raw_response(self) -> AttachmentsResourceWithRawResponse:
+ """
+ This property can be used as a prefix for any HTTP method call to return
+ the raw response object instead of the parsed content.
+
+ For more information, see https://www.github.com/Xquik-dev/x-twitter-scraper-python#accessing-raw-response-data-eg-headers
+ """
+ return AttachmentsResourceWithRawResponse(self)
+
+ @cached_property
+ def with_streaming_response(self) -> AttachmentsResourceWithStreamingResponse:
+ """
+ An alternative to `.with_raw_response` that doesn't eagerly read the response body.
+
+ For more information, see https://www.github.com/Xquik-dev/x-twitter-scraper-python#with_streaming_response
+ """
+ return AttachmentsResourceWithStreamingResponse(self)
+
+ def download(
+ self,
+ id: str,
+ *,
+ range: str | Omit = omit,
+ # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
+ # The extra values given here take precedence over values defined on the client or passed to this method.
+ extra_headers: Headers | None = None,
+ extra_query: Query | None = None,
+ extra_body: Body | None = None,
+ timeout: float | httpx.Timeout | None | NotGiven = not_given,
+ ) -> BinaryAPIResponse:
+ """Streams an authenticated user's support image or video.
+
+ Video requests support
+ one standard byte range for seeking and resumable playback.
+
+ Args:
+ extra_headers: Send extra headers
+
+ extra_query: Add additional query parameters to the request
+
+ extra_body: Add additional JSON properties to the request
+
+ timeout: Override the client-level default timeout for this request, in seconds
+ """
+ if not id:
+ raise ValueError(f"Expected a non-empty value for `id` but received {id!r}")
+ extra_headers = {"Accept": "application/octet-stream", **(extra_headers or {})}
+ extra_headers = {**strip_not_given({"Range": range}), **(extra_headers or {})}
+ return self._get(
+ path_template("/support/attachments/{id}", id=id),
+ options=make_request_options(
+ extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
+ ),
+ cast_to=BinaryAPIResponse,
+ )
+
+
+class AsyncAttachmentsResource(AsyncAPIResource):
+ """Support ticket management"""
+
+ @cached_property
+ def with_raw_response(self) -> AsyncAttachmentsResourceWithRawResponse:
+ """
+ This property can be used as a prefix for any HTTP method call to return
+ the raw response object instead of the parsed content.
+
+ For more information, see https://www.github.com/Xquik-dev/x-twitter-scraper-python#accessing-raw-response-data-eg-headers
+ """
+ return AsyncAttachmentsResourceWithRawResponse(self)
+
+ @cached_property
+ def with_streaming_response(self) -> AsyncAttachmentsResourceWithStreamingResponse:
+ """
+ An alternative to `.with_raw_response` that doesn't eagerly read the response body.
+
+ For more information, see https://www.github.com/Xquik-dev/x-twitter-scraper-python#with_streaming_response
+ """
+ return AsyncAttachmentsResourceWithStreamingResponse(self)
+
+ async def download(
+ self,
+ id: str,
+ *,
+ range: str | Omit = omit,
+ # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
+ # The extra values given here take precedence over values defined on the client or passed to this method.
+ extra_headers: Headers | None = None,
+ extra_query: Query | None = None,
+ extra_body: Body | None = None,
+ timeout: float | httpx.Timeout | None | NotGiven = not_given,
+ ) -> AsyncBinaryAPIResponse:
+ """Streams an authenticated user's support image or video.
+
+ Video requests support
+ one standard byte range for seeking and resumable playback.
+
+ Args:
+ extra_headers: Send extra headers
+
+ extra_query: Add additional query parameters to the request
+
+ extra_body: Add additional JSON properties to the request
+
+ timeout: Override the client-level default timeout for this request, in seconds
+ """
+ if not id:
+ raise ValueError(f"Expected a non-empty value for `id` but received {id!r}")
+ extra_headers = {"Accept": "application/octet-stream", **(extra_headers or {})}
+ extra_headers = {**strip_not_given({"Range": range}), **(extra_headers or {})}
+ return await self._get(
+ path_template("/support/attachments/{id}", id=id),
+ options=make_request_options(
+ extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
+ ),
+ cast_to=AsyncBinaryAPIResponse,
+ )
+
+
+class AttachmentsResourceWithRawResponse:
+ def __init__(self, attachments: AttachmentsResource) -> None:
+ self._attachments = attachments
+
+ self.download = to_custom_raw_response_wrapper(
+ attachments.download,
+ BinaryAPIResponse,
+ )
+
+
+class AsyncAttachmentsResourceWithRawResponse:
+ def __init__(self, attachments: AsyncAttachmentsResource) -> None:
+ self._attachments = attachments
+
+ self.download = async_to_custom_raw_response_wrapper(
+ attachments.download,
+ AsyncBinaryAPIResponse,
+ )
+
+
+class AttachmentsResourceWithStreamingResponse:
+ def __init__(self, attachments: AttachmentsResource) -> None:
+ self._attachments = attachments
+
+ self.download = to_custom_streamed_response_wrapper(
+ attachments.download,
+ StreamedBinaryAPIResponse,
+ )
+
+
+class AsyncAttachmentsResourceWithStreamingResponse:
+ def __init__(self, attachments: AsyncAttachmentsResource) -> None:
+ self._attachments = attachments
+
+ self.download = async_to_custom_streamed_response_wrapper(
+ attachments.download,
+ AsyncStreamedBinaryAPIResponse,
+ )
diff --git a/src/x_twitter_scraper/resources/support/support.py b/src/x_twitter_scraper/resources/support/support.py
index c5a3feb..895dac2 100644
--- a/src/x_twitter_scraper/resources/support/support.py
+++ b/src/x_twitter_scraper/resources/support/support.py
@@ -16,11 +16,24 @@
)
from ..._compat import cached_property
from ..._resource import SyncAPIResource, AsyncAPIResource
+from .attachments import (
+ AttachmentsResource,
+ AsyncAttachmentsResource,
+ AttachmentsResourceWithRawResponse,
+ AsyncAttachmentsResourceWithRawResponse,
+ AttachmentsResourceWithStreamingResponse,
+ AsyncAttachmentsResourceWithStreamingResponse,
+)
__all__ = ["SupportResource", "AsyncSupportResource"]
class SupportResource(SyncAPIResource):
+ @cached_property
+ def attachments(self) -> AttachmentsResource:
+ """Support ticket management"""
+ return AttachmentsResource(self._client)
+
@cached_property
def tickets(self) -> TicketsResource:
"""Support ticket management"""
@@ -47,6 +60,11 @@ def with_streaming_response(self) -> SupportResourceWithStreamingResponse:
class AsyncSupportResource(AsyncAPIResource):
+ @cached_property
+ def attachments(self) -> AsyncAttachmentsResource:
+ """Support ticket management"""
+ return AsyncAttachmentsResource(self._client)
+
@cached_property
def tickets(self) -> AsyncTicketsResource:
"""Support ticket management"""
@@ -76,6 +94,11 @@ class SupportResourceWithRawResponse:
def __init__(self, support: SupportResource) -> None:
self._support = support
+ @cached_property
+ def attachments(self) -> AttachmentsResourceWithRawResponse:
+ """Support ticket management"""
+ return AttachmentsResourceWithRawResponse(self._support.attachments)
+
@cached_property
def tickets(self) -> TicketsResourceWithRawResponse:
"""Support ticket management"""
@@ -86,6 +109,11 @@ class AsyncSupportResourceWithRawResponse:
def __init__(self, support: AsyncSupportResource) -> None:
self._support = support
+ @cached_property
+ def attachments(self) -> AsyncAttachmentsResourceWithRawResponse:
+ """Support ticket management"""
+ return AsyncAttachmentsResourceWithRawResponse(self._support.attachments)
+
@cached_property
def tickets(self) -> AsyncTicketsResourceWithRawResponse:
"""Support ticket management"""
@@ -96,6 +124,11 @@ class SupportResourceWithStreamingResponse:
def __init__(self, support: SupportResource) -> None:
self._support = support
+ @cached_property
+ def attachments(self) -> AttachmentsResourceWithStreamingResponse:
+ """Support ticket management"""
+ return AttachmentsResourceWithStreamingResponse(self._support.attachments)
+
@cached_property
def tickets(self) -> TicketsResourceWithStreamingResponse:
"""Support ticket management"""
@@ -106,6 +139,11 @@ class AsyncSupportResourceWithStreamingResponse:
def __init__(self, support: AsyncSupportResource) -> None:
self._support = support
+ @cached_property
+ def attachments(self) -> AsyncAttachmentsResourceWithStreamingResponse:
+ """Support ticket management"""
+ return AsyncAttachmentsResourceWithStreamingResponse(self._support.attachments)
+
@cached_property
def tickets(self) -> AsyncTicketsResourceWithStreamingResponse:
"""Support ticket management"""
diff --git a/src/x_twitter_scraper/resources/x/communities/communities.py b/src/x_twitter_scraper/resources/x/communities/communities.py
index 60ee7f8..fd22ae6 100644
--- a/src/x_twitter_scraper/resources/x/communities/communities.py
+++ b/src/x_twitter_scraper/resources/x/communities/communities.py
@@ -217,8 +217,22 @@ def retrieve_members(
self,
id: str,
*,
+ bio_contains: str | Omit = omit,
cursor: str | Omit = omit,
+ has_location: bool | Omit = omit,
+ has_website: bool | Omit = omit,
+ location_contains: str | Omit = omit,
+ max_followers: int | Omit = omit,
+ max_following: int | Omit = omit,
+ max_statuses: int | Omit = omit,
+ min_account_age_days: int | Omit = omit,
+ min_followers: int | Omit = omit,
+ min_following: int | Omit = omit,
+ min_statuses: int | Omit = omit,
page_size: int | Omit = omit,
+ username_contains: str | Omit = omit,
+ verified_only: bool | Omit = omit,
+ verified_type: str | Omit = omit,
# Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
# The extra values given here take precedence over values defined on the client or passed to this method.
extra_headers: Headers | None = None,
@@ -230,12 +244,40 @@ def retrieve_members(
List members of a community
Args:
+ bio_contains: Match any comma-separated or line-separated bio term, ignoring case.
+
cursor: Pagination cursor
+ has_location: Only return profiles with a location.
+
+ has_website: Only return profiles with a website.
+
+ location_contains: Match a location substring, ignoring case.
+
+ max_followers: Maximum follower count. Missing counts pass this maximum.
+
+ max_following: Maximum following count.
+
+ max_statuses: Maximum post count. maxPosts is also accepted.
+
+ min_account_age_days: Minimum account age in whole days.
+
+ min_followers: Minimum follower count. Filtering happens before billing.
+
+ min_following: Minimum following count.
+
+ min_statuses: Minimum post count. minPosts is also accepted.
+
page_size: Items per page (20-200, default 20). This is an upper bound for paid
authenticated calls: remaining credits can reduce the returned page size, and
zero affordable results returns 402 insufficient_credits.
+ username_contains: Match a username substring, ignoring case.
+
+ verified_only: Only return verified profiles.
+
+ verified_type: Match the verification type exactly, ignoring case.
+
extra_headers: Send extra headers
extra_query: Add additional query parameters to the request
@@ -255,8 +297,22 @@ def retrieve_members(
timeout=timeout,
query=maybe_transform(
{
+ "bio_contains": bio_contains,
"cursor": cursor,
+ "has_location": has_location,
+ "has_website": has_website,
+ "location_contains": location_contains,
+ "max_followers": max_followers,
+ "max_following": max_following,
+ "max_statuses": max_statuses,
+ "min_account_age_days": min_account_age_days,
+ "min_followers": min_followers,
+ "min_following": min_following,
+ "min_statuses": min_statuses,
"page_size": page_size,
+ "username_contains": username_contains,
+ "verified_only": verified_only,
+ "verified_type": verified_type,
},
community_retrieve_members_params.CommunityRetrieveMembersParams,
),
@@ -268,7 +324,21 @@ def retrieve_moderators(
self,
id: str,
*,
+ bio_contains: str | Omit = omit,
cursor: str | Omit = omit,
+ has_location: bool | Omit = omit,
+ has_website: bool | Omit = omit,
+ location_contains: str | Omit = omit,
+ max_followers: int | Omit = omit,
+ max_following: int | Omit = omit,
+ max_statuses: int | Omit = omit,
+ min_account_age_days: int | Omit = omit,
+ min_followers: int | Omit = omit,
+ min_following: int | Omit = omit,
+ min_statuses: int | Omit = omit,
+ username_contains: str | Omit = omit,
+ verified_only: bool | Omit = omit,
+ verified_type: str | Omit = omit,
# Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
# The extra values given here take precedence over values defined on the client or passed to this method.
extra_headers: Headers | None = None,
@@ -280,8 +350,36 @@ def retrieve_moderators(
List moderators of a community
Args:
+ bio_contains: Match any comma-separated or line-separated bio term, ignoring case.
+
cursor: Pagination cursor for community moderators
+ has_location: Only return profiles with a location.
+
+ has_website: Only return profiles with a website.
+
+ location_contains: Match a location substring, ignoring case.
+
+ max_followers: Maximum follower count. Missing counts pass this maximum.
+
+ max_following: Maximum following count.
+
+ max_statuses: Maximum post count. maxPosts is also accepted.
+
+ min_account_age_days: Minimum account age in whole days.
+
+ min_followers: Minimum follower count. Filtering happens before billing.
+
+ min_following: Minimum following count.
+
+ min_statuses: Minimum post count. minPosts is also accepted.
+
+ username_contains: Match a username substring, ignoring case.
+
+ verified_only: Only return verified profiles.
+
+ verified_type: Match the verification type exactly, ignoring case.
+
extra_headers: Send extra headers
extra_query: Add additional query parameters to the request
@@ -300,7 +398,24 @@ def retrieve_moderators(
extra_body=extra_body,
timeout=timeout,
query=maybe_transform(
- {"cursor": cursor}, community_retrieve_moderators_params.CommunityRetrieveModeratorsParams
+ {
+ "bio_contains": bio_contains,
+ "cursor": cursor,
+ "has_location": has_location,
+ "has_website": has_website,
+ "location_contains": location_contains,
+ "max_followers": max_followers,
+ "max_following": max_following,
+ "max_statuses": max_statuses,
+ "min_account_age_days": min_account_age_days,
+ "min_followers": min_followers,
+ "min_following": min_following,
+ "min_statuses": min_statuses,
+ "username_contains": username_contains,
+ "verified_only": verified_only,
+ "verified_type": verified_type,
+ },
+ community_retrieve_moderators_params.CommunityRetrieveModeratorsParams,
),
),
cast_to=PaginatedUsers,
@@ -532,8 +647,22 @@ async def retrieve_members(
self,
id: str,
*,
+ bio_contains: str | Omit = omit,
cursor: str | Omit = omit,
+ has_location: bool | Omit = omit,
+ has_website: bool | Omit = omit,
+ location_contains: str | Omit = omit,
+ max_followers: int | Omit = omit,
+ max_following: int | Omit = omit,
+ max_statuses: int | Omit = omit,
+ min_account_age_days: int | Omit = omit,
+ min_followers: int | Omit = omit,
+ min_following: int | Omit = omit,
+ min_statuses: int | Omit = omit,
page_size: int | Omit = omit,
+ username_contains: str | Omit = omit,
+ verified_only: bool | Omit = omit,
+ verified_type: str | Omit = omit,
# Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
# The extra values given here take precedence over values defined on the client or passed to this method.
extra_headers: Headers | None = None,
@@ -545,12 +674,40 @@ async def retrieve_members(
List members of a community
Args:
+ bio_contains: Match any comma-separated or line-separated bio term, ignoring case.
+
cursor: Pagination cursor
+ has_location: Only return profiles with a location.
+
+ has_website: Only return profiles with a website.
+
+ location_contains: Match a location substring, ignoring case.
+
+ max_followers: Maximum follower count. Missing counts pass this maximum.
+
+ max_following: Maximum following count.
+
+ max_statuses: Maximum post count. maxPosts is also accepted.
+
+ min_account_age_days: Minimum account age in whole days.
+
+ min_followers: Minimum follower count. Filtering happens before billing.
+
+ min_following: Minimum following count.
+
+ min_statuses: Minimum post count. minPosts is also accepted.
+
page_size: Items per page (20-200, default 20). This is an upper bound for paid
authenticated calls: remaining credits can reduce the returned page size, and
zero affordable results returns 402 insufficient_credits.
+ username_contains: Match a username substring, ignoring case.
+
+ verified_only: Only return verified profiles.
+
+ verified_type: Match the verification type exactly, ignoring case.
+
extra_headers: Send extra headers
extra_query: Add additional query parameters to the request
@@ -570,8 +727,22 @@ async def retrieve_members(
timeout=timeout,
query=await async_maybe_transform(
{
+ "bio_contains": bio_contains,
"cursor": cursor,
+ "has_location": has_location,
+ "has_website": has_website,
+ "location_contains": location_contains,
+ "max_followers": max_followers,
+ "max_following": max_following,
+ "max_statuses": max_statuses,
+ "min_account_age_days": min_account_age_days,
+ "min_followers": min_followers,
+ "min_following": min_following,
+ "min_statuses": min_statuses,
"page_size": page_size,
+ "username_contains": username_contains,
+ "verified_only": verified_only,
+ "verified_type": verified_type,
},
community_retrieve_members_params.CommunityRetrieveMembersParams,
),
@@ -583,7 +754,21 @@ async def retrieve_moderators(
self,
id: str,
*,
+ bio_contains: str | Omit = omit,
cursor: str | Omit = omit,
+ has_location: bool | Omit = omit,
+ has_website: bool | Omit = omit,
+ location_contains: str | Omit = omit,
+ max_followers: int | Omit = omit,
+ max_following: int | Omit = omit,
+ max_statuses: int | Omit = omit,
+ min_account_age_days: int | Omit = omit,
+ min_followers: int | Omit = omit,
+ min_following: int | Omit = omit,
+ min_statuses: int | Omit = omit,
+ username_contains: str | Omit = omit,
+ verified_only: bool | Omit = omit,
+ verified_type: str | Omit = omit,
# Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
# The extra values given here take precedence over values defined on the client or passed to this method.
extra_headers: Headers | None = None,
@@ -595,8 +780,36 @@ async def retrieve_moderators(
List moderators of a community
Args:
+ bio_contains: Match any comma-separated or line-separated bio term, ignoring case.
+
cursor: Pagination cursor for community moderators
+ has_location: Only return profiles with a location.
+
+ has_website: Only return profiles with a website.
+
+ location_contains: Match a location substring, ignoring case.
+
+ max_followers: Maximum follower count. Missing counts pass this maximum.
+
+ max_following: Maximum following count.
+
+ max_statuses: Maximum post count. maxPosts is also accepted.
+
+ min_account_age_days: Minimum account age in whole days.
+
+ min_followers: Minimum follower count. Filtering happens before billing.
+
+ min_following: Minimum following count.
+
+ min_statuses: Minimum post count. minPosts is also accepted.
+
+ username_contains: Match a username substring, ignoring case.
+
+ verified_only: Only return verified profiles.
+
+ verified_type: Match the verification type exactly, ignoring case.
+
extra_headers: Send extra headers
extra_query: Add additional query parameters to the request
@@ -615,7 +828,24 @@ async def retrieve_moderators(
extra_body=extra_body,
timeout=timeout,
query=await async_maybe_transform(
- {"cursor": cursor}, community_retrieve_moderators_params.CommunityRetrieveModeratorsParams
+ {
+ "bio_contains": bio_contains,
+ "cursor": cursor,
+ "has_location": has_location,
+ "has_website": has_website,
+ "location_contains": location_contains,
+ "max_followers": max_followers,
+ "max_following": max_following,
+ "max_statuses": max_statuses,
+ "min_account_age_days": min_account_age_days,
+ "min_followers": min_followers,
+ "min_following": min_following,
+ "min_statuses": min_statuses,
+ "username_contains": username_contains,
+ "verified_only": verified_only,
+ "verified_type": verified_type,
+ },
+ community_retrieve_moderators_params.CommunityRetrieveModeratorsParams,
),
),
cast_to=PaginatedUsers,
diff --git a/src/x_twitter_scraper/resources/x/lists.py b/src/x_twitter_scraper/resources/x/lists.py
index a3454d3..f2042af 100644
--- a/src/x_twitter_scraper/resources/x/lists.py
+++ b/src/x_twitter_scraper/resources/x/lists.py
@@ -52,8 +52,22 @@ def retrieve_followers(
self,
id: str,
*,
+ bio_contains: str | Omit = omit,
cursor: str | Omit = omit,
+ has_location: bool | Omit = omit,
+ has_website: bool | Omit = omit,
+ location_contains: str | Omit = omit,
+ max_followers: int | Omit = omit,
+ max_following: int | Omit = omit,
+ max_statuses: int | Omit = omit,
+ min_account_age_days: int | Omit = omit,
+ min_followers: int | Omit = omit,
+ min_following: int | Omit = omit,
+ min_statuses: int | Omit = omit,
page_size: int | Omit = omit,
+ username_contains: str | Omit = omit,
+ verified_only: bool | Omit = omit,
+ verified_type: str | Omit = omit,
# Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
# The extra values given here take precedence over values defined on the client or passed to this method.
extra_headers: Headers | None = None,
@@ -65,12 +79,39 @@ def retrieve_followers(
List followers of an X List
Args:
+ bio_contains: Match any comma-separated or line-separated bio term, ignoring case.
+
cursor: Pagination cursor for list followers
- page_size: Maximum user profiles requested from this page (20-200, default 200). The
- response can contain fewer profiles because the source returned fewer or
- remaining credits cover fewer results. Keep requesting next_cursor while
- has_next_page is true. The deprecated limit and count aliases remain accepted.
+ has_location: Only return profiles with a location.
+
+ has_website: Only return profiles with a website.
+
+ location_contains: Match a location substring, ignoring case.
+
+ max_followers: Maximum follower count. Missing counts pass this maximum.
+
+ max_following: Maximum following count.
+
+ max_statuses: Maximum post count. maxPosts is also accepted.
+
+ min_account_age_days: Minimum account age in whole days.
+
+ min_followers: Minimum follower count. Filtering happens before billing.
+
+ min_following: Minimum following count.
+
+ min_statuses: Minimum post count. minPosts is also accepted.
+
+ page_size: Maximum user profiles requested from this page (20-200, default 200). Source,
+ filters, or credits can return fewer profiles. Keep requesting next_cursor while
+ has_next_page is true. Deprecated aliases remain accepted.
+
+ username_contains: Match a username substring, ignoring case.
+
+ verified_only: Only return verified profiles.
+
+ verified_type: Match the verification type exactly, ignoring case.
extra_headers: Send extra headers
@@ -91,8 +132,22 @@ def retrieve_followers(
timeout=timeout,
query=maybe_transform(
{
+ "bio_contains": bio_contains,
"cursor": cursor,
+ "has_location": has_location,
+ "has_website": has_website,
+ "location_contains": location_contains,
+ "max_followers": max_followers,
+ "max_following": max_following,
+ "max_statuses": max_statuses,
+ "min_account_age_days": min_account_age_days,
+ "min_followers": min_followers,
+ "min_following": min_following,
+ "min_statuses": min_statuses,
"page_size": page_size,
+ "username_contains": username_contains,
+ "verified_only": verified_only,
+ "verified_type": verified_type,
},
list_retrieve_followers_params.ListRetrieveFollowersParams,
),
@@ -104,8 +159,22 @@ def retrieve_members(
self,
id: str,
*,
+ bio_contains: str | Omit = omit,
cursor: str | Omit = omit,
+ has_location: bool | Omit = omit,
+ has_website: bool | Omit = omit,
+ location_contains: str | Omit = omit,
+ max_followers: int | Omit = omit,
+ max_following: int | Omit = omit,
+ max_statuses: int | Omit = omit,
+ min_account_age_days: int | Omit = omit,
+ min_followers: int | Omit = omit,
+ min_following: int | Omit = omit,
+ min_statuses: int | Omit = omit,
page_size: int | Omit = omit,
+ username_contains: str | Omit = omit,
+ verified_only: bool | Omit = omit,
+ verified_type: str | Omit = omit,
# Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
# The extra values given here take precedence over values defined on the client or passed to this method.
extra_headers: Headers | None = None,
@@ -117,10 +186,38 @@ def retrieve_members(
List members of an X List
Args:
+ bio_contains: Match any comma-separated or line-separated bio term, ignoring case.
+
cursor: Pagination cursor for list members
+ has_location: Only return profiles with a location.
+
+ has_website: Only return profiles with a website.
+
+ location_contains: Match a location substring, ignoring case.
+
+ max_followers: Maximum follower count. Missing counts pass this maximum.
+
+ max_following: Maximum following count.
+
+ max_statuses: Maximum post count. maxPosts is also accepted.
+
+ min_account_age_days: Minimum account age in whole days.
+
+ min_followers: Minimum follower count. Filtering happens before billing.
+
+ min_following: Minimum following count.
+
+ min_statuses: Minimum post count. minPosts is also accepted.
+
page_size: Members per page (20-200, default 20)
+ username_contains: Match a username substring, ignoring case.
+
+ verified_only: Only return verified profiles.
+
+ verified_type: Match the verification type exactly, ignoring case.
+
extra_headers: Send extra headers
extra_query: Add additional query parameters to the request
@@ -140,8 +237,22 @@ def retrieve_members(
timeout=timeout,
query=maybe_transform(
{
+ "bio_contains": bio_contains,
"cursor": cursor,
+ "has_location": has_location,
+ "has_website": has_website,
+ "location_contains": location_contains,
+ "max_followers": max_followers,
+ "max_following": max_following,
+ "max_statuses": max_statuses,
+ "min_account_age_days": min_account_age_days,
+ "min_followers": min_followers,
+ "min_following": min_following,
+ "min_statuses": min_statuses,
"page_size": page_size,
+ "username_contains": username_contains,
+ "verified_only": verified_only,
+ "verified_type": verified_type,
},
list_retrieve_members_params.ListRetrieveMembersParams,
),
@@ -239,8 +350,22 @@ async def retrieve_followers(
self,
id: str,
*,
+ bio_contains: str | Omit = omit,
cursor: str | Omit = omit,
+ has_location: bool | Omit = omit,
+ has_website: bool | Omit = omit,
+ location_contains: str | Omit = omit,
+ max_followers: int | Omit = omit,
+ max_following: int | Omit = omit,
+ max_statuses: int | Omit = omit,
+ min_account_age_days: int | Omit = omit,
+ min_followers: int | Omit = omit,
+ min_following: int | Omit = omit,
+ min_statuses: int | Omit = omit,
page_size: int | Omit = omit,
+ username_contains: str | Omit = omit,
+ verified_only: bool | Omit = omit,
+ verified_type: str | Omit = omit,
# Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
# The extra values given here take precedence over values defined on the client or passed to this method.
extra_headers: Headers | None = None,
@@ -252,12 +377,39 @@ async def retrieve_followers(
List followers of an X List
Args:
+ bio_contains: Match any comma-separated or line-separated bio term, ignoring case.
+
cursor: Pagination cursor for list followers
- page_size: Maximum user profiles requested from this page (20-200, default 200). The
- response can contain fewer profiles because the source returned fewer or
- remaining credits cover fewer results. Keep requesting next_cursor while
- has_next_page is true. The deprecated limit and count aliases remain accepted.
+ has_location: Only return profiles with a location.
+
+ has_website: Only return profiles with a website.
+
+ location_contains: Match a location substring, ignoring case.
+
+ max_followers: Maximum follower count. Missing counts pass this maximum.
+
+ max_following: Maximum following count.
+
+ max_statuses: Maximum post count. maxPosts is also accepted.
+
+ min_account_age_days: Minimum account age in whole days.
+
+ min_followers: Minimum follower count. Filtering happens before billing.
+
+ min_following: Minimum following count.
+
+ min_statuses: Minimum post count. minPosts is also accepted.
+
+ page_size: Maximum user profiles requested from this page (20-200, default 200). Source,
+ filters, or credits can return fewer profiles. Keep requesting next_cursor while
+ has_next_page is true. Deprecated aliases remain accepted.
+
+ username_contains: Match a username substring, ignoring case.
+
+ verified_only: Only return verified profiles.
+
+ verified_type: Match the verification type exactly, ignoring case.
extra_headers: Send extra headers
@@ -278,8 +430,22 @@ async def retrieve_followers(
timeout=timeout,
query=await async_maybe_transform(
{
+ "bio_contains": bio_contains,
"cursor": cursor,
+ "has_location": has_location,
+ "has_website": has_website,
+ "location_contains": location_contains,
+ "max_followers": max_followers,
+ "max_following": max_following,
+ "max_statuses": max_statuses,
+ "min_account_age_days": min_account_age_days,
+ "min_followers": min_followers,
+ "min_following": min_following,
+ "min_statuses": min_statuses,
"page_size": page_size,
+ "username_contains": username_contains,
+ "verified_only": verified_only,
+ "verified_type": verified_type,
},
list_retrieve_followers_params.ListRetrieveFollowersParams,
),
@@ -291,8 +457,22 @@ async def retrieve_members(
self,
id: str,
*,
+ bio_contains: str | Omit = omit,
cursor: str | Omit = omit,
+ has_location: bool | Omit = omit,
+ has_website: bool | Omit = omit,
+ location_contains: str | Omit = omit,
+ max_followers: int | Omit = omit,
+ max_following: int | Omit = omit,
+ max_statuses: int | Omit = omit,
+ min_account_age_days: int | Omit = omit,
+ min_followers: int | Omit = omit,
+ min_following: int | Omit = omit,
+ min_statuses: int | Omit = omit,
page_size: int | Omit = omit,
+ username_contains: str | Omit = omit,
+ verified_only: bool | Omit = omit,
+ verified_type: str | Omit = omit,
# Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
# The extra values given here take precedence over values defined on the client or passed to this method.
extra_headers: Headers | None = None,
@@ -304,10 +484,38 @@ async def retrieve_members(
List members of an X List
Args:
+ bio_contains: Match any comma-separated or line-separated bio term, ignoring case.
+
cursor: Pagination cursor for list members
+ has_location: Only return profiles with a location.
+
+ has_website: Only return profiles with a website.
+
+ location_contains: Match a location substring, ignoring case.
+
+ max_followers: Maximum follower count. Missing counts pass this maximum.
+
+ max_following: Maximum following count.
+
+ max_statuses: Maximum post count. maxPosts is also accepted.
+
+ min_account_age_days: Minimum account age in whole days.
+
+ min_followers: Minimum follower count. Filtering happens before billing.
+
+ min_following: Minimum following count.
+
+ min_statuses: Minimum post count. minPosts is also accepted.
+
page_size: Members per page (20-200, default 20)
+ username_contains: Match a username substring, ignoring case.
+
+ verified_only: Only return verified profiles.
+
+ verified_type: Match the verification type exactly, ignoring case.
+
extra_headers: Send extra headers
extra_query: Add additional query parameters to the request
@@ -327,8 +535,22 @@ async def retrieve_members(
timeout=timeout,
query=await async_maybe_transform(
{
+ "bio_contains": bio_contains,
"cursor": cursor,
+ "has_location": has_location,
+ "has_website": has_website,
+ "location_contains": location_contains,
+ "max_followers": max_followers,
+ "max_following": max_following,
+ "max_statuses": max_statuses,
+ "min_account_age_days": min_account_age_days,
+ "min_followers": min_followers,
+ "min_following": min_following,
+ "min_statuses": min_statuses,
"page_size": page_size,
+ "username_contains": username_contains,
+ "verified_only": verified_only,
+ "verified_type": verified_type,
},
list_retrieve_members_params.ListRetrieveMembersParams,
),
diff --git a/src/x_twitter_scraper/resources/x/tweets/tweets.py b/src/x_twitter_scraper/resources/x/tweets/tweets.py
index 3f4cc10..b0874ee 100644
--- a/src/x_twitter_scraper/resources/x/tweets/tweets.py
+++ b/src/x_twitter_scraper/resources/x/tweets/tweets.py
@@ -6,7 +6,7 @@
from __future__ import annotations
-from typing import Union
+from typing import Any, Union, cast
from datetime import date
from typing_extensions import Literal
@@ -54,6 +54,7 @@
from ....types.shared.paginated_tweets import PaginatedTweets
from ....types.x.tweet_create_response import TweetCreateResponse
from ....types.x.tweet_delete_response import TweetDeleteResponse
+from ....types.x.tweet_search_response import TweetSearchResponse
from ....types.x.tweet_retrieve_response import TweetRetrieveResponse
from ....types.x.tweet_get_replies_response import TweetGetRepliesResponse
@@ -260,8 +261,22 @@ def get_favoriters(
self,
id: str,
*,
+ bio_contains: str | Omit = omit,
cursor: str | Omit = omit,
+ has_location: bool | Omit = omit,
+ has_website: bool | Omit = omit,
+ location_contains: str | Omit = omit,
+ max_followers: int | Omit = omit,
+ max_following: int | Omit = omit,
+ max_statuses: int | Omit = omit,
+ min_account_age_days: int | Omit = omit,
+ min_followers: int | Omit = omit,
+ min_following: int | Omit = omit,
+ min_statuses: int | Omit = omit,
page_size: int | Omit = omit,
+ username_contains: str | Omit = omit,
+ verified_only: bool | Omit = omit,
+ verified_type: str | Omit = omit,
# Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
# The extra values given here take precedence over values defined on the client or passed to this method.
extra_headers: Headers | None = None,
@@ -276,12 +291,39 @@ def get_favoriters(
424 `favoriters_unavailable` instead of a misleading empty success.
Args:
+ bio_contains: Match any comma-separated or line-separated bio term, ignoring case.
+
cursor: Pagination cursor for favoriters
- page_size: Maximum user profiles requested from this page (20-200, default 200). The
- response can contain fewer profiles because the source returned fewer or
- remaining credits cover fewer results. Keep requesting next_cursor while
- has_next_page is true. The deprecated limit and count aliases remain accepted.
+ has_location: Only return profiles with a location.
+
+ has_website: Only return profiles with a website.
+
+ location_contains: Match a location substring, ignoring case.
+
+ max_followers: Maximum follower count. Missing counts pass this maximum.
+
+ max_following: Maximum following count.
+
+ max_statuses: Maximum post count. maxPosts is also accepted.
+
+ min_account_age_days: Minimum account age in whole days.
+
+ min_followers: Minimum follower count. Filtering happens before billing.
+
+ min_following: Minimum following count.
+
+ min_statuses: Minimum post count. minPosts is also accepted.
+
+ page_size: Maximum user profiles requested from this page (20-200, default 200). Source,
+ filters, or credits can return fewer profiles. Keep requesting next_cursor while
+ has_next_page is true. Deprecated aliases remain accepted.
+
+ username_contains: Match a username substring, ignoring case.
+
+ verified_only: Only return verified profiles.
+
+ verified_type: Match the verification type exactly, ignoring case.
extra_headers: Send extra headers
@@ -302,8 +344,22 @@ def get_favoriters(
timeout=timeout,
query=maybe_transform(
{
+ "bio_contains": bio_contains,
"cursor": cursor,
+ "has_location": has_location,
+ "has_website": has_website,
+ "location_contains": location_contains,
+ "max_followers": max_followers,
+ "max_following": max_following,
+ "max_statuses": max_statuses,
+ "min_account_age_days": min_account_age_days,
+ "min_followers": min_followers,
+ "min_following": min_following,
+ "min_statuses": min_statuses,
"page_size": page_size,
+ "username_contains": username_contains,
+ "verified_only": verified_only,
+ "verified_type": verified_type,
},
tweet_get_favoriters_params.TweetGetFavoritersParams,
),
@@ -316,35 +372,54 @@ def get_quotes(
id: str,
*,
any_words: str | Omit = omit,
+ blue_verified_only: bool | Omit = omit,
+ card_name: str | Omit = omit,
cashtags: str | Omit = omit,
conversation_id: str | Omit = omit,
cursor: str | Omit = omit,
exact_phrase: str | Omit = omit,
+ exclude_source: str | Omit = omit,
exclude_words: str | Omit = omit,
from_user: str | Omit = omit,
+ geocode: str | Omit = omit,
hashtags: str | Omit = omit,
include_replies: bool | Omit = omit,
in_reply_to_tweet_id: str | Omit = omit,
language: str | Omit = omit,
+ max_faves: int | Omit = omit,
+ max_id: str | Omit = omit,
+ max_quotes: int | Omit = omit,
+ max_replies: int | Omit = omit,
+ max_retweets: int | Omit = omit,
media_type: Literal["images", "videos", "gifs", "media", "links", "none"] | Omit = omit,
mentioning: str | Omit = omit,
+ min_bookmarks: int | Omit = omit,
min_faves: int | Omit = omit,
min_quotes: int | Omit = omit,
min_replies: int | Omit = omit,
min_retweets: int | Omit = omit,
+ min_views: int | Omit = omit,
+ native_retweets: bool | Omit = omit,
+ near: str | Omit = omit,
+ news: bool | Omit = omit,
page_size: int | Omit = omit,
quotes: Literal["include", "exclude", "only"] | Omit = omit,
quotes_of_tweet_id: str | Omit = omit,
replies: Literal["include", "exclude", "only"] | Omit = omit,
retweets: Literal["include", "exclude", "only"] | Omit = omit,
retweets_of_tweet_id: str | Omit = omit,
+ safe: bool | Omit = omit,
since_date: Union[str, date] | Omit = omit,
+ since_id: str | Omit = omit,
since_time: str | Omit = omit,
+ source: str | Omit = omit,
to_user: str | Omit = omit,
until_date: Union[str, date] | Omit = omit,
until_time: str | Omit = omit,
url: str | Omit = omit,
verified_only: bool | Omit = omit,
+ within: str | Omit = omit,
+ within_time: str | Omit = omit,
# Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
# The extra values given here take precedence over values defined on the client or passed to this method.
extra_headers: Headers | None = None,
@@ -359,6 +434,10 @@ def get_quotes(
any_words: Words or quoted phrases where any one can match. Separate with spaces, commas,
or lines.
+ blue_verified_only: Only return tweets from Blue-verified authors.
+
+ card_name: Match the Tweet card name.
+
cashtags: Cashtags separated by spaces, commas, or lines.
conversation_id: Conversation ID filter.
@@ -367,10 +446,14 @@ def get_quotes(
exact_phrase: Exact phrase to match.
+ exclude_source: Exclude a source application.
+
exclude_words: Words or quoted phrases to exclude. Separate with spaces, commas, or lines.
from_user: Filter by author username.
+ geocode: Match latitude, longitude, and radius.
+
hashtags: Hashtags separated by spaces, commas, or lines.
include_replies: Include reply quotes (default false)
@@ -379,10 +462,22 @@ def get_quotes(
language: Language code filter, e.g. en or tr.
+ max_faves: Maximum likes threshold. maxLikes is also accepted.
+
+ max_id: Return Tweets older than this Tweet ID.
+
+ max_quotes: Maximum quotes threshold.
+
+ max_replies: Maximum replies threshold.
+
+ max_retweets: Maximum retweets threshold.
+
media_type: Filter by media type.
mentioning: Filter tweets mentioning a username.
+ min_bookmarks: Minimum bookmark count threshold.
+
min_faves: Minimum likes threshold.
min_quotes: Minimum quote count threshold.
@@ -391,6 +486,14 @@ def get_quotes(
min_retweets: Minimum retweets threshold.
+ min_views: Minimum view count threshold.
+
+ native_retweets: Only return native reposts.
+
+ near: Match a place name.
+
+ news: Only return news results.
+
page_size: Maximum page items (1-100, default 20). Source, filters, or credits can reduce
results. Continue while has_next_page is true. Deprecated limit and count
aliases remain accepted.
@@ -405,10 +508,16 @@ def get_quotes(
retweets_of_tweet_id: Only retweets of this tweet ID.
+ safe: Enable the safe-search filter.
+
since_date: Start date in YYYY-MM-DD format.
+ since_id: Return Tweets newer than this Tweet ID.
+
since_time: Unix timestamp - return quotes posted after this time
+ source: Match the source application.
+
to_user: Filter replies sent to a username.
until_date: End date in YYYY-MM-DD format.
@@ -419,6 +528,10 @@ def get_quotes(
verified_only: Only return tweets from verified authors.
+ within: Set the radius for the near filter.
+
+ within_time: Match Tweets inside a recent time window.
+
extra_headers: Send extra headers
extra_query: Add additional query parameters to the request
@@ -439,35 +552,54 @@ def get_quotes(
query=maybe_transform(
{
"any_words": any_words,
+ "blue_verified_only": blue_verified_only,
+ "card_name": card_name,
"cashtags": cashtags,
"conversation_id": conversation_id,
"cursor": cursor,
"exact_phrase": exact_phrase,
+ "exclude_source": exclude_source,
"exclude_words": exclude_words,
"from_user": from_user,
+ "geocode": geocode,
"hashtags": hashtags,
"include_replies": include_replies,
"in_reply_to_tweet_id": in_reply_to_tweet_id,
"language": language,
+ "max_faves": max_faves,
+ "max_id": max_id,
+ "max_quotes": max_quotes,
+ "max_replies": max_replies,
+ "max_retweets": max_retweets,
"media_type": media_type,
"mentioning": mentioning,
+ "min_bookmarks": min_bookmarks,
"min_faves": min_faves,
"min_quotes": min_quotes,
"min_replies": min_replies,
"min_retweets": min_retweets,
+ "min_views": min_views,
+ "native_retweets": native_retweets,
+ "near": near,
+ "news": news,
"page_size": page_size,
"quotes": quotes,
"quotes_of_tweet_id": quotes_of_tweet_id,
"replies": replies,
"retweets": retweets,
"retweets_of_tweet_id": retweets_of_tweet_id,
+ "safe": safe,
"since_date": since_date,
+ "since_id": since_id,
"since_time": since_time,
+ "source": source,
"to_user": to_user,
"until_date": until_date,
"until_time": until_time,
"url": url,
"verified_only": verified_only,
+ "within": within,
+ "within_time": within_time,
},
tweet_get_quotes_params.TweetGetQuotesParams,
),
@@ -480,36 +612,61 @@ def get_replies(
id: str,
*,
any_words: str | Omit = omit,
+ blue_verified_only: bool | Omit = omit,
+ card_name: str | Omit = omit,
cashtags: str | Omit = omit,
conversation_id: str | Omit = omit,
cursor: str | Omit = omit,
exact_phrase: str | Omit = omit,
+ exclude_original_author: bool | Omit = omit,
+ exclude_source: str | Omit = omit,
exclude_words: str | Omit = omit,
from_user: str | Omit = omit,
+ geocode: str | Omit = omit,
hashtags: str | Omit = omit,
+ has_media_only: bool | Omit = omit,
+ include_original_post: bool | Omit = omit,
in_reply_to_tweet_id: str | Omit = omit,
language: str | Omit = omit,
limit: int | Omit = omit,
+ max_depth: int | Omit = omit,
+ max_faves: int | Omit = omit,
+ max_id: str | Omit = omit,
+ max_quotes: int | Omit = omit,
+ max_replies: int | Omit = omit,
+ max_retweets: int | Omit = omit,
media_type: Literal["images", "videos", "gifs", "media", "links", "none"] | Omit = omit,
mentioning: str | Omit = omit,
+ min_bookmarks: int | Omit = omit,
min_faves: int | Omit = omit,
min_quotes: int | Omit = omit,
min_replies: int | Omit = omit,
min_retweets: int | Omit = omit,
- mode: Literal["complete"] | Omit = omit,
+ min_views: int | Omit = omit,
+ mode: Literal["standard", "complete"] | Omit = omit,
+ native_retweets: bool | Omit = omit,
+ near: str | Omit = omit,
+ news: bool | Omit = omit,
page_size: int | Omit = omit,
quotes: Literal["include", "exclude", "only"] | Omit = omit,
quotes_of_tweet_id: str | Omit = omit,
replies: Literal["include", "exclude", "only"] | Omit = omit,
retweets: Literal["include", "exclude", "only"] | Omit = omit,
retweets_of_tweet_id: str | Omit = omit,
+ safe: bool | Omit = omit,
+ scope: Literal["all", "direct", "nested"] | Omit = omit,
since_date: Union[str, date] | Omit = omit,
+ since_id: str | Omit = omit,
since_time: str | Omit = omit,
+ sort: Literal["relevance", "latest", "oldest", "likes"] | Omit = omit,
+ source: str | Omit = omit,
to_user: str | Omit = omit,
until_date: Union[str, date] | Omit = omit,
until_time: str | Omit = omit,
url: str | Omit = omit,
verified_only: bool | Omit = omit,
+ within: str | Omit = omit,
+ within_time: str | Omit = omit,
# Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
# The extra values given here take precedence over values defined on the client or passed to this method.
extra_headers: Headers | None = None,
@@ -519,41 +676,69 @@ def get_replies(
) -> TweetGetRepliesResponse:
"""Returns direct replies.
- Complete mode merges available timeline views, supported
- rankings, every forward cursor module, labeled hidden-content branches,
- exact-parent time partitions scaled to the reported reply count, and search. It
- separates nested replies and returns 424 below 80% coverage.
+ Omit mode for automatic maximum coverage with resumable
+ pagination. Complete mode returns nested replies, diagnostics, and 424 when
+ direct coverage stays below 80%.
Args:
any_words: Words or quoted phrases where any one can match. Separate with spaces, commas,
or lines.
+ blue_verified_only: Only return tweets from Blue-verified authors.
+
+ card_name: Match the Tweet card name.
+
cashtags: Cashtags separated by spaces, commas, or lines.
conversation_id: Conversation ID filter.
- cursor: Pagination cursor for tweet replies
+ cursor: Cursor from the previous response. Xquik cursors resume automatic coverage.
+ Existing unprefixed cursors keep legacy standard behavior.
exact_phrase: Exact phrase to match.
+ exclude_original_author: Exclude replies written by the source-post author.
+
+ exclude_source: Exclude a source application.
+
exclude_words: Words or quoted phrases to exclude. Separate with spaces, commas, or lines.
from_user: Filter by author username.
+ geocode: Match latitude, longitude, and radius.
+
hashtags: Hashtags separated by spaces, commas, or lines.
+ has_media_only: Only return replies containing media.
+
+ include_original_post: Include the source post and count it toward limit.
+
in_reply_to_tweet_id: Only replies to this tweet ID.
language: Language code filter, e.g. en or tr.
- limit: With mode=complete, maximum combined direct and nested reply rows (1-25000).
- Without complete mode, this is the deprecated pageSize alias and uses the normal
- 1-100 page range.
+ limit: With mode=complete, maximum combined direct and nested reply rows (1-25000,
+ default 25000). Automatic pages accept 1-300. Standard pages accept 1-100.
+ Prefer pageSize outside complete mode.
+
+ max_depth: Maximum reply depth from the source post.
+
+ max_faves: Maximum likes threshold. maxLikes is also accepted.
+
+ max_id: Return Tweets older than this Tweet ID.
+
+ max_quotes: Maximum quotes threshold.
+
+ max_replies: Maximum replies threshold.
+
+ max_retweets: Maximum retweets threshold.
media_type: Filter by media type.
mentioning: Filter tweets mentioning a username.
+ min_bookmarks: Minimum bookmark count threshold.
+
min_faves: Minimum likes threshold.
min_quotes: Minimum quote count threshold.
@@ -562,12 +747,21 @@ def get_replies(
min_retweets: Minimum retweets threshold.
- mode: Set complete for maximum-coverage collection. Complete mode accepts only limit.
- Remove cursor, pageSize, count, time ranges, and tweet filters.
+ min_views: Minimum view count threshold.
- page_size: Maximum page items (1-100, default 20). Source, filters, or credits can reduce
- results. Continue while has_next_page is true. Deprecated limit and count
- aliases remain accepted.
+ mode: Optional advanced override. Omit mode for automatic maximum direct reply
+ coverage with pagination. Standard keeps legacy pagination. Complete returns
+ direct and nested replies with diagnostics, scope, depth, sorting, and
+ original-post controls.
+
+ native_retweets: Only return native reposts.
+
+ near: Match a place name.
+
+ news: Only return news results.
+
+ page_size: Automatic pages accept 1-300 Tweets. Standard pages keep 1-100. Default 20.
+ Continue while has_next_page is true. Deprecated aliases remain accepted.
quotes: Quote mode.
@@ -579,10 +773,20 @@ def get_replies(
retweets_of_tweet_id: Only retweets of this tweet ID.
+ safe: Enable the safe-search filter.
+
+ scope: Select all replies, direct replies, or nested replies.
+
since_date: Start date in YYYY-MM-DD format.
+ since_id: Return Tweets newer than this Tweet ID.
+
since_time: Unix timestamp - return replies posted after this time
+ sort: Sort the selected replies before applying limit.
+
+ source: Match the source application.
+
to_user: Filter replies sent to a username.
until_date: End date in YYYY-MM-DD format.
@@ -593,6 +797,10 @@ def get_replies(
verified_only: Only return tweets from verified authors.
+ within: Set the radius for the near filter.
+
+ within_time: Match Tweets inside a recent time window.
+
extra_headers: Send extra headers
extra_query: Add additional query parameters to the request
@@ -613,36 +821,61 @@ def get_replies(
query=maybe_transform(
{
"any_words": any_words,
+ "blue_verified_only": blue_verified_only,
+ "card_name": card_name,
"cashtags": cashtags,
"conversation_id": conversation_id,
"cursor": cursor,
"exact_phrase": exact_phrase,
+ "exclude_original_author": exclude_original_author,
+ "exclude_source": exclude_source,
"exclude_words": exclude_words,
"from_user": from_user,
+ "geocode": geocode,
"hashtags": hashtags,
+ "has_media_only": has_media_only,
+ "include_original_post": include_original_post,
"in_reply_to_tweet_id": in_reply_to_tweet_id,
"language": language,
"limit": limit,
+ "max_depth": max_depth,
+ "max_faves": max_faves,
+ "max_id": max_id,
+ "max_quotes": max_quotes,
+ "max_replies": max_replies,
+ "max_retweets": max_retweets,
"media_type": media_type,
"mentioning": mentioning,
+ "min_bookmarks": min_bookmarks,
"min_faves": min_faves,
"min_quotes": min_quotes,
"min_replies": min_replies,
"min_retweets": min_retweets,
+ "min_views": min_views,
"mode": mode,
+ "native_retweets": native_retweets,
+ "near": near,
+ "news": news,
"page_size": page_size,
"quotes": quotes,
"quotes_of_tweet_id": quotes_of_tweet_id,
"replies": replies,
"retweets": retweets,
"retweets_of_tweet_id": retweets_of_tweet_id,
+ "safe": safe,
+ "scope": scope,
"since_date": since_date,
+ "since_id": since_id,
"since_time": since_time,
+ "sort": sort,
+ "source": source,
"to_user": to_user,
"until_date": until_date,
"until_time": until_time,
"url": url,
"verified_only": verified_only,
+ "within": within,
+ "within_time": within_time,
},
tweet_get_replies_params.TweetGetRepliesParams,
),
@@ -654,8 +887,22 @@ def get_retweeters(
self,
id: str,
*,
+ bio_contains: str | Omit = omit,
cursor: str | Omit = omit,
+ has_location: bool | Omit = omit,
+ has_website: bool | Omit = omit,
+ location_contains: str | Omit = omit,
+ max_followers: int | Omit = omit,
+ max_following: int | Omit = omit,
+ max_statuses: int | Omit = omit,
+ min_account_age_days: int | Omit = omit,
+ min_followers: int | Omit = omit,
+ min_following: int | Omit = omit,
+ min_statuses: int | Omit = omit,
page_size: int | Omit = omit,
+ username_contains: str | Omit = omit,
+ verified_only: bool | Omit = omit,
+ verified_type: str | Omit = omit,
# Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
# The extra values given here take precedence over values defined on the client or passed to this method.
extra_headers: Headers | None = None,
@@ -667,12 +914,39 @@ def get_retweeters(
List users who retweeted a tweet
Args:
+ bio_contains: Match any comma-separated or line-separated bio term, ignoring case.
+
cursor: Pagination cursor for retweeters
- page_size: Maximum user profiles requested from this page (20-200, default 200). The
- response can contain fewer profiles because the source returned fewer or
- remaining credits cover fewer results. Keep requesting next_cursor while
- has_next_page is true. The deprecated limit and count aliases remain accepted.
+ has_location: Only return profiles with a location.
+
+ has_website: Only return profiles with a website.
+
+ location_contains: Match a location substring, ignoring case.
+
+ max_followers: Maximum follower count. Missing counts pass this maximum.
+
+ max_following: Maximum following count.
+
+ max_statuses: Maximum post count. maxPosts is also accepted.
+
+ min_account_age_days: Minimum account age in whole days.
+
+ min_followers: Minimum follower count. Filtering happens before billing.
+
+ min_following: Minimum following count.
+
+ min_statuses: Minimum post count. minPosts is also accepted.
+
+ page_size: Maximum user profiles requested from this page (20-200, default 200). Source,
+ filters, or credits can return fewer profiles. Keep requesting next_cursor while
+ has_next_page is true. Deprecated aliases remain accepted.
+
+ username_contains: Match a username substring, ignoring case.
+
+ verified_only: Only return verified profiles.
+
+ verified_type: Match the verification type exactly, ignoring case.
extra_headers: Send extra headers
@@ -693,8 +967,22 @@ def get_retweeters(
timeout=timeout,
query=maybe_transform(
{
+ "bio_contains": bio_contains,
"cursor": cursor,
+ "has_location": has_location,
+ "has_website": has_website,
+ "location_contains": location_contains,
+ "max_followers": max_followers,
+ "max_following": max_following,
+ "max_statuses": max_statuses,
+ "min_account_age_days": min_account_age_days,
+ "min_followers": min_followers,
+ "min_following": min_following,
+ "min_statuses": min_statuses,
"page_size": page_size,
+ "username_contains": username_contains,
+ "verified_only": verified_only,
+ "verified_type": verified_type,
},
tweet_get_retweeters_params.TweetGetRetweetersParams,
),
@@ -759,24 +1047,39 @@ def search(
q: str,
advanced_query: str | Omit = omit,
any_words: str | Omit = omit,
+ blue_verified_only: bool | Omit = omit,
bounding_box: str | Omit = omit,
+ card_name: str | Omit = omit,
cashtags: str | Omit = omit,
conversation_id: str | Omit = omit,
cursor: str | Omit = omit,
exact_phrase: str | Omit = omit,
+ exclude_source: str | Omit = omit,
exclude_words: str | Omit = omit,
from_user: str | Omit = omit,
+ geocode: str | Omit = omit,
hashtags: str | Omit = omit,
in_reply_to_tweet_id: str | Omit = omit,
language: str | Omit = omit,
limit: int | Omit = omit,
list_id: str | Omit = omit,
+ max_faves: int | Omit = omit,
+ max_id: str | Omit = omit,
+ max_quotes: int | Omit = omit,
+ max_replies: int | Omit = omit,
+ max_retweets: int | Omit = omit,
media_type: Literal["images", "videos", "gifs", "media", "links", "none"] | Omit = omit,
mentioning: str | Omit = omit,
+ min_bookmarks: int | Omit = omit,
min_faves: int | Omit = omit,
min_quotes: int | Omit = omit,
min_replies: int | Omit = omit,
min_retweets: int | Omit = omit,
+ min_views: int | Omit = omit,
+ mode: Literal["standard", "coverage"] | Omit = omit,
+ native_retweets: bool | Omit = omit,
+ near: str | Omit = omit,
+ news: bool | Omit = omit,
place: str | Omit = omit,
place_country: str | Omit = omit,
point_radius: str | Omit = omit,
@@ -786,62 +1089,88 @@ def search(
replies: Literal["include", "exclude", "only"] | Omit = omit,
retweets: Literal["include", "exclude", "only"] | Omit = omit,
retweets_of_tweet_id: str | Omit = omit,
+ safe: bool | Omit = omit,
since_date: Union[str, date] | Omit = omit,
+ since_id: str | Omit = omit,
since_time: str | Omit = omit,
+ source: str | Omit = omit,
to_user: str | Omit = omit,
until_date: Union[str, date] | Omit = omit,
until_time: str | Omit = omit,
url: str | Omit = omit,
verified_only: bool | Omit = omit,
+ within: str | Omit = omit,
+ within_time: str | Omit = omit,
# Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
# The extra values given here take precedence over values defined on the client or passed to this method.
extra_headers: Headers | None = None,
extra_query: Query | None = None,
extra_body: Body | None = None,
timeout: float | httpx.Timeout | None | NotGiven = not_given,
- ) -> PaginatedTweets:
- """
- Search tweets by query, Tweet ID, X status URL, or account date window
+ ) -> TweetSearchResponse:
+ """No-mode search maximizes coverage.
Args:
- q: Search query (keywords,
+ q: Query, Tweet ID, or status URL.
+
+ Valid inline bounds apply per page.
advanced_query: Raw advanced search query appended as-is.
any_words: Words or quoted phrases where any one can match. Separate with spaces, commas,
or lines.
+ blue_verified_only: Only return tweets from Blue-verified authors.
+
bounding_box: Geo bounding box, e.g. -74.1 40.6 -73.9 40.8.
+ card_name: Match the Tweet card name.
+
cashtags: Cashtags separated by spaces, commas, or lines.
conversation_id: Conversation ID filter.
- cursor: Pagination cursor from previous response
+ cursor: Cursor from the previous response. Xquik cursors resume automatic coverage.
+ Existing unprefixed cursors keep legacy standard behavior.
exact_phrase: Exact phrase to match.
+ exclude_source: Exclude a source application.
+
exclude_words: Words or quoted phrases to exclude. Separate with spaces, commas, or lines.
from_user: Filter by author username.
+ geocode: Match latitude, longitude, and radius.
+
hashtags: Hashtags separated by spaces, commas, or lines.
in_reply_to_tweet_id: Only replies to this tweet ID.
language: Language code filter, e.g. en or tr.
- limit: Max tweets to return (server paginates internally). Omit for single page (~20).
- This is an upper bound for paid authenticated calls: remaining credits can
- reduce the returned page size, and zero affordable results returns 402
- insufficient_credits.
+ limit: Result upper bound. Omit it for the existing 20-row page size. Explicit coverage
+ defaults to 2000 and allows 10000. For paid requests, remaining credits can
+ reduce results. Zero affordable results returns 402.
list_id: Search within a list ID.
+ max_faves: Maximum likes threshold. maxLikes is also accepted.
+
+ max_id: Return Tweets older than this Tweet ID.
+
+ max_quotes: Maximum quotes threshold.
+
+ max_replies: Maximum replies threshold.
+
+ max_retweets: Maximum retweets threshold.
+
media_type: Filter by media type.
mentioning: Filter tweets mentioning a username.
+ min_bookmarks: Minimum bookmark count threshold.
+
min_faves: Minimum likes threshold.
min_quotes: Minimum quote count threshold.
@@ -850,6 +1179,17 @@ def search(
min_retweets: Minimum retweets threshold.
+ min_views: Minimum view count threshold.
+
+ mode: Omit mode for resumable maximum coverage. Standard keeps legacy pagination.
+ Coverage returns diagnostics once and rejects cursors.
+
+ native_retweets: Only return native reposts.
+
+ near: Match a place name.
+
+ news: Only return news results.
+
place: Search within a place ID.
place_country: Search within a country code.
@@ -868,20 +1208,30 @@ def search(
retweets_of_tweet_id: Only retweets of this tweet ID.
+ safe: Enable the safe-search filter.
+
since_date: Start date in YYYY-MM-DD format.
- since_time: ISO 8601 timestamp - only return tweets after this time
+ since_id: Return Tweets newer than this Tweet ID.
+
+ since_time: Inclusive ISO bound.
+
+ source: Match the source application.
to_user: Filter replies sent to a username.
until_date: End date in YYYY-MM-DD format.
- until_time: ISO 8601 timestamp - only return tweets before this time
+ until_time: Exclusive ISO bound.
url: URL substring or domain filter.
verified_only: Only return tweets from verified authors.
+ within: Set the radius for the near filter.
+
+ within_time: Match Tweets inside a recent time window.
+
extra_headers: Send extra headers
extra_query: Add additional query parameters to the request
@@ -890,57 +1240,82 @@ def search(
timeout: Override the client-level default timeout for this request, in seconds
"""
- return self._get(
- "/x/tweets/search",
- options=make_request_options(
- extra_headers=extra_headers,
- extra_query=extra_query,
- extra_body=extra_body,
- timeout=timeout,
- query=maybe_transform(
- {
- "q": q,
- "advanced_query": advanced_query,
- "any_words": any_words,
- "bounding_box": bounding_box,
- "cashtags": cashtags,
- "conversation_id": conversation_id,
- "cursor": cursor,
- "exact_phrase": exact_phrase,
- "exclude_words": exclude_words,
- "from_user": from_user,
- "hashtags": hashtags,
- "in_reply_to_tweet_id": in_reply_to_tweet_id,
- "language": language,
- "limit": limit,
- "list_id": list_id,
- "media_type": media_type,
- "mentioning": mentioning,
- "min_faves": min_faves,
- "min_quotes": min_quotes,
- "min_replies": min_replies,
- "min_retweets": min_retweets,
- "place": place,
- "place_country": place_country,
- "point_radius": point_radius,
- "query_type": query_type,
- "quotes": quotes,
- "quotes_of_tweet_id": quotes_of_tweet_id,
- "replies": replies,
- "retweets": retweets,
- "retweets_of_tweet_id": retweets_of_tweet_id,
- "since_date": since_date,
- "since_time": since_time,
- "to_user": to_user,
- "until_date": until_date,
- "until_time": until_time,
- "url": url,
- "verified_only": verified_only,
- },
- tweet_search_params.TweetSearchParams,
+ return cast(
+ TweetSearchResponse,
+ self._get(
+ "/x/tweets/search",
+ options=make_request_options(
+ extra_headers=extra_headers,
+ extra_query=extra_query,
+ extra_body=extra_body,
+ timeout=timeout,
+ query=maybe_transform(
+ {
+ "q": q,
+ "advanced_query": advanced_query,
+ "any_words": any_words,
+ "blue_verified_only": blue_verified_only,
+ "bounding_box": bounding_box,
+ "card_name": card_name,
+ "cashtags": cashtags,
+ "conversation_id": conversation_id,
+ "cursor": cursor,
+ "exact_phrase": exact_phrase,
+ "exclude_source": exclude_source,
+ "exclude_words": exclude_words,
+ "from_user": from_user,
+ "geocode": geocode,
+ "hashtags": hashtags,
+ "in_reply_to_tweet_id": in_reply_to_tweet_id,
+ "language": language,
+ "limit": limit,
+ "list_id": list_id,
+ "max_faves": max_faves,
+ "max_id": max_id,
+ "max_quotes": max_quotes,
+ "max_replies": max_replies,
+ "max_retweets": max_retweets,
+ "media_type": media_type,
+ "mentioning": mentioning,
+ "min_bookmarks": min_bookmarks,
+ "min_faves": min_faves,
+ "min_quotes": min_quotes,
+ "min_replies": min_replies,
+ "min_retweets": min_retweets,
+ "min_views": min_views,
+ "mode": mode,
+ "native_retweets": native_retweets,
+ "near": near,
+ "news": news,
+ "place": place,
+ "place_country": place_country,
+ "point_radius": point_radius,
+ "query_type": query_type,
+ "quotes": quotes,
+ "quotes_of_tweet_id": quotes_of_tweet_id,
+ "replies": replies,
+ "retweets": retweets,
+ "retweets_of_tweet_id": retweets_of_tweet_id,
+ "safe": safe,
+ "since_date": since_date,
+ "since_id": since_id,
+ "since_time": since_time,
+ "source": source,
+ "to_user": to_user,
+ "until_date": until_date,
+ "until_time": until_time,
+ "url": url,
+ "verified_only": verified_only,
+ "within": within,
+ "within_time": within_time,
+ },
+ tweet_search_params.TweetSearchParams,
+ ),
),
+ cast_to=cast(
+ Any, TweetSearchResponse
+ ), # Union types cannot be passed in as arguments in the type system
),
- cast_to=PaginatedTweets,
)
@@ -1144,8 +1519,22 @@ async def get_favoriters(
self,
id: str,
*,
+ bio_contains: str | Omit = omit,
cursor: str | Omit = omit,
+ has_location: bool | Omit = omit,
+ has_website: bool | Omit = omit,
+ location_contains: str | Omit = omit,
+ max_followers: int | Omit = omit,
+ max_following: int | Omit = omit,
+ max_statuses: int | Omit = omit,
+ min_account_age_days: int | Omit = omit,
+ min_followers: int | Omit = omit,
+ min_following: int | Omit = omit,
+ min_statuses: int | Omit = omit,
page_size: int | Omit = omit,
+ username_contains: str | Omit = omit,
+ verified_only: bool | Omit = omit,
+ verified_type: str | Omit = omit,
# Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
# The extra values given here take precedence over values defined on the client or passed to this method.
extra_headers: Headers | None = None,
@@ -1160,12 +1549,39 @@ async def get_favoriters(
424 `favoriters_unavailable` instead of a misleading empty success.
Args:
+ bio_contains: Match any comma-separated or line-separated bio term, ignoring case.
+
cursor: Pagination cursor for favoriters
- page_size: Maximum user profiles requested from this page (20-200, default 200). The
- response can contain fewer profiles because the source returned fewer or
- remaining credits cover fewer results. Keep requesting next_cursor while
- has_next_page is true. The deprecated limit and count aliases remain accepted.
+ has_location: Only return profiles with a location.
+
+ has_website: Only return profiles with a website.
+
+ location_contains: Match a location substring, ignoring case.
+
+ max_followers: Maximum follower count. Missing counts pass this maximum.
+
+ max_following: Maximum following count.
+
+ max_statuses: Maximum post count. maxPosts is also accepted.
+
+ min_account_age_days: Minimum account age in whole days.
+
+ min_followers: Minimum follower count. Filtering happens before billing.
+
+ min_following: Minimum following count.
+
+ min_statuses: Minimum post count. minPosts is also accepted.
+
+ page_size: Maximum user profiles requested from this page (20-200, default 200). Source,
+ filters, or credits can return fewer profiles. Keep requesting next_cursor while
+ has_next_page is true. Deprecated aliases remain accepted.
+
+ username_contains: Match a username substring, ignoring case.
+
+ verified_only: Only return verified profiles.
+
+ verified_type: Match the verification type exactly, ignoring case.
extra_headers: Send extra headers
@@ -1186,8 +1602,22 @@ async def get_favoriters(
timeout=timeout,
query=await async_maybe_transform(
{
+ "bio_contains": bio_contains,
"cursor": cursor,
+ "has_location": has_location,
+ "has_website": has_website,
+ "location_contains": location_contains,
+ "max_followers": max_followers,
+ "max_following": max_following,
+ "max_statuses": max_statuses,
+ "min_account_age_days": min_account_age_days,
+ "min_followers": min_followers,
+ "min_following": min_following,
+ "min_statuses": min_statuses,
"page_size": page_size,
+ "username_contains": username_contains,
+ "verified_only": verified_only,
+ "verified_type": verified_type,
},
tweet_get_favoriters_params.TweetGetFavoritersParams,
),
@@ -1200,35 +1630,54 @@ async def get_quotes(
id: str,
*,
any_words: str | Omit = omit,
+ blue_verified_only: bool | Omit = omit,
+ card_name: str | Omit = omit,
cashtags: str | Omit = omit,
conversation_id: str | Omit = omit,
cursor: str | Omit = omit,
exact_phrase: str | Omit = omit,
+ exclude_source: str | Omit = omit,
exclude_words: str | Omit = omit,
from_user: str | Omit = omit,
+ geocode: str | Omit = omit,
hashtags: str | Omit = omit,
include_replies: bool | Omit = omit,
in_reply_to_tweet_id: str | Omit = omit,
language: str | Omit = omit,
+ max_faves: int | Omit = omit,
+ max_id: str | Omit = omit,
+ max_quotes: int | Omit = omit,
+ max_replies: int | Omit = omit,
+ max_retweets: int | Omit = omit,
media_type: Literal["images", "videos", "gifs", "media", "links", "none"] | Omit = omit,
mentioning: str | Omit = omit,
+ min_bookmarks: int | Omit = omit,
min_faves: int | Omit = omit,
min_quotes: int | Omit = omit,
min_replies: int | Omit = omit,
min_retweets: int | Omit = omit,
+ min_views: int | Omit = omit,
+ native_retweets: bool | Omit = omit,
+ near: str | Omit = omit,
+ news: bool | Omit = omit,
page_size: int | Omit = omit,
quotes: Literal["include", "exclude", "only"] | Omit = omit,
quotes_of_tweet_id: str | Omit = omit,
replies: Literal["include", "exclude", "only"] | Omit = omit,
retweets: Literal["include", "exclude", "only"] | Omit = omit,
retweets_of_tweet_id: str | Omit = omit,
+ safe: bool | Omit = omit,
since_date: Union[str, date] | Omit = omit,
+ since_id: str | Omit = omit,
since_time: str | Omit = omit,
+ source: str | Omit = omit,
to_user: str | Omit = omit,
until_date: Union[str, date] | Omit = omit,
until_time: str | Omit = omit,
url: str | Omit = omit,
verified_only: bool | Omit = omit,
+ within: str | Omit = omit,
+ within_time: str | Omit = omit,
# Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
# The extra values given here take precedence over values defined on the client or passed to this method.
extra_headers: Headers | None = None,
@@ -1243,6 +1692,10 @@ async def get_quotes(
any_words: Words or quoted phrases where any one can match. Separate with spaces, commas,
or lines.
+ blue_verified_only: Only return tweets from Blue-verified authors.
+
+ card_name: Match the Tweet card name.
+
cashtags: Cashtags separated by spaces, commas, or lines.
conversation_id: Conversation ID filter.
@@ -1251,10 +1704,14 @@ async def get_quotes(
exact_phrase: Exact phrase to match.
+ exclude_source: Exclude a source application.
+
exclude_words: Words or quoted phrases to exclude. Separate with spaces, commas, or lines.
from_user: Filter by author username.
+ geocode: Match latitude, longitude, and radius.
+
hashtags: Hashtags separated by spaces, commas, or lines.
include_replies: Include reply quotes (default false)
@@ -1263,10 +1720,22 @@ async def get_quotes(
language: Language code filter, e.g. en or tr.
+ max_faves: Maximum likes threshold. maxLikes is also accepted.
+
+ max_id: Return Tweets older than this Tweet ID.
+
+ max_quotes: Maximum quotes threshold.
+
+ max_replies: Maximum replies threshold.
+
+ max_retweets: Maximum retweets threshold.
+
media_type: Filter by media type.
mentioning: Filter tweets mentioning a username.
+ min_bookmarks: Minimum bookmark count threshold.
+
min_faves: Minimum likes threshold.
min_quotes: Minimum quote count threshold.
@@ -1275,6 +1744,14 @@ async def get_quotes(
min_retweets: Minimum retweets threshold.
+ min_views: Minimum view count threshold.
+
+ native_retweets: Only return native reposts.
+
+ near: Match a place name.
+
+ news: Only return news results.
+
page_size: Maximum page items (1-100, default 20). Source, filters, or credits can reduce
results. Continue while has_next_page is true. Deprecated limit and count
aliases remain accepted.
@@ -1289,10 +1766,16 @@ async def get_quotes(
retweets_of_tweet_id: Only retweets of this tweet ID.
+ safe: Enable the safe-search filter.
+
since_date: Start date in YYYY-MM-DD format.
+ since_id: Return Tweets newer than this Tweet ID.
+
since_time: Unix timestamp - return quotes posted after this time
+ source: Match the source application.
+
to_user: Filter replies sent to a username.
until_date: End date in YYYY-MM-DD format.
@@ -1303,6 +1786,10 @@ async def get_quotes(
verified_only: Only return tweets from verified authors.
+ within: Set the radius for the near filter.
+
+ within_time: Match Tweets inside a recent time window.
+
extra_headers: Send extra headers
extra_query: Add additional query parameters to the request
@@ -1323,35 +1810,54 @@ async def get_quotes(
query=await async_maybe_transform(
{
"any_words": any_words,
+ "blue_verified_only": blue_verified_only,
+ "card_name": card_name,
"cashtags": cashtags,
"conversation_id": conversation_id,
"cursor": cursor,
"exact_phrase": exact_phrase,
+ "exclude_source": exclude_source,
"exclude_words": exclude_words,
"from_user": from_user,
+ "geocode": geocode,
"hashtags": hashtags,
"include_replies": include_replies,
"in_reply_to_tweet_id": in_reply_to_tweet_id,
"language": language,
+ "max_faves": max_faves,
+ "max_id": max_id,
+ "max_quotes": max_quotes,
+ "max_replies": max_replies,
+ "max_retweets": max_retweets,
"media_type": media_type,
"mentioning": mentioning,
+ "min_bookmarks": min_bookmarks,
"min_faves": min_faves,
"min_quotes": min_quotes,
"min_replies": min_replies,
"min_retweets": min_retweets,
+ "min_views": min_views,
+ "native_retweets": native_retweets,
+ "near": near,
+ "news": news,
"page_size": page_size,
"quotes": quotes,
"quotes_of_tweet_id": quotes_of_tweet_id,
"replies": replies,
"retweets": retweets,
"retweets_of_tweet_id": retweets_of_tweet_id,
+ "safe": safe,
"since_date": since_date,
+ "since_id": since_id,
"since_time": since_time,
+ "source": source,
"to_user": to_user,
"until_date": until_date,
"until_time": until_time,
"url": url,
"verified_only": verified_only,
+ "within": within,
+ "within_time": within_time,
},
tweet_get_quotes_params.TweetGetQuotesParams,
),
@@ -1364,36 +1870,61 @@ async def get_replies(
id: str,
*,
any_words: str | Omit = omit,
+ blue_verified_only: bool | Omit = omit,
+ card_name: str | Omit = omit,
cashtags: str | Omit = omit,
conversation_id: str | Omit = omit,
cursor: str | Omit = omit,
exact_phrase: str | Omit = omit,
+ exclude_original_author: bool | Omit = omit,
+ exclude_source: str | Omit = omit,
exclude_words: str | Omit = omit,
from_user: str | Omit = omit,
+ geocode: str | Omit = omit,
hashtags: str | Omit = omit,
+ has_media_only: bool | Omit = omit,
+ include_original_post: bool | Omit = omit,
in_reply_to_tweet_id: str | Omit = omit,
language: str | Omit = omit,
limit: int | Omit = omit,
+ max_depth: int | Omit = omit,
+ max_faves: int | Omit = omit,
+ max_id: str | Omit = omit,
+ max_quotes: int | Omit = omit,
+ max_replies: int | Omit = omit,
+ max_retweets: int | Omit = omit,
media_type: Literal["images", "videos", "gifs", "media", "links", "none"] | Omit = omit,
mentioning: str | Omit = omit,
+ min_bookmarks: int | Omit = omit,
min_faves: int | Omit = omit,
min_quotes: int | Omit = omit,
min_replies: int | Omit = omit,
min_retweets: int | Omit = omit,
- mode: Literal["complete"] | Omit = omit,
+ min_views: int | Omit = omit,
+ mode: Literal["standard", "complete"] | Omit = omit,
+ native_retweets: bool | Omit = omit,
+ near: str | Omit = omit,
+ news: bool | Omit = omit,
page_size: int | Omit = omit,
quotes: Literal["include", "exclude", "only"] | Omit = omit,
quotes_of_tweet_id: str | Omit = omit,
replies: Literal["include", "exclude", "only"] | Omit = omit,
retweets: Literal["include", "exclude", "only"] | Omit = omit,
retweets_of_tweet_id: str | Omit = omit,
+ safe: bool | Omit = omit,
+ scope: Literal["all", "direct", "nested"] | Omit = omit,
since_date: Union[str, date] | Omit = omit,
+ since_id: str | Omit = omit,
since_time: str | Omit = omit,
+ sort: Literal["relevance", "latest", "oldest", "likes"] | Omit = omit,
+ source: str | Omit = omit,
to_user: str | Omit = omit,
until_date: Union[str, date] | Omit = omit,
until_time: str | Omit = omit,
url: str | Omit = omit,
verified_only: bool | Omit = omit,
+ within: str | Omit = omit,
+ within_time: str | Omit = omit,
# Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
# The extra values given here take precedence over values defined on the client or passed to this method.
extra_headers: Headers | None = None,
@@ -1403,41 +1934,69 @@ async def get_replies(
) -> TweetGetRepliesResponse:
"""Returns direct replies.
- Complete mode merges available timeline views, supported
- rankings, every forward cursor module, labeled hidden-content branches,
- exact-parent time partitions scaled to the reported reply count, and search. It
- separates nested replies and returns 424 below 80% coverage.
+ Omit mode for automatic maximum coverage with resumable
+ pagination. Complete mode returns nested replies, diagnostics, and 424 when
+ direct coverage stays below 80%.
Args:
any_words: Words or quoted phrases where any one can match. Separate with spaces, commas,
or lines.
+ blue_verified_only: Only return tweets from Blue-verified authors.
+
+ card_name: Match the Tweet card name.
+
cashtags: Cashtags separated by spaces, commas, or lines.
conversation_id: Conversation ID filter.
- cursor: Pagination cursor for tweet replies
+ cursor: Cursor from the previous response. Xquik cursors resume automatic coverage.
+ Existing unprefixed cursors keep legacy standard behavior.
exact_phrase: Exact phrase to match.
+ exclude_original_author: Exclude replies written by the source-post author.
+
+ exclude_source: Exclude a source application.
+
exclude_words: Words or quoted phrases to exclude. Separate with spaces, commas, or lines.
from_user: Filter by author username.
+ geocode: Match latitude, longitude, and radius.
+
hashtags: Hashtags separated by spaces, commas, or lines.
+ has_media_only: Only return replies containing media.
+
+ include_original_post: Include the source post and count it toward limit.
+
in_reply_to_tweet_id: Only replies to this tweet ID.
language: Language code filter, e.g. en or tr.
- limit: With mode=complete, maximum combined direct and nested reply rows (1-25000).
- Without complete mode, this is the deprecated pageSize alias and uses the normal
- 1-100 page range.
+ limit: With mode=complete, maximum combined direct and nested reply rows (1-25000,
+ default 25000). Automatic pages accept 1-300. Standard pages accept 1-100.
+ Prefer pageSize outside complete mode.
+
+ max_depth: Maximum reply depth from the source post.
+
+ max_faves: Maximum likes threshold. maxLikes is also accepted.
+
+ max_id: Return Tweets older than this Tweet ID.
+
+ max_quotes: Maximum quotes threshold.
+
+ max_replies: Maximum replies threshold.
+
+ max_retweets: Maximum retweets threshold.
media_type: Filter by media type.
mentioning: Filter tweets mentioning a username.
+ min_bookmarks: Minimum bookmark count threshold.
+
min_faves: Minimum likes threshold.
min_quotes: Minimum quote count threshold.
@@ -1446,12 +2005,21 @@ async def get_replies(
min_retweets: Minimum retweets threshold.
- mode: Set complete for maximum-coverage collection. Complete mode accepts only limit.
- Remove cursor, pageSize, count, time ranges, and tweet filters.
+ min_views: Minimum view count threshold.
- page_size: Maximum page items (1-100, default 20). Source, filters, or credits can reduce
- results. Continue while has_next_page is true. Deprecated limit and count
- aliases remain accepted.
+ mode: Optional advanced override. Omit mode for automatic maximum direct reply
+ coverage with pagination. Standard keeps legacy pagination. Complete returns
+ direct and nested replies with diagnostics, scope, depth, sorting, and
+ original-post controls.
+
+ native_retweets: Only return native reposts.
+
+ near: Match a place name.
+
+ news: Only return news results.
+
+ page_size: Automatic pages accept 1-300 Tweets. Standard pages keep 1-100. Default 20.
+ Continue while has_next_page is true. Deprecated aliases remain accepted.
quotes: Quote mode.
@@ -1463,10 +2031,20 @@ async def get_replies(
retweets_of_tweet_id: Only retweets of this tweet ID.
+ safe: Enable the safe-search filter.
+
+ scope: Select all replies, direct replies, or nested replies.
+
since_date: Start date in YYYY-MM-DD format.
+ since_id: Return Tweets newer than this Tweet ID.
+
since_time: Unix timestamp - return replies posted after this time
+ sort: Sort the selected replies before applying limit.
+
+ source: Match the source application.
+
to_user: Filter replies sent to a username.
until_date: End date in YYYY-MM-DD format.
@@ -1477,6 +2055,10 @@ async def get_replies(
verified_only: Only return tweets from verified authors.
+ within: Set the radius for the near filter.
+
+ within_time: Match Tweets inside a recent time window.
+
extra_headers: Send extra headers
extra_query: Add additional query parameters to the request
@@ -1497,36 +2079,61 @@ async def get_replies(
query=await async_maybe_transform(
{
"any_words": any_words,
+ "blue_verified_only": blue_verified_only,
+ "card_name": card_name,
"cashtags": cashtags,
"conversation_id": conversation_id,
"cursor": cursor,
"exact_phrase": exact_phrase,
+ "exclude_original_author": exclude_original_author,
+ "exclude_source": exclude_source,
"exclude_words": exclude_words,
"from_user": from_user,
+ "geocode": geocode,
"hashtags": hashtags,
+ "has_media_only": has_media_only,
+ "include_original_post": include_original_post,
"in_reply_to_tweet_id": in_reply_to_tweet_id,
"language": language,
"limit": limit,
+ "max_depth": max_depth,
+ "max_faves": max_faves,
+ "max_id": max_id,
+ "max_quotes": max_quotes,
+ "max_replies": max_replies,
+ "max_retweets": max_retweets,
"media_type": media_type,
"mentioning": mentioning,
+ "min_bookmarks": min_bookmarks,
"min_faves": min_faves,
"min_quotes": min_quotes,
"min_replies": min_replies,
"min_retweets": min_retweets,
+ "min_views": min_views,
"mode": mode,
+ "native_retweets": native_retweets,
+ "near": near,
+ "news": news,
"page_size": page_size,
"quotes": quotes,
"quotes_of_tweet_id": quotes_of_tweet_id,
"replies": replies,
"retweets": retweets,
"retweets_of_tweet_id": retweets_of_tweet_id,
+ "safe": safe,
+ "scope": scope,
"since_date": since_date,
+ "since_id": since_id,
"since_time": since_time,
+ "sort": sort,
+ "source": source,
"to_user": to_user,
"until_date": until_date,
"until_time": until_time,
"url": url,
"verified_only": verified_only,
+ "within": within,
+ "within_time": within_time,
},
tweet_get_replies_params.TweetGetRepliesParams,
),
@@ -1538,8 +2145,22 @@ async def get_retweeters(
self,
id: str,
*,
+ bio_contains: str | Omit = omit,
cursor: str | Omit = omit,
+ has_location: bool | Omit = omit,
+ has_website: bool | Omit = omit,
+ location_contains: str | Omit = omit,
+ max_followers: int | Omit = omit,
+ max_following: int | Omit = omit,
+ max_statuses: int | Omit = omit,
+ min_account_age_days: int | Omit = omit,
+ min_followers: int | Omit = omit,
+ min_following: int | Omit = omit,
+ min_statuses: int | Omit = omit,
page_size: int | Omit = omit,
+ username_contains: str | Omit = omit,
+ verified_only: bool | Omit = omit,
+ verified_type: str | Omit = omit,
# Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
# The extra values given here take precedence over values defined on the client or passed to this method.
extra_headers: Headers | None = None,
@@ -1551,12 +2172,39 @@ async def get_retweeters(
List users who retweeted a tweet
Args:
+ bio_contains: Match any comma-separated or line-separated bio term, ignoring case.
+
cursor: Pagination cursor for retweeters
- page_size: Maximum user profiles requested from this page (20-200, default 200). The
- response can contain fewer profiles because the source returned fewer or
- remaining credits cover fewer results. Keep requesting next_cursor while
- has_next_page is true. The deprecated limit and count aliases remain accepted.
+ has_location: Only return profiles with a location.
+
+ has_website: Only return profiles with a website.
+
+ location_contains: Match a location substring, ignoring case.
+
+ max_followers: Maximum follower count. Missing counts pass this maximum.
+
+ max_following: Maximum following count.
+
+ max_statuses: Maximum post count. maxPosts is also accepted.
+
+ min_account_age_days: Minimum account age in whole days.
+
+ min_followers: Minimum follower count. Filtering happens before billing.
+
+ min_following: Minimum following count.
+
+ min_statuses: Minimum post count. minPosts is also accepted.
+
+ page_size: Maximum user profiles requested from this page (20-200, default 200). Source,
+ filters, or credits can return fewer profiles. Keep requesting next_cursor while
+ has_next_page is true. Deprecated aliases remain accepted.
+
+ username_contains: Match a username substring, ignoring case.
+
+ verified_only: Only return verified profiles.
+
+ verified_type: Match the verification type exactly, ignoring case.
extra_headers: Send extra headers
@@ -1577,8 +2225,22 @@ async def get_retweeters(
timeout=timeout,
query=await async_maybe_transform(
{
+ "bio_contains": bio_contains,
"cursor": cursor,
+ "has_location": has_location,
+ "has_website": has_website,
+ "location_contains": location_contains,
+ "max_followers": max_followers,
+ "max_following": max_following,
+ "max_statuses": max_statuses,
+ "min_account_age_days": min_account_age_days,
+ "min_followers": min_followers,
+ "min_following": min_following,
+ "min_statuses": min_statuses,
"page_size": page_size,
+ "username_contains": username_contains,
+ "verified_only": verified_only,
+ "verified_type": verified_type,
},
tweet_get_retweeters_params.TweetGetRetweetersParams,
),
@@ -1643,24 +2305,39 @@ async def search(
q: str,
advanced_query: str | Omit = omit,
any_words: str | Omit = omit,
+ blue_verified_only: bool | Omit = omit,
bounding_box: str | Omit = omit,
+ card_name: str | Omit = omit,
cashtags: str | Omit = omit,
conversation_id: str | Omit = omit,
cursor: str | Omit = omit,
exact_phrase: str | Omit = omit,
+ exclude_source: str | Omit = omit,
exclude_words: str | Omit = omit,
from_user: str | Omit = omit,
+ geocode: str | Omit = omit,
hashtags: str | Omit = omit,
in_reply_to_tweet_id: str | Omit = omit,
language: str | Omit = omit,
limit: int | Omit = omit,
list_id: str | Omit = omit,
+ max_faves: int | Omit = omit,
+ max_id: str | Omit = omit,
+ max_quotes: int | Omit = omit,
+ max_replies: int | Omit = omit,
+ max_retweets: int | Omit = omit,
media_type: Literal["images", "videos", "gifs", "media", "links", "none"] | Omit = omit,
mentioning: str | Omit = omit,
+ min_bookmarks: int | Omit = omit,
min_faves: int | Omit = omit,
min_quotes: int | Omit = omit,
min_replies: int | Omit = omit,
min_retweets: int | Omit = omit,
+ min_views: int | Omit = omit,
+ mode: Literal["standard", "coverage"] | Omit = omit,
+ native_retweets: bool | Omit = omit,
+ near: str | Omit = omit,
+ news: bool | Omit = omit,
place: str | Omit = omit,
place_country: str | Omit = omit,
point_radius: str | Omit = omit,
@@ -1670,62 +2347,88 @@ async def search(
replies: Literal["include", "exclude", "only"] | Omit = omit,
retweets: Literal["include", "exclude", "only"] | Omit = omit,
retweets_of_tweet_id: str | Omit = omit,
+ safe: bool | Omit = omit,
since_date: Union[str, date] | Omit = omit,
+ since_id: str | Omit = omit,
since_time: str | Omit = omit,
+ source: str | Omit = omit,
to_user: str | Omit = omit,
until_date: Union[str, date] | Omit = omit,
until_time: str | Omit = omit,
url: str | Omit = omit,
verified_only: bool | Omit = omit,
+ within: str | Omit = omit,
+ within_time: str | Omit = omit,
# Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
# The extra values given here take precedence over values defined on the client or passed to this method.
extra_headers: Headers | None = None,
extra_query: Query | None = None,
extra_body: Body | None = None,
timeout: float | httpx.Timeout | None | NotGiven = not_given,
- ) -> PaginatedTweets:
- """
- Search tweets by query, Tweet ID, X status URL, or account date window
+ ) -> TweetSearchResponse:
+ """No-mode search maximizes coverage.
Args:
- q: Search query (keywords,
+ q: Query, Tweet ID, or status URL.
+
+ Valid inline bounds apply per page.
advanced_query: Raw advanced search query appended as-is.
any_words: Words or quoted phrases where any one can match. Separate with spaces, commas,
or lines.
+ blue_verified_only: Only return tweets from Blue-verified authors.
+
bounding_box: Geo bounding box, e.g. -74.1 40.6 -73.9 40.8.
+ card_name: Match the Tweet card name.
+
cashtags: Cashtags separated by spaces, commas, or lines.
conversation_id: Conversation ID filter.
- cursor: Pagination cursor from previous response
+ cursor: Cursor from the previous response. Xquik cursors resume automatic coverage.
+ Existing unprefixed cursors keep legacy standard behavior.
exact_phrase: Exact phrase to match.
+ exclude_source: Exclude a source application.
+
exclude_words: Words or quoted phrases to exclude. Separate with spaces, commas, or lines.
from_user: Filter by author username.
+ geocode: Match latitude, longitude, and radius.
+
hashtags: Hashtags separated by spaces, commas, or lines.
in_reply_to_tweet_id: Only replies to this tweet ID.
language: Language code filter, e.g. en or tr.
- limit: Max tweets to return (server paginates internally). Omit for single page (~20).
- This is an upper bound for paid authenticated calls: remaining credits can
- reduce the returned page size, and zero affordable results returns 402
- insufficient_credits.
+ limit: Result upper bound. Omit it for the existing 20-row page size. Explicit coverage
+ defaults to 2000 and allows 10000. For paid requests, remaining credits can
+ reduce results. Zero affordable results returns 402.
list_id: Search within a list ID.
+ max_faves: Maximum likes threshold. maxLikes is also accepted.
+
+ max_id: Return Tweets older than this Tweet ID.
+
+ max_quotes: Maximum quotes threshold.
+
+ max_replies: Maximum replies threshold.
+
+ max_retweets: Maximum retweets threshold.
+
media_type: Filter by media type.
mentioning: Filter tweets mentioning a username.
+ min_bookmarks: Minimum bookmark count threshold.
+
min_faves: Minimum likes threshold.
min_quotes: Minimum quote count threshold.
@@ -1734,6 +2437,17 @@ async def search(
min_retweets: Minimum retweets threshold.
+ min_views: Minimum view count threshold.
+
+ mode: Omit mode for resumable maximum coverage. Standard keeps legacy pagination.
+ Coverage returns diagnostics once and rejects cursors.
+
+ native_retweets: Only return native reposts.
+
+ near: Match a place name.
+
+ news: Only return news results.
+
place: Search within a place ID.
place_country: Search within a country code.
@@ -1752,20 +2466,30 @@ async def search(
retweets_of_tweet_id: Only retweets of this tweet ID.
+ safe: Enable the safe-search filter.
+
since_date: Start date in YYYY-MM-DD format.
- since_time: ISO 8601 timestamp - only return tweets after this time
+ since_id: Return Tweets newer than this Tweet ID.
+
+ since_time: Inclusive ISO bound.
+
+ source: Match the source application.
to_user: Filter replies sent to a username.
until_date: End date in YYYY-MM-DD format.
- until_time: ISO 8601 timestamp - only return tweets before this time
+ until_time: Exclusive ISO bound.
url: URL substring or domain filter.
verified_only: Only return tweets from verified authors.
+ within: Set the radius for the near filter.
+
+ within_time: Match Tweets inside a recent time window.
+
extra_headers: Send extra headers
extra_query: Add additional query parameters to the request
@@ -1774,57 +2498,82 @@ async def search(
timeout: Override the client-level default timeout for this request, in seconds
"""
- return await self._get(
- "/x/tweets/search",
- options=make_request_options(
- extra_headers=extra_headers,
- extra_query=extra_query,
- extra_body=extra_body,
- timeout=timeout,
- query=await async_maybe_transform(
- {
- "q": q,
- "advanced_query": advanced_query,
- "any_words": any_words,
- "bounding_box": bounding_box,
- "cashtags": cashtags,
- "conversation_id": conversation_id,
- "cursor": cursor,
- "exact_phrase": exact_phrase,
- "exclude_words": exclude_words,
- "from_user": from_user,
- "hashtags": hashtags,
- "in_reply_to_tweet_id": in_reply_to_tweet_id,
- "language": language,
- "limit": limit,
- "list_id": list_id,
- "media_type": media_type,
- "mentioning": mentioning,
- "min_faves": min_faves,
- "min_quotes": min_quotes,
- "min_replies": min_replies,
- "min_retweets": min_retweets,
- "place": place,
- "place_country": place_country,
- "point_radius": point_radius,
- "query_type": query_type,
- "quotes": quotes,
- "quotes_of_tweet_id": quotes_of_tweet_id,
- "replies": replies,
- "retweets": retweets,
- "retweets_of_tweet_id": retweets_of_tweet_id,
- "since_date": since_date,
- "since_time": since_time,
- "to_user": to_user,
- "until_date": until_date,
- "until_time": until_time,
- "url": url,
- "verified_only": verified_only,
- },
- tweet_search_params.TweetSearchParams,
+ return cast(
+ TweetSearchResponse,
+ await self._get(
+ "/x/tweets/search",
+ options=make_request_options(
+ extra_headers=extra_headers,
+ extra_query=extra_query,
+ extra_body=extra_body,
+ timeout=timeout,
+ query=await async_maybe_transform(
+ {
+ "q": q,
+ "advanced_query": advanced_query,
+ "any_words": any_words,
+ "blue_verified_only": blue_verified_only,
+ "bounding_box": bounding_box,
+ "card_name": card_name,
+ "cashtags": cashtags,
+ "conversation_id": conversation_id,
+ "cursor": cursor,
+ "exact_phrase": exact_phrase,
+ "exclude_source": exclude_source,
+ "exclude_words": exclude_words,
+ "from_user": from_user,
+ "geocode": geocode,
+ "hashtags": hashtags,
+ "in_reply_to_tweet_id": in_reply_to_tweet_id,
+ "language": language,
+ "limit": limit,
+ "list_id": list_id,
+ "max_faves": max_faves,
+ "max_id": max_id,
+ "max_quotes": max_quotes,
+ "max_replies": max_replies,
+ "max_retweets": max_retweets,
+ "media_type": media_type,
+ "mentioning": mentioning,
+ "min_bookmarks": min_bookmarks,
+ "min_faves": min_faves,
+ "min_quotes": min_quotes,
+ "min_replies": min_replies,
+ "min_retweets": min_retweets,
+ "min_views": min_views,
+ "mode": mode,
+ "native_retweets": native_retweets,
+ "near": near,
+ "news": news,
+ "place": place,
+ "place_country": place_country,
+ "point_radius": point_radius,
+ "query_type": query_type,
+ "quotes": quotes,
+ "quotes_of_tweet_id": quotes_of_tweet_id,
+ "replies": replies,
+ "retweets": retweets,
+ "retweets_of_tweet_id": retweets_of_tweet_id,
+ "safe": safe,
+ "since_date": since_date,
+ "since_id": since_id,
+ "since_time": since_time,
+ "source": source,
+ "to_user": to_user,
+ "until_date": until_date,
+ "until_time": until_time,
+ "url": url,
+ "verified_only": verified_only,
+ "within": within,
+ "within_time": within_time,
+ },
+ tweet_search_params.TweetSearchParams,
+ ),
),
+ cast_to=cast(
+ Any, TweetSearchResponse
+ ), # Union types cannot be passed in as arguments in the type system
),
- cast_to=PaginatedTweets,
)
diff --git a/src/x_twitter_scraper/resources/x/users/users.py b/src/x_twitter_scraper/resources/x/users/users.py
index c32eb4c..f80363a 100644
--- a/src/x_twitter_scraper/resources/x/users/users.py
+++ b/src/x_twitter_scraper/resources/x/users/users.py
@@ -6,7 +6,7 @@
from __future__ import annotations
-from typing import Union
+from typing import Any, Union, cast
from datetime import date
from typing_extensions import Literal
@@ -50,6 +50,9 @@
from ....types.shared.paginated_tweets import PaginatedTweets
from ....types.x.user_retrieve_batch_response import UserRetrieveBatchResponse
from ....types.x.user_remove_follower_response import UserRemoveFollowerResponse
+from ....types.x.user_retrieve_followers_response import UserRetrieveFollowersResponse
+from ....types.x.user_retrieve_following_response import UserRetrieveFollowingResponse
+from ....types.x.user_retrieve_verified_followers_response import UserRetrieveVerifiedFollowersResponse
__all__ = ["UsersResource", "AsyncUsersResource"]
@@ -194,16 +197,31 @@ def retrieve_followers(
id: str,
*,
after: str | Omit = omit,
+ bio_contains: str | Omit = omit,
cursor: str | Omit = omit,
+ has_location: bool | Omit = omit,
+ has_website: bool | Omit = omit,
limit: int | Omit = omit,
+ location_contains: str | Omit = omit,
+ max_followers: int | Omit = omit,
+ max_following: int | Omit = omit,
+ max_statuses: int | Omit = omit,
+ min_account_age_days: int | Omit = omit,
+ min_followers: int | Omit = omit,
+ min_following: int | Omit = omit,
+ min_statuses: int | Omit = omit,
+ mode: Literal["standard", "coverage"] | Omit = omit,
page_size: int | Omit = omit,
+ username_contains: str | Omit = omit,
+ verified_only: bool | Omit = omit,
+ verified_type: str | Omit = omit,
# Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
# The extra values given here take precedence over values defined on the client or passed to this method.
extra_headers: Headers | None = None,
extra_query: Query | None = None,
extra_body: Body | None = None,
timeout: float | httpx.Timeout | None | NotGiven = not_given,
- ) -> PaginatedUsers:
+ ) -> UserRetrieveFollowersResponse:
"""List followers of a user
Args:
@@ -211,14 +229,45 @@ def retrieve_followers(
Prefer cursor.
- cursor: Pagination cursor for followers list
+ bio_contains: Match any comma-separated or line-separated bio term, ignoring case.
+
+ cursor: Cursor from the previous response. Xquik cursors resume automatic coverage.
+ Existing unprefixed cursors keep legacy standard behavior.
+
+ has_location: Only return profiles with a location.
+
+ has_website: Only return profiles with a website.
+
+ limit: Legacy page-size alias outside explicit coverage mode. Coverage accepts 1-10000.
+ Prefer pageSize.
+
+ location_contains: Match a location substring, ignoring case.
+
+ max_followers: Maximum follower count. Missing counts pass this maximum.
+
+ max_following: Maximum following count.
+
+ max_statuses: Maximum post count. maxPosts is also accepted.
+
+ min_account_age_days: Minimum account age in whole days.
+
+ min_followers: Minimum follower count. Filtering happens before billing.
+
+ min_following: Minimum following count.
+
+ min_statuses: Minimum post count. minPosts is also accepted.
+
+ mode: Omit mode for resumable maximum coverage. Standard keeps legacy pagination.
+ Coverage returns diagnostics once and rejects cursors.
- limit: Legacy integer page size alias for following lists. Prefer pageSize.
+ page_size: Maximum user profiles: automatic 300; standard 200. Sources return fewer
+ profiles. Continue with has_next_page.
- page_size: Maximum user profiles requested from this page (20-200, default 200). The
- response can contain fewer profiles because the source returned fewer or
- remaining credits cover fewer results. Keep requesting next_cursor while
- has_next_page is true. The deprecated limit and count aliases remain accepted.
+ username_contains: Match a username substring, ignoring case.
+
+ verified_only: Only return verified profiles.
+
+ verified_type: Match the verification type exactly, ignoring case.
extra_headers: Send extra headers
@@ -230,32 +279,66 @@ def retrieve_followers(
"""
if not id:
raise ValueError(f"Expected a non-empty value for `id` but received {id!r}")
- return self._get(
- path_template("/x/users/{id}/followers", id=id),
- options=make_request_options(
- extra_headers=extra_headers,
- extra_query=extra_query,
- extra_body=extra_body,
- timeout=timeout,
- query=maybe_transform(
- {
- "after": after,
- "cursor": cursor,
- "limit": limit,
- "page_size": page_size,
- },
- user_retrieve_followers_params.UserRetrieveFollowersParams,
+ return cast(
+ UserRetrieveFollowersResponse,
+ self._get(
+ path_template("/x/users/{id}/followers", id=id),
+ options=make_request_options(
+ extra_headers=extra_headers,
+ extra_query=extra_query,
+ extra_body=extra_body,
+ timeout=timeout,
+ query=maybe_transform(
+ {
+ "after": after,
+ "bio_contains": bio_contains,
+ "cursor": cursor,
+ "has_location": has_location,
+ "has_website": has_website,
+ "limit": limit,
+ "location_contains": location_contains,
+ "max_followers": max_followers,
+ "max_following": max_following,
+ "max_statuses": max_statuses,
+ "min_account_age_days": min_account_age_days,
+ "min_followers": min_followers,
+ "min_following": min_following,
+ "min_statuses": min_statuses,
+ "mode": mode,
+ "page_size": page_size,
+ "username_contains": username_contains,
+ "verified_only": verified_only,
+ "verified_type": verified_type,
+ },
+ user_retrieve_followers_params.UserRetrieveFollowersParams,
+ ),
),
+ cast_to=cast(
+ Any, UserRetrieveFollowersResponse
+ ), # Union types cannot be passed in as arguments in the type system
),
- cast_to=PaginatedUsers,
)
def retrieve_followers_you_know(
self,
id: str,
*,
+ bio_contains: str | Omit = omit,
cursor: str | Omit = omit,
+ has_location: bool | Omit = omit,
+ has_website: bool | Omit = omit,
+ location_contains: str | Omit = omit,
+ max_followers: int | Omit = omit,
+ max_following: int | Omit = omit,
+ max_statuses: int | Omit = omit,
+ min_account_age_days: int | Omit = omit,
+ min_followers: int | Omit = omit,
+ min_following: int | Omit = omit,
+ min_statuses: int | Omit = omit,
page_size: int | Omit = omit,
+ username_contains: str | Omit = omit,
+ verified_only: bool | Omit = omit,
+ verified_type: str | Omit = omit,
# Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
# The extra values given here take precedence over values defined on the client or passed to this method.
extra_headers: Headers | None = None,
@@ -267,12 +350,39 @@ def retrieve_followers_you_know(
List mutual followers between you and a user
Args:
+ bio_contains: Match any comma-separated or line-separated bio term, ignoring case.
+
cursor: Pagination cursor for followers-you-know
- page_size: Maximum user profiles requested from this page (20-200, default 200). The
- response can contain fewer profiles because the source returned fewer or
- remaining credits cover fewer results. Keep requesting next_cursor while
- has_next_page is true. The deprecated limit and count aliases remain accepted.
+ has_location: Only return profiles with a location.
+
+ has_website: Only return profiles with a website.
+
+ location_contains: Match a location substring, ignoring case.
+
+ max_followers: Maximum follower count. Missing counts pass this maximum.
+
+ max_following: Maximum following count.
+
+ max_statuses: Maximum post count. maxPosts is also accepted.
+
+ min_account_age_days: Minimum account age in whole days.
+
+ min_followers: Minimum follower count. Filtering happens before billing.
+
+ min_following: Minimum following count.
+
+ min_statuses: Minimum post count. minPosts is also accepted.
+
+ page_size: Maximum user profiles requested from this page (20-200, default 200). Source,
+ filters, or credits can return fewer profiles. Keep requesting next_cursor while
+ has_next_page is true. Deprecated aliases remain accepted.
+
+ username_contains: Match a username substring, ignoring case.
+
+ verified_only: Only return verified profiles.
+
+ verified_type: Match the verification type exactly, ignoring case.
extra_headers: Send extra headers
@@ -293,8 +403,22 @@ def retrieve_followers_you_know(
timeout=timeout,
query=maybe_transform(
{
+ "bio_contains": bio_contains,
"cursor": cursor,
+ "has_location": has_location,
+ "has_website": has_website,
+ "location_contains": location_contains,
+ "max_followers": max_followers,
+ "max_following": max_following,
+ "max_statuses": max_statuses,
+ "min_account_age_days": min_account_age_days,
+ "min_followers": min_followers,
+ "min_following": min_following,
+ "min_statuses": min_statuses,
"page_size": page_size,
+ "username_contains": username_contains,
+ "verified_only": verified_only,
+ "verified_type": verified_type,
},
user_retrieve_followers_you_know_params.UserRetrieveFollowersYouKnowParams,
),
@@ -307,16 +431,31 @@ def retrieve_following(
id: str,
*,
after: str | Omit = omit,
+ bio_contains: str | Omit = omit,
cursor: str | Omit = omit,
+ has_location: bool | Omit = omit,
+ has_website: bool | Omit = omit,
limit: int | Omit = omit,
+ location_contains: str | Omit = omit,
+ max_followers: int | Omit = omit,
+ max_following: int | Omit = omit,
+ max_statuses: int | Omit = omit,
+ min_account_age_days: int | Omit = omit,
+ min_followers: int | Omit = omit,
+ min_following: int | Omit = omit,
+ min_statuses: int | Omit = omit,
+ mode: Literal["standard", "coverage"] | Omit = omit,
page_size: int | Omit = omit,
+ username_contains: str | Omit = omit,
+ verified_only: bool | Omit = omit,
+ verified_type: str | Omit = omit,
# Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
# The extra values given here take precedence over values defined on the client or passed to this method.
extra_headers: Headers | None = None,
extra_query: Query | None = None,
extra_body: Body | None = None,
timeout: float | httpx.Timeout | None | NotGiven = not_given,
- ) -> PaginatedUsers:
+ ) -> UserRetrieveFollowingResponse:
"""List accounts a user follows
Args:
@@ -324,14 +463,45 @@ def retrieve_following(
Prefer cursor.
- cursor: Pagination cursor for following list
+ bio_contains: Match any comma-separated or line-separated bio term, ignoring case.
+
+ cursor: Cursor from the previous response. Xquik cursors resume automatic coverage.
+ Existing unprefixed cursors keep legacy standard behavior.
+
+ has_location: Only return profiles with a location.
+
+ has_website: Only return profiles with a website.
+
+ limit: Legacy page-size alias outside explicit coverage mode. Coverage accepts 1-10000.
+ Prefer pageSize.
+
+ location_contains: Match a location substring, ignoring case.
+
+ max_followers: Maximum follower count. Missing counts pass this maximum.
+
+ max_following: Maximum following count.
+
+ max_statuses: Maximum post count. maxPosts is also accepted.
+
+ min_account_age_days: Minimum account age in whole days.
+
+ min_followers: Minimum follower count. Filtering happens before billing.
+
+ min_following: Minimum following count.
- limit: Legacy page size alias. Prefer pageSize.
+ min_statuses: Minimum post count. minPosts is also accepted.
- page_size: Maximum user profiles requested from this page (20-200, default 200). The
- response can contain fewer profiles because the source returned fewer or
- remaining credits cover fewer results. Keep requesting next_cursor while
- has_next_page is true. The deprecated limit and count aliases remain accepted.
+ mode: Omit mode for resumable maximum coverage. Standard keeps legacy pagination.
+ Coverage returns diagnostics once and rejects cursors.
+
+ page_size: Maximum user profiles: automatic 300; standard 200. Sources return fewer
+ profiles. Continue with has_next_page.
+
+ username_contains: Match a username substring, ignoring case.
+
+ verified_only: Only return verified profiles.
+
+ verified_type: Match the verification type exactly, ignoring case.
extra_headers: Send extra headers
@@ -343,24 +513,44 @@ def retrieve_following(
"""
if not id:
raise ValueError(f"Expected a non-empty value for `id` but received {id!r}")
- return self._get(
- path_template("/x/users/{id}/following", id=id),
- options=make_request_options(
- extra_headers=extra_headers,
- extra_query=extra_query,
- extra_body=extra_body,
- timeout=timeout,
- query=maybe_transform(
- {
- "after": after,
- "cursor": cursor,
- "limit": limit,
- "page_size": page_size,
- },
- user_retrieve_following_params.UserRetrieveFollowingParams,
+ return cast(
+ UserRetrieveFollowingResponse,
+ self._get(
+ path_template("/x/users/{id}/following", id=id),
+ options=make_request_options(
+ extra_headers=extra_headers,
+ extra_query=extra_query,
+ extra_body=extra_body,
+ timeout=timeout,
+ query=maybe_transform(
+ {
+ "after": after,
+ "bio_contains": bio_contains,
+ "cursor": cursor,
+ "has_location": has_location,
+ "has_website": has_website,
+ "limit": limit,
+ "location_contains": location_contains,
+ "max_followers": max_followers,
+ "max_following": max_following,
+ "max_statuses": max_statuses,
+ "min_account_age_days": min_account_age_days,
+ "min_followers": min_followers,
+ "min_following": min_following,
+ "min_statuses": min_statuses,
+ "mode": mode,
+ "page_size": page_size,
+ "username_contains": username_contains,
+ "verified_only": verified_only,
+ "verified_type": verified_type,
+ },
+ user_retrieve_following_params.UserRetrieveFollowingParams,
+ ),
),
+ cast_to=cast(
+ Any, UserRetrieveFollowingResponse
+ ), # Union types cannot be passed in as arguments in the type system
),
- cast_to=PaginatedUsers,
)
def retrieve_likes(
@@ -368,32 +558,51 @@ def retrieve_likes(
id: str,
*,
any_words: str | Omit = omit,
+ blue_verified_only: bool | Omit = omit,
+ card_name: str | Omit = omit,
cashtags: str | Omit = omit,
conversation_id: str | Omit = omit,
cursor: str | Omit = omit,
exact_phrase: str | Omit = omit,
+ exclude_source: str | Omit = omit,
exclude_words: str | Omit = omit,
from_user: str | Omit = omit,
+ geocode: str | Omit = omit,
hashtags: str | Omit = omit,
in_reply_to_tweet_id: str | Omit = omit,
language: str | Omit = omit,
+ max_faves: int | Omit = omit,
+ max_id: str | Omit = omit,
+ max_quotes: int | Omit = omit,
+ max_replies: int | Omit = omit,
+ max_retweets: int | Omit = omit,
media_type: Literal["images", "videos", "gifs", "media", "links", "none"] | Omit = omit,
mentioning: str | Omit = omit,
+ min_bookmarks: int | Omit = omit,
min_faves: int | Omit = omit,
min_quotes: int | Omit = omit,
min_replies: int | Omit = omit,
min_retweets: int | Omit = omit,
+ min_views: int | Omit = omit,
+ native_retweets: bool | Omit = omit,
+ near: str | Omit = omit,
+ news: bool | Omit = omit,
page_size: int | Omit = omit,
quotes: Literal["include", "exclude", "only"] | Omit = omit,
quotes_of_tweet_id: str | Omit = omit,
replies: Literal["include", "exclude", "only"] | Omit = omit,
retweets: Literal["include", "exclude", "only"] | Omit = omit,
retweets_of_tweet_id: str | Omit = omit,
+ safe: bool | Omit = omit,
since_date: Union[str, date] | Omit = omit,
+ since_id: str | Omit = omit,
+ source: str | Omit = omit,
to_user: str | Omit = omit,
until_date: Union[str, date] | Omit = omit,
url: str | Omit = omit,
verified_only: bool | Omit = omit,
+ within: str | Omit = omit,
+ within_time: str | Omit = omit,
# Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
# The extra values given here take precedence over values defined on the client or passed to this method.
extra_headers: Headers | None = None,
@@ -408,6 +617,10 @@ def retrieve_likes(
any_words: Words or quoted phrases where any one can match. Separate with spaces, commas,
or lines.
+ blue_verified_only: Only return tweets from Blue-verified authors.
+
+ card_name: Match the Tweet card name.
+
cashtags: Cashtags separated by spaces, commas, or lines.
conversation_id: Conversation ID filter.
@@ -416,20 +629,36 @@ def retrieve_likes(
exact_phrase: Exact phrase to match.
+ exclude_source: Exclude a source application.
+
exclude_words: Words or quoted phrases to exclude. Separate with spaces, commas, or lines.
from_user: Filter by author username.
+ geocode: Match latitude, longitude, and radius.
+
hashtags: Hashtags separated by spaces, commas, or lines.
in_reply_to_tweet_id: Only replies to this tweet ID.
language: Language code filter, e.g. en or tr.
+ max_faves: Maximum likes threshold. maxLikes is also accepted.
+
+ max_id: Return Tweets older than this Tweet ID.
+
+ max_quotes: Maximum quotes threshold.
+
+ max_replies: Maximum replies threshold.
+
+ max_retweets: Maximum retweets threshold.
+
media_type: Filter by media type.
mentioning: Filter tweets mentioning a username.
+ min_bookmarks: Minimum bookmark count threshold.
+
min_faves: Minimum likes threshold.
min_quotes: Minimum quote count threshold.
@@ -438,6 +667,14 @@ def retrieve_likes(
min_retweets: Minimum retweets threshold.
+ min_views: Minimum view count threshold.
+
+ native_retweets: Only return native reposts.
+
+ near: Match a place name.
+
+ news: Only return news results.
+
page_size: Maximum page items (1-100, default 20). Source, filters, or credits can reduce
results. Continue while has_next_page is true. Deprecated limit and count
aliases remain accepted.
@@ -452,8 +689,14 @@ def retrieve_likes(
retweets_of_tweet_id: Only retweets of this tweet ID.
+ safe: Enable the safe-search filter.
+
since_date: Start date in YYYY-MM-DD format.
+ since_id: Return Tweets newer than this Tweet ID.
+
+ source: Match the source application.
+
to_user: Filter replies sent to a username.
until_date: End date in YYYY-MM-DD format.
@@ -462,6 +705,10 @@ def retrieve_likes(
verified_only: Only return tweets from verified authors.
+ within: Set the radius for the near filter.
+
+ within_time: Match Tweets inside a recent time window.
+
extra_headers: Send extra headers
extra_query: Add additional query parameters to the request
@@ -482,32 +729,51 @@ def retrieve_likes(
query=maybe_transform(
{
"any_words": any_words,
+ "blue_verified_only": blue_verified_only,
+ "card_name": card_name,
"cashtags": cashtags,
"conversation_id": conversation_id,
"cursor": cursor,
"exact_phrase": exact_phrase,
+ "exclude_source": exclude_source,
"exclude_words": exclude_words,
"from_user": from_user,
+ "geocode": geocode,
"hashtags": hashtags,
"in_reply_to_tweet_id": in_reply_to_tweet_id,
"language": language,
+ "max_faves": max_faves,
+ "max_id": max_id,
+ "max_quotes": max_quotes,
+ "max_replies": max_replies,
+ "max_retweets": max_retweets,
"media_type": media_type,
"mentioning": mentioning,
+ "min_bookmarks": min_bookmarks,
"min_faves": min_faves,
"min_quotes": min_quotes,
"min_replies": min_replies,
"min_retweets": min_retweets,
+ "min_views": min_views,
+ "native_retweets": native_retweets,
+ "near": near,
+ "news": news,
"page_size": page_size,
"quotes": quotes,
"quotes_of_tweet_id": quotes_of_tweet_id,
"replies": replies,
"retweets": retweets,
"retweets_of_tweet_id": retweets_of_tweet_id,
+ "safe": safe,
"since_date": since_date,
+ "since_id": since_id,
+ "source": source,
"to_user": to_user,
"until_date": until_date,
"url": url,
"verified_only": verified_only,
+ "within": within,
+ "within_time": within_time,
},
user_retrieve_likes_params.UserRetrieveLikesParams,
),
@@ -520,32 +786,51 @@ def retrieve_media(
id: str,
*,
any_words: str | Omit = omit,
+ blue_verified_only: bool | Omit = omit,
+ card_name: str | Omit = omit,
cashtags: str | Omit = omit,
conversation_id: str | Omit = omit,
cursor: str | Omit = omit,
exact_phrase: str | Omit = omit,
+ exclude_source: str | Omit = omit,
exclude_words: str | Omit = omit,
from_user: str | Omit = omit,
+ geocode: str | Omit = omit,
hashtags: str | Omit = omit,
in_reply_to_tweet_id: str | Omit = omit,
language: str | Omit = omit,
+ max_faves: int | Omit = omit,
+ max_id: str | Omit = omit,
+ max_quotes: int | Omit = omit,
+ max_replies: int | Omit = omit,
+ max_retweets: int | Omit = omit,
media_type: Literal["images", "videos", "gifs", "media", "links", "none"] | Omit = omit,
mentioning: str | Omit = omit,
+ min_bookmarks: int | Omit = omit,
min_faves: int | Omit = omit,
min_quotes: int | Omit = omit,
min_replies: int | Omit = omit,
min_retweets: int | Omit = omit,
+ min_views: int | Omit = omit,
+ native_retweets: bool | Omit = omit,
+ near: str | Omit = omit,
+ news: bool | Omit = omit,
page_size: int | Omit = omit,
quotes: Literal["include", "exclude", "only"] | Omit = omit,
quotes_of_tweet_id: str | Omit = omit,
replies: Literal["include", "exclude", "only"] | Omit = omit,
retweets: Literal["include", "exclude", "only"] | Omit = omit,
retweets_of_tweet_id: str | Omit = omit,
+ safe: bool | Omit = omit,
since_date: Union[str, date] | Omit = omit,
+ since_id: str | Omit = omit,
+ source: str | Omit = omit,
to_user: str | Omit = omit,
until_date: Union[str, date] | Omit = omit,
url: str | Omit = omit,
verified_only: bool | Omit = omit,
+ within: str | Omit = omit,
+ within_time: str | Omit = omit,
# Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
# The extra values given here take precedence over values defined on the client or passed to this method.
extra_headers: Headers | None = None,
@@ -560,6 +845,10 @@ def retrieve_media(
any_words: Words or quoted phrases where any one can match. Separate with spaces, commas,
or lines.
+ blue_verified_only: Only return tweets from Blue-verified authors.
+
+ card_name: Match the Tweet card name.
+
cashtags: Cashtags separated by spaces, commas, or lines.
conversation_id: Conversation ID filter.
@@ -568,20 +857,36 @@ def retrieve_media(
exact_phrase: Exact phrase to match.
+ exclude_source: Exclude a source application.
+
exclude_words: Words or quoted phrases to exclude. Separate with spaces, commas, or lines.
from_user: Filter by author username.
+ geocode: Match latitude, longitude, and radius.
+
hashtags: Hashtags separated by spaces, commas, or lines.
in_reply_to_tweet_id: Only replies to this tweet ID.
language: Language code filter, e.g. en or tr.
+ max_faves: Maximum likes threshold. maxLikes is also accepted.
+
+ max_id: Return Tweets older than this Tweet ID.
+
+ max_quotes: Maximum quotes threshold.
+
+ max_replies: Maximum replies threshold.
+
+ max_retweets: Maximum retweets threshold.
+
media_type: Filter by media type.
mentioning: Filter tweets mentioning a username.
+ min_bookmarks: Minimum bookmark count threshold.
+
min_faves: Minimum likes threshold.
min_quotes: Minimum quote count threshold.
@@ -590,6 +895,14 @@ def retrieve_media(
min_retweets: Minimum retweets threshold.
+ min_views: Minimum view count threshold.
+
+ native_retweets: Only return native reposts.
+
+ near: Match a place name.
+
+ news: Only return news results.
+
page_size: Maximum page items (1-100, default 20). Source, filters, or credits can reduce
results. Continue while has_next_page is true. Deprecated limit and count
aliases remain accepted.
@@ -604,8 +917,14 @@ def retrieve_media(
retweets_of_tweet_id: Only retweets of this tweet ID.
+ safe: Enable the safe-search filter.
+
since_date: Start date in YYYY-MM-DD format.
+ since_id: Return Tweets newer than this Tweet ID.
+
+ source: Match the source application.
+
to_user: Filter replies sent to a username.
until_date: End date in YYYY-MM-DD format.
@@ -614,6 +933,10 @@ def retrieve_media(
verified_only: Only return tweets from verified authors.
+ within: Set the radius for the near filter.
+
+ within_time: Match Tweets inside a recent time window.
+
extra_headers: Send extra headers
extra_query: Add additional query parameters to the request
@@ -634,32 +957,51 @@ def retrieve_media(
query=maybe_transform(
{
"any_words": any_words,
+ "blue_verified_only": blue_verified_only,
+ "card_name": card_name,
"cashtags": cashtags,
"conversation_id": conversation_id,
"cursor": cursor,
"exact_phrase": exact_phrase,
+ "exclude_source": exclude_source,
"exclude_words": exclude_words,
"from_user": from_user,
+ "geocode": geocode,
"hashtags": hashtags,
"in_reply_to_tweet_id": in_reply_to_tweet_id,
"language": language,
+ "max_faves": max_faves,
+ "max_id": max_id,
+ "max_quotes": max_quotes,
+ "max_replies": max_replies,
+ "max_retweets": max_retweets,
"media_type": media_type,
"mentioning": mentioning,
+ "min_bookmarks": min_bookmarks,
"min_faves": min_faves,
"min_quotes": min_quotes,
"min_replies": min_replies,
"min_retweets": min_retweets,
+ "min_views": min_views,
+ "native_retweets": native_retweets,
+ "near": near,
+ "news": news,
"page_size": page_size,
"quotes": quotes,
"quotes_of_tweet_id": quotes_of_tweet_id,
"replies": replies,
"retweets": retweets,
"retweets_of_tweet_id": retweets_of_tweet_id,
+ "safe": safe,
"since_date": since_date,
+ "since_id": since_id,
+ "source": source,
"to_user": to_user,
"until_date": until_date,
"url": url,
"verified_only": verified_only,
+ "within": within,
+ "within_time": within_time,
},
user_retrieve_media_params.UserRetrieveMediaParams,
),
@@ -672,34 +1014,53 @@ def retrieve_mentions(
id: str,
*,
any_words: str | Omit = omit,
+ blue_verified_only: bool | Omit = omit,
+ card_name: str | Omit = omit,
cashtags: str | Omit = omit,
conversation_id: str | Omit = omit,
cursor: str | Omit = omit,
exact_phrase: str | Omit = omit,
+ exclude_source: str | Omit = omit,
exclude_words: str | Omit = omit,
from_user: str | Omit = omit,
+ geocode: str | Omit = omit,
hashtags: str | Omit = omit,
in_reply_to_tweet_id: str | Omit = omit,
language: str | Omit = omit,
+ max_faves: int | Omit = omit,
+ max_id: str | Omit = omit,
+ max_quotes: int | Omit = omit,
+ max_replies: int | Omit = omit,
+ max_retweets: int | Omit = omit,
media_type: Literal["images", "videos", "gifs", "media", "links", "none"] | Omit = omit,
mentioning: str | Omit = omit,
+ min_bookmarks: int | Omit = omit,
min_faves: int | Omit = omit,
min_quotes: int | Omit = omit,
min_replies: int | Omit = omit,
min_retweets: int | Omit = omit,
+ min_views: int | Omit = omit,
+ native_retweets: bool | Omit = omit,
+ near: str | Omit = omit,
+ news: bool | Omit = omit,
page_size: int | Omit = omit,
quotes: Literal["include", "exclude", "only"] | Omit = omit,
quotes_of_tweet_id: str | Omit = omit,
replies: Literal["include", "exclude", "only"] | Omit = omit,
retweets: Literal["include", "exclude", "only"] | Omit = omit,
retweets_of_tweet_id: str | Omit = omit,
+ safe: bool | Omit = omit,
since_date: Union[str, date] | Omit = omit,
+ since_id: str | Omit = omit,
since_time: str | Omit = omit,
+ source: str | Omit = omit,
to_user: str | Omit = omit,
until_date: Union[str, date] | Omit = omit,
until_time: str | Omit = omit,
url: str | Omit = omit,
verified_only: bool | Omit = omit,
+ within: str | Omit = omit,
+ within_time: str | Omit = omit,
# Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
# The extra values given here take precedence over values defined on the client or passed to this method.
extra_headers: Headers | None = None,
@@ -714,6 +1075,10 @@ def retrieve_mentions(
any_words: Words or quoted phrases where any one can match. Separate with spaces, commas,
or lines.
+ blue_verified_only: Only return tweets from Blue-verified authors.
+
+ card_name: Match the Tweet card name.
+
cashtags: Cashtags separated by spaces, commas, or lines.
conversation_id: Conversation ID filter.
@@ -722,20 +1087,36 @@ def retrieve_mentions(
exact_phrase: Exact phrase to match.
+ exclude_source: Exclude a source application.
+
exclude_words: Words or quoted phrases to exclude. Separate with spaces, commas, or lines.
from_user: Filter by author username.
+ geocode: Match latitude, longitude, and radius.
+
hashtags: Hashtags separated by spaces, commas, or lines.
in_reply_to_tweet_id: Only replies to this tweet ID.
language: Language code filter, e.g. en or tr.
+ max_faves: Maximum likes threshold. maxLikes is also accepted.
+
+ max_id: Return Tweets older than this Tweet ID.
+
+ max_quotes: Maximum quotes threshold.
+
+ max_replies: Maximum replies threshold.
+
+ max_retweets: Maximum retweets threshold.
+
media_type: Filter by media type.
mentioning: Filter tweets mentioning a username.
+ min_bookmarks: Minimum bookmark count threshold.
+
min_faves: Minimum likes threshold.
min_quotes: Minimum quote count threshold.
@@ -744,6 +1125,14 @@ def retrieve_mentions(
min_retweets: Minimum retweets threshold.
+ min_views: Minimum view count threshold.
+
+ native_retweets: Only return native reposts.
+
+ near: Match a place name.
+
+ news: Only return news results.
+
page_size: Maximum page items (1-100, default 20). Source, filters, or credits can reduce
results. Continue while has_next_page is true. Deprecated limit and count
aliases remain accepted.
@@ -758,10 +1147,16 @@ def retrieve_mentions(
retweets_of_tweet_id: Only retweets of this tweet ID.
+ safe: Enable the safe-search filter.
+
since_date: Start date in YYYY-MM-DD format.
+ since_id: Return Tweets newer than this Tweet ID.
+
since_time: Unix timestamp - return mentions after this time
+ source: Match the source application.
+
to_user: Filter replies sent to a username.
until_date: End date in YYYY-MM-DD format.
@@ -772,6 +1167,10 @@ def retrieve_mentions(
verified_only: Only return tweets from verified authors.
+ within: Set the radius for the near filter.
+
+ within_time: Match Tweets inside a recent time window.
+
extra_headers: Send extra headers
extra_query: Add additional query parameters to the request
@@ -792,34 +1191,53 @@ def retrieve_mentions(
query=maybe_transform(
{
"any_words": any_words,
+ "blue_verified_only": blue_verified_only,
+ "card_name": card_name,
"cashtags": cashtags,
"conversation_id": conversation_id,
"cursor": cursor,
"exact_phrase": exact_phrase,
+ "exclude_source": exclude_source,
"exclude_words": exclude_words,
"from_user": from_user,
+ "geocode": geocode,
"hashtags": hashtags,
"in_reply_to_tweet_id": in_reply_to_tweet_id,
"language": language,
+ "max_faves": max_faves,
+ "max_id": max_id,
+ "max_quotes": max_quotes,
+ "max_replies": max_replies,
+ "max_retweets": max_retweets,
"media_type": media_type,
"mentioning": mentioning,
+ "min_bookmarks": min_bookmarks,
"min_faves": min_faves,
"min_quotes": min_quotes,
"min_replies": min_replies,
"min_retweets": min_retweets,
+ "min_views": min_views,
+ "native_retweets": native_retweets,
+ "near": near,
+ "news": news,
"page_size": page_size,
"quotes": quotes,
"quotes_of_tweet_id": quotes_of_tweet_id,
"replies": replies,
"retweets": retweets,
"retweets_of_tweet_id": retweets_of_tweet_id,
+ "safe": safe,
"since_date": since_date,
+ "since_id": since_id,
"since_time": since_time,
+ "source": source,
"to_user": to_user,
"until_date": until_date,
"until_time": until_time,
"url": url,
"verified_only": verified_only,
+ "within": within,
+ "within_time": within_time,
},
user_retrieve_mentions_params.UserRetrieveMentionsParams,
),
@@ -832,33 +1250,52 @@ def retrieve_replies(
id: str,
*,
any_words: str | Omit = omit,
+ blue_verified_only: bool | Omit = omit,
+ card_name: str | Omit = omit,
cashtags: str | Omit = omit,
conversation_id: str | Omit = omit,
cursor: str | Omit = omit,
exact_phrase: str | Omit = omit,
+ exclude_source: str | Omit = omit,
exclude_words: str | Omit = omit,
from_user: str | Omit = omit,
+ geocode: str | Omit = omit,
hashtags: str | Omit = omit,
include_parent_tweet: bool | Omit = omit,
in_reply_to_tweet_id: str | Omit = omit,
language: str | Omit = omit,
+ max_faves: int | Omit = omit,
+ max_id: str | Omit = omit,
+ max_quotes: int | Omit = omit,
+ max_replies: int | Omit = omit,
+ max_retweets: int | Omit = omit,
media_type: Literal["images", "videos", "gifs", "media", "links", "none"] | Omit = omit,
mentioning: str | Omit = omit,
+ min_bookmarks: int | Omit = omit,
min_faves: int | Omit = omit,
min_quotes: int | Omit = omit,
min_replies: int | Omit = omit,
min_retweets: int | Omit = omit,
+ min_views: int | Omit = omit,
+ native_retweets: bool | Omit = omit,
+ near: str | Omit = omit,
+ news: bool | Omit = omit,
page_size: int | Omit = omit,
quotes: Literal["include", "exclude", "only"] | Omit = omit,
quotes_of_tweet_id: str | Omit = omit,
replies: Literal["include", "exclude", "only"] | Omit = omit,
retweets: Literal["include", "exclude", "only"] | Omit = omit,
retweets_of_tweet_id: str | Omit = omit,
+ safe: bool | Omit = omit,
since_date: Union[str, date] | Omit = omit,
+ since_id: str | Omit = omit,
+ source: str | Omit = omit,
to_user: str | Omit = omit,
until_date: Union[str, date] | Omit = omit,
url: str | Omit = omit,
verified_only: bool | Omit = omit,
+ within: str | Omit = omit,
+ within_time: str | Omit = omit,
# Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
# The extra values given here take precedence over values defined on the client or passed to this method.
extra_headers: Headers | None = None,
@@ -866,25 +1303,37 @@ def retrieve_replies(
extra_body: Body | None = None,
timeout: float | httpx.Timeout | None | NotGiven = not_given,
) -> PaginatedTweets:
- """
- Returns the user's timeline with replies included by default.
+ """Returns target-authored posts and replies.
+
+ Omit mode for automatic maximum
+ coverage. Pass next_cursor unchanged. Unprefixed cursors stay legacy. Excludes
+ other-author context.
Args:
any_words: Words or quoted phrases where any one can match. Separate with spaces, commas,
or lines.
+ blue_verified_only: Only return tweets from Blue-verified authors.
+
+ card_name: Match the Tweet card name.
+
cashtags: Cashtags separated by spaces, commas, or lines.
conversation_id: Conversation ID filter.
- cursor: Pagination cursor for user replies
+ cursor: Cursor from the previous response. Xquik cursors resume automatic coverage.
+ Existing unprefixed cursors keep legacy standard behavior.
exact_phrase: Exact phrase to match.
+ exclude_source: Exclude a source application.
+
exclude_words: Words or quoted phrases to exclude. Separate with spaces, commas, or lines.
from_user: Filter by author username.
+ geocode: Match latitude, longitude, and radius.
+
hashtags: Hashtags separated by spaces, commas, or lines.
include_parent_tweet: Include each reply's parent tweet.
@@ -893,10 +1342,22 @@ def retrieve_replies(
language: Language code filter, e.g. en or tr.
+ max_faves: Maximum likes threshold. maxLikes is also accepted.
+
+ max_id: Return Tweets older than this Tweet ID.
+
+ max_quotes: Maximum quotes threshold.
+
+ max_replies: Maximum replies threshold.
+
+ max_retweets: Maximum retweets threshold.
+
media_type: Filter by media type.
mentioning: Filter tweets mentioning a username.
+ min_bookmarks: Minimum bookmark count threshold.
+
min_faves: Minimum likes threshold.
min_quotes: Minimum quote count threshold.
@@ -905,9 +1366,16 @@ def retrieve_replies(
min_retweets: Minimum retweets threshold.
- page_size: Maximum page items (1-100, default 20). Source, filters, or credits can reduce
- results. Continue while has_next_page is true. Deprecated limit and count
- aliases remain accepted.
+ min_views: Minimum view count threshold.
+
+ native_retweets: Only return native reposts.
+
+ near: Match a place name.
+
+ news: Only return news results.
+
+ page_size: Automatic pages accept 1-300 Tweets. Standard pages keep 1-100. Default 20.
+ Continue while has_next_page is true. Deprecated aliases remain accepted.
quotes: Quote mode.
@@ -919,8 +1387,14 @@ def retrieve_replies(
retweets_of_tweet_id: Only retweets of this tweet ID.
+ safe: Enable the safe-search filter.
+
since_date: Start date in YYYY-MM-DD format.
+ since_id: Return Tweets newer than this Tweet ID.
+
+ source: Match the source application.
+
to_user: Filter replies sent to a username.
until_date: End date in YYYY-MM-DD format.
@@ -929,6 +1403,10 @@ def retrieve_replies(
verified_only: Only return tweets from verified authors.
+ within: Set the radius for the near filter.
+
+ within_time: Match Tweets inside a recent time window.
+
extra_headers: Send extra headers
extra_query: Add additional query parameters to the request
@@ -949,33 +1427,52 @@ def retrieve_replies(
query=maybe_transform(
{
"any_words": any_words,
+ "blue_verified_only": blue_verified_only,
+ "card_name": card_name,
"cashtags": cashtags,
"conversation_id": conversation_id,
"cursor": cursor,
"exact_phrase": exact_phrase,
+ "exclude_source": exclude_source,
"exclude_words": exclude_words,
"from_user": from_user,
+ "geocode": geocode,
"hashtags": hashtags,
"include_parent_tweet": include_parent_tweet,
"in_reply_to_tweet_id": in_reply_to_tweet_id,
"language": language,
+ "max_faves": max_faves,
+ "max_id": max_id,
+ "max_quotes": max_quotes,
+ "max_replies": max_replies,
+ "max_retweets": max_retweets,
"media_type": media_type,
"mentioning": mentioning,
+ "min_bookmarks": min_bookmarks,
"min_faves": min_faves,
"min_quotes": min_quotes,
"min_replies": min_replies,
"min_retweets": min_retweets,
+ "min_views": min_views,
+ "native_retweets": native_retweets,
+ "near": near,
+ "news": news,
"page_size": page_size,
"quotes": quotes,
"quotes_of_tweet_id": quotes_of_tweet_id,
"replies": replies,
"retweets": retweets,
"retweets_of_tweet_id": retweets_of_tweet_id,
+ "safe": safe,
"since_date": since_date,
+ "since_id": since_id,
+ "source": source,
"to_user": to_user,
"until_date": until_date,
"url": url,
"verified_only": verified_only,
+ "within": within,
+ "within_time": within_time,
},
user_retrieve_replies_params.UserRetrieveRepliesParams,
),
@@ -987,7 +1484,21 @@ def retrieve_search(
self,
*,
q: str,
+ bio_contains: str | Omit = omit,
cursor: str | Omit = omit,
+ has_location: bool | Omit = omit,
+ has_website: bool | Omit = omit,
+ location_contains: str | Omit = omit,
+ max_followers: int | Omit = omit,
+ max_following: int | Omit = omit,
+ max_statuses: int | Omit = omit,
+ min_account_age_days: int | Omit = omit,
+ min_followers: int | Omit = omit,
+ min_following: int | Omit = omit,
+ min_statuses: int | Omit = omit,
+ username_contains: str | Omit = omit,
+ verified_only: bool | Omit = omit,
+ verified_type: str | Omit = omit,
# Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
# The extra values given here take precedence over values defined on the client or passed to this method.
extra_headers: Headers | None = None,
@@ -1001,8 +1512,36 @@ def retrieve_search(
Args:
q: User search query
+ bio_contains: Match any comma-separated or line-separated bio term, ignoring case.
+
cursor: Pagination cursor for user search
+ has_location: Only return profiles with a location.
+
+ has_website: Only return profiles with a website.
+
+ location_contains: Match a location substring, ignoring case.
+
+ max_followers: Maximum follower count. Missing counts pass this maximum.
+
+ max_following: Maximum following count.
+
+ max_statuses: Maximum post count. maxPosts is also accepted.
+
+ min_account_age_days: Minimum account age in whole days.
+
+ min_followers: Minimum follower count. Filtering happens before billing.
+
+ min_following: Minimum following count.
+
+ min_statuses: Minimum post count. minPosts is also accepted.
+
+ username_contains: Match a username substring, ignoring case.
+
+ verified_only: Only return verified profiles.
+
+ verified_type: Match the verification type exactly, ignoring case.
+
extra_headers: Send extra headers
extra_query: Add additional query parameters to the request
@@ -1021,7 +1560,21 @@ def retrieve_search(
query=maybe_transform(
{
"q": q,
+ "bio_contains": bio_contains,
"cursor": cursor,
+ "has_location": has_location,
+ "has_website": has_website,
+ "location_contains": location_contains,
+ "max_followers": max_followers,
+ "max_following": max_following,
+ "max_statuses": max_statuses,
+ "min_account_age_days": min_account_age_days,
+ "min_followers": min_followers,
+ "min_following": min_following,
+ "min_statuses": min_statuses,
+ "username_contains": username_contains,
+ "verified_only": verified_only,
+ "verified_type": verified_type,
},
user_retrieve_search_params.UserRetrieveSearchParams,
),
@@ -1034,34 +1587,53 @@ def retrieve_tweets(
id: str,
*,
any_words: str | Omit = omit,
+ blue_verified_only: bool | Omit = omit,
+ card_name: str | Omit = omit,
cashtags: str | Omit = omit,
conversation_id: str | Omit = omit,
cursor: str | Omit = omit,
exact_phrase: str | Omit = omit,
+ exclude_source: str | Omit = omit,
exclude_words: str | Omit = omit,
from_user: str | Omit = omit,
+ geocode: str | Omit = omit,
hashtags: str | Omit = omit,
include_parent_tweet: bool | Omit = omit,
include_replies: bool | Omit = omit,
in_reply_to_tweet_id: str | Omit = omit,
language: str | Omit = omit,
+ max_faves: int | Omit = omit,
+ max_id: str | Omit = omit,
+ max_quotes: int | Omit = omit,
+ max_replies: int | Omit = omit,
+ max_retweets: int | Omit = omit,
media_type: Literal["images", "videos", "gifs", "media", "links", "none"] | Omit = omit,
mentioning: str | Omit = omit,
+ min_bookmarks: int | Omit = omit,
min_faves: int | Omit = omit,
min_quotes: int | Omit = omit,
min_replies: int | Omit = omit,
min_retweets: int | Omit = omit,
+ min_views: int | Omit = omit,
+ native_retweets: bool | Omit = omit,
+ near: str | Omit = omit,
+ news: bool | Omit = omit,
page_size: int | Omit = omit,
quotes: Literal["include", "exclude", "only"] | Omit = omit,
quotes_of_tweet_id: str | Omit = omit,
replies: Literal["include", "exclude", "only"] | Omit = omit,
retweets: Literal["include", "exclude", "only"] | Omit = omit,
retweets_of_tweet_id: str | Omit = omit,
+ safe: bool | Omit = omit,
since_date: Union[str, date] | Omit = omit,
+ since_id: str | Omit = omit,
+ source: str | Omit = omit,
to_user: str | Omit = omit,
until_date: Union[str, date] | Omit = omit,
url: str | Omit = omit,
verified_only: bool | Omit = omit,
+ within: str | Omit = omit,
+ within_time: str | Omit = omit,
# Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
# The extra values given here take precedence over values defined on the client or passed to this method.
extra_headers: Headers | None = None,
@@ -1069,25 +1641,36 @@ def retrieve_tweets(
extra_body: Body | None = None,
timeout: float | httpx.Timeout | None | NotGiven = not_given,
) -> PaginatedTweets:
- """
- List recent tweets posted by a user
+ """Omit mode for automatic maximum coverage.
+
+ Pass next_cursor unchanged. Unprefixed
+ cursors use legacy pagination. Shape and billing stay the same.
Args:
any_words: Words or quoted phrases where any one can match. Separate with spaces, commas,
or lines.
+ blue_verified_only: Only return tweets from Blue-verified authors.
+
+ card_name: Match the Tweet card name.
+
cashtags: Cashtags separated by spaces, commas, or lines.
conversation_id: Conversation ID filter.
- cursor: Pagination cursor for user tweets
+ cursor: Cursor from the previous response. Xquik cursors resume automatic coverage.
+ Existing unprefixed cursors keep legacy standard behavior.
exact_phrase: Exact phrase to match.
+ exclude_source: Exclude a source application.
+
exclude_words: Words or quoted phrases to exclude. Separate with spaces, commas, or lines.
from_user: Filter by author username.
+ geocode: Match latitude, longitude, and radius.
+
hashtags: Hashtags separated by spaces, commas, or lines.
include_parent_tweet: Include parent tweet for replies
@@ -1098,10 +1681,22 @@ def retrieve_tweets(
language: Language code filter, e.g. en or tr.
+ max_faves: Maximum likes threshold. maxLikes is also accepted.
+
+ max_id: Return Tweets older than this Tweet ID.
+
+ max_quotes: Maximum quotes threshold.
+
+ max_replies: Maximum replies threshold.
+
+ max_retweets: Maximum retweets threshold.
+
media_type: Filter by media type.
mentioning: Filter tweets mentioning a username.
+ min_bookmarks: Minimum bookmark count threshold.
+
min_faves: Minimum likes threshold.
min_quotes: Minimum quote count threshold.
@@ -1110,9 +1705,16 @@ def retrieve_tweets(
min_retweets: Minimum retweets threshold.
- page_size: Maximum page items (1-100, default 20). Source, filters, or credits can reduce
- results. Continue while has_next_page is true. Deprecated limit and count
- aliases remain accepted.
+ min_views: Minimum view count threshold.
+
+ native_retweets: Only return native reposts.
+
+ near: Match a place name.
+
+ news: Only return news results.
+
+ page_size: Automatic pages accept 1-300 Tweets. Standard pages keep 1-100. Default 20.
+ Continue while has_next_page is true. Deprecated aliases remain accepted.
quotes: Quote mode.
@@ -1124,8 +1726,14 @@ def retrieve_tweets(
retweets_of_tweet_id: Only retweets of this tweet ID.
+ safe: Enable the safe-search filter.
+
since_date: Start date in YYYY-MM-DD format.
+ since_id: Return Tweets newer than this Tweet ID.
+
+ source: Match the source application.
+
to_user: Filter replies sent to a username.
until_date: End date in YYYY-MM-DD format.
@@ -1134,6 +1742,10 @@ def retrieve_tweets(
verified_only: Only return tweets from verified authors.
+ within: Set the radius for the near filter.
+
+ within_time: Match Tweets inside a recent time window.
+
extra_headers: Send extra headers
extra_query: Add additional query parameters to the request
@@ -1154,34 +1766,53 @@ def retrieve_tweets(
query=maybe_transform(
{
"any_words": any_words,
+ "blue_verified_only": blue_verified_only,
+ "card_name": card_name,
"cashtags": cashtags,
"conversation_id": conversation_id,
"cursor": cursor,
"exact_phrase": exact_phrase,
+ "exclude_source": exclude_source,
"exclude_words": exclude_words,
"from_user": from_user,
+ "geocode": geocode,
"hashtags": hashtags,
"include_parent_tweet": include_parent_tweet,
"include_replies": include_replies,
"in_reply_to_tweet_id": in_reply_to_tweet_id,
"language": language,
+ "max_faves": max_faves,
+ "max_id": max_id,
+ "max_quotes": max_quotes,
+ "max_replies": max_replies,
+ "max_retweets": max_retweets,
"media_type": media_type,
"mentioning": mentioning,
+ "min_bookmarks": min_bookmarks,
"min_faves": min_faves,
"min_quotes": min_quotes,
"min_replies": min_replies,
"min_retweets": min_retweets,
+ "min_views": min_views,
+ "native_retweets": native_retweets,
+ "near": near,
+ "news": news,
"page_size": page_size,
"quotes": quotes,
"quotes_of_tweet_id": quotes_of_tweet_id,
"replies": replies,
"retweets": retweets,
"retweets_of_tweet_id": retweets_of_tweet_id,
+ "safe": safe,
"since_date": since_date,
+ "since_id": since_id,
+ "source": source,
"to_user": to_user,
"until_date": until_date,
"url": url,
"verified_only": verified_only,
+ "within": within,
+ "within_time": within_time,
},
user_retrieve_tweets_params.UserRetrieveTweetsParams,
),
@@ -1193,25 +1824,78 @@ def retrieve_verified_followers(
self,
id: str,
*,
+ after: str | Omit = omit,
+ bio_contains: str | Omit = omit,
cursor: str | Omit = omit,
+ has_location: bool | Omit = omit,
+ has_website: bool | Omit = omit,
+ limit: int | Omit = omit,
+ location_contains: str | Omit = omit,
+ max_followers: int | Omit = omit,
+ max_following: int | Omit = omit,
+ max_statuses: int | Omit = omit,
+ min_account_age_days: int | Omit = omit,
+ min_followers: int | Omit = omit,
+ min_following: int | Omit = omit,
+ min_statuses: int | Omit = omit,
+ mode: Literal["standard", "coverage"] | Omit = omit,
page_size: int | Omit = omit,
+ username_contains: str | Omit = omit,
+ verified_only: bool | Omit = omit,
+ verified_type: str | Omit = omit,
# Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
# The extra values given here take precedence over values defined on the client or passed to this method.
extra_headers: Headers | None = None,
extra_query: Query | None = None,
extra_body: Body | None = None,
timeout: float | httpx.Timeout | None | NotGiven = not_given,
- ) -> PaginatedUsers:
- """
- List verified followers of a user
+ ) -> UserRetrieveVerifiedFollowersResponse:
+ """List verified followers of a user
Args:
- cursor: Pagination cursor for verified followers
+ after: Legacy cursor alias.
+
+ Prefer cursor.
- page_size: Maximum user profiles requested from this page (20-200, default 200). The
- response can contain fewer profiles because the source returned fewer or
- remaining credits cover fewer results. Keep requesting next_cursor while
- has_next_page is true. The deprecated limit and count aliases remain accepted.
+ bio_contains: Match any comma-separated or line-separated bio term, ignoring case.
+
+ cursor: Cursor from the previous response. Xquik cursors resume automatic coverage.
+ Existing unprefixed cursors keep legacy standard behavior.
+
+ has_location: Only return profiles with a location.
+
+ has_website: Only return profiles with a website.
+
+ limit: Legacy page-size alias outside explicit coverage mode. Coverage accepts 1-10000.
+ Prefer pageSize.
+
+ location_contains: Match a location substring, ignoring case.
+
+ max_followers: Maximum follower count. Missing counts pass this maximum.
+
+ max_following: Maximum following count.
+
+ max_statuses: Maximum post count. maxPosts is also accepted.
+
+ min_account_age_days: Minimum account age in whole days.
+
+ min_followers: Minimum follower count. Filtering happens before billing.
+
+ min_following: Minimum following count.
+
+ min_statuses: Minimum post count. minPosts is also accepted.
+
+ mode: Omit mode for resumable maximum coverage. Standard keeps legacy pagination.
+ Coverage returns diagnostics once and rejects cursors.
+
+ page_size: Maximum user profiles: automatic 300; standard 200. Sources return fewer
+ profiles. Continue with has_next_page.
+
+ username_contains: Match a username substring, ignoring case.
+
+ verified_only: Only return verified profiles.
+
+ verified_type: Match the verification type exactly, ignoring case.
extra_headers: Send extra headers
@@ -1223,22 +1907,44 @@ def retrieve_verified_followers(
"""
if not id:
raise ValueError(f"Expected a non-empty value for `id` but received {id!r}")
- return self._get(
- path_template("/x/users/{id}/verified-followers", id=id),
- options=make_request_options(
- extra_headers=extra_headers,
- extra_query=extra_query,
- extra_body=extra_body,
- timeout=timeout,
- query=maybe_transform(
- {
- "cursor": cursor,
- "page_size": page_size,
- },
- user_retrieve_verified_followers_params.UserRetrieveVerifiedFollowersParams,
+ return cast(
+ UserRetrieveVerifiedFollowersResponse,
+ self._get(
+ path_template("/x/users/{id}/verified-followers", id=id),
+ options=make_request_options(
+ extra_headers=extra_headers,
+ extra_query=extra_query,
+ extra_body=extra_body,
+ timeout=timeout,
+ query=maybe_transform(
+ {
+ "after": after,
+ "bio_contains": bio_contains,
+ "cursor": cursor,
+ "has_location": has_location,
+ "has_website": has_website,
+ "limit": limit,
+ "location_contains": location_contains,
+ "max_followers": max_followers,
+ "max_following": max_following,
+ "max_statuses": max_statuses,
+ "min_account_age_days": min_account_age_days,
+ "min_followers": min_followers,
+ "min_following": min_following,
+ "min_statuses": min_statuses,
+ "mode": mode,
+ "page_size": page_size,
+ "username_contains": username_contains,
+ "verified_only": verified_only,
+ "verified_type": verified_type,
+ },
+ user_retrieve_verified_followers_params.UserRetrieveVerifiedFollowersParams,
+ ),
),
+ cast_to=cast(
+ Any, UserRetrieveVerifiedFollowersResponse
+ ), # Union types cannot be passed in as arguments in the type system
),
- cast_to=PaginatedUsers,
)
@@ -1384,16 +2090,31 @@ async def retrieve_followers(
id: str,
*,
after: str | Omit = omit,
+ bio_contains: str | Omit = omit,
cursor: str | Omit = omit,
+ has_location: bool | Omit = omit,
+ has_website: bool | Omit = omit,
limit: int | Omit = omit,
+ location_contains: str | Omit = omit,
+ max_followers: int | Omit = omit,
+ max_following: int | Omit = omit,
+ max_statuses: int | Omit = omit,
+ min_account_age_days: int | Omit = omit,
+ min_followers: int | Omit = omit,
+ min_following: int | Omit = omit,
+ min_statuses: int | Omit = omit,
+ mode: Literal["standard", "coverage"] | Omit = omit,
page_size: int | Omit = omit,
+ username_contains: str | Omit = omit,
+ verified_only: bool | Omit = omit,
+ verified_type: str | Omit = omit,
# Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
# The extra values given here take precedence over values defined on the client or passed to this method.
extra_headers: Headers | None = None,
extra_query: Query | None = None,
extra_body: Body | None = None,
timeout: float | httpx.Timeout | None | NotGiven = not_given,
- ) -> PaginatedUsers:
+ ) -> UserRetrieveFollowersResponse:
"""List followers of a user
Args:
@@ -1401,14 +2122,45 @@ async def retrieve_followers(
Prefer cursor.
- cursor: Pagination cursor for followers list
+ bio_contains: Match any comma-separated or line-separated bio term, ignoring case.
+
+ cursor: Cursor from the previous response. Xquik cursors resume automatic coverage.
+ Existing unprefixed cursors keep legacy standard behavior.
+
+ has_location: Only return profiles with a location.
+
+ has_website: Only return profiles with a website.
+
+ limit: Legacy page-size alias outside explicit coverage mode. Coverage accepts 1-10000.
+ Prefer pageSize.
+
+ location_contains: Match a location substring, ignoring case.
+
+ max_followers: Maximum follower count. Missing counts pass this maximum.
+
+ max_following: Maximum following count.
+
+ max_statuses: Maximum post count. maxPosts is also accepted.
+
+ min_account_age_days: Minimum account age in whole days.
+
+ min_followers: Minimum follower count. Filtering happens before billing.
+
+ min_following: Minimum following count.
+
+ min_statuses: Minimum post count. minPosts is also accepted.
+
+ mode: Omit mode for resumable maximum coverage. Standard keeps legacy pagination.
+ Coverage returns diagnostics once and rejects cursors.
- limit: Legacy integer page size alias for following lists. Prefer pageSize.
+ page_size: Maximum user profiles: automatic 300; standard 200. Sources return fewer
+ profiles. Continue with has_next_page.
- page_size: Maximum user profiles requested from this page (20-200, default 200). The
- response can contain fewer profiles because the source returned fewer or
- remaining credits cover fewer results. Keep requesting next_cursor while
- has_next_page is true. The deprecated limit and count aliases remain accepted.
+ username_contains: Match a username substring, ignoring case.
+
+ verified_only: Only return verified profiles.
+
+ verified_type: Match the verification type exactly, ignoring case.
extra_headers: Send extra headers
@@ -1420,32 +2172,66 @@ async def retrieve_followers(
"""
if not id:
raise ValueError(f"Expected a non-empty value for `id` but received {id!r}")
- return await self._get(
- path_template("/x/users/{id}/followers", id=id),
- options=make_request_options(
- extra_headers=extra_headers,
- extra_query=extra_query,
- extra_body=extra_body,
- timeout=timeout,
- query=await async_maybe_transform(
- {
- "after": after,
- "cursor": cursor,
- "limit": limit,
- "page_size": page_size,
- },
- user_retrieve_followers_params.UserRetrieveFollowersParams,
+ return cast(
+ UserRetrieveFollowersResponse,
+ await self._get(
+ path_template("/x/users/{id}/followers", id=id),
+ options=make_request_options(
+ extra_headers=extra_headers,
+ extra_query=extra_query,
+ extra_body=extra_body,
+ timeout=timeout,
+ query=await async_maybe_transform(
+ {
+ "after": after,
+ "bio_contains": bio_contains,
+ "cursor": cursor,
+ "has_location": has_location,
+ "has_website": has_website,
+ "limit": limit,
+ "location_contains": location_contains,
+ "max_followers": max_followers,
+ "max_following": max_following,
+ "max_statuses": max_statuses,
+ "min_account_age_days": min_account_age_days,
+ "min_followers": min_followers,
+ "min_following": min_following,
+ "min_statuses": min_statuses,
+ "mode": mode,
+ "page_size": page_size,
+ "username_contains": username_contains,
+ "verified_only": verified_only,
+ "verified_type": verified_type,
+ },
+ user_retrieve_followers_params.UserRetrieveFollowersParams,
+ ),
),
+ cast_to=cast(
+ Any, UserRetrieveFollowersResponse
+ ), # Union types cannot be passed in as arguments in the type system
),
- cast_to=PaginatedUsers,
)
async def retrieve_followers_you_know(
self,
id: str,
*,
+ bio_contains: str | Omit = omit,
cursor: str | Omit = omit,
+ has_location: bool | Omit = omit,
+ has_website: bool | Omit = omit,
+ location_contains: str | Omit = omit,
+ max_followers: int | Omit = omit,
+ max_following: int | Omit = omit,
+ max_statuses: int | Omit = omit,
+ min_account_age_days: int | Omit = omit,
+ min_followers: int | Omit = omit,
+ min_following: int | Omit = omit,
+ min_statuses: int | Omit = omit,
page_size: int | Omit = omit,
+ username_contains: str | Omit = omit,
+ verified_only: bool | Omit = omit,
+ verified_type: str | Omit = omit,
# Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
# The extra values given here take precedence over values defined on the client or passed to this method.
extra_headers: Headers | None = None,
@@ -1457,12 +2243,39 @@ async def retrieve_followers_you_know(
List mutual followers between you and a user
Args:
+ bio_contains: Match any comma-separated or line-separated bio term, ignoring case.
+
cursor: Pagination cursor for followers-you-know
- page_size: Maximum user profiles requested from this page (20-200, default 200). The
- response can contain fewer profiles because the source returned fewer or
- remaining credits cover fewer results. Keep requesting next_cursor while
- has_next_page is true. The deprecated limit and count aliases remain accepted.
+ has_location: Only return profiles with a location.
+
+ has_website: Only return profiles with a website.
+
+ location_contains: Match a location substring, ignoring case.
+
+ max_followers: Maximum follower count. Missing counts pass this maximum.
+
+ max_following: Maximum following count.
+
+ max_statuses: Maximum post count. maxPosts is also accepted.
+
+ min_account_age_days: Minimum account age in whole days.
+
+ min_followers: Minimum follower count. Filtering happens before billing.
+
+ min_following: Minimum following count.
+
+ min_statuses: Minimum post count. minPosts is also accepted.
+
+ page_size: Maximum user profiles requested from this page (20-200, default 200). Source,
+ filters, or credits can return fewer profiles. Keep requesting next_cursor while
+ has_next_page is true. Deprecated aliases remain accepted.
+
+ username_contains: Match a username substring, ignoring case.
+
+ verified_only: Only return verified profiles.
+
+ verified_type: Match the verification type exactly, ignoring case.
extra_headers: Send extra headers
@@ -1483,8 +2296,22 @@ async def retrieve_followers_you_know(
timeout=timeout,
query=await async_maybe_transform(
{
+ "bio_contains": bio_contains,
"cursor": cursor,
+ "has_location": has_location,
+ "has_website": has_website,
+ "location_contains": location_contains,
+ "max_followers": max_followers,
+ "max_following": max_following,
+ "max_statuses": max_statuses,
+ "min_account_age_days": min_account_age_days,
+ "min_followers": min_followers,
+ "min_following": min_following,
+ "min_statuses": min_statuses,
"page_size": page_size,
+ "username_contains": username_contains,
+ "verified_only": verified_only,
+ "verified_type": verified_type,
},
user_retrieve_followers_you_know_params.UserRetrieveFollowersYouKnowParams,
),
@@ -1497,16 +2324,31 @@ async def retrieve_following(
id: str,
*,
after: str | Omit = omit,
+ bio_contains: str | Omit = omit,
cursor: str | Omit = omit,
+ has_location: bool | Omit = omit,
+ has_website: bool | Omit = omit,
limit: int | Omit = omit,
+ location_contains: str | Omit = omit,
+ max_followers: int | Omit = omit,
+ max_following: int | Omit = omit,
+ max_statuses: int | Omit = omit,
+ min_account_age_days: int | Omit = omit,
+ min_followers: int | Omit = omit,
+ min_following: int | Omit = omit,
+ min_statuses: int | Omit = omit,
+ mode: Literal["standard", "coverage"] | Omit = omit,
page_size: int | Omit = omit,
+ username_contains: str | Omit = omit,
+ verified_only: bool | Omit = omit,
+ verified_type: str | Omit = omit,
# Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
# The extra values given here take precedence over values defined on the client or passed to this method.
extra_headers: Headers | None = None,
extra_query: Query | None = None,
extra_body: Body | None = None,
timeout: float | httpx.Timeout | None | NotGiven = not_given,
- ) -> PaginatedUsers:
+ ) -> UserRetrieveFollowingResponse:
"""List accounts a user follows
Args:
@@ -1514,14 +2356,45 @@ async def retrieve_following(
Prefer cursor.
- cursor: Pagination cursor for following list
+ bio_contains: Match any comma-separated or line-separated bio term, ignoring case.
+
+ cursor: Cursor from the previous response. Xquik cursors resume automatic coverage.
+ Existing unprefixed cursors keep legacy standard behavior.
+
+ has_location: Only return profiles with a location.
+
+ has_website: Only return profiles with a website.
+
+ limit: Legacy page-size alias outside explicit coverage mode. Coverage accepts 1-10000.
+ Prefer pageSize.
+
+ location_contains: Match a location substring, ignoring case.
+
+ max_followers: Maximum follower count. Missing counts pass this maximum.
+
+ max_following: Maximum following count.
+
+ max_statuses: Maximum post count. maxPosts is also accepted.
+
+ min_account_age_days: Minimum account age in whole days.
+
+ min_followers: Minimum follower count. Filtering happens before billing.
+
+ min_following: Minimum following count.
- limit: Legacy page size alias. Prefer pageSize.
+ min_statuses: Minimum post count. minPosts is also accepted.
- page_size: Maximum user profiles requested from this page (20-200, default 200). The
- response can contain fewer profiles because the source returned fewer or
- remaining credits cover fewer results. Keep requesting next_cursor while
- has_next_page is true. The deprecated limit and count aliases remain accepted.
+ mode: Omit mode for resumable maximum coverage. Standard keeps legacy pagination.
+ Coverage returns diagnostics once and rejects cursors.
+
+ page_size: Maximum user profiles: automatic 300; standard 200. Sources return fewer
+ profiles. Continue with has_next_page.
+
+ username_contains: Match a username substring, ignoring case.
+
+ verified_only: Only return verified profiles.
+
+ verified_type: Match the verification type exactly, ignoring case.
extra_headers: Send extra headers
@@ -1533,24 +2406,44 @@ async def retrieve_following(
"""
if not id:
raise ValueError(f"Expected a non-empty value for `id` but received {id!r}")
- return await self._get(
- path_template("/x/users/{id}/following", id=id),
- options=make_request_options(
- extra_headers=extra_headers,
- extra_query=extra_query,
- extra_body=extra_body,
- timeout=timeout,
- query=await async_maybe_transform(
- {
- "after": after,
- "cursor": cursor,
- "limit": limit,
- "page_size": page_size,
- },
- user_retrieve_following_params.UserRetrieveFollowingParams,
+ return cast(
+ UserRetrieveFollowingResponse,
+ await self._get(
+ path_template("/x/users/{id}/following", id=id),
+ options=make_request_options(
+ extra_headers=extra_headers,
+ extra_query=extra_query,
+ extra_body=extra_body,
+ timeout=timeout,
+ query=await async_maybe_transform(
+ {
+ "after": after,
+ "bio_contains": bio_contains,
+ "cursor": cursor,
+ "has_location": has_location,
+ "has_website": has_website,
+ "limit": limit,
+ "location_contains": location_contains,
+ "max_followers": max_followers,
+ "max_following": max_following,
+ "max_statuses": max_statuses,
+ "min_account_age_days": min_account_age_days,
+ "min_followers": min_followers,
+ "min_following": min_following,
+ "min_statuses": min_statuses,
+ "mode": mode,
+ "page_size": page_size,
+ "username_contains": username_contains,
+ "verified_only": verified_only,
+ "verified_type": verified_type,
+ },
+ user_retrieve_following_params.UserRetrieveFollowingParams,
+ ),
),
+ cast_to=cast(
+ Any, UserRetrieveFollowingResponse
+ ), # Union types cannot be passed in as arguments in the type system
),
- cast_to=PaginatedUsers,
)
async def retrieve_likes(
@@ -1558,32 +2451,51 @@ async def retrieve_likes(
id: str,
*,
any_words: str | Omit = omit,
+ blue_verified_only: bool | Omit = omit,
+ card_name: str | Omit = omit,
cashtags: str | Omit = omit,
conversation_id: str | Omit = omit,
cursor: str | Omit = omit,
exact_phrase: str | Omit = omit,
+ exclude_source: str | Omit = omit,
exclude_words: str | Omit = omit,
from_user: str | Omit = omit,
+ geocode: str | Omit = omit,
hashtags: str | Omit = omit,
in_reply_to_tweet_id: str | Omit = omit,
language: str | Omit = omit,
+ max_faves: int | Omit = omit,
+ max_id: str | Omit = omit,
+ max_quotes: int | Omit = omit,
+ max_replies: int | Omit = omit,
+ max_retweets: int | Omit = omit,
media_type: Literal["images", "videos", "gifs", "media", "links", "none"] | Omit = omit,
mentioning: str | Omit = omit,
+ min_bookmarks: int | Omit = omit,
min_faves: int | Omit = omit,
min_quotes: int | Omit = omit,
min_replies: int | Omit = omit,
min_retweets: int | Omit = omit,
+ min_views: int | Omit = omit,
+ native_retweets: bool | Omit = omit,
+ near: str | Omit = omit,
+ news: bool | Omit = omit,
page_size: int | Omit = omit,
quotes: Literal["include", "exclude", "only"] | Omit = omit,
quotes_of_tweet_id: str | Omit = omit,
replies: Literal["include", "exclude", "only"] | Omit = omit,
retweets: Literal["include", "exclude", "only"] | Omit = omit,
retweets_of_tweet_id: str | Omit = omit,
+ safe: bool | Omit = omit,
since_date: Union[str, date] | Omit = omit,
+ since_id: str | Omit = omit,
+ source: str | Omit = omit,
to_user: str | Omit = omit,
until_date: Union[str, date] | Omit = omit,
url: str | Omit = omit,
verified_only: bool | Omit = omit,
+ within: str | Omit = omit,
+ within_time: str | Omit = omit,
# Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
# The extra values given here take precedence over values defined on the client or passed to this method.
extra_headers: Headers | None = None,
@@ -1598,6 +2510,10 @@ async def retrieve_likes(
any_words: Words or quoted phrases where any one can match. Separate with spaces, commas,
or lines.
+ blue_verified_only: Only return tweets from Blue-verified authors.
+
+ card_name: Match the Tweet card name.
+
cashtags: Cashtags separated by spaces, commas, or lines.
conversation_id: Conversation ID filter.
@@ -1606,20 +2522,36 @@ async def retrieve_likes(
exact_phrase: Exact phrase to match.
+ exclude_source: Exclude a source application.
+
exclude_words: Words or quoted phrases to exclude. Separate with spaces, commas, or lines.
from_user: Filter by author username.
+ geocode: Match latitude, longitude, and radius.
+
hashtags: Hashtags separated by spaces, commas, or lines.
in_reply_to_tweet_id: Only replies to this tweet ID.
language: Language code filter, e.g. en or tr.
+ max_faves: Maximum likes threshold. maxLikes is also accepted.
+
+ max_id: Return Tweets older than this Tweet ID.
+
+ max_quotes: Maximum quotes threshold.
+
+ max_replies: Maximum replies threshold.
+
+ max_retweets: Maximum retweets threshold.
+
media_type: Filter by media type.
mentioning: Filter tweets mentioning a username.
+ min_bookmarks: Minimum bookmark count threshold.
+
min_faves: Minimum likes threshold.
min_quotes: Minimum quote count threshold.
@@ -1628,6 +2560,14 @@ async def retrieve_likes(
min_retweets: Minimum retweets threshold.
+ min_views: Minimum view count threshold.
+
+ native_retweets: Only return native reposts.
+
+ near: Match a place name.
+
+ news: Only return news results.
+
page_size: Maximum page items (1-100, default 20). Source, filters, or credits can reduce
results. Continue while has_next_page is true. Deprecated limit and count
aliases remain accepted.
@@ -1642,8 +2582,14 @@ async def retrieve_likes(
retweets_of_tweet_id: Only retweets of this tweet ID.
+ safe: Enable the safe-search filter.
+
since_date: Start date in YYYY-MM-DD format.
+ since_id: Return Tweets newer than this Tweet ID.
+
+ source: Match the source application.
+
to_user: Filter replies sent to a username.
until_date: End date in YYYY-MM-DD format.
@@ -1652,6 +2598,10 @@ async def retrieve_likes(
verified_only: Only return tweets from verified authors.
+ within: Set the radius for the near filter.
+
+ within_time: Match Tweets inside a recent time window.
+
extra_headers: Send extra headers
extra_query: Add additional query parameters to the request
@@ -1672,32 +2622,51 @@ async def retrieve_likes(
query=await async_maybe_transform(
{
"any_words": any_words,
+ "blue_verified_only": blue_verified_only,
+ "card_name": card_name,
"cashtags": cashtags,
"conversation_id": conversation_id,
"cursor": cursor,
"exact_phrase": exact_phrase,
+ "exclude_source": exclude_source,
"exclude_words": exclude_words,
"from_user": from_user,
+ "geocode": geocode,
"hashtags": hashtags,
"in_reply_to_tweet_id": in_reply_to_tweet_id,
"language": language,
+ "max_faves": max_faves,
+ "max_id": max_id,
+ "max_quotes": max_quotes,
+ "max_replies": max_replies,
+ "max_retweets": max_retweets,
"media_type": media_type,
"mentioning": mentioning,
+ "min_bookmarks": min_bookmarks,
"min_faves": min_faves,
"min_quotes": min_quotes,
"min_replies": min_replies,
"min_retweets": min_retweets,
+ "min_views": min_views,
+ "native_retweets": native_retweets,
+ "near": near,
+ "news": news,
"page_size": page_size,
"quotes": quotes,
"quotes_of_tweet_id": quotes_of_tweet_id,
"replies": replies,
"retweets": retweets,
"retweets_of_tweet_id": retweets_of_tweet_id,
+ "safe": safe,
"since_date": since_date,
+ "since_id": since_id,
+ "source": source,
"to_user": to_user,
"until_date": until_date,
"url": url,
"verified_only": verified_only,
+ "within": within,
+ "within_time": within_time,
},
user_retrieve_likes_params.UserRetrieveLikesParams,
),
@@ -1710,32 +2679,51 @@ async def retrieve_media(
id: str,
*,
any_words: str | Omit = omit,
+ blue_verified_only: bool | Omit = omit,
+ card_name: str | Omit = omit,
cashtags: str | Omit = omit,
conversation_id: str | Omit = omit,
cursor: str | Omit = omit,
exact_phrase: str | Omit = omit,
+ exclude_source: str | Omit = omit,
exclude_words: str | Omit = omit,
from_user: str | Omit = omit,
+ geocode: str | Omit = omit,
hashtags: str | Omit = omit,
in_reply_to_tweet_id: str | Omit = omit,
language: str | Omit = omit,
+ max_faves: int | Omit = omit,
+ max_id: str | Omit = omit,
+ max_quotes: int | Omit = omit,
+ max_replies: int | Omit = omit,
+ max_retweets: int | Omit = omit,
media_type: Literal["images", "videos", "gifs", "media", "links", "none"] | Omit = omit,
mentioning: str | Omit = omit,
+ min_bookmarks: int | Omit = omit,
min_faves: int | Omit = omit,
min_quotes: int | Omit = omit,
min_replies: int | Omit = omit,
min_retweets: int | Omit = omit,
+ min_views: int | Omit = omit,
+ native_retweets: bool | Omit = omit,
+ near: str | Omit = omit,
+ news: bool | Omit = omit,
page_size: int | Omit = omit,
quotes: Literal["include", "exclude", "only"] | Omit = omit,
quotes_of_tweet_id: str | Omit = omit,
replies: Literal["include", "exclude", "only"] | Omit = omit,
retweets: Literal["include", "exclude", "only"] | Omit = omit,
retweets_of_tweet_id: str | Omit = omit,
+ safe: bool | Omit = omit,
since_date: Union[str, date] | Omit = omit,
+ since_id: str | Omit = omit,
+ source: str | Omit = omit,
to_user: str | Omit = omit,
until_date: Union[str, date] | Omit = omit,
url: str | Omit = omit,
verified_only: bool | Omit = omit,
+ within: str | Omit = omit,
+ within_time: str | Omit = omit,
# Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
# The extra values given here take precedence over values defined on the client or passed to this method.
extra_headers: Headers | None = None,
@@ -1750,6 +2738,10 @@ async def retrieve_media(
any_words: Words or quoted phrases where any one can match. Separate with spaces, commas,
or lines.
+ blue_verified_only: Only return tweets from Blue-verified authors.
+
+ card_name: Match the Tweet card name.
+
cashtags: Cashtags separated by spaces, commas, or lines.
conversation_id: Conversation ID filter.
@@ -1758,20 +2750,36 @@ async def retrieve_media(
exact_phrase: Exact phrase to match.
+ exclude_source: Exclude a source application.
+
exclude_words: Words or quoted phrases to exclude. Separate with spaces, commas, or lines.
from_user: Filter by author username.
+ geocode: Match latitude, longitude, and radius.
+
hashtags: Hashtags separated by spaces, commas, or lines.
in_reply_to_tweet_id: Only replies to this tweet ID.
language: Language code filter, e.g. en or tr.
+ max_faves: Maximum likes threshold. maxLikes is also accepted.
+
+ max_id: Return Tweets older than this Tweet ID.
+
+ max_quotes: Maximum quotes threshold.
+
+ max_replies: Maximum replies threshold.
+
+ max_retweets: Maximum retweets threshold.
+
media_type: Filter by media type.
mentioning: Filter tweets mentioning a username.
+ min_bookmarks: Minimum bookmark count threshold.
+
min_faves: Minimum likes threshold.
min_quotes: Minimum quote count threshold.
@@ -1780,6 +2788,14 @@ async def retrieve_media(
min_retweets: Minimum retweets threshold.
+ min_views: Minimum view count threshold.
+
+ native_retweets: Only return native reposts.
+
+ near: Match a place name.
+
+ news: Only return news results.
+
page_size: Maximum page items (1-100, default 20). Source, filters, or credits can reduce
results. Continue while has_next_page is true. Deprecated limit and count
aliases remain accepted.
@@ -1794,8 +2810,14 @@ async def retrieve_media(
retweets_of_tweet_id: Only retweets of this tweet ID.
+ safe: Enable the safe-search filter.
+
since_date: Start date in YYYY-MM-DD format.
+ since_id: Return Tweets newer than this Tweet ID.
+
+ source: Match the source application.
+
to_user: Filter replies sent to a username.
until_date: End date in YYYY-MM-DD format.
@@ -1804,6 +2826,10 @@ async def retrieve_media(
verified_only: Only return tweets from verified authors.
+ within: Set the radius for the near filter.
+
+ within_time: Match Tweets inside a recent time window.
+
extra_headers: Send extra headers
extra_query: Add additional query parameters to the request
@@ -1824,32 +2850,51 @@ async def retrieve_media(
query=await async_maybe_transform(
{
"any_words": any_words,
+ "blue_verified_only": blue_verified_only,
+ "card_name": card_name,
"cashtags": cashtags,
"conversation_id": conversation_id,
"cursor": cursor,
"exact_phrase": exact_phrase,
+ "exclude_source": exclude_source,
"exclude_words": exclude_words,
"from_user": from_user,
+ "geocode": geocode,
"hashtags": hashtags,
"in_reply_to_tweet_id": in_reply_to_tweet_id,
"language": language,
+ "max_faves": max_faves,
+ "max_id": max_id,
+ "max_quotes": max_quotes,
+ "max_replies": max_replies,
+ "max_retweets": max_retweets,
"media_type": media_type,
"mentioning": mentioning,
+ "min_bookmarks": min_bookmarks,
"min_faves": min_faves,
"min_quotes": min_quotes,
"min_replies": min_replies,
"min_retweets": min_retweets,
+ "min_views": min_views,
+ "native_retweets": native_retweets,
+ "near": near,
+ "news": news,
"page_size": page_size,
"quotes": quotes,
"quotes_of_tweet_id": quotes_of_tweet_id,
"replies": replies,
"retweets": retweets,
"retweets_of_tweet_id": retweets_of_tweet_id,
+ "safe": safe,
"since_date": since_date,
+ "since_id": since_id,
+ "source": source,
"to_user": to_user,
"until_date": until_date,
"url": url,
"verified_only": verified_only,
+ "within": within,
+ "within_time": within_time,
},
user_retrieve_media_params.UserRetrieveMediaParams,
),
@@ -1862,34 +2907,53 @@ async def retrieve_mentions(
id: str,
*,
any_words: str | Omit = omit,
+ blue_verified_only: bool | Omit = omit,
+ card_name: str | Omit = omit,
cashtags: str | Omit = omit,
conversation_id: str | Omit = omit,
cursor: str | Omit = omit,
exact_phrase: str | Omit = omit,
+ exclude_source: str | Omit = omit,
exclude_words: str | Omit = omit,
from_user: str | Omit = omit,
+ geocode: str | Omit = omit,
hashtags: str | Omit = omit,
in_reply_to_tweet_id: str | Omit = omit,
language: str | Omit = omit,
+ max_faves: int | Omit = omit,
+ max_id: str | Omit = omit,
+ max_quotes: int | Omit = omit,
+ max_replies: int | Omit = omit,
+ max_retweets: int | Omit = omit,
media_type: Literal["images", "videos", "gifs", "media", "links", "none"] | Omit = omit,
mentioning: str | Omit = omit,
+ min_bookmarks: int | Omit = omit,
min_faves: int | Omit = omit,
min_quotes: int | Omit = omit,
min_replies: int | Omit = omit,
min_retweets: int | Omit = omit,
+ min_views: int | Omit = omit,
+ native_retweets: bool | Omit = omit,
+ near: str | Omit = omit,
+ news: bool | Omit = omit,
page_size: int | Omit = omit,
quotes: Literal["include", "exclude", "only"] | Omit = omit,
quotes_of_tweet_id: str | Omit = omit,
replies: Literal["include", "exclude", "only"] | Omit = omit,
retweets: Literal["include", "exclude", "only"] | Omit = omit,
retweets_of_tweet_id: str | Omit = omit,
+ safe: bool | Omit = omit,
since_date: Union[str, date] | Omit = omit,
+ since_id: str | Omit = omit,
since_time: str | Omit = omit,
+ source: str | Omit = omit,
to_user: str | Omit = omit,
until_date: Union[str, date] | Omit = omit,
until_time: str | Omit = omit,
url: str | Omit = omit,
verified_only: bool | Omit = omit,
+ within: str | Omit = omit,
+ within_time: str | Omit = omit,
# Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
# The extra values given here take precedence over values defined on the client or passed to this method.
extra_headers: Headers | None = None,
@@ -1904,6 +2968,10 @@ async def retrieve_mentions(
any_words: Words or quoted phrases where any one can match. Separate with spaces, commas,
or lines.
+ blue_verified_only: Only return tweets from Blue-verified authors.
+
+ card_name: Match the Tweet card name.
+
cashtags: Cashtags separated by spaces, commas, or lines.
conversation_id: Conversation ID filter.
@@ -1912,20 +2980,36 @@ async def retrieve_mentions(
exact_phrase: Exact phrase to match.
+ exclude_source: Exclude a source application.
+
exclude_words: Words or quoted phrases to exclude. Separate with spaces, commas, or lines.
from_user: Filter by author username.
+ geocode: Match latitude, longitude, and radius.
+
hashtags: Hashtags separated by spaces, commas, or lines.
in_reply_to_tweet_id: Only replies to this tweet ID.
language: Language code filter, e.g. en or tr.
+ max_faves: Maximum likes threshold. maxLikes is also accepted.
+
+ max_id: Return Tweets older than this Tweet ID.
+
+ max_quotes: Maximum quotes threshold.
+
+ max_replies: Maximum replies threshold.
+
+ max_retweets: Maximum retweets threshold.
+
media_type: Filter by media type.
mentioning: Filter tweets mentioning a username.
+ min_bookmarks: Minimum bookmark count threshold.
+
min_faves: Minimum likes threshold.
min_quotes: Minimum quote count threshold.
@@ -1934,6 +3018,14 @@ async def retrieve_mentions(
min_retweets: Minimum retweets threshold.
+ min_views: Minimum view count threshold.
+
+ native_retweets: Only return native reposts.
+
+ near: Match a place name.
+
+ news: Only return news results.
+
page_size: Maximum page items (1-100, default 20). Source, filters, or credits can reduce
results. Continue while has_next_page is true. Deprecated limit and count
aliases remain accepted.
@@ -1948,10 +3040,16 @@ async def retrieve_mentions(
retweets_of_tweet_id: Only retweets of this tweet ID.
+ safe: Enable the safe-search filter.
+
since_date: Start date in YYYY-MM-DD format.
+ since_id: Return Tweets newer than this Tweet ID.
+
since_time: Unix timestamp - return mentions after this time
+ source: Match the source application.
+
to_user: Filter replies sent to a username.
until_date: End date in YYYY-MM-DD format.
@@ -1962,6 +3060,10 @@ async def retrieve_mentions(
verified_only: Only return tweets from verified authors.
+ within: Set the radius for the near filter.
+
+ within_time: Match Tweets inside a recent time window.
+
extra_headers: Send extra headers
extra_query: Add additional query parameters to the request
@@ -1982,34 +3084,53 @@ async def retrieve_mentions(
query=await async_maybe_transform(
{
"any_words": any_words,
+ "blue_verified_only": blue_verified_only,
+ "card_name": card_name,
"cashtags": cashtags,
"conversation_id": conversation_id,
"cursor": cursor,
"exact_phrase": exact_phrase,
+ "exclude_source": exclude_source,
"exclude_words": exclude_words,
"from_user": from_user,
+ "geocode": geocode,
"hashtags": hashtags,
"in_reply_to_tweet_id": in_reply_to_tweet_id,
"language": language,
+ "max_faves": max_faves,
+ "max_id": max_id,
+ "max_quotes": max_quotes,
+ "max_replies": max_replies,
+ "max_retweets": max_retweets,
"media_type": media_type,
"mentioning": mentioning,
+ "min_bookmarks": min_bookmarks,
"min_faves": min_faves,
"min_quotes": min_quotes,
"min_replies": min_replies,
"min_retweets": min_retweets,
+ "min_views": min_views,
+ "native_retweets": native_retweets,
+ "near": near,
+ "news": news,
"page_size": page_size,
"quotes": quotes,
"quotes_of_tweet_id": quotes_of_tweet_id,
"replies": replies,
"retweets": retweets,
"retweets_of_tweet_id": retweets_of_tweet_id,
+ "safe": safe,
"since_date": since_date,
+ "since_id": since_id,
"since_time": since_time,
+ "source": source,
"to_user": to_user,
"until_date": until_date,
"until_time": until_time,
"url": url,
"verified_only": verified_only,
+ "within": within,
+ "within_time": within_time,
},
user_retrieve_mentions_params.UserRetrieveMentionsParams,
),
@@ -2022,33 +3143,52 @@ async def retrieve_replies(
id: str,
*,
any_words: str | Omit = omit,
+ blue_verified_only: bool | Omit = omit,
+ card_name: str | Omit = omit,
cashtags: str | Omit = omit,
conversation_id: str | Omit = omit,
cursor: str | Omit = omit,
exact_phrase: str | Omit = omit,
+ exclude_source: str | Omit = omit,
exclude_words: str | Omit = omit,
from_user: str | Omit = omit,
+ geocode: str | Omit = omit,
hashtags: str | Omit = omit,
include_parent_tweet: bool | Omit = omit,
in_reply_to_tweet_id: str | Omit = omit,
language: str | Omit = omit,
+ max_faves: int | Omit = omit,
+ max_id: str | Omit = omit,
+ max_quotes: int | Omit = omit,
+ max_replies: int | Omit = omit,
+ max_retweets: int | Omit = omit,
media_type: Literal["images", "videos", "gifs", "media", "links", "none"] | Omit = omit,
mentioning: str | Omit = omit,
+ min_bookmarks: int | Omit = omit,
min_faves: int | Omit = omit,
min_quotes: int | Omit = omit,
min_replies: int | Omit = omit,
min_retweets: int | Omit = omit,
+ min_views: int | Omit = omit,
+ native_retweets: bool | Omit = omit,
+ near: str | Omit = omit,
+ news: bool | Omit = omit,
page_size: int | Omit = omit,
quotes: Literal["include", "exclude", "only"] | Omit = omit,
quotes_of_tweet_id: str | Omit = omit,
replies: Literal["include", "exclude", "only"] | Omit = omit,
retweets: Literal["include", "exclude", "only"] | Omit = omit,
retweets_of_tweet_id: str | Omit = omit,
+ safe: bool | Omit = omit,
since_date: Union[str, date] | Omit = omit,
+ since_id: str | Omit = omit,
+ source: str | Omit = omit,
to_user: str | Omit = omit,
until_date: Union[str, date] | Omit = omit,
url: str | Omit = omit,
verified_only: bool | Omit = omit,
+ within: str | Omit = omit,
+ within_time: str | Omit = omit,
# Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
# The extra values given here take precedence over values defined on the client or passed to this method.
extra_headers: Headers | None = None,
@@ -2056,25 +3196,37 @@ async def retrieve_replies(
extra_body: Body | None = None,
timeout: float | httpx.Timeout | None | NotGiven = not_given,
) -> PaginatedTweets:
- """
- Returns the user's timeline with replies included by default.
+ """Returns target-authored posts and replies.
+
+ Omit mode for automatic maximum
+ coverage. Pass next_cursor unchanged. Unprefixed cursors stay legacy. Excludes
+ other-author context.
Args:
any_words: Words or quoted phrases where any one can match. Separate with spaces, commas,
or lines.
+ blue_verified_only: Only return tweets from Blue-verified authors.
+
+ card_name: Match the Tweet card name.
+
cashtags: Cashtags separated by spaces, commas, or lines.
conversation_id: Conversation ID filter.
- cursor: Pagination cursor for user replies
+ cursor: Cursor from the previous response. Xquik cursors resume automatic coverage.
+ Existing unprefixed cursors keep legacy standard behavior.
exact_phrase: Exact phrase to match.
+ exclude_source: Exclude a source application.
+
exclude_words: Words or quoted phrases to exclude. Separate with spaces, commas, or lines.
from_user: Filter by author username.
+ geocode: Match latitude, longitude, and radius.
+
hashtags: Hashtags separated by spaces, commas, or lines.
include_parent_tweet: Include each reply's parent tweet.
@@ -2083,10 +3235,22 @@ async def retrieve_replies(
language: Language code filter, e.g. en or tr.
+ max_faves: Maximum likes threshold. maxLikes is also accepted.
+
+ max_id: Return Tweets older than this Tweet ID.
+
+ max_quotes: Maximum quotes threshold.
+
+ max_replies: Maximum replies threshold.
+
+ max_retweets: Maximum retweets threshold.
+
media_type: Filter by media type.
mentioning: Filter tweets mentioning a username.
+ min_bookmarks: Minimum bookmark count threshold.
+
min_faves: Minimum likes threshold.
min_quotes: Minimum quote count threshold.
@@ -2095,9 +3259,16 @@ async def retrieve_replies(
min_retweets: Minimum retweets threshold.
- page_size: Maximum page items (1-100, default 20). Source, filters, or credits can reduce
- results. Continue while has_next_page is true. Deprecated limit and count
- aliases remain accepted.
+ min_views: Minimum view count threshold.
+
+ native_retweets: Only return native reposts.
+
+ near: Match a place name.
+
+ news: Only return news results.
+
+ page_size: Automatic pages accept 1-300 Tweets. Standard pages keep 1-100. Default 20.
+ Continue while has_next_page is true. Deprecated aliases remain accepted.
quotes: Quote mode.
@@ -2109,8 +3280,14 @@ async def retrieve_replies(
retweets_of_tweet_id: Only retweets of this tweet ID.
+ safe: Enable the safe-search filter.
+
since_date: Start date in YYYY-MM-DD format.
+ since_id: Return Tweets newer than this Tweet ID.
+
+ source: Match the source application.
+
to_user: Filter replies sent to a username.
until_date: End date in YYYY-MM-DD format.
@@ -2119,6 +3296,10 @@ async def retrieve_replies(
verified_only: Only return tweets from verified authors.
+ within: Set the radius for the near filter.
+
+ within_time: Match Tweets inside a recent time window.
+
extra_headers: Send extra headers
extra_query: Add additional query parameters to the request
@@ -2139,33 +3320,52 @@ async def retrieve_replies(
query=await async_maybe_transform(
{
"any_words": any_words,
+ "blue_verified_only": blue_verified_only,
+ "card_name": card_name,
"cashtags": cashtags,
"conversation_id": conversation_id,
"cursor": cursor,
"exact_phrase": exact_phrase,
+ "exclude_source": exclude_source,
"exclude_words": exclude_words,
"from_user": from_user,
+ "geocode": geocode,
"hashtags": hashtags,
"include_parent_tweet": include_parent_tweet,
"in_reply_to_tweet_id": in_reply_to_tweet_id,
"language": language,
+ "max_faves": max_faves,
+ "max_id": max_id,
+ "max_quotes": max_quotes,
+ "max_replies": max_replies,
+ "max_retweets": max_retweets,
"media_type": media_type,
"mentioning": mentioning,
+ "min_bookmarks": min_bookmarks,
"min_faves": min_faves,
"min_quotes": min_quotes,
"min_replies": min_replies,
"min_retweets": min_retweets,
+ "min_views": min_views,
+ "native_retweets": native_retweets,
+ "near": near,
+ "news": news,
"page_size": page_size,
"quotes": quotes,
"quotes_of_tweet_id": quotes_of_tweet_id,
"replies": replies,
"retweets": retweets,
"retweets_of_tweet_id": retweets_of_tweet_id,
+ "safe": safe,
"since_date": since_date,
+ "since_id": since_id,
+ "source": source,
"to_user": to_user,
"until_date": until_date,
"url": url,
"verified_only": verified_only,
+ "within": within,
+ "within_time": within_time,
},
user_retrieve_replies_params.UserRetrieveRepliesParams,
),
@@ -2177,7 +3377,21 @@ async def retrieve_search(
self,
*,
q: str,
+ bio_contains: str | Omit = omit,
cursor: str | Omit = omit,
+ has_location: bool | Omit = omit,
+ has_website: bool | Omit = omit,
+ location_contains: str | Omit = omit,
+ max_followers: int | Omit = omit,
+ max_following: int | Omit = omit,
+ max_statuses: int | Omit = omit,
+ min_account_age_days: int | Omit = omit,
+ min_followers: int | Omit = omit,
+ min_following: int | Omit = omit,
+ min_statuses: int | Omit = omit,
+ username_contains: str | Omit = omit,
+ verified_only: bool | Omit = omit,
+ verified_type: str | Omit = omit,
# Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
# The extra values given here take precedence over values defined on the client or passed to this method.
extra_headers: Headers | None = None,
@@ -2191,8 +3405,36 @@ async def retrieve_search(
Args:
q: User search query
+ bio_contains: Match any comma-separated or line-separated bio term, ignoring case.
+
cursor: Pagination cursor for user search
+ has_location: Only return profiles with a location.
+
+ has_website: Only return profiles with a website.
+
+ location_contains: Match a location substring, ignoring case.
+
+ max_followers: Maximum follower count. Missing counts pass this maximum.
+
+ max_following: Maximum following count.
+
+ max_statuses: Maximum post count. maxPosts is also accepted.
+
+ min_account_age_days: Minimum account age in whole days.
+
+ min_followers: Minimum follower count. Filtering happens before billing.
+
+ min_following: Minimum following count.
+
+ min_statuses: Minimum post count. minPosts is also accepted.
+
+ username_contains: Match a username substring, ignoring case.
+
+ verified_only: Only return verified profiles.
+
+ verified_type: Match the verification type exactly, ignoring case.
+
extra_headers: Send extra headers
extra_query: Add additional query parameters to the request
@@ -2211,7 +3453,21 @@ async def retrieve_search(
query=await async_maybe_transform(
{
"q": q,
+ "bio_contains": bio_contains,
"cursor": cursor,
+ "has_location": has_location,
+ "has_website": has_website,
+ "location_contains": location_contains,
+ "max_followers": max_followers,
+ "max_following": max_following,
+ "max_statuses": max_statuses,
+ "min_account_age_days": min_account_age_days,
+ "min_followers": min_followers,
+ "min_following": min_following,
+ "min_statuses": min_statuses,
+ "username_contains": username_contains,
+ "verified_only": verified_only,
+ "verified_type": verified_type,
},
user_retrieve_search_params.UserRetrieveSearchParams,
),
@@ -2224,34 +3480,53 @@ async def retrieve_tweets(
id: str,
*,
any_words: str | Omit = omit,
+ blue_verified_only: bool | Omit = omit,
+ card_name: str | Omit = omit,
cashtags: str | Omit = omit,
conversation_id: str | Omit = omit,
cursor: str | Omit = omit,
exact_phrase: str | Omit = omit,
+ exclude_source: str | Omit = omit,
exclude_words: str | Omit = omit,
from_user: str | Omit = omit,
+ geocode: str | Omit = omit,
hashtags: str | Omit = omit,
include_parent_tweet: bool | Omit = omit,
include_replies: bool | Omit = omit,
in_reply_to_tweet_id: str | Omit = omit,
language: str | Omit = omit,
+ max_faves: int | Omit = omit,
+ max_id: str | Omit = omit,
+ max_quotes: int | Omit = omit,
+ max_replies: int | Omit = omit,
+ max_retweets: int | Omit = omit,
media_type: Literal["images", "videos", "gifs", "media", "links", "none"] | Omit = omit,
mentioning: str | Omit = omit,
+ min_bookmarks: int | Omit = omit,
min_faves: int | Omit = omit,
min_quotes: int | Omit = omit,
min_replies: int | Omit = omit,
min_retweets: int | Omit = omit,
+ min_views: int | Omit = omit,
+ native_retweets: bool | Omit = omit,
+ near: str | Omit = omit,
+ news: bool | Omit = omit,
page_size: int | Omit = omit,
quotes: Literal["include", "exclude", "only"] | Omit = omit,
quotes_of_tweet_id: str | Omit = omit,
replies: Literal["include", "exclude", "only"] | Omit = omit,
retweets: Literal["include", "exclude", "only"] | Omit = omit,
retweets_of_tweet_id: str | Omit = omit,
+ safe: bool | Omit = omit,
since_date: Union[str, date] | Omit = omit,
+ since_id: str | Omit = omit,
+ source: str | Omit = omit,
to_user: str | Omit = omit,
until_date: Union[str, date] | Omit = omit,
url: str | Omit = omit,
verified_only: bool | Omit = omit,
+ within: str | Omit = omit,
+ within_time: str | Omit = omit,
# Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
# The extra values given here take precedence over values defined on the client or passed to this method.
extra_headers: Headers | None = None,
@@ -2259,25 +3534,36 @@ async def retrieve_tweets(
extra_body: Body | None = None,
timeout: float | httpx.Timeout | None | NotGiven = not_given,
) -> PaginatedTweets:
- """
- List recent tweets posted by a user
+ """Omit mode for automatic maximum coverage.
+
+ Pass next_cursor unchanged. Unprefixed
+ cursors use legacy pagination. Shape and billing stay the same.
Args:
any_words: Words or quoted phrases where any one can match. Separate with spaces, commas,
or lines.
+ blue_verified_only: Only return tweets from Blue-verified authors.
+
+ card_name: Match the Tweet card name.
+
cashtags: Cashtags separated by spaces, commas, or lines.
conversation_id: Conversation ID filter.
- cursor: Pagination cursor for user tweets
+ cursor: Cursor from the previous response. Xquik cursors resume automatic coverage.
+ Existing unprefixed cursors keep legacy standard behavior.
exact_phrase: Exact phrase to match.
+ exclude_source: Exclude a source application.
+
exclude_words: Words or quoted phrases to exclude. Separate with spaces, commas, or lines.
from_user: Filter by author username.
+ geocode: Match latitude, longitude, and radius.
+
hashtags: Hashtags separated by spaces, commas, or lines.
include_parent_tweet: Include parent tweet for replies
@@ -2288,10 +3574,22 @@ async def retrieve_tweets(
language: Language code filter, e.g. en or tr.
+ max_faves: Maximum likes threshold. maxLikes is also accepted.
+
+ max_id: Return Tweets older than this Tweet ID.
+
+ max_quotes: Maximum quotes threshold.
+
+ max_replies: Maximum replies threshold.
+
+ max_retweets: Maximum retweets threshold.
+
media_type: Filter by media type.
mentioning: Filter tweets mentioning a username.
+ min_bookmarks: Minimum bookmark count threshold.
+
min_faves: Minimum likes threshold.
min_quotes: Minimum quote count threshold.
@@ -2300,9 +3598,16 @@ async def retrieve_tweets(
min_retweets: Minimum retweets threshold.
- page_size: Maximum page items (1-100, default 20). Source, filters, or credits can reduce
- results. Continue while has_next_page is true. Deprecated limit and count
- aliases remain accepted.
+ min_views: Minimum view count threshold.
+
+ native_retweets: Only return native reposts.
+
+ near: Match a place name.
+
+ news: Only return news results.
+
+ page_size: Automatic pages accept 1-300 Tweets. Standard pages keep 1-100. Default 20.
+ Continue while has_next_page is true. Deprecated aliases remain accepted.
quotes: Quote mode.
@@ -2314,8 +3619,14 @@ async def retrieve_tweets(
retweets_of_tweet_id: Only retweets of this tweet ID.
+ safe: Enable the safe-search filter.
+
since_date: Start date in YYYY-MM-DD format.
+ since_id: Return Tweets newer than this Tweet ID.
+
+ source: Match the source application.
+
to_user: Filter replies sent to a username.
until_date: End date in YYYY-MM-DD format.
@@ -2324,6 +3635,10 @@ async def retrieve_tweets(
verified_only: Only return tweets from verified authors.
+ within: Set the radius for the near filter.
+
+ within_time: Match Tweets inside a recent time window.
+
extra_headers: Send extra headers
extra_query: Add additional query parameters to the request
@@ -2344,34 +3659,53 @@ async def retrieve_tweets(
query=await async_maybe_transform(
{
"any_words": any_words,
+ "blue_verified_only": blue_verified_only,
+ "card_name": card_name,
"cashtags": cashtags,
"conversation_id": conversation_id,
"cursor": cursor,
"exact_phrase": exact_phrase,
+ "exclude_source": exclude_source,
"exclude_words": exclude_words,
"from_user": from_user,
+ "geocode": geocode,
"hashtags": hashtags,
"include_parent_tweet": include_parent_tweet,
"include_replies": include_replies,
"in_reply_to_tweet_id": in_reply_to_tweet_id,
"language": language,
+ "max_faves": max_faves,
+ "max_id": max_id,
+ "max_quotes": max_quotes,
+ "max_replies": max_replies,
+ "max_retweets": max_retweets,
"media_type": media_type,
"mentioning": mentioning,
+ "min_bookmarks": min_bookmarks,
"min_faves": min_faves,
"min_quotes": min_quotes,
"min_replies": min_replies,
"min_retweets": min_retweets,
+ "min_views": min_views,
+ "native_retweets": native_retweets,
+ "near": near,
+ "news": news,
"page_size": page_size,
"quotes": quotes,
"quotes_of_tweet_id": quotes_of_tweet_id,
"replies": replies,
"retweets": retweets,
"retweets_of_tweet_id": retweets_of_tweet_id,
+ "safe": safe,
"since_date": since_date,
+ "since_id": since_id,
+ "source": source,
"to_user": to_user,
"until_date": until_date,
"url": url,
"verified_only": verified_only,
+ "within": within,
+ "within_time": within_time,
},
user_retrieve_tweets_params.UserRetrieveTweetsParams,
),
@@ -2383,25 +3717,78 @@ async def retrieve_verified_followers(
self,
id: str,
*,
+ after: str | Omit = omit,
+ bio_contains: str | Omit = omit,
cursor: str | Omit = omit,
+ has_location: bool | Omit = omit,
+ has_website: bool | Omit = omit,
+ limit: int | Omit = omit,
+ location_contains: str | Omit = omit,
+ max_followers: int | Omit = omit,
+ max_following: int | Omit = omit,
+ max_statuses: int | Omit = omit,
+ min_account_age_days: int | Omit = omit,
+ min_followers: int | Omit = omit,
+ min_following: int | Omit = omit,
+ min_statuses: int | Omit = omit,
+ mode: Literal["standard", "coverage"] | Omit = omit,
page_size: int | Omit = omit,
+ username_contains: str | Omit = omit,
+ verified_only: bool | Omit = omit,
+ verified_type: str | Omit = omit,
# Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
# The extra values given here take precedence over values defined on the client or passed to this method.
extra_headers: Headers | None = None,
extra_query: Query | None = None,
extra_body: Body | None = None,
timeout: float | httpx.Timeout | None | NotGiven = not_given,
- ) -> PaginatedUsers:
- """
- List verified followers of a user
+ ) -> UserRetrieveVerifiedFollowersResponse:
+ """List verified followers of a user
Args:
- cursor: Pagination cursor for verified followers
+ after: Legacy cursor alias.
+
+ Prefer cursor.
- page_size: Maximum user profiles requested from this page (20-200, default 200). The
- response can contain fewer profiles because the source returned fewer or
- remaining credits cover fewer results. Keep requesting next_cursor while
- has_next_page is true. The deprecated limit and count aliases remain accepted.
+ bio_contains: Match any comma-separated or line-separated bio term, ignoring case.
+
+ cursor: Cursor from the previous response. Xquik cursors resume automatic coverage.
+ Existing unprefixed cursors keep legacy standard behavior.
+
+ has_location: Only return profiles with a location.
+
+ has_website: Only return profiles with a website.
+
+ limit: Legacy page-size alias outside explicit coverage mode. Coverage accepts 1-10000.
+ Prefer pageSize.
+
+ location_contains: Match a location substring, ignoring case.
+
+ max_followers: Maximum follower count. Missing counts pass this maximum.
+
+ max_following: Maximum following count.
+
+ max_statuses: Maximum post count. maxPosts is also accepted.
+
+ min_account_age_days: Minimum account age in whole days.
+
+ min_followers: Minimum follower count. Filtering happens before billing.
+
+ min_following: Minimum following count.
+
+ min_statuses: Minimum post count. minPosts is also accepted.
+
+ mode: Omit mode for resumable maximum coverage. Standard keeps legacy pagination.
+ Coverage returns diagnostics once and rejects cursors.
+
+ page_size: Maximum user profiles: automatic 300; standard 200. Sources return fewer
+ profiles. Continue with has_next_page.
+
+ username_contains: Match a username substring, ignoring case.
+
+ verified_only: Only return verified profiles.
+
+ verified_type: Match the verification type exactly, ignoring case.
extra_headers: Send extra headers
@@ -2413,22 +3800,44 @@ async def retrieve_verified_followers(
"""
if not id:
raise ValueError(f"Expected a non-empty value for `id` but received {id!r}")
- return await self._get(
- path_template("/x/users/{id}/verified-followers", id=id),
- options=make_request_options(
- extra_headers=extra_headers,
- extra_query=extra_query,
- extra_body=extra_body,
- timeout=timeout,
- query=await async_maybe_transform(
- {
- "cursor": cursor,
- "page_size": page_size,
- },
- user_retrieve_verified_followers_params.UserRetrieveVerifiedFollowersParams,
+ return cast(
+ UserRetrieveVerifiedFollowersResponse,
+ await self._get(
+ path_template("/x/users/{id}/verified-followers", id=id),
+ options=make_request_options(
+ extra_headers=extra_headers,
+ extra_query=extra_query,
+ extra_body=extra_body,
+ timeout=timeout,
+ query=await async_maybe_transform(
+ {
+ "after": after,
+ "bio_contains": bio_contains,
+ "cursor": cursor,
+ "has_location": has_location,
+ "has_website": has_website,
+ "limit": limit,
+ "location_contains": location_contains,
+ "max_followers": max_followers,
+ "max_following": max_following,
+ "max_statuses": max_statuses,
+ "min_account_age_days": min_account_age_days,
+ "min_followers": min_followers,
+ "min_following": min_following,
+ "min_statuses": min_statuses,
+ "mode": mode,
+ "page_size": page_size,
+ "username_contains": username_contains,
+ "verified_only": verified_only,
+ "verified_type": verified_type,
+ },
+ user_retrieve_verified_followers_params.UserRetrieveVerifiedFollowersParams,
+ ),
),
+ cast_to=cast(
+ Any, UserRetrieveVerifiedFollowersResponse
+ ), # Union types cannot be passed in as arguments in the type system
),
- cast_to=PaginatedUsers,
)
diff --git a/src/x_twitter_scraper/types/draw_export_params.py b/src/x_twitter_scraper/types/draw_export_params.py
index 558c04f..c5395d7 100644
--- a/src/x_twitter_scraper/types/draw_export_params.py
+++ b/src/x_twitter_scraper/types/draw_export_params.py
@@ -13,7 +13,11 @@
class DrawExportParams(TypedDict, total=False):
format: Required[Literal["csv", "json", "md", "md-document", "pdf", "txt", "xlsx"]]
- """Export output format"""
+ """Export output format.
+
+ PDF entry exports include up to 10,000 rows. Other entry formats include up to
+ 100,000 rows.
+ """
type: Literal["winners", "entries"]
"""Export winners or all entries"""
diff --git a/src/x_twitter_scraper/types/draw_list_params.py b/src/x_twitter_scraper/types/draw_list_params.py
index bec6d02..e0e1791 100644
--- a/src/x_twitter_scraper/types/draw_list_params.py
+++ b/src/x_twitter_scraper/types/draw_list_params.py
@@ -13,7 +13,7 @@
class DrawListParams(TypedDict, total=False):
cursor: str
- """Cursor for keyset pagination from prior response next_cursor"""
+ """Previous nextCursor."""
limit: int
"""Maximum number of items to return (1-100, default 50).
diff --git a/src/x_twitter_scraper/types/event_list_params.py b/src/x_twitter_scraper/types/event_list_params.py
index a7b5dc4..ea4730a 100644
--- a/src/x_twitter_scraper/types/event_list_params.py
+++ b/src/x_twitter_scraper/types/event_list_params.py
@@ -16,11 +16,14 @@
class EventListParams(TypedDict, total=False):
cursor: str
- """Cursor for keyset pagination from prior response next_cursor"""
+ """Previous nextCursor."""
event_type: Annotated[EventType, PropertyInfo(alias="eventType")]
"""Filter events by type"""
+ keyword_monitor_id: Annotated[str, PropertyInfo(alias="keywordMonitorId")]
+ """Keyword monitor ID."""
+
limit: int
"""Maximum number of items to return (1-100, default 50).
@@ -30,4 +33,4 @@ class EventListParams(TypedDict, total=False):
"""
monitor_id: Annotated[str, PropertyInfo(alias="monitorId")]
- """Filter events by monitor ID"""
+ """Account monitor ID."""
diff --git a/src/x_twitter_scraper/types/extraction_estimate_cost_params.py b/src/x_twitter_scraper/types/extraction_estimate_cost_params.py
index f4b2873..3e241f2 100644
--- a/src/x_twitter_scraper/types/extraction_estimate_cost_params.py
+++ b/src/x_twitter_scraper/types/extraction_estimate_cost_params.py
@@ -6,13 +6,14 @@
from __future__ import annotations
-from typing import Union
-from datetime import date
-from typing_extensions import Literal, Required, Annotated, TypedDict
+from typing import Union, Iterable
+from datetime import date, datetime
+from typing_extensions import Literal, Required, Annotated, TypeAlias, TypedDict
+from .._types import SequenceNotStr
from .._utils import PropertyInfo
-__all__ = ["ExtractionEstimateCostParams"]
+__all__ = ["ExtractionEstimateCostParams", "RelationTarget", "Target", "TargetUnionMember1"]
class ExtractionEstimateCostParams(TypedDict, total=False):
@@ -49,133 +50,334 @@ class ExtractionEstimateCostParams(TypedDict, total=False):
"""Identifier for the extraction tool used to run a job."""
advanced_query: Annotated[str, PropertyInfo(alias="advancedQuery")]
- """Raw advanced query string appended to the estimate (tweet_search_extractor)"""
+ """Raw advanced search query appended as-is (tweet_search_extractor)"""
any_words: Annotated[str, PropertyInfo(alias="anyWords")]
- """Alternative words or quoted phrases for estimated results.
+ """Words or quoted phrases where any one can match.
- Separate with spaces, commas, or lines.
+ Separate with spaces, commas, or lines. (tweet_search_extractor)
"""
+ bio_contains: Annotated[str, PropertyInfo(alias="bioContains")]
+ """Bio terms separated by commas or lines."""
+
+ blue_verified_only: Annotated[bool, PropertyInfo(alias="blueVerifiedOnly")]
+ """Return only Blue-verified Tweet authors."""
+
bounding_box: Annotated[str, PropertyInfo(alias="boundingBox")]
- """Geo bounding box used for estimation, e.g.
+ """Geo bounding box, e.g. -74.1 40.6 -73.9 40.8 (tweet_search_extractor)"""
- -74.1 40.6 -73.9 40.8 (tweet_search_extractor)
- """
+ card_name: Annotated[str, PropertyInfo(alias="cardName")]
+ """Match the Tweet card name."""
cashtags: str
- """Cashtags applied to the estimate, separated by spaces, commas, or lines."""
+ """Cashtags separated by spaces, commas, or lines. (tweet_search_extractor)"""
+
+ collection_strategy: Annotated[
+ Literal["auto", "complete", "direct", "search", "thread"], PropertyInfo(alias="collectionStrategy")
+ ]
+ """Reply collection strategy."""
conversation_id: Annotated[str, PropertyInfo(alias="conversationId")]
- """Conversation ID filter used for estimation (tweet_search_extractor)"""
+ """Conversation ID filter (tweet_search_extractor)"""
+
+ dedupe_across_targets: Annotated[bool, PropertyInfo(alias="dedupeAcrossTargets")]
+ """Merge duplicate results across collection targets."""
+
+ dedupe_mode: Annotated[Literal["none", "first", "merge"], PropertyInfo(alias="dedupeMode")]
+ """Keep target duplicates, first rows, or merged overlap."""
exact_phrase: Annotated[str, PropertyInfo(alias="exactPhrase")]
- """Exact phrase filter for search estimation"""
+ """Exact phrase to match (tweet_search_extractor)"""
+
+ exclude_original_author: Annotated[bool, PropertyInfo(alias="excludeOriginalAuthor")]
+ """Exclude replies from the source author."""
+
+ exclude_source: Annotated[str, PropertyInfo(alias="excludeSource")]
+ """Exclude a source application."""
exclude_words: Annotated[str, PropertyInfo(alias="excludeWords")]
- """Words or quoted phrases excluded from estimated results.
+ """Words or quoted phrases to exclude.
- Separate with spaces, commas, or lines.
+ Separate with spaces, commas, or lines. (tweet_search_extractor)
"""
from_user: Annotated[str, PropertyInfo(alias="fromUser")]
- """Estimate only tweets from this author username (tweet_search_extractor)"""
+ """Filter by author username (tweet_search_extractor)"""
+
+ geocode: str
+ """Match latitude, longitude, and radius."""
hashtags: str
- """Hashtags applied to the estimate, separated by spaces, commas, or lines."""
+ """Hashtags separated by spaces, commas, or lines. (tweet_search_extractor)"""
+
+ has_location: Annotated[bool, PropertyInfo(alias="hasLocation")]
+ """Require a profile location."""
+
+ has_media_only: Annotated[bool, PropertyInfo(alias="hasMediaOnly")]
+ """Return only replies with media."""
+
+ has_website: Annotated[bool, PropertyInfo(alias="hasWebsite")]
+ """Require a profile website."""
+
+ include_original_post: Annotated[bool, PropertyInfo(alias="includeOriginalPost")]
+ """Include the source post in reply results."""
+
+ include_search_terms: Annotated[bool, PropertyInfo(alias="includeSearchTerms")]
+ """Add matching search terms to collection metadata."""
+
+ include_target_metadata: Annotated[bool, PropertyInfo(alias="includeTargetMetadata")]
+ """Add source target metadata to each result."""
in_reply_to_tweet_id: Annotated[str, PropertyInfo(alias="inReplyToTweetId")]
- """Estimate only replies to this tweet ID (tweet_search_extractor)"""
+ """Only replies to this tweet ID (tweet_search_extractor)"""
language: str
- """Language code used for estimate filtering (tweet_search_extractor)"""
+ """Language code filter (tweet_search_extractor)"""
list_id: Annotated[str, PropertyInfo(alias="listId")]
- """Estimate search results within this list ID (tweet_search_extractor)"""
+ """Search within a list ID (tweet_search_extractor)"""
+
+ location_contains: Annotated[str, PropertyInfo(alias="locationContains")]
+ """Required profile location text."""
+
+ max_depth: Annotated[int, PropertyInfo(alias="maxDepth")]
+ """Maximum nested reply depth."""
+
+ max_followers: Annotated[int, PropertyInfo(alias="maxFollowers")]
+ """Maximum follower count for profile results."""
+
+ max_following: Annotated[int, PropertyInfo(alias="maxFollowing")]
+ """Maximum following count for profile results."""
+
+ max_id: Annotated[str, PropertyInfo(alias="maxId")]
+ """Return Tweets older than this Tweet ID."""
+
+ max_items_per_target: Annotated[int, PropertyInfo(alias="maxItemsPerTarget")]
+ """Maximum results collected for each target."""
+
+ max_likes: Annotated[int, PropertyInfo(alias="maxLikes")]
+ """Maximum Tweet like count."""
+
+ max_pages_per_target: Annotated[int, PropertyInfo(alias="maxPagesPerTarget")]
+ """Reply pages collected for each target."""
+
+ max_posts: Annotated[int, PropertyInfo(alias="maxPosts")]
+ """Maximum post count for profile results."""
+
+ max_quotes: Annotated[int, PropertyInfo(alias="maxQuotes")]
+ """Maximum Tweet quote count."""
+
+ max_replies: Annotated[int, PropertyInfo(alias="maxReplies")]
+ """Maximum Tweet reply count."""
+
+ max_retweets: Annotated[int, PropertyInfo(alias="maxRetweets")]
+ """Maximum Tweet repost count."""
media_type: Annotated[
Literal["images", "videos", "gifs", "media", "links", "none"], PropertyInfo(alias="mediaType")
]
- """Media type used for estimate filtering (tweet_search_extractor)"""
+ """Media type filter (tweet_search_extractor)"""
mentioning: str
- """Estimate tweets mentioning this username (tweet_search_extractor)"""
+ """Filter tweets mentioning a username (tweet_search_extractor)"""
+
+ min_account_age_days: Annotated[int, PropertyInfo(alias="minAccountAgeDays")]
+ """Minimum profile age in days."""
+
+ min_bookmarks: Annotated[int, PropertyInfo(alias="minBookmarks")]
+ """Minimum Tweet bookmark count."""
min_faves: Annotated[int, PropertyInfo(alias="minFaves")]
- """Minimum likes threshold for estimated results (tweet_search_extractor)"""
+ """Minimum likes threshold (tweet_search_extractor)"""
+
+ min_followers: Annotated[int, PropertyInfo(alias="minFollowers")]
+ """Minimum follower count for profile results."""
+
+ min_following: Annotated[int, PropertyInfo(alias="minFollowing")]
+ """Minimum following count for profile results."""
+
+ min_posts: Annotated[int, PropertyInfo(alias="minPosts")]
+ """Minimum post count for profile results."""
min_quotes: Annotated[int, PropertyInfo(alias="minQuotes")]
- """Minimum quote count threshold for estimated results (tweet_search_extractor)"""
+ """Minimum quote count threshold (tweet_search_extractor)"""
min_replies: Annotated[int, PropertyInfo(alias="minReplies")]
- """Minimum replies threshold for estimated results (tweet_search_extractor)"""
+ """Minimum replies threshold (tweet_search_extractor)"""
min_retweets: Annotated[int, PropertyInfo(alias="minRetweets")]
- """Minimum retweets threshold for estimated results (tweet_search_extractor)"""
+ """Minimum retweets threshold (tweet_search_extractor)"""
+
+ min_views: Annotated[int, PropertyInfo(alias="minViews")]
+ """Minimum Tweet view count."""
+
+ native_retweets: Annotated[bool, PropertyInfo(alias="nativeRetweets")]
+ """Only return native reposts."""
+
+ near: str
+ """Match a place name."""
+
+ news: bool
+ """Only return news results."""
+
+ overlap_mode: Annotated[bool, PropertyInfo(alias="overlapMode")]
+ """Shortcut for dedupeMode=merge."""
place: str
- """Estimate search results within this place ID (tweet_search_extractor)"""
+ """Search within a place ID (tweet_search_extractor)"""
place_country: Annotated[str, PropertyInfo(alias="placeCountry")]
- """Estimate search results within this country code (tweet_search_extractor)"""
+ """Search within a country code (tweet_search_extractor)"""
point_radius: Annotated[str, PropertyInfo(alias="pointRadius")]
- """Geo point radius used for estimation, e.g.
+ """Geo point radius, e.g. -73.99 40.73 25mi (tweet_search_extractor)"""
- -73.99 40.73 25mi (tweet_search_extractor)
- """
+ query_type: Annotated[Literal["Latest", "Top", "Both"], PropertyInfo(alias="queryType")]
+ """Search ranking applied to every query."""
quotes: Literal["include", "exclude", "only"]
- """Quote mode used for estimation (tweet_search_extractor)"""
+ """Quote mode (tweet_search_extractor)"""
quotes_of_tweet_id: Annotated[str, PropertyInfo(alias="quotesOfTweetId")]
- """Estimate only quotes of this tweet ID (tweet_search_extractor)"""
+ """Only quotes of this tweet ID (tweet_search_extractor)"""
+
+ relation_targets: Annotated[Iterable[RelationTarget], PropertyInfo(alias="relationTargets")]
+ """Profile relations processed within one job."""
replies: Literal["include", "exclude", "only"]
- """Reply mode used for estimation (tweet_search_extractor)"""
+ """Reply mode (tweet_search_extractor)"""
results_limit: Annotated[int, PropertyInfo(alias="resultsLimit")]
- """Maximum number of results to estimate.
+ """Maximum number of results to extract.
- When set, the estimate caps projected results to this value.
+ When set, the extraction stops after reaching this limit.
"""
retweets: Literal["include", "exclude", "only"]
- """Retweet mode used for estimation (tweet_search_extractor)"""
+ """Retweet mode (tweet_search_extractor)"""
retweets_of_tweet_id: Annotated[str, PropertyInfo(alias="retweetsOfTweetId")]
- """Estimate only retweets of this tweet ID (tweet_search_extractor)"""
+ """Only retweets of this tweet ID (tweet_search_extractor)"""
+
+ safe: bool
+ """Enable the safe-search filter."""
+
+ scope: Literal["all", "direct", "nested"]
+ """Reply depth scope."""
+
+ search_queries: Annotated[SequenceNotStr[str], PropertyInfo(alias="searchQueries")]
+ """Search queries processed as one collection job."""
search_query: Annotated[str, PropertyInfo(alias="searchQuery")]
- """Query used to price tweet_search_extractor or community_search."""
+ """Required for tweet_search_extractor & community_search."""
since_date: Annotated[Union[str, date], PropertyInfo(alias="sinceDate", format="iso8601")]
- """Estimate start date in YYYY-MM-DD format (tweet_search_extractor)"""
+ """Start date YYYY-MM-DD (tweet_search_extractor)"""
+
+ since_id: Annotated[str, PropertyInfo(alias="sinceId")]
+ """Return Tweets newer than this Tweet ID."""
+
+ since_time: Annotated[Union[Union[str, datetime], int], PropertyInfo(alias="sinceTime", format="iso8601")]
+ """Reply start time as ISO 8601 or Unix seconds."""
+
+ sort: Literal["relevance", "latest", "oldest", "likes"]
+ """Reply result order."""
+
+ source: str
+ """Match the source application."""
+
+ start_cursor: Annotated[str, PropertyInfo(alias="startCursor")]
+ """Resume one reply target from this cursor."""
target_community_id: Annotated[str, PropertyInfo(alias="targetCommunityId")]
- """Community ID used to price community_post_extractor or community_search."""
+ """Required for community_post_extractor & community_search."""
+
+ target_community_ids: Annotated[SequenceNotStr[str], PropertyInfo(alias="targetCommunityIds")]
+ """Community IDs processed as one collection job."""
target_list_id: Annotated[str, PropertyInfo(alias="targetListId")]
"""
- List ID used to price list_follower_explorer, list_member_extractor, or
+ Required for list_follower_explorer, list_member_extractor &
list_post_extractor.
"""
+ target_list_ids: Annotated[SequenceNotStr[str], PropertyInfo(alias="targetListIds")]
+ """List IDs processed as one collection job."""
+
+ targets: SequenceNotStr[Target]
+ """Mixed targets auto-routed within one job."""
+
target_space_id: Annotated[str, PropertyInfo(alias="targetSpaceId")]
- """Space ID used to price space_explorer."""
+ """Required for space_explorer."""
target_tweet_id: Annotated[str, PropertyInfo(alias="targetTweetId")]
+ target_tweet_ids: Annotated[SequenceNotStr[str], PropertyInfo(alias="targetTweetIds")]
+ """Tweet IDs processed as one collection job."""
+
target_username: Annotated[str, PropertyInfo(alias="targetUsername")]
+ target_usernames: Annotated[SequenceNotStr[str], PropertyInfo(alias="targetUsernames")]
+ """Usernames processed as one collection job."""
+
to_user: Annotated[str, PropertyInfo(alias="toUser")]
- """Estimate replies sent to this username (tweet_search_extractor)"""
+ """Filter replies sent to a username (tweet_search_extractor)"""
until_date: Annotated[Union[str, date], PropertyInfo(alias="untilDate", format="iso8601")]
- """Estimate end date in YYYY-MM-DD format (tweet_search_extractor)"""
+ """End date YYYY-MM-DD (tweet_search_extractor)"""
+
+ until_time: Annotated[Union[Union[str, datetime], int], PropertyInfo(alias="untilTime", format="iso8601")]
+ """Reply end time as ISO 8601 or Unix seconds."""
url: str
- """URL substring or domain filter used for estimation (tweet_search_extractor)"""
+ """URL substring or domain filter (tweet_search_extractor)"""
+
+ username_contains: Annotated[str, PropertyInfo(alias="usernameContains")]
+ """Required username text."""
verified_only: Annotated[bool, PropertyInfo(alias="verifiedOnly")]
- """Estimate only verified authors (tweet_search_extractor)"""
+ """Only verified authors (tweet_search_extractor)"""
+
+ verified_type: Annotated[str, PropertyInfo(alias="verifiedType")]
+ """Exact profile verification type."""
+
+ within: str
+ """Set the radius for the near filter."""
+
+ within_time: Annotated[str, PropertyInfo(alias="withinTime")]
+ """Match Tweets inside a recent time window."""
+
+
+class RelationTarget(TypedDict, total=False):
+ """One target and relation in a mixed profile collection."""
+
+ relation: Required[
+ Literal["community_members", "followers", "following", "list_followers", "list_members", "verified_followers"]
+ ]
+
+ value: Required[str]
+
+
+class TargetUnionMember1(TypedDict, total=False):
+ kind: Required[
+ Literal[
+ "favoriters",
+ "list",
+ "profile",
+ "profile_likes",
+ "profile_media",
+ "profile_replies",
+ "quotes",
+ "replies",
+ "retweeters",
+ "search",
+ "thread",
+ "tweet",
+ ]
+ ]
+
+ value: Required[str]
+
+
+Target: TypeAlias = Union[str, TargetUnionMember1]
diff --git a/src/x_twitter_scraper/types/extraction_estimate_cost_response.py b/src/x_twitter_scraper/types/extraction_estimate_cost_response.py
index 3dd72af..402c42d 100644
--- a/src/x_twitter_scraper/types/extraction_estimate_cost_response.py
+++ b/src/x_twitter_scraper/types/extraction_estimate_cost_response.py
@@ -26,6 +26,7 @@ class ExtractionEstimateCostResponse(BaseModel):
source: Literal[
"followers",
"following",
+ "collection",
"paginationCap",
"posts",
"quoteCount",
diff --git a/src/x_twitter_scraper/types/extraction_export_results_params.py b/src/x_twitter_scraper/types/extraction_export_results_params.py
index 6c1bd7b..f8114fb 100644
--- a/src/x_twitter_scraper/types/extraction_export_results_params.py
+++ b/src/x_twitter_scraper/types/extraction_export_results_params.py
@@ -6,7 +6,11 @@
from __future__ import annotations
-from typing_extensions import Literal, Required, TypedDict
+from typing import Union
+from datetime import date
+from typing_extensions import Literal, Required, Annotated, TypedDict
+
+from .._utils import PropertyInfo
__all__ = ["ExtractionExportResultsParams"]
@@ -14,3 +18,57 @@
class ExtractionExportResultsParams(TypedDict, total=False):
format: Required[Literal["csv", "json", "md", "md-document", "pdf", "txt", "xlsx"]]
"""Export file format"""
+
+ has_description: Annotated[bool, PropertyInfo(alias="hasDescription")]
+ """Require a non-empty description."""
+
+ has_location: Annotated[bool, PropertyInfo(alias="hasLocation")]
+ """Require a non-empty location."""
+
+ has_media: Annotated[bool, PropertyInfo(alias="hasMedia")]
+ """Require media."""
+
+ lang: str
+ """Filter by language code."""
+
+ max_followers: Annotated[int, PropertyInfo(alias="maxFollowers")]
+ """Maximum follower count."""
+
+ max_following: Annotated[int, PropertyInfo(alias="maxFollowing")]
+ """Maximum following count."""
+
+ max_posts: Annotated[int, PropertyInfo(alias="maxPosts")]
+ """Maximum post count."""
+
+ min_followers: Annotated[int, PropertyInfo(alias="minFollowers")]
+ """Minimum follower count."""
+
+ min_following: Annotated[int, PropertyInfo(alias="minFollowing")]
+ """Minimum following count."""
+
+ min_likes: Annotated[int, PropertyInfo(alias="minLikes")]
+ """Minimum like count."""
+
+ min_posts: Annotated[int, PropertyInfo(alias="minPosts")]
+ """Minimum post count."""
+
+ min_replies: Annotated[int, PropertyInfo(alias="minReplies")]
+ """Minimum reply count."""
+
+ min_retweets: Annotated[int, PropertyInfo(alias="minRetweets")]
+ """Minimum repost count."""
+
+ min_views: Annotated[int, PropertyInfo(alias="minViews")]
+ """Minimum view count."""
+
+ search: str
+ """Search exported result text."""
+
+ since_date: Annotated[Union[str, date], PropertyInfo(alias="sinceDate", format="iso8601")]
+ """Include results on or after this date."""
+
+ until_date: Annotated[Union[str, date], PropertyInfo(alias="untilDate", format="iso8601")]
+ """Include results on or before this date."""
+
+ verified: bool
+ """Filter by verified status."""
diff --git a/src/x_twitter_scraper/types/extraction_list_params.py b/src/x_twitter_scraper/types/extraction_list_params.py
index 30325af..f97b8d4 100644
--- a/src/x_twitter_scraper/types/extraction_list_params.py
+++ b/src/x_twitter_scraper/types/extraction_list_params.py
@@ -15,7 +15,7 @@
class ExtractionListParams(TypedDict, total=False):
cursor: str
- """Cursor for keyset pagination from prior response next_cursor"""
+ """Previous nextCursor."""
limit: int
"""Maximum number of items to return (1-100, default 50).
diff --git a/src/x_twitter_scraper/types/extraction_retrieve_params.py b/src/x_twitter_scraper/types/extraction_retrieve_params.py
index acda1bd..f756579 100644
--- a/src/x_twitter_scraper/types/extraction_retrieve_params.py
+++ b/src/x_twitter_scraper/types/extraction_retrieve_params.py
@@ -6,14 +6,28 @@
from __future__ import annotations
-from typing_extensions import TypedDict
+from typing_extensions import Literal, Annotated, TypedDict
+
+from .._utils import PropertyInfo
__all__ = ["ExtractionRetrieveParams"]
class ExtractionRetrieveParams(TypedDict, total=False):
cursor: str
- """Cursor for keyset pagination from prior response next_cursor"""
+ """Previous nextCursor."""
+
+ field_style: Annotated[Literal["source", "camelCase", "snake_case"], PropertyInfo(alias="fieldStyle")]
+ """Preserve source keys or convert result field names."""
+
+ include_raw: Annotated[bool, PropertyInfo(alias="includeRaw")]
+ """Use outputMode=raw instead."""
limit: int
"""Maximum number of results to return (1-1000, default 100)"""
+
+ output_mode: Annotated[Literal["compact", "full", "raw"], PropertyInfo(alias="outputMode")]
+ """Select compact, full, or raw-compatible result fields."""
+
+ output_preset: Annotated[Literal["nested", "flat"], PropertyInfo(alias="outputPreset")]
+ """Keep enrichment nested or merge it into each result."""
diff --git a/src/x_twitter_scraper/types/extraction_run_params.py b/src/x_twitter_scraper/types/extraction_run_params.py
index bf4b15a..34f063e 100644
--- a/src/x_twitter_scraper/types/extraction_run_params.py
+++ b/src/x_twitter_scraper/types/extraction_run_params.py
@@ -6,13 +6,14 @@
from __future__ import annotations
-from typing import Union
-from datetime import date
-from typing_extensions import Literal, Required, Annotated, TypedDict
+from typing import Union, Iterable
+from datetime import date, datetime
+from typing_extensions import Literal, Required, Annotated, TypeAlias, TypedDict
+from .._types import SequenceNotStr
from .._utils import PropertyInfo
-__all__ = ["ExtractionRunParams"]
+__all__ = ["ExtractionRunParams", "RelationTarget", "Target", "TargetUnionMember1"]
class ExtractionRunParams(TypedDict, total=False):
@@ -48,6 +49,9 @@ class ExtractionRunParams(TypedDict, total=False):
]
"""Identifier for the extraction tool used to run a job."""
+ dry_run: bool
+ """Estimate cost without creating an extraction."""
+
advanced_query: Annotated[str, PropertyInfo(alias="advancedQuery")]
"""Raw advanced search query appended as-is (tweet_search_extractor)"""
@@ -57,18 +61,44 @@ class ExtractionRunParams(TypedDict, total=False):
Separate with spaces, commas, or lines. (tweet_search_extractor)
"""
+ bio_contains: Annotated[str, PropertyInfo(alias="bioContains")]
+ """Bio terms separated by commas or lines."""
+
+ blue_verified_only: Annotated[bool, PropertyInfo(alias="blueVerifiedOnly")]
+ """Return only Blue-verified Tweet authors."""
+
bounding_box: Annotated[str, PropertyInfo(alias="boundingBox")]
"""Geo bounding box, e.g. -74.1 40.6 -73.9 40.8 (tweet_search_extractor)"""
+ card_name: Annotated[str, PropertyInfo(alias="cardName")]
+ """Match the Tweet card name."""
+
cashtags: str
"""Cashtags separated by spaces, commas, or lines. (tweet_search_extractor)"""
+ collection_strategy: Annotated[
+ Literal["auto", "complete", "direct", "search", "thread"], PropertyInfo(alias="collectionStrategy")
+ ]
+ """Reply collection strategy."""
+
conversation_id: Annotated[str, PropertyInfo(alias="conversationId")]
"""Conversation ID filter (tweet_search_extractor)"""
+ dedupe_across_targets: Annotated[bool, PropertyInfo(alias="dedupeAcrossTargets")]
+ """Merge duplicate results across collection targets."""
+
+ dedupe_mode: Annotated[Literal["none", "first", "merge"], PropertyInfo(alias="dedupeMode")]
+ """Keep target duplicates, first rows, or merged overlap."""
+
exact_phrase: Annotated[str, PropertyInfo(alias="exactPhrase")]
"""Exact phrase to match (tweet_search_extractor)"""
+ exclude_original_author: Annotated[bool, PropertyInfo(alias="excludeOriginalAuthor")]
+ """Exclude replies from the source author."""
+
+ exclude_source: Annotated[str, PropertyInfo(alias="excludeSource")]
+ """Exclude a source application."""
+
exclude_words: Annotated[str, PropertyInfo(alias="excludeWords")]
"""Words or quoted phrases to exclude.
@@ -78,9 +108,30 @@ class ExtractionRunParams(TypedDict, total=False):
from_user: Annotated[str, PropertyInfo(alias="fromUser")]
"""Filter by author username (tweet_search_extractor)"""
+ geocode: str
+ """Match latitude, longitude, and radius."""
+
hashtags: str
"""Hashtags separated by spaces, commas, or lines. (tweet_search_extractor)"""
+ has_location: Annotated[bool, PropertyInfo(alias="hasLocation")]
+ """Require a profile location."""
+
+ has_media_only: Annotated[bool, PropertyInfo(alias="hasMediaOnly")]
+ """Return only replies with media."""
+
+ has_website: Annotated[bool, PropertyInfo(alias="hasWebsite")]
+ """Require a profile website."""
+
+ include_original_post: Annotated[bool, PropertyInfo(alias="includeOriginalPost")]
+ """Include the source post in reply results."""
+
+ include_search_terms: Annotated[bool, PropertyInfo(alias="includeSearchTerms")]
+ """Add matching search terms to collection metadata."""
+
+ include_target_metadata: Annotated[bool, PropertyInfo(alias="includeTargetMetadata")]
+ """Add source target metadata to each result."""
+
in_reply_to_tweet_id: Annotated[str, PropertyInfo(alias="inReplyToTweetId")]
"""Only replies to this tweet ID (tweet_search_extractor)"""
@@ -90,6 +141,42 @@ class ExtractionRunParams(TypedDict, total=False):
list_id: Annotated[str, PropertyInfo(alias="listId")]
"""Search within a list ID (tweet_search_extractor)"""
+ location_contains: Annotated[str, PropertyInfo(alias="locationContains")]
+ """Required profile location text."""
+
+ max_depth: Annotated[int, PropertyInfo(alias="maxDepth")]
+ """Maximum nested reply depth."""
+
+ max_followers: Annotated[int, PropertyInfo(alias="maxFollowers")]
+ """Maximum follower count for profile results."""
+
+ max_following: Annotated[int, PropertyInfo(alias="maxFollowing")]
+ """Maximum following count for profile results."""
+
+ max_id: Annotated[str, PropertyInfo(alias="maxId")]
+ """Return Tweets older than this Tweet ID."""
+
+ max_items_per_target: Annotated[int, PropertyInfo(alias="maxItemsPerTarget")]
+ """Maximum results collected for each target."""
+
+ max_likes: Annotated[int, PropertyInfo(alias="maxLikes")]
+ """Maximum Tweet like count."""
+
+ max_pages_per_target: Annotated[int, PropertyInfo(alias="maxPagesPerTarget")]
+ """Reply pages collected for each target."""
+
+ max_posts: Annotated[int, PropertyInfo(alias="maxPosts")]
+ """Maximum post count for profile results."""
+
+ max_quotes: Annotated[int, PropertyInfo(alias="maxQuotes")]
+ """Maximum Tweet quote count."""
+
+ max_replies: Annotated[int, PropertyInfo(alias="maxReplies")]
+ """Maximum Tweet reply count."""
+
+ max_retweets: Annotated[int, PropertyInfo(alias="maxRetweets")]
+ """Maximum Tweet repost count."""
+
media_type: Annotated[
Literal["images", "videos", "gifs", "media", "links", "none"], PropertyInfo(alias="mediaType")
]
@@ -98,9 +185,24 @@ class ExtractionRunParams(TypedDict, total=False):
mentioning: str
"""Filter tweets mentioning a username (tweet_search_extractor)"""
+ min_account_age_days: Annotated[int, PropertyInfo(alias="minAccountAgeDays")]
+ """Minimum profile age in days."""
+
+ min_bookmarks: Annotated[int, PropertyInfo(alias="minBookmarks")]
+ """Minimum Tweet bookmark count."""
+
min_faves: Annotated[int, PropertyInfo(alias="minFaves")]
"""Minimum likes threshold (tweet_search_extractor)"""
+ min_followers: Annotated[int, PropertyInfo(alias="minFollowers")]
+ """Minimum follower count for profile results."""
+
+ min_following: Annotated[int, PropertyInfo(alias="minFollowing")]
+ """Minimum following count for profile results."""
+
+ min_posts: Annotated[int, PropertyInfo(alias="minPosts")]
+ """Minimum post count for profile results."""
+
min_quotes: Annotated[int, PropertyInfo(alias="minQuotes")]
"""Minimum quote count threshold (tweet_search_extractor)"""
@@ -110,6 +212,21 @@ class ExtractionRunParams(TypedDict, total=False):
min_retweets: Annotated[int, PropertyInfo(alias="minRetweets")]
"""Minimum retweets threshold (tweet_search_extractor)"""
+ min_views: Annotated[int, PropertyInfo(alias="minViews")]
+ """Minimum Tweet view count."""
+
+ native_retweets: Annotated[bool, PropertyInfo(alias="nativeRetweets")]
+ """Only return native reposts."""
+
+ near: str
+ """Match a place name."""
+
+ news: bool
+ """Only return news results."""
+
+ overlap_mode: Annotated[bool, PropertyInfo(alias="overlapMode")]
+ """Shortcut for dedupeMode=merge."""
+
place: str
"""Search within a place ID (tweet_search_extractor)"""
@@ -119,12 +236,18 @@ class ExtractionRunParams(TypedDict, total=False):
point_radius: Annotated[str, PropertyInfo(alias="pointRadius")]
"""Geo point radius, e.g. -73.99 40.73 25mi (tweet_search_extractor)"""
+ query_type: Annotated[Literal["Latest", "Top", "Both"], PropertyInfo(alias="queryType")]
+ """Search ranking applied to every query."""
+
quotes: Literal["include", "exclude", "only"]
"""Quote mode (tweet_search_extractor)"""
quotes_of_tweet_id: Annotated[str, PropertyInfo(alias="quotesOfTweetId")]
"""Only quotes of this tweet ID (tweet_search_extractor)"""
+ relation_targets: Annotated[Iterable[RelationTarget], PropertyInfo(alias="relationTargets")]
+ """Profile relations processed within one job."""
+
replies: Literal["include", "exclude", "only"]
"""Reply mode (tweet_search_extractor)"""
@@ -140,36 +263,124 @@ class ExtractionRunParams(TypedDict, total=False):
retweets_of_tweet_id: Annotated[str, PropertyInfo(alias="retweetsOfTweetId")]
"""Only retweets of this tweet ID (tweet_search_extractor)"""
+ safe: bool
+ """Enable the safe-search filter."""
+
+ scope: Literal["all", "direct", "nested"]
+ """Reply depth scope."""
+
+ search_queries: Annotated[SequenceNotStr[str], PropertyInfo(alias="searchQueries")]
+ """Search queries processed as one collection job."""
+
search_query: Annotated[str, PropertyInfo(alias="searchQuery")]
"""Required for tweet_search_extractor & community_search."""
since_date: Annotated[Union[str, date], PropertyInfo(alias="sinceDate", format="iso8601")]
"""Start date YYYY-MM-DD (tweet_search_extractor)"""
+ since_id: Annotated[str, PropertyInfo(alias="sinceId")]
+ """Return Tweets newer than this Tweet ID."""
+
+ since_time: Annotated[Union[Union[str, datetime], int], PropertyInfo(alias="sinceTime", format="iso8601")]
+ """Reply start time as ISO 8601 or Unix seconds."""
+
+ sort: Literal["relevance", "latest", "oldest", "likes"]
+ """Reply result order."""
+
+ source: str
+ """Match the source application."""
+
+ start_cursor: Annotated[str, PropertyInfo(alias="startCursor")]
+ """Resume one reply target from this cursor."""
+
target_community_id: Annotated[str, PropertyInfo(alias="targetCommunityId")]
"""Required for community_post_extractor & community_search."""
+ target_community_ids: Annotated[SequenceNotStr[str], PropertyInfo(alias="targetCommunityIds")]
+ """Community IDs processed as one collection job."""
+
target_list_id: Annotated[str, PropertyInfo(alias="targetListId")]
"""
Required for list_follower_explorer, list_member_extractor &
list_post_extractor.
"""
+ target_list_ids: Annotated[SequenceNotStr[str], PropertyInfo(alias="targetListIds")]
+ """List IDs processed as one collection job."""
+
+ targets: SequenceNotStr[Target]
+ """Mixed targets auto-routed within one job."""
+
target_space_id: Annotated[str, PropertyInfo(alias="targetSpaceId")]
"""Required for space_explorer."""
target_tweet_id: Annotated[str, PropertyInfo(alias="targetTweetId")]
+ target_tweet_ids: Annotated[SequenceNotStr[str], PropertyInfo(alias="targetTweetIds")]
+ """Tweet IDs processed as one collection job."""
+
target_username: Annotated[str, PropertyInfo(alias="targetUsername")]
+ target_usernames: Annotated[SequenceNotStr[str], PropertyInfo(alias="targetUsernames")]
+ """Usernames processed as one collection job."""
+
to_user: Annotated[str, PropertyInfo(alias="toUser")]
"""Filter replies sent to a username (tweet_search_extractor)"""
until_date: Annotated[Union[str, date], PropertyInfo(alias="untilDate", format="iso8601")]
"""End date YYYY-MM-DD (tweet_search_extractor)"""
+ until_time: Annotated[Union[Union[str, datetime], int], PropertyInfo(alias="untilTime", format="iso8601")]
+ """Reply end time as ISO 8601 or Unix seconds."""
+
url: str
"""URL substring or domain filter (tweet_search_extractor)"""
+ username_contains: Annotated[str, PropertyInfo(alias="usernameContains")]
+ """Required username text."""
+
verified_only: Annotated[bool, PropertyInfo(alias="verifiedOnly")]
"""Only verified authors (tweet_search_extractor)"""
+
+ verified_type: Annotated[str, PropertyInfo(alias="verifiedType")]
+ """Exact profile verification type."""
+
+ within: str
+ """Set the radius for the near filter."""
+
+ within_time: Annotated[str, PropertyInfo(alias="withinTime")]
+ """Match Tweets inside a recent time window."""
+
+
+class RelationTarget(TypedDict, total=False):
+ """One target and relation in a mixed profile collection."""
+
+ relation: Required[
+ Literal["community_members", "followers", "following", "list_followers", "list_members", "verified_followers"]
+ ]
+
+ value: Required[str]
+
+
+class TargetUnionMember1(TypedDict, total=False):
+ kind: Required[
+ Literal[
+ "favoriters",
+ "list",
+ "profile",
+ "profile_likes",
+ "profile_media",
+ "profile_replies",
+ "quotes",
+ "replies",
+ "retweeters",
+ "search",
+ "thread",
+ "tweet",
+ ]
+ ]
+
+ value: Required[str]
+
+
+Target: TypeAlias = Union[str, TargetUnionMember1]
diff --git a/src/x_twitter_scraper/types/extraction_run_response.py b/src/x_twitter_scraper/types/extraction_run_response.py
index d05ff94..4ee0209 100644
--- a/src/x_twitter_scraper/types/extraction_run_response.py
+++ b/src/x_twitter_scraper/types/extraction_run_response.py
@@ -4,7 +4,7 @@
# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
-from typing_extensions import Literal
+from typing import Optional
from pydantic import Field as FieldInfo
@@ -14,33 +14,14 @@
class ExtractionRunResponse(BaseModel):
- id: str
-
- status: Literal["running"]
-
- tool_type: Literal[
- "article_extractor",
- "community_extractor",
- "community_moderator_explorer",
- "community_post_extractor",
- "community_search",
- "favoriters",
- "follower_explorer",
- "following_explorer",
- "list_follower_explorer",
- "list_member_extractor",
- "list_post_extractor",
- "mention_extractor",
- "people_search",
- "post_extractor",
- "quote_extractor",
- "reply_extractor",
- "repost_extractor",
- "space_explorer",
- "thread_extractor",
- "tweet_search_extractor",
- "user_likes",
- "user_media",
- "verified_follower_explorer",
- ] = FieldInfo(alias="toolType")
- """Identifier for the extraction tool used to run a job."""
+ allowed: bool
+
+ credits_available: str = FieldInfo(alias="creditsAvailable")
+
+ credits_required: str = FieldInfo(alias="creditsRequired")
+
+ estimated_results: int = FieldInfo(alias="estimatedResults")
+
+ source: str
+
+ resolved_x_user_id: Optional[str] = FieldInfo(alias="resolvedXUserId", default=None)
diff --git a/src/x_twitter_scraper/types/monitor.py b/src/x_twitter_scraper/types/monitor.py
index c820e7e..e9f29e3 100644
--- a/src/x_twitter_scraper/types/monitor.py
+++ b/src/x_twitter_scraper/types/monitor.py
@@ -4,8 +4,9 @@
# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
-from typing import List
+from typing import List, Optional
from datetime import datetime
+from typing_extensions import Literal
from pydantic import Field as FieldInfo
@@ -33,3 +34,9 @@ class Monitor(BaseModel):
username: str
x_user_id: str = FieldInfo(alias="xUserId")
+
+ paused_at: Optional[datetime] = FieldInfo(alias="pausedAt", default=None)
+ """When Xquik automatically paused this monitor."""
+
+ paused_reason: Optional[Literal["x_user_not_found"]] = FieldInfo(alias="pausedReason", default=None)
+ """Why Xquik automatically paused this monitor."""
diff --git a/src/x_twitter_scraper/types/shared/error.py b/src/x_twitter_scraper/types/shared/error.py
index 892cb9a..0e16514 100644
--- a/src/x_twitter_scraper/types/shared/error.py
+++ b/src/x_twitter_scraper/types/shared/error.py
@@ -43,6 +43,7 @@ class ErrorValueStructuredError(BaseModel):
"missing_params",
"missing_query",
"monitor_already_exists",
+ "monitor_profile_unavailable",
"no_media",
"no_credits",
"no_subscription",
@@ -60,6 +61,8 @@ class ErrorValueStructuredError(BaseModel):
"checkout_unavailable",
"connection_challenge_expired",
"connection_challenge_inactive",
+ "coverage_cursor_gone",
+ "coverage_cursor_unavailable",
"draft_not_found",
"favoriters_unavailable",
"forbidden",
@@ -69,6 +72,7 @@ class ErrorValueStructuredError(BaseModel):
"idempotency_conflict",
"idempotency_key_conflict",
"invalid_community_id",
+ "invalid_coverage_cursor",
"invalid_idempotency_key",
"invalid_list_id",
"invalid_payment_amount",
@@ -159,6 +163,7 @@ class ErrorValueStructuredError(BaseModel):
"missing_params",
"missing_query",
"monitor_already_exists",
+ "monitor_profile_unavailable",
"no_media",
"no_credits",
"no_subscription",
@@ -176,6 +181,8 @@ class ErrorValueStructuredError(BaseModel):
"checkout_unavailable",
"connection_challenge_expired",
"connection_challenge_inactive",
+ "coverage_cursor_gone",
+ "coverage_cursor_unavailable",
"draft_not_found",
"favoriters_unavailable",
"forbidden",
@@ -185,6 +192,7 @@ class ErrorValueStructuredError(BaseModel):
"idempotency_conflict",
"idempotency_key_conflict",
"invalid_community_id",
+ "invalid_coverage_cursor",
"invalid_idempotency_key",
"invalid_list_id",
"invalid_payment_amount",
diff --git a/src/x_twitter_scraper/types/shared/paginated_tweets.py b/src/x_twitter_scraper/types/shared/paginated_tweets.py
index 4ad997a..b2800e6 100644
--- a/src/x_twitter_scraper/types/shared/paginated_tweets.py
+++ b/src/x_twitter_scraper/types/shared/paginated_tweets.py
@@ -14,9 +14,8 @@
class PaginatedTweets(BaseModel):
- """Paginated tweets.
-
- Source visibility, filters, or remaining credits can reduce results. An empty filtered page can still have has_next_page true. Follow next_cursor while has_next_page is true. Zero affordable results returns 402 insufficient_credits.
+ """
+ No-mode search, user Tweet, user reply, and direct reply reads use automatic coverage. Shape, filters, aliases, and billing stay compatible. Unprefixed cursors remain legacy. Follow next_cursor while has_next_page is true. An empty filtered page can still have has_next_page true.
"""
has_next_page: bool
diff --git a/src/x_twitter_scraper/types/shared/paginated_users.py b/src/x_twitter_scraper/types/shared/paginated_users.py
index 11580a9..a789246 100644
--- a/src/x_twitter_scraper/types/shared/paginated_users.py
+++ b/src/x_twitter_scraper/types/shared/paginated_users.py
@@ -15,7 +15,7 @@
class PaginatedUsers(BaseModel):
"""Paginated user profiles.
- The item count can be lower than pageSize when the source returns fewer profiles or remaining credits cover fewer results. Follow next_cursor while has_next_page is true. A relationship can naturally contain fewer profiles than requested. Zero affordable results returns 402 insufficient_credits.
+ No-mode follower, following, and verified follower requests merge independent views automatically. Response fields, page size, aliases, filters, and per-returned-profile billing stay unchanged. Existing unprefixed cursors retain legacy behavior. Follow next_cursor while has_next_page is true.
"""
has_next_page: bool
diff --git a/src/x_twitter_scraper/types/x/__init__.py b/src/x_twitter_scraper/types/x/__init__.py
index dfb924b..86b1a70 100644
--- a/src/x_twitter_scraper/types/x/__init__.py
+++ b/src/x_twitter_scraper/types/x/__init__.py
@@ -27,6 +27,7 @@
from .profile_update_params import ProfileUpdateParams as ProfileUpdateParams
from .tweet_create_response import TweetCreateResponse as TweetCreateResponse
from .tweet_delete_response import TweetDeleteResponse as TweetDeleteResponse
+from .tweet_search_response import TweetSearchResponse as TweetSearchResponse
from .account_create_response import AccountCreateResponse as AccountCreateResponse
from .account_delete_response import AccountDeleteResponse as AccountDeleteResponse
from .account_reauth_response import AccountReauthResponse as AccountReauthResponse
@@ -69,6 +70,8 @@
from .write_action_retrieve_response import WriteActionRetrieveResponse as WriteActionRetrieveResponse
from .community_retrieve_info_response import CommunityRetrieveInfoResponse as CommunityRetrieveInfoResponse
from .community_retrieve_search_params import CommunityRetrieveSearchParams as CommunityRetrieveSearchParams
+from .user_retrieve_followers_response import UserRetrieveFollowersResponse as UserRetrieveFollowersResponse
+from .user_retrieve_following_response import UserRetrieveFollowingResponse as UserRetrieveFollowingResponse
from .community_retrieve_members_params import CommunityRetrieveMembersParams as CommunityRetrieveMembersParams
from .bookmark_retrieve_folders_response import BookmarkRetrieveFoldersResponse as BookmarkRetrieveFoldersResponse
from .community_retrieve_moderators_params import CommunityRetrieveModeratorsParams as CommunityRetrieveModeratorsParams
@@ -78,6 +81,9 @@
from .user_retrieve_verified_followers_params import (
UserRetrieveVerifiedFollowersParams as UserRetrieveVerifiedFollowersParams,
)
+from .user_retrieve_verified_followers_response import (
+ UserRetrieveVerifiedFollowersResponse as UserRetrieveVerifiedFollowersResponse,
+)
from .account_connection_challenge_submit_params import (
AccountConnectionChallengeSubmitParams as AccountConnectionChallengeSubmitParams,
)
diff --git a/src/x_twitter_scraper/types/x/community_retrieve_members_params.py b/src/x_twitter_scraper/types/x/community_retrieve_members_params.py
index 463385a..6d0bed5 100644
--- a/src/x_twitter_scraper/types/x/community_retrieve_members_params.py
+++ b/src/x_twitter_scraper/types/x/community_retrieve_members_params.py
@@ -14,9 +14,42 @@
class CommunityRetrieveMembersParams(TypedDict, total=False):
+ bio_contains: Annotated[str, PropertyInfo(alias="bioContains")]
+ """Match any comma-separated or line-separated bio term, ignoring case."""
+
cursor: str
"""Pagination cursor"""
+ has_location: Annotated[bool, PropertyInfo(alias="hasLocation")]
+ """Only return profiles with a location."""
+
+ has_website: Annotated[bool, PropertyInfo(alias="hasWebsite")]
+ """Only return profiles with a website."""
+
+ location_contains: Annotated[str, PropertyInfo(alias="locationContains")]
+ """Match a location substring, ignoring case."""
+
+ max_followers: Annotated[int, PropertyInfo(alias="maxFollowers")]
+ """Maximum follower count. Missing counts pass this maximum."""
+
+ max_following: Annotated[int, PropertyInfo(alias="maxFollowing")]
+ """Maximum following count."""
+
+ max_statuses: Annotated[int, PropertyInfo(alias="maxStatuses")]
+ """Maximum post count. maxPosts is also accepted."""
+
+ min_account_age_days: Annotated[int, PropertyInfo(alias="minAccountAgeDays")]
+ """Minimum account age in whole days."""
+
+ min_followers: Annotated[int, PropertyInfo(alias="minFollowers")]
+ """Minimum follower count. Filtering happens before billing."""
+
+ min_following: Annotated[int, PropertyInfo(alias="minFollowing")]
+ """Minimum following count."""
+
+ min_statuses: Annotated[int, PropertyInfo(alias="minStatuses")]
+ """Minimum post count. minPosts is also accepted."""
+
page_size: Annotated[int, PropertyInfo(alias="pageSize")]
"""Items per page (20-200, default 20).
@@ -24,3 +57,12 @@ class CommunityRetrieveMembersParams(TypedDict, total=False):
reduce the returned page size, and zero affordable results returns 402
insufficient_credits.
"""
+
+ username_contains: Annotated[str, PropertyInfo(alias="usernameContains")]
+ """Match a username substring, ignoring case."""
+
+ verified_only: Annotated[bool, PropertyInfo(alias="verifiedOnly")]
+ """Only return verified profiles."""
+
+ verified_type: Annotated[str, PropertyInfo(alias="verifiedType")]
+ """Match the verification type exactly, ignoring case."""
diff --git a/src/x_twitter_scraper/types/x/community_retrieve_moderators_params.py b/src/x_twitter_scraper/types/x/community_retrieve_moderators_params.py
index a5f9031..36d4bc7 100644
--- a/src/x_twitter_scraper/types/x/community_retrieve_moderators_params.py
+++ b/src/x_twitter_scraper/types/x/community_retrieve_moderators_params.py
@@ -6,11 +6,55 @@
from __future__ import annotations
-from typing_extensions import TypedDict
+from typing_extensions import Annotated, TypedDict
+
+from ..._utils import PropertyInfo
__all__ = ["CommunityRetrieveModeratorsParams"]
class CommunityRetrieveModeratorsParams(TypedDict, total=False):
+ bio_contains: Annotated[str, PropertyInfo(alias="bioContains")]
+ """Match any comma-separated or line-separated bio term, ignoring case."""
+
cursor: str
"""Pagination cursor for community moderators"""
+
+ has_location: Annotated[bool, PropertyInfo(alias="hasLocation")]
+ """Only return profiles with a location."""
+
+ has_website: Annotated[bool, PropertyInfo(alias="hasWebsite")]
+ """Only return profiles with a website."""
+
+ location_contains: Annotated[str, PropertyInfo(alias="locationContains")]
+ """Match a location substring, ignoring case."""
+
+ max_followers: Annotated[int, PropertyInfo(alias="maxFollowers")]
+ """Maximum follower count. Missing counts pass this maximum."""
+
+ max_following: Annotated[int, PropertyInfo(alias="maxFollowing")]
+ """Maximum following count."""
+
+ max_statuses: Annotated[int, PropertyInfo(alias="maxStatuses")]
+ """Maximum post count. maxPosts is also accepted."""
+
+ min_account_age_days: Annotated[int, PropertyInfo(alias="minAccountAgeDays")]
+ """Minimum account age in whole days."""
+
+ min_followers: Annotated[int, PropertyInfo(alias="minFollowers")]
+ """Minimum follower count. Filtering happens before billing."""
+
+ min_following: Annotated[int, PropertyInfo(alias="minFollowing")]
+ """Minimum following count."""
+
+ min_statuses: Annotated[int, PropertyInfo(alias="minStatuses")]
+ """Minimum post count. minPosts is also accepted."""
+
+ username_contains: Annotated[str, PropertyInfo(alias="usernameContains")]
+ """Match a username substring, ignoring case."""
+
+ verified_only: Annotated[bool, PropertyInfo(alias="verifiedOnly")]
+ """Only return verified profiles."""
+
+ verified_type: Annotated[str, PropertyInfo(alias="verifiedType")]
+ """Match the verification type exactly, ignoring case."""
diff --git a/src/x_twitter_scraper/types/x/list_retrieve_followers_params.py b/src/x_twitter_scraper/types/x/list_retrieve_followers_params.py
index 1a0c1f3..c4067cf 100644
--- a/src/x_twitter_scraper/types/x/list_retrieve_followers_params.py
+++ b/src/x_twitter_scraper/types/x/list_retrieve_followers_params.py
@@ -14,13 +14,54 @@
class ListRetrieveFollowersParams(TypedDict, total=False):
+ bio_contains: Annotated[str, PropertyInfo(alias="bioContains")]
+ """Match any comma-separated or line-separated bio term, ignoring case."""
+
cursor: str
"""Pagination cursor for list followers"""
+ has_location: Annotated[bool, PropertyInfo(alias="hasLocation")]
+ """Only return profiles with a location."""
+
+ has_website: Annotated[bool, PropertyInfo(alias="hasWebsite")]
+ """Only return profiles with a website."""
+
+ location_contains: Annotated[str, PropertyInfo(alias="locationContains")]
+ """Match a location substring, ignoring case."""
+
+ max_followers: Annotated[int, PropertyInfo(alias="maxFollowers")]
+ """Maximum follower count. Missing counts pass this maximum."""
+
+ max_following: Annotated[int, PropertyInfo(alias="maxFollowing")]
+ """Maximum following count."""
+
+ max_statuses: Annotated[int, PropertyInfo(alias="maxStatuses")]
+ """Maximum post count. maxPosts is also accepted."""
+
+ min_account_age_days: Annotated[int, PropertyInfo(alias="minAccountAgeDays")]
+ """Minimum account age in whole days."""
+
+ min_followers: Annotated[int, PropertyInfo(alias="minFollowers")]
+ """Minimum follower count. Filtering happens before billing."""
+
+ min_following: Annotated[int, PropertyInfo(alias="minFollowing")]
+ """Minimum following count."""
+
+ min_statuses: Annotated[int, PropertyInfo(alias="minStatuses")]
+ """Minimum post count. minPosts is also accepted."""
+
page_size: Annotated[int, PropertyInfo(alias="pageSize")]
"""Maximum user profiles requested from this page (20-200, default 200).
- The response can contain fewer profiles because the source returned fewer or
- remaining credits cover fewer results. Keep requesting next_cursor while
- has_next_page is true. The deprecated limit and count aliases remain accepted.
+ Source, filters, or credits can return fewer profiles. Keep requesting
+ next_cursor while has_next_page is true. Deprecated aliases remain accepted.
"""
+
+ username_contains: Annotated[str, PropertyInfo(alias="usernameContains")]
+ """Match a username substring, ignoring case."""
+
+ verified_only: Annotated[bool, PropertyInfo(alias="verifiedOnly")]
+ """Only return verified profiles."""
+
+ verified_type: Annotated[str, PropertyInfo(alias="verifiedType")]
+ """Match the verification type exactly, ignoring case."""
diff --git a/src/x_twitter_scraper/types/x/list_retrieve_members_params.py b/src/x_twitter_scraper/types/x/list_retrieve_members_params.py
index 6460986..9a1b394 100644
--- a/src/x_twitter_scraper/types/x/list_retrieve_members_params.py
+++ b/src/x_twitter_scraper/types/x/list_retrieve_members_params.py
@@ -14,8 +14,50 @@
class ListRetrieveMembersParams(TypedDict, total=False):
+ bio_contains: Annotated[str, PropertyInfo(alias="bioContains")]
+ """Match any comma-separated or line-separated bio term, ignoring case."""
+
cursor: str
"""Pagination cursor for list members"""
+ has_location: Annotated[bool, PropertyInfo(alias="hasLocation")]
+ """Only return profiles with a location."""
+
+ has_website: Annotated[bool, PropertyInfo(alias="hasWebsite")]
+ """Only return profiles with a website."""
+
+ location_contains: Annotated[str, PropertyInfo(alias="locationContains")]
+ """Match a location substring, ignoring case."""
+
+ max_followers: Annotated[int, PropertyInfo(alias="maxFollowers")]
+ """Maximum follower count. Missing counts pass this maximum."""
+
+ max_following: Annotated[int, PropertyInfo(alias="maxFollowing")]
+ """Maximum following count."""
+
+ max_statuses: Annotated[int, PropertyInfo(alias="maxStatuses")]
+ """Maximum post count. maxPosts is also accepted."""
+
+ min_account_age_days: Annotated[int, PropertyInfo(alias="minAccountAgeDays")]
+ """Minimum account age in whole days."""
+
+ min_followers: Annotated[int, PropertyInfo(alias="minFollowers")]
+ """Minimum follower count. Filtering happens before billing."""
+
+ min_following: Annotated[int, PropertyInfo(alias="minFollowing")]
+ """Minimum following count."""
+
+ min_statuses: Annotated[int, PropertyInfo(alias="minStatuses")]
+ """Minimum post count. minPosts is also accepted."""
+
page_size: Annotated[int, PropertyInfo(alias="pageSize")]
"""Members per page (20-200, default 20)"""
+
+ username_contains: Annotated[str, PropertyInfo(alias="usernameContains")]
+ """Match a username substring, ignoring case."""
+
+ verified_only: Annotated[bool, PropertyInfo(alias="verifiedOnly")]
+ """Only return verified profiles."""
+
+ verified_type: Annotated[str, PropertyInfo(alias="verifiedType")]
+ """Match the verification type exactly, ignoring case."""
diff --git a/src/x_twitter_scraper/types/x/tweet_get_favoriters_params.py b/src/x_twitter_scraper/types/x/tweet_get_favoriters_params.py
index dcd4fb9..6370c23 100644
--- a/src/x_twitter_scraper/types/x/tweet_get_favoriters_params.py
+++ b/src/x_twitter_scraper/types/x/tweet_get_favoriters_params.py
@@ -14,13 +14,54 @@
class TweetGetFavoritersParams(TypedDict, total=False):
+ bio_contains: Annotated[str, PropertyInfo(alias="bioContains")]
+ """Match any comma-separated or line-separated bio term, ignoring case."""
+
cursor: str
"""Pagination cursor for favoriters"""
+ has_location: Annotated[bool, PropertyInfo(alias="hasLocation")]
+ """Only return profiles with a location."""
+
+ has_website: Annotated[bool, PropertyInfo(alias="hasWebsite")]
+ """Only return profiles with a website."""
+
+ location_contains: Annotated[str, PropertyInfo(alias="locationContains")]
+ """Match a location substring, ignoring case."""
+
+ max_followers: Annotated[int, PropertyInfo(alias="maxFollowers")]
+ """Maximum follower count. Missing counts pass this maximum."""
+
+ max_following: Annotated[int, PropertyInfo(alias="maxFollowing")]
+ """Maximum following count."""
+
+ max_statuses: Annotated[int, PropertyInfo(alias="maxStatuses")]
+ """Maximum post count. maxPosts is also accepted."""
+
+ min_account_age_days: Annotated[int, PropertyInfo(alias="minAccountAgeDays")]
+ """Minimum account age in whole days."""
+
+ min_followers: Annotated[int, PropertyInfo(alias="minFollowers")]
+ """Minimum follower count. Filtering happens before billing."""
+
+ min_following: Annotated[int, PropertyInfo(alias="minFollowing")]
+ """Minimum following count."""
+
+ min_statuses: Annotated[int, PropertyInfo(alias="minStatuses")]
+ """Minimum post count. minPosts is also accepted."""
+
page_size: Annotated[int, PropertyInfo(alias="pageSize")]
"""Maximum user profiles requested from this page (20-200, default 200).
- The response can contain fewer profiles because the source returned fewer or
- remaining credits cover fewer results. Keep requesting next_cursor while
- has_next_page is true. The deprecated limit and count aliases remain accepted.
+ Source, filters, or credits can return fewer profiles. Keep requesting
+ next_cursor while has_next_page is true. Deprecated aliases remain accepted.
"""
+
+ username_contains: Annotated[str, PropertyInfo(alias="usernameContains")]
+ """Match a username substring, ignoring case."""
+
+ verified_only: Annotated[bool, PropertyInfo(alias="verifiedOnly")]
+ """Only return verified profiles."""
+
+ verified_type: Annotated[str, PropertyInfo(alias="verifiedType")]
+ """Match the verification type exactly, ignoring case."""
diff --git a/src/x_twitter_scraper/types/x/tweet_get_quotes_params.py b/src/x_twitter_scraper/types/x/tweet_get_quotes_params.py
index 64babcd..05518fd 100644
--- a/src/x_twitter_scraper/types/x/tweet_get_quotes_params.py
+++ b/src/x_twitter_scraper/types/x/tweet_get_quotes_params.py
@@ -22,6 +22,12 @@ class TweetGetQuotesParams(TypedDict, total=False):
Separate with spaces, commas, or lines.
"""
+ blue_verified_only: Annotated[bool, PropertyInfo(alias="blueVerifiedOnly")]
+ """Only return tweets from Blue-verified authors."""
+
+ card_name: Annotated[str, PropertyInfo(alias="cardName")]
+ """Match the Tweet card name."""
+
cashtags: str
"""Cashtags separated by spaces, commas, or lines."""
@@ -34,12 +40,18 @@ class TweetGetQuotesParams(TypedDict, total=False):
exact_phrase: Annotated[str, PropertyInfo(alias="exactPhrase")]
"""Exact phrase to match."""
+ exclude_source: Annotated[str, PropertyInfo(alias="excludeSource")]
+ """Exclude a source application."""
+
exclude_words: Annotated[str, PropertyInfo(alias="excludeWords")]
"""Words or quoted phrases to exclude. Separate with spaces, commas, or lines."""
from_user: Annotated[str, PropertyInfo(alias="fromUser")]
"""Filter by author username."""
+ geocode: str
+ """Match latitude, longitude, and radius."""
+
hashtags: str
"""Hashtags separated by spaces, commas, or lines."""
@@ -52,6 +64,21 @@ class TweetGetQuotesParams(TypedDict, total=False):
language: str
"""Language code filter, e.g. en or tr."""
+ max_faves: Annotated[int, PropertyInfo(alias="maxFaves")]
+ """Maximum likes threshold. maxLikes is also accepted."""
+
+ max_id: Annotated[str, PropertyInfo(alias="maxId")]
+ """Return Tweets older than this Tweet ID."""
+
+ max_quotes: Annotated[int, PropertyInfo(alias="maxQuotes")]
+ """Maximum quotes threshold."""
+
+ max_replies: Annotated[int, PropertyInfo(alias="maxReplies")]
+ """Maximum replies threshold."""
+
+ max_retweets: Annotated[int, PropertyInfo(alias="maxRetweets")]
+ """Maximum retweets threshold."""
+
media_type: Annotated[
Literal["images", "videos", "gifs", "media", "links", "none"], PropertyInfo(alias="mediaType")
]
@@ -60,6 +87,9 @@ class TweetGetQuotesParams(TypedDict, total=False):
mentioning: str
"""Filter tweets mentioning a username."""
+ min_bookmarks: Annotated[int, PropertyInfo(alias="minBookmarks")]
+ """Minimum bookmark count threshold."""
+
min_faves: Annotated[int, PropertyInfo(alias="minFaves")]
"""Minimum likes threshold."""
@@ -72,6 +102,18 @@ class TweetGetQuotesParams(TypedDict, total=False):
min_retweets: Annotated[int, PropertyInfo(alias="minRetweets")]
"""Minimum retweets threshold."""
+ min_views: Annotated[int, PropertyInfo(alias="minViews")]
+ """Minimum view count threshold."""
+
+ native_retweets: Annotated[bool, PropertyInfo(alias="nativeRetweets")]
+ """Only return native reposts."""
+
+ near: str
+ """Match a place name."""
+
+ news: bool
+ """Only return news results."""
+
page_size: Annotated[int, PropertyInfo(alias="pageSize")]
"""Maximum page items (1-100, default 20).
@@ -94,12 +136,21 @@ class TweetGetQuotesParams(TypedDict, total=False):
retweets_of_tweet_id: Annotated[str, PropertyInfo(alias="retweetsOfTweetId")]
"""Only retweets of this tweet ID."""
+ safe: bool
+ """Enable the safe-search filter."""
+
since_date: Annotated[Union[str, date], PropertyInfo(alias="sinceDate", format="iso8601")]
"""Start date in YYYY-MM-DD format."""
+ since_id: Annotated[str, PropertyInfo(alias="sinceId")]
+ """Return Tweets newer than this Tweet ID."""
+
since_time: Annotated[str, PropertyInfo(alias="sinceTime")]
"""Unix timestamp - return quotes posted after this time"""
+ source: str
+ """Match the source application."""
+
to_user: Annotated[str, PropertyInfo(alias="toUser")]
"""Filter replies sent to a username."""
@@ -114,3 +165,9 @@ class TweetGetQuotesParams(TypedDict, total=False):
verified_only: Annotated[bool, PropertyInfo(alias="verifiedOnly")]
"""Only return tweets from verified authors."""
+
+ within: str
+ """Set the radius for the near filter."""
+
+ within_time: Annotated[str, PropertyInfo(alias="withinTime")]
+ """Match Tweets inside a recent time window."""
diff --git a/src/x_twitter_scraper/types/x/tweet_get_replies_params.py b/src/x_twitter_scraper/types/x/tweet_get_replies_params.py
index f505b0d..af8fe78 100644
--- a/src/x_twitter_scraper/types/x/tweet_get_replies_params.py
+++ b/src/x_twitter_scraper/types/x/tweet_get_replies_params.py
@@ -22,6 +22,12 @@ class TweetGetRepliesParams(TypedDict, total=False):
Separate with spaces, commas, or lines.
"""
+ blue_verified_only: Annotated[bool, PropertyInfo(alias="blueVerifiedOnly")]
+ """Only return tweets from Blue-verified authors."""
+
+ card_name: Annotated[str, PropertyInfo(alias="cardName")]
+ """Match the Tweet card name."""
+
cashtags: str
"""Cashtags separated by spaces, commas, or lines."""
@@ -29,20 +35,39 @@ class TweetGetRepliesParams(TypedDict, total=False):
"""Conversation ID filter."""
cursor: str
- """Pagination cursor for tweet replies"""
+ """Cursor from the previous response.
+
+ Xquik cursors resume automatic coverage. Existing unprefixed cursors keep legacy
+ standard behavior.
+ """
exact_phrase: Annotated[str, PropertyInfo(alias="exactPhrase")]
"""Exact phrase to match."""
+ exclude_original_author: Annotated[bool, PropertyInfo(alias="excludeOriginalAuthor")]
+ """Exclude replies written by the source-post author."""
+
+ exclude_source: Annotated[str, PropertyInfo(alias="excludeSource")]
+ """Exclude a source application."""
+
exclude_words: Annotated[str, PropertyInfo(alias="excludeWords")]
"""Words or quoted phrases to exclude. Separate with spaces, commas, or lines."""
from_user: Annotated[str, PropertyInfo(alias="fromUser")]
"""Filter by author username."""
+ geocode: str
+ """Match latitude, longitude, and radius."""
+
hashtags: str
"""Hashtags separated by spaces, commas, or lines."""
+ has_media_only: Annotated[bool, PropertyInfo(alias="hasMediaOnly")]
+ """Only return replies containing media."""
+
+ include_original_post: Annotated[bool, PropertyInfo(alias="includeOriginalPost")]
+ """Include the source post and count it toward limit."""
+
in_reply_to_tweet_id: Annotated[str, PropertyInfo(alias="inReplyToTweetId")]
"""Only replies to this tweet ID."""
@@ -50,11 +75,29 @@ class TweetGetRepliesParams(TypedDict, total=False):
"""Language code filter, e.g. en or tr."""
limit: int
- """With mode=complete, maximum combined direct and nested reply rows (1-25000).
-
- Without complete mode, this is the deprecated pageSize alias and uses the normal
- 1-100 page range.
"""
+ With mode=complete, maximum combined direct and nested reply rows (1-25000,
+ default 25000). Automatic pages accept 1-300. Standard pages accept 1-100.
+ Prefer pageSize outside complete mode.
+ """
+
+ max_depth: Annotated[int, PropertyInfo(alias="maxDepth")]
+ """Maximum reply depth from the source post."""
+
+ max_faves: Annotated[int, PropertyInfo(alias="maxFaves")]
+ """Maximum likes threshold. maxLikes is also accepted."""
+
+ max_id: Annotated[str, PropertyInfo(alias="maxId")]
+ """Return Tweets older than this Tweet ID."""
+
+ max_quotes: Annotated[int, PropertyInfo(alias="maxQuotes")]
+ """Maximum quotes threshold."""
+
+ max_replies: Annotated[int, PropertyInfo(alias="maxReplies")]
+ """Maximum replies threshold."""
+
+ max_retweets: Annotated[int, PropertyInfo(alias="maxRetweets")]
+ """Maximum retweets threshold."""
media_type: Annotated[
Literal["images", "videos", "gifs", "media", "links", "none"], PropertyInfo(alias="mediaType")
@@ -64,6 +107,9 @@ class TweetGetRepliesParams(TypedDict, total=False):
mentioning: str
"""Filter tweets mentioning a username."""
+ min_bookmarks: Annotated[int, PropertyInfo(alias="minBookmarks")]
+ """Minimum bookmark count threshold."""
+
min_faves: Annotated[int, PropertyInfo(alias="minFaves")]
"""Minimum likes threshold."""
@@ -76,18 +122,31 @@ class TweetGetRepliesParams(TypedDict, total=False):
min_retweets: Annotated[int, PropertyInfo(alias="minRetweets")]
"""Minimum retweets threshold."""
- mode: Literal["complete"]
- """Set complete for maximum-coverage collection.
+ min_views: Annotated[int, PropertyInfo(alias="minViews")]
+ """Minimum view count threshold."""
+
+ mode: Literal["standard", "complete"]
+ """Optional advanced override.
- Complete mode accepts only limit. Remove cursor, pageSize, count, time ranges,
- and tweet filters.
+ Omit mode for automatic maximum direct reply coverage with pagination. Standard
+ keeps legacy pagination. Complete returns direct and nested replies with
+ diagnostics, scope, depth, sorting, and original-post controls.
"""
+ native_retweets: Annotated[bool, PropertyInfo(alias="nativeRetweets")]
+ """Only return native reposts."""
+
+ near: str
+ """Match a place name."""
+
+ news: bool
+ """Only return news results."""
+
page_size: Annotated[int, PropertyInfo(alias="pageSize")]
- """Maximum page items (1-100, default 20).
+ """Automatic pages accept 1-300 Tweets.
- Source, filters, or credits can reduce results. Continue while has_next_page is
- true. Deprecated limit and count aliases remain accepted.
+ Standard pages keep 1-100. Default 20. Continue while has_next_page is true.
+ Deprecated aliases remain accepted.
"""
quotes: Literal["include", "exclude", "only"]
@@ -105,12 +164,27 @@ class TweetGetRepliesParams(TypedDict, total=False):
retweets_of_tweet_id: Annotated[str, PropertyInfo(alias="retweetsOfTweetId")]
"""Only retweets of this tweet ID."""
+ safe: bool
+ """Enable the safe-search filter."""
+
+ scope: Literal["all", "direct", "nested"]
+ """Select all replies, direct replies, or nested replies."""
+
since_date: Annotated[Union[str, date], PropertyInfo(alias="sinceDate", format="iso8601")]
"""Start date in YYYY-MM-DD format."""
+ since_id: Annotated[str, PropertyInfo(alias="sinceId")]
+ """Return Tweets newer than this Tweet ID."""
+
since_time: Annotated[str, PropertyInfo(alias="sinceTime")]
"""Unix timestamp - return replies posted after this time"""
+ sort: Literal["relevance", "latest", "oldest", "likes"]
+ """Sort the selected replies before applying limit."""
+
+ source: str
+ """Match the source application."""
+
to_user: Annotated[str, PropertyInfo(alias="toUser")]
"""Filter replies sent to a username."""
@@ -125,3 +199,9 @@ class TweetGetRepliesParams(TypedDict, total=False):
verified_only: Annotated[bool, PropertyInfo(alias="verifiedOnly")]
"""Only return tweets from verified authors."""
+
+ within: str
+ """Set the radius for the near filter."""
+
+ within_time: Annotated[str, PropertyInfo(alias="withinTime")]
+ """Match Tweets inside a recent time window."""
diff --git a/src/x_twitter_scraper/types/x/tweet_get_replies_response.py b/src/x_twitter_scraper/types/x/tweet_get_replies_response.py
index 5b55421..abdf911 100644
--- a/src/x_twitter_scraper/types/x/tweet_get_replies_response.py
+++ b/src/x_twitter_scraper/types/x/tweet_get_replies_response.py
@@ -136,9 +136,9 @@ class TweetGetRepliesResponseDiagnostic(BaseModel):
class TweetGetRepliesResponse(PaginatedTweets):
- """Reply rows.
+ """Direct reply rows.
- Complete mode also returns nested replies and coverage diagnostics. Keep nested replies separate from direct coverage.
+ No-mode requests use resumable automatic coverage. Complete mode also returns nested replies and coverage diagnostics. Keep nested replies separate from direct coverage.
"""
diagnostic: Optional[TweetGetRepliesResponseDiagnostic] = None
diff --git a/src/x_twitter_scraper/types/x/tweet_get_retweeters_params.py b/src/x_twitter_scraper/types/x/tweet_get_retweeters_params.py
index 744d5dc..dbfe740 100644
--- a/src/x_twitter_scraper/types/x/tweet_get_retweeters_params.py
+++ b/src/x_twitter_scraper/types/x/tweet_get_retweeters_params.py
@@ -14,13 +14,54 @@
class TweetGetRetweetersParams(TypedDict, total=False):
+ bio_contains: Annotated[str, PropertyInfo(alias="bioContains")]
+ """Match any comma-separated or line-separated bio term, ignoring case."""
+
cursor: str
"""Pagination cursor for retweeters"""
+ has_location: Annotated[bool, PropertyInfo(alias="hasLocation")]
+ """Only return profiles with a location."""
+
+ has_website: Annotated[bool, PropertyInfo(alias="hasWebsite")]
+ """Only return profiles with a website."""
+
+ location_contains: Annotated[str, PropertyInfo(alias="locationContains")]
+ """Match a location substring, ignoring case."""
+
+ max_followers: Annotated[int, PropertyInfo(alias="maxFollowers")]
+ """Maximum follower count. Missing counts pass this maximum."""
+
+ max_following: Annotated[int, PropertyInfo(alias="maxFollowing")]
+ """Maximum following count."""
+
+ max_statuses: Annotated[int, PropertyInfo(alias="maxStatuses")]
+ """Maximum post count. maxPosts is also accepted."""
+
+ min_account_age_days: Annotated[int, PropertyInfo(alias="minAccountAgeDays")]
+ """Minimum account age in whole days."""
+
+ min_followers: Annotated[int, PropertyInfo(alias="minFollowers")]
+ """Minimum follower count. Filtering happens before billing."""
+
+ min_following: Annotated[int, PropertyInfo(alias="minFollowing")]
+ """Minimum following count."""
+
+ min_statuses: Annotated[int, PropertyInfo(alias="minStatuses")]
+ """Minimum post count. minPosts is also accepted."""
+
page_size: Annotated[int, PropertyInfo(alias="pageSize")]
"""Maximum user profiles requested from this page (20-200, default 200).
- The response can contain fewer profiles because the source returned fewer or
- remaining credits cover fewer results. Keep requesting next_cursor while
- has_next_page is true. The deprecated limit and count aliases remain accepted.
+ Source, filters, or credits can return fewer profiles. Keep requesting
+ next_cursor while has_next_page is true. Deprecated aliases remain accepted.
"""
+
+ username_contains: Annotated[str, PropertyInfo(alias="usernameContains")]
+ """Match a username substring, ignoring case."""
+
+ verified_only: Annotated[bool, PropertyInfo(alias="verifiedOnly")]
+ """Only return verified profiles."""
+
+ verified_type: Annotated[str, PropertyInfo(alias="verifiedType")]
+ """Match the verification type exactly, ignoring case."""
diff --git a/src/x_twitter_scraper/types/x/tweet_search_params.py b/src/x_twitter_scraper/types/x/tweet_search_params.py
index 25e4991..84ecbd7 100644
--- a/src/x_twitter_scraper/types/x/tweet_search_params.py
+++ b/src/x_twitter_scraper/types/x/tweet_search_params.py
@@ -17,7 +17,7 @@
class TweetSearchParams(TypedDict, total=False):
q: Required[str]
- """Search query (keywords,"""
+ """Query, Tweet ID, or status URL. Valid inline bounds apply per page."""
advanced_query: Annotated[str, PropertyInfo(alias="advancedQuery")]
"""Raw advanced search query appended as-is."""
@@ -28,9 +28,15 @@ class TweetSearchParams(TypedDict, total=False):
Separate with spaces, commas, or lines.
"""
+ blue_verified_only: Annotated[bool, PropertyInfo(alias="blueVerifiedOnly")]
+ """Only return tweets from Blue-verified authors."""
+
bounding_box: Annotated[str, PropertyInfo(alias="boundingBox")]
"""Geo bounding box, e.g. -74.1 40.6 -73.9 40.8."""
+ card_name: Annotated[str, PropertyInfo(alias="cardName")]
+ """Match the Tweet card name."""
+
cashtags: str
"""Cashtags separated by spaces, commas, or lines."""
@@ -38,17 +44,27 @@ class TweetSearchParams(TypedDict, total=False):
"""Conversation ID filter."""
cursor: str
- """Pagination cursor from previous response"""
+ """Cursor from the previous response.
+
+ Xquik cursors resume automatic coverage. Existing unprefixed cursors keep legacy
+ standard behavior.
+ """
exact_phrase: Annotated[str, PropertyInfo(alias="exactPhrase")]
"""Exact phrase to match."""
+ exclude_source: Annotated[str, PropertyInfo(alias="excludeSource")]
+ """Exclude a source application."""
+
exclude_words: Annotated[str, PropertyInfo(alias="excludeWords")]
"""Words or quoted phrases to exclude. Separate with spaces, commas, or lines."""
from_user: Annotated[str, PropertyInfo(alias="fromUser")]
"""Filter by author username."""
+ geocode: str
+ """Match latitude, longitude, and radius."""
+
hashtags: str
"""Hashtags separated by spaces, commas, or lines."""
@@ -59,16 +75,31 @@ class TweetSearchParams(TypedDict, total=False):
"""Language code filter, e.g. en or tr."""
limit: int
- """Max tweets to return (server paginates internally).
+ """Result upper bound.
- Omit for single page (~20). This is an upper bound for paid authenticated calls:
- remaining credits can reduce the returned page size, and zero affordable results
- returns 402 insufficient_credits.
+ Omit it for the existing 20-row page size. Explicit coverage defaults to 2000
+ and allows 10000. For paid requests, remaining credits can reduce results. Zero
+ affordable results returns 402.
"""
list_id: Annotated[str, PropertyInfo(alias="listId")]
"""Search within a list ID."""
+ max_faves: Annotated[int, PropertyInfo(alias="maxFaves")]
+ """Maximum likes threshold. maxLikes is also accepted."""
+
+ max_id: Annotated[str, PropertyInfo(alias="maxId")]
+ """Return Tweets older than this Tweet ID."""
+
+ max_quotes: Annotated[int, PropertyInfo(alias="maxQuotes")]
+ """Maximum quotes threshold."""
+
+ max_replies: Annotated[int, PropertyInfo(alias="maxReplies")]
+ """Maximum replies threshold."""
+
+ max_retweets: Annotated[int, PropertyInfo(alias="maxRetweets")]
+ """Maximum retweets threshold."""
+
media_type: Annotated[
Literal["images", "videos", "gifs", "media", "links", "none"], PropertyInfo(alias="mediaType")
]
@@ -77,6 +108,9 @@ class TweetSearchParams(TypedDict, total=False):
mentioning: str
"""Filter tweets mentioning a username."""
+ min_bookmarks: Annotated[int, PropertyInfo(alias="minBookmarks")]
+ """Minimum bookmark count threshold."""
+
min_faves: Annotated[int, PropertyInfo(alias="minFaves")]
"""Minimum likes threshold."""
@@ -89,6 +123,25 @@ class TweetSearchParams(TypedDict, total=False):
min_retweets: Annotated[int, PropertyInfo(alias="minRetweets")]
"""Minimum retweets threshold."""
+ min_views: Annotated[int, PropertyInfo(alias="minViews")]
+ """Minimum view count threshold."""
+
+ mode: Literal["standard", "coverage"]
+ """Omit mode for resumable maximum coverage.
+
+ Standard keeps legacy pagination. Coverage returns diagnostics once and rejects
+ cursors.
+ """
+
+ native_retweets: Annotated[bool, PropertyInfo(alias="nativeRetweets")]
+ """Only return native reposts."""
+
+ near: str
+ """Match a place name."""
+
+ news: bool
+ """Only return news results."""
+
place: str
"""Search within a place ID."""
@@ -116,11 +169,20 @@ class TweetSearchParams(TypedDict, total=False):
retweets_of_tweet_id: Annotated[str, PropertyInfo(alias="retweetsOfTweetId")]
"""Only retweets of this tweet ID."""
+ safe: bool
+ """Enable the safe-search filter."""
+
since_date: Annotated[Union[str, date], PropertyInfo(alias="sinceDate", format="iso8601")]
"""Start date in YYYY-MM-DD format."""
+ since_id: Annotated[str, PropertyInfo(alias="sinceId")]
+ """Return Tweets newer than this Tweet ID."""
+
since_time: Annotated[str, PropertyInfo(alias="sinceTime")]
- """ISO 8601 timestamp - only return tweets after this time"""
+ """Inclusive ISO bound."""
+
+ source: str
+ """Match the source application."""
to_user: Annotated[str, PropertyInfo(alias="toUser")]
"""Filter replies sent to a username."""
@@ -129,10 +191,16 @@ class TweetSearchParams(TypedDict, total=False):
"""End date in YYYY-MM-DD format."""
until_time: Annotated[str, PropertyInfo(alias="untilTime")]
- """ISO 8601 timestamp - only return tweets before this time"""
+ """Exclusive ISO bound."""
url: str
"""URL substring or domain filter."""
verified_only: Annotated[bool, PropertyInfo(alias="verifiedOnly")]
"""Only return tweets from verified authors."""
+
+ within: str
+ """Set the radius for the near filter."""
+
+ within_time: Annotated[str, PropertyInfo(alias="withinTime")]
+ """Match Tweets inside a recent time window."""
diff --git a/src/x_twitter_scraper/types/x/tweet_search_response.py b/src/x_twitter_scraper/types/x/tweet_search_response.py
new file mode 100644
index 0000000..c3e4f1d
--- /dev/null
+++ b/src/x_twitter_scraper/types/x/tweet_search_response.py
@@ -0,0 +1,102 @@
+# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+from __future__ import annotations
+
+from typing import List, Union, Optional
+from datetime import datetime
+from typing_extensions import Literal, TypeAlias
+
+from pydantic import Field as FieldInfo
+
+from ..._models import BaseModel
+from ..shared.paginated_tweets import PaginatedTweets
+
+__all__ = [
+ "TweetSearchResponse",
+ "TweetSearchCoverageResponse",
+ "TweetSearchCoverageResponseDiagnostic",
+ "TweetSearchCoverageResponseDiagnosticStrategy",
+ "TweetSearchCoverageResponseDiagnosticStrategyWindow",
+]
+
+
+class TweetSearchCoverageResponseDiagnosticStrategyWindow(BaseModel):
+ """Non-overlapping time partition used by one strategy."""
+
+ since_time: datetime = FieldInfo(alias="sinceTime")
+
+ until_time: datetime = FieldInfo(alias="untilTime")
+
+
+class TweetSearchCoverageResponseDiagnosticStrategy(BaseModel):
+ duplicate_count: int = FieldInfo(alias="duplicateCount")
+
+ pages_fetched: int = FieldInfo(alias="pagesFetched")
+
+ query_type: Literal["Latest", "Top"] = FieldInfo(alias="queryType")
+
+ stop_reason: Literal[
+ "cursor_failure", "deadline", "exhausted", "failed", "page_limit", "result_limit", "stalled"
+ ] = FieldInfo(alias="stopReason")
+
+ strategy: int
+
+ unique_added: int = FieldInfo(alias="uniqueAdded")
+
+ window: Optional[TweetSearchCoverageResponseDiagnosticStrategyWindow] = None
+ """Non-overlapping time partition used by one strategy."""
+
+
+class TweetSearchCoverageResponseDiagnostic(BaseModel):
+ """Coverage evidence across parallel search strategies."""
+
+ complete: bool
+ """True when every strategy exhausted its source."""
+
+ cursor_failure_count: int = FieldInfo(alias="cursorFailureCount")
+
+ deadline_reached: bool = FieldInfo(alias="deadlineReached")
+
+ duplicate_count: int = FieldInfo(alias="duplicateCount")
+
+ failed_strategy_count: int = FieldInfo(alias="failedStrategyCount")
+
+ malformed_count: int = FieldInfo(alias="malformedCount")
+
+ pages_fetched: int = FieldInfo(alias="pagesFetched")
+
+ partitioned: bool
+ """Whether bounded time windows ran in parallel."""
+
+ response_truncated: bool = FieldInfo(alias="responseTruncated")
+ """Whether credits or the requested limit reduced output."""
+
+ result_limit_reached: bool = FieldInfo(alias="resultLimitReached")
+
+ returned_tweets: int = FieldInfo(alias="returnedTweets")
+
+ stalled_strategy_count: int = FieldInfo(alias="stalledStrategyCount")
+
+ strategies: List[TweetSearchCoverageResponseDiagnosticStrategy]
+
+ strategy_count: int = FieldInfo(alias="strategyCount")
+
+ unique_tweets: int = FieldInfo(alias="uniqueTweets")
+
+
+class TweetSearchCoverageResponse(PaginatedTweets):
+ """
+ No-mode search, user Tweet, user reply, and direct reply reads use automatic coverage. Shape, filters, aliases, and billing stay compatible. Unprefixed cursors remain legacy. Follow next_cursor while has_next_page is true. An empty filtered page can still have has_next_page true.
+ """
+
+ diagnostic: TweetSearchCoverageResponseDiagnostic
+ """Coverage evidence across parallel search strategies."""
+
+ has_next_page: Optional[Literal[False]] = None # type: ignore
+
+ next_cursor: Optional[Literal[""]] = None # type: ignore
+
+
+TweetSearchResponse: TypeAlias = Union["PaginatedTweets", TweetSearchCoverageResponse]
+
+from ..shared.paginated_tweets import PaginatedTweets
diff --git a/src/x_twitter_scraper/types/x/user_retrieve_followers_params.py b/src/x_twitter_scraper/types/x/user_retrieve_followers_params.py
index 14ccbc1..b8b98a7 100644
--- a/src/x_twitter_scraper/types/x/user_retrieve_followers_params.py
+++ b/src/x_twitter_scraper/types/x/user_retrieve_followers_params.py
@@ -6,7 +6,7 @@
from __future__ import annotations
-from typing_extensions import Annotated, TypedDict
+from typing_extensions import Literal, Annotated, TypedDict
from ..._utils import PropertyInfo
@@ -17,16 +17,70 @@ class UserRetrieveFollowersParams(TypedDict, total=False):
after: str
"""Legacy cursor alias. Prefer cursor."""
+ bio_contains: Annotated[str, PropertyInfo(alias="bioContains")]
+ """Match any comma-separated or line-separated bio term, ignoring case."""
+
cursor: str
- """Pagination cursor for followers list"""
+ """Cursor from the previous response.
+
+ Xquik cursors resume automatic coverage. Existing unprefixed cursors keep legacy
+ standard behavior.
+ """
+
+ has_location: Annotated[bool, PropertyInfo(alias="hasLocation")]
+ """Only return profiles with a location."""
+
+ has_website: Annotated[bool, PropertyInfo(alias="hasWebsite")]
+ """Only return profiles with a website."""
limit: int
- """Legacy integer page size alias for following lists. Prefer pageSize."""
+ """Legacy page-size alias outside explicit coverage mode.
+
+ Coverage accepts 1-10000. Prefer pageSize.
+ """
+
+ location_contains: Annotated[str, PropertyInfo(alias="locationContains")]
+ """Match a location substring, ignoring case."""
+
+ max_followers: Annotated[int, PropertyInfo(alias="maxFollowers")]
+ """Maximum follower count. Missing counts pass this maximum."""
+
+ max_following: Annotated[int, PropertyInfo(alias="maxFollowing")]
+ """Maximum following count."""
+
+ max_statuses: Annotated[int, PropertyInfo(alias="maxStatuses")]
+ """Maximum post count. maxPosts is also accepted."""
+
+ min_account_age_days: Annotated[int, PropertyInfo(alias="minAccountAgeDays")]
+ """Minimum account age in whole days."""
+
+ min_followers: Annotated[int, PropertyInfo(alias="minFollowers")]
+ """Minimum follower count. Filtering happens before billing."""
+
+ min_following: Annotated[int, PropertyInfo(alias="minFollowing")]
+ """Minimum following count."""
+
+ min_statuses: Annotated[int, PropertyInfo(alias="minStatuses")]
+ """Minimum post count. minPosts is also accepted."""
+
+ mode: Literal["standard", "coverage"]
+ """Omit mode for resumable maximum coverage.
+
+ Standard keeps legacy pagination. Coverage returns diagnostics once and rejects
+ cursors.
+ """
page_size: Annotated[int, PropertyInfo(alias="pageSize")]
- """Maximum user profiles requested from this page (20-200, default 200).
+ """Maximum user profiles: automatic 300; standard 200.
- The response can contain fewer profiles because the source returned fewer or
- remaining credits cover fewer results. Keep requesting next_cursor while
- has_next_page is true. The deprecated limit and count aliases remain accepted.
+ Sources return fewer profiles. Continue with has_next_page.
"""
+
+ username_contains: Annotated[str, PropertyInfo(alias="usernameContains")]
+ """Match a username substring, ignoring case."""
+
+ verified_only: Annotated[bool, PropertyInfo(alias="verifiedOnly")]
+ """Only return verified profiles."""
+
+ verified_type: Annotated[str, PropertyInfo(alias="verifiedType")]
+ """Match the verification type exactly, ignoring case."""
diff --git a/src/x_twitter_scraper/types/x/user_retrieve_followers_response.py b/src/x_twitter_scraper/types/x/user_retrieve_followers_response.py
new file mode 100644
index 0000000..af8971e
--- /dev/null
+++ b/src/x_twitter_scraper/types/x/user_retrieve_followers_response.py
@@ -0,0 +1,81 @@
+# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+from typing import List, Union, Optional
+from typing_extensions import Literal, TypeAlias
+
+from pydantic import Field as FieldInfo
+
+from ..._models import BaseModel
+from ..shared.paginated_users import PaginatedUsers
+
+__all__ = [
+ "UserRetrieveFollowersResponse",
+ "UserListCoverageResponse",
+ "UserListCoverageResponseDiagnostic",
+ "UserListCoverageResponseDiagnosticStrategy",
+]
+
+
+class UserListCoverageResponseDiagnosticStrategy(BaseModel):
+ duplicate_count: int = FieldInfo(alias="duplicateCount")
+
+ pages_fetched: int = FieldInfo(alias="pagesFetched")
+
+ stop_reason: Literal[
+ "cursor_failure", "deadline", "exhausted", "failed", "page_limit", "result_limit", "stalled"
+ ] = FieldInfo(alias="stopReason")
+
+ strategy: int
+
+ unique_added: int = FieldInfo(alias="uniqueAdded")
+
+
+class UserListCoverageResponseDiagnostic(BaseModel):
+ """Coverage evidence across parallel relationship strategies."""
+
+ complete: bool
+ """True when every strategy exhausted its source."""
+
+ cursor_failure_count: int = FieldInfo(alias="cursorFailureCount")
+
+ deadline_reached: bool = FieldInfo(alias="deadlineReached")
+
+ duplicate_count: int = FieldInfo(alias="duplicateCount")
+
+ failed_strategy_count: int = FieldInfo(alias="failedStrategyCount")
+
+ malformed_count: int = FieldInfo(alias="malformedCount")
+
+ pages_fetched: int = FieldInfo(alias="pagesFetched")
+
+ response_truncated: bool = FieldInfo(alias="responseTruncated")
+ """Whether credits or the requested limit reduced output."""
+
+ result_limit_reached: bool = FieldInfo(alias="resultLimitReached")
+
+ returned_users: int = FieldInfo(alias="returnedUsers")
+
+ stalled_strategy_count: int = FieldInfo(alias="stalledStrategyCount")
+
+ strategies: List[UserListCoverageResponseDiagnosticStrategy]
+
+ strategy_count: int = FieldInfo(alias="strategyCount")
+
+ unique_users: int = FieldInfo(alias="uniqueUsers")
+
+
+class UserListCoverageResponse(PaginatedUsers):
+ """Paginated user profiles.
+
+ No-mode follower, following, and verified follower requests merge independent views automatically. Response fields, page size, aliases, filters, and per-returned-profile billing stay unchanged. Existing unprefixed cursors retain legacy behavior. Follow next_cursor while has_next_page is true.
+ """
+
+ diagnostic: UserListCoverageResponseDiagnostic
+ """Coverage evidence across parallel relationship strategies."""
+
+ has_next_page: Optional[Literal[False]] = None # type: ignore
+
+ next_cursor: Optional[Literal[""]] = None # type: ignore
+
+
+UserRetrieveFollowersResponse: TypeAlias = Union[PaginatedUsers, UserListCoverageResponse]
diff --git a/src/x_twitter_scraper/types/x/user_retrieve_followers_you_know_params.py b/src/x_twitter_scraper/types/x/user_retrieve_followers_you_know_params.py
index d357835..5e436e7 100644
--- a/src/x_twitter_scraper/types/x/user_retrieve_followers_you_know_params.py
+++ b/src/x_twitter_scraper/types/x/user_retrieve_followers_you_know_params.py
@@ -14,13 +14,54 @@
class UserRetrieveFollowersYouKnowParams(TypedDict, total=False):
+ bio_contains: Annotated[str, PropertyInfo(alias="bioContains")]
+ """Match any comma-separated or line-separated bio term, ignoring case."""
+
cursor: str
"""Pagination cursor for followers-you-know"""
+ has_location: Annotated[bool, PropertyInfo(alias="hasLocation")]
+ """Only return profiles with a location."""
+
+ has_website: Annotated[bool, PropertyInfo(alias="hasWebsite")]
+ """Only return profiles with a website."""
+
+ location_contains: Annotated[str, PropertyInfo(alias="locationContains")]
+ """Match a location substring, ignoring case."""
+
+ max_followers: Annotated[int, PropertyInfo(alias="maxFollowers")]
+ """Maximum follower count. Missing counts pass this maximum."""
+
+ max_following: Annotated[int, PropertyInfo(alias="maxFollowing")]
+ """Maximum following count."""
+
+ max_statuses: Annotated[int, PropertyInfo(alias="maxStatuses")]
+ """Maximum post count. maxPosts is also accepted."""
+
+ min_account_age_days: Annotated[int, PropertyInfo(alias="minAccountAgeDays")]
+ """Minimum account age in whole days."""
+
+ min_followers: Annotated[int, PropertyInfo(alias="minFollowers")]
+ """Minimum follower count. Filtering happens before billing."""
+
+ min_following: Annotated[int, PropertyInfo(alias="minFollowing")]
+ """Minimum following count."""
+
+ min_statuses: Annotated[int, PropertyInfo(alias="minStatuses")]
+ """Minimum post count. minPosts is also accepted."""
+
page_size: Annotated[int, PropertyInfo(alias="pageSize")]
"""Maximum user profiles requested from this page (20-200, default 200).
- The response can contain fewer profiles because the source returned fewer or
- remaining credits cover fewer results. Keep requesting next_cursor while
- has_next_page is true. The deprecated limit and count aliases remain accepted.
+ Source, filters, or credits can return fewer profiles. Keep requesting
+ next_cursor while has_next_page is true. Deprecated aliases remain accepted.
"""
+
+ username_contains: Annotated[str, PropertyInfo(alias="usernameContains")]
+ """Match a username substring, ignoring case."""
+
+ verified_only: Annotated[bool, PropertyInfo(alias="verifiedOnly")]
+ """Only return verified profiles."""
+
+ verified_type: Annotated[str, PropertyInfo(alias="verifiedType")]
+ """Match the verification type exactly, ignoring case."""
diff --git a/src/x_twitter_scraper/types/x/user_retrieve_following_params.py b/src/x_twitter_scraper/types/x/user_retrieve_following_params.py
index 3784f9c..f0f926a 100644
--- a/src/x_twitter_scraper/types/x/user_retrieve_following_params.py
+++ b/src/x_twitter_scraper/types/x/user_retrieve_following_params.py
@@ -6,7 +6,7 @@
from __future__ import annotations
-from typing_extensions import Annotated, TypedDict
+from typing_extensions import Literal, Annotated, TypedDict
from ..._utils import PropertyInfo
@@ -17,16 +17,70 @@ class UserRetrieveFollowingParams(TypedDict, total=False):
after: str
"""Deprecated following cursor alias. Prefer cursor."""
+ bio_contains: Annotated[str, PropertyInfo(alias="bioContains")]
+ """Match any comma-separated or line-separated bio term, ignoring case."""
+
cursor: str
- """Pagination cursor for following list"""
+ """Cursor from the previous response.
+
+ Xquik cursors resume automatic coverage. Existing unprefixed cursors keep legacy
+ standard behavior.
+ """
+
+ has_location: Annotated[bool, PropertyInfo(alias="hasLocation")]
+ """Only return profiles with a location."""
+
+ has_website: Annotated[bool, PropertyInfo(alias="hasWebsite")]
+ """Only return profiles with a website."""
limit: int
- """Legacy page size alias. Prefer pageSize."""
+ """Legacy page-size alias outside explicit coverage mode.
+
+ Coverage accepts 1-10000. Prefer pageSize.
+ """
+
+ location_contains: Annotated[str, PropertyInfo(alias="locationContains")]
+ """Match a location substring, ignoring case."""
+
+ max_followers: Annotated[int, PropertyInfo(alias="maxFollowers")]
+ """Maximum follower count. Missing counts pass this maximum."""
+
+ max_following: Annotated[int, PropertyInfo(alias="maxFollowing")]
+ """Maximum following count."""
+
+ max_statuses: Annotated[int, PropertyInfo(alias="maxStatuses")]
+ """Maximum post count. maxPosts is also accepted."""
+
+ min_account_age_days: Annotated[int, PropertyInfo(alias="minAccountAgeDays")]
+ """Minimum account age in whole days."""
+
+ min_followers: Annotated[int, PropertyInfo(alias="minFollowers")]
+ """Minimum follower count. Filtering happens before billing."""
+
+ min_following: Annotated[int, PropertyInfo(alias="minFollowing")]
+ """Minimum following count."""
+
+ min_statuses: Annotated[int, PropertyInfo(alias="minStatuses")]
+ """Minimum post count. minPosts is also accepted."""
+
+ mode: Literal["standard", "coverage"]
+ """Omit mode for resumable maximum coverage.
+
+ Standard keeps legacy pagination. Coverage returns diagnostics once and rejects
+ cursors.
+ """
page_size: Annotated[int, PropertyInfo(alias="pageSize")]
- """Maximum user profiles requested from this page (20-200, default 200).
+ """Maximum user profiles: automatic 300; standard 200.
- The response can contain fewer profiles because the source returned fewer or
- remaining credits cover fewer results. Keep requesting next_cursor while
- has_next_page is true. The deprecated limit and count aliases remain accepted.
+ Sources return fewer profiles. Continue with has_next_page.
"""
+
+ username_contains: Annotated[str, PropertyInfo(alias="usernameContains")]
+ """Match a username substring, ignoring case."""
+
+ verified_only: Annotated[bool, PropertyInfo(alias="verifiedOnly")]
+ """Only return verified profiles."""
+
+ verified_type: Annotated[str, PropertyInfo(alias="verifiedType")]
+ """Match the verification type exactly, ignoring case."""
diff --git a/src/x_twitter_scraper/types/x/user_retrieve_following_response.py b/src/x_twitter_scraper/types/x/user_retrieve_following_response.py
new file mode 100644
index 0000000..cd0c867
--- /dev/null
+++ b/src/x_twitter_scraper/types/x/user_retrieve_following_response.py
@@ -0,0 +1,81 @@
+# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+from typing import List, Union, Optional
+from typing_extensions import Literal, TypeAlias
+
+from pydantic import Field as FieldInfo
+
+from ..._models import BaseModel
+from ..shared.paginated_users import PaginatedUsers
+
+__all__ = [
+ "UserRetrieveFollowingResponse",
+ "UserListCoverageResponse",
+ "UserListCoverageResponseDiagnostic",
+ "UserListCoverageResponseDiagnosticStrategy",
+]
+
+
+class UserListCoverageResponseDiagnosticStrategy(BaseModel):
+ duplicate_count: int = FieldInfo(alias="duplicateCount")
+
+ pages_fetched: int = FieldInfo(alias="pagesFetched")
+
+ stop_reason: Literal[
+ "cursor_failure", "deadline", "exhausted", "failed", "page_limit", "result_limit", "stalled"
+ ] = FieldInfo(alias="stopReason")
+
+ strategy: int
+
+ unique_added: int = FieldInfo(alias="uniqueAdded")
+
+
+class UserListCoverageResponseDiagnostic(BaseModel):
+ """Coverage evidence across parallel relationship strategies."""
+
+ complete: bool
+ """True when every strategy exhausted its source."""
+
+ cursor_failure_count: int = FieldInfo(alias="cursorFailureCount")
+
+ deadline_reached: bool = FieldInfo(alias="deadlineReached")
+
+ duplicate_count: int = FieldInfo(alias="duplicateCount")
+
+ failed_strategy_count: int = FieldInfo(alias="failedStrategyCount")
+
+ malformed_count: int = FieldInfo(alias="malformedCount")
+
+ pages_fetched: int = FieldInfo(alias="pagesFetched")
+
+ response_truncated: bool = FieldInfo(alias="responseTruncated")
+ """Whether credits or the requested limit reduced output."""
+
+ result_limit_reached: bool = FieldInfo(alias="resultLimitReached")
+
+ returned_users: int = FieldInfo(alias="returnedUsers")
+
+ stalled_strategy_count: int = FieldInfo(alias="stalledStrategyCount")
+
+ strategies: List[UserListCoverageResponseDiagnosticStrategy]
+
+ strategy_count: int = FieldInfo(alias="strategyCount")
+
+ unique_users: int = FieldInfo(alias="uniqueUsers")
+
+
+class UserListCoverageResponse(PaginatedUsers):
+ """Paginated user profiles.
+
+ No-mode follower, following, and verified follower requests merge independent views automatically. Response fields, page size, aliases, filters, and per-returned-profile billing stay unchanged. Existing unprefixed cursors retain legacy behavior. Follow next_cursor while has_next_page is true.
+ """
+
+ diagnostic: UserListCoverageResponseDiagnostic
+ """Coverage evidence across parallel relationship strategies."""
+
+ has_next_page: Optional[Literal[False]] = None # type: ignore
+
+ next_cursor: Optional[Literal[""]] = None # type: ignore
+
+
+UserRetrieveFollowingResponse: TypeAlias = Union[PaginatedUsers, UserListCoverageResponse]
diff --git a/src/x_twitter_scraper/types/x/user_retrieve_likes_params.py b/src/x_twitter_scraper/types/x/user_retrieve_likes_params.py
index 255f9d9..6ddf22e 100644
--- a/src/x_twitter_scraper/types/x/user_retrieve_likes_params.py
+++ b/src/x_twitter_scraper/types/x/user_retrieve_likes_params.py
@@ -22,6 +22,12 @@ class UserRetrieveLikesParams(TypedDict, total=False):
Separate with spaces, commas, or lines.
"""
+ blue_verified_only: Annotated[bool, PropertyInfo(alias="blueVerifiedOnly")]
+ """Only return tweets from Blue-verified authors."""
+
+ card_name: Annotated[str, PropertyInfo(alias="cardName")]
+ """Match the Tweet card name."""
+
cashtags: str
"""Cashtags separated by spaces, commas, or lines."""
@@ -34,12 +40,18 @@ class UserRetrieveLikesParams(TypedDict, total=False):
exact_phrase: Annotated[str, PropertyInfo(alias="exactPhrase")]
"""Exact phrase to match."""
+ exclude_source: Annotated[str, PropertyInfo(alias="excludeSource")]
+ """Exclude a source application."""
+
exclude_words: Annotated[str, PropertyInfo(alias="excludeWords")]
"""Words or quoted phrases to exclude. Separate with spaces, commas, or lines."""
from_user: Annotated[str, PropertyInfo(alias="fromUser")]
"""Filter by author username."""
+ geocode: str
+ """Match latitude, longitude, and radius."""
+
hashtags: str
"""Hashtags separated by spaces, commas, or lines."""
@@ -49,6 +61,21 @@ class UserRetrieveLikesParams(TypedDict, total=False):
language: str
"""Language code filter, e.g. en or tr."""
+ max_faves: Annotated[int, PropertyInfo(alias="maxFaves")]
+ """Maximum likes threshold. maxLikes is also accepted."""
+
+ max_id: Annotated[str, PropertyInfo(alias="maxId")]
+ """Return Tweets older than this Tweet ID."""
+
+ max_quotes: Annotated[int, PropertyInfo(alias="maxQuotes")]
+ """Maximum quotes threshold."""
+
+ max_replies: Annotated[int, PropertyInfo(alias="maxReplies")]
+ """Maximum replies threshold."""
+
+ max_retweets: Annotated[int, PropertyInfo(alias="maxRetweets")]
+ """Maximum retweets threshold."""
+
media_type: Annotated[
Literal["images", "videos", "gifs", "media", "links", "none"], PropertyInfo(alias="mediaType")
]
@@ -57,6 +84,9 @@ class UserRetrieveLikesParams(TypedDict, total=False):
mentioning: str
"""Filter tweets mentioning a username."""
+ min_bookmarks: Annotated[int, PropertyInfo(alias="minBookmarks")]
+ """Minimum bookmark count threshold."""
+
min_faves: Annotated[int, PropertyInfo(alias="minFaves")]
"""Minimum likes threshold."""
@@ -69,6 +99,18 @@ class UserRetrieveLikesParams(TypedDict, total=False):
min_retweets: Annotated[int, PropertyInfo(alias="minRetweets")]
"""Minimum retweets threshold."""
+ min_views: Annotated[int, PropertyInfo(alias="minViews")]
+ """Minimum view count threshold."""
+
+ native_retweets: Annotated[bool, PropertyInfo(alias="nativeRetweets")]
+ """Only return native reposts."""
+
+ near: str
+ """Match a place name."""
+
+ news: bool
+ """Only return news results."""
+
page_size: Annotated[int, PropertyInfo(alias="pageSize")]
"""Maximum page items (1-100, default 20).
@@ -91,9 +133,18 @@ class UserRetrieveLikesParams(TypedDict, total=False):
retweets_of_tweet_id: Annotated[str, PropertyInfo(alias="retweetsOfTweetId")]
"""Only retweets of this tweet ID."""
+ safe: bool
+ """Enable the safe-search filter."""
+
since_date: Annotated[Union[str, date], PropertyInfo(alias="sinceDate", format="iso8601")]
"""Start date in YYYY-MM-DD format."""
+ since_id: Annotated[str, PropertyInfo(alias="sinceId")]
+ """Return Tweets newer than this Tweet ID."""
+
+ source: str
+ """Match the source application."""
+
to_user: Annotated[str, PropertyInfo(alias="toUser")]
"""Filter replies sent to a username."""
@@ -105,3 +156,9 @@ class UserRetrieveLikesParams(TypedDict, total=False):
verified_only: Annotated[bool, PropertyInfo(alias="verifiedOnly")]
"""Only return tweets from verified authors."""
+
+ within: str
+ """Set the radius for the near filter."""
+
+ within_time: Annotated[str, PropertyInfo(alias="withinTime")]
+ """Match Tweets inside a recent time window."""
diff --git a/src/x_twitter_scraper/types/x/user_retrieve_media_params.py b/src/x_twitter_scraper/types/x/user_retrieve_media_params.py
index 3730305..04c9a91 100644
--- a/src/x_twitter_scraper/types/x/user_retrieve_media_params.py
+++ b/src/x_twitter_scraper/types/x/user_retrieve_media_params.py
@@ -22,6 +22,12 @@ class UserRetrieveMediaParams(TypedDict, total=False):
Separate with spaces, commas, or lines.
"""
+ blue_verified_only: Annotated[bool, PropertyInfo(alias="blueVerifiedOnly")]
+ """Only return tweets from Blue-verified authors."""
+
+ card_name: Annotated[str, PropertyInfo(alias="cardName")]
+ """Match the Tweet card name."""
+
cashtags: str
"""Cashtags separated by spaces, commas, or lines."""
@@ -34,12 +40,18 @@ class UserRetrieveMediaParams(TypedDict, total=False):
exact_phrase: Annotated[str, PropertyInfo(alias="exactPhrase")]
"""Exact phrase to match."""
+ exclude_source: Annotated[str, PropertyInfo(alias="excludeSource")]
+ """Exclude a source application."""
+
exclude_words: Annotated[str, PropertyInfo(alias="excludeWords")]
"""Words or quoted phrases to exclude. Separate with spaces, commas, or lines."""
from_user: Annotated[str, PropertyInfo(alias="fromUser")]
"""Filter by author username."""
+ geocode: str
+ """Match latitude, longitude, and radius."""
+
hashtags: str
"""Hashtags separated by spaces, commas, or lines."""
@@ -49,6 +61,21 @@ class UserRetrieveMediaParams(TypedDict, total=False):
language: str
"""Language code filter, e.g. en or tr."""
+ max_faves: Annotated[int, PropertyInfo(alias="maxFaves")]
+ """Maximum likes threshold. maxLikes is also accepted."""
+
+ max_id: Annotated[str, PropertyInfo(alias="maxId")]
+ """Return Tweets older than this Tweet ID."""
+
+ max_quotes: Annotated[int, PropertyInfo(alias="maxQuotes")]
+ """Maximum quotes threshold."""
+
+ max_replies: Annotated[int, PropertyInfo(alias="maxReplies")]
+ """Maximum replies threshold."""
+
+ max_retweets: Annotated[int, PropertyInfo(alias="maxRetweets")]
+ """Maximum retweets threshold."""
+
media_type: Annotated[
Literal["images", "videos", "gifs", "media", "links", "none"], PropertyInfo(alias="mediaType")
]
@@ -57,6 +84,9 @@ class UserRetrieveMediaParams(TypedDict, total=False):
mentioning: str
"""Filter tweets mentioning a username."""
+ min_bookmarks: Annotated[int, PropertyInfo(alias="minBookmarks")]
+ """Minimum bookmark count threshold."""
+
min_faves: Annotated[int, PropertyInfo(alias="minFaves")]
"""Minimum likes threshold."""
@@ -69,6 +99,18 @@ class UserRetrieveMediaParams(TypedDict, total=False):
min_retweets: Annotated[int, PropertyInfo(alias="minRetweets")]
"""Minimum retweets threshold."""
+ min_views: Annotated[int, PropertyInfo(alias="minViews")]
+ """Minimum view count threshold."""
+
+ native_retweets: Annotated[bool, PropertyInfo(alias="nativeRetweets")]
+ """Only return native reposts."""
+
+ near: str
+ """Match a place name."""
+
+ news: bool
+ """Only return news results."""
+
page_size: Annotated[int, PropertyInfo(alias="pageSize")]
"""Maximum page items (1-100, default 20).
@@ -91,9 +133,18 @@ class UserRetrieveMediaParams(TypedDict, total=False):
retweets_of_tweet_id: Annotated[str, PropertyInfo(alias="retweetsOfTweetId")]
"""Only retweets of this tweet ID."""
+ safe: bool
+ """Enable the safe-search filter."""
+
since_date: Annotated[Union[str, date], PropertyInfo(alias="sinceDate", format="iso8601")]
"""Start date in YYYY-MM-DD format."""
+ since_id: Annotated[str, PropertyInfo(alias="sinceId")]
+ """Return Tweets newer than this Tweet ID."""
+
+ source: str
+ """Match the source application."""
+
to_user: Annotated[str, PropertyInfo(alias="toUser")]
"""Filter replies sent to a username."""
@@ -105,3 +156,9 @@ class UserRetrieveMediaParams(TypedDict, total=False):
verified_only: Annotated[bool, PropertyInfo(alias="verifiedOnly")]
"""Only return tweets from verified authors."""
+
+ within: str
+ """Set the radius for the near filter."""
+
+ within_time: Annotated[str, PropertyInfo(alias="withinTime")]
+ """Match Tweets inside a recent time window."""
diff --git a/src/x_twitter_scraper/types/x/user_retrieve_mentions_params.py b/src/x_twitter_scraper/types/x/user_retrieve_mentions_params.py
index 8731903..07598a6 100644
--- a/src/x_twitter_scraper/types/x/user_retrieve_mentions_params.py
+++ b/src/x_twitter_scraper/types/x/user_retrieve_mentions_params.py
@@ -22,6 +22,12 @@ class UserRetrieveMentionsParams(TypedDict, total=False):
Separate with spaces, commas, or lines.
"""
+ blue_verified_only: Annotated[bool, PropertyInfo(alias="blueVerifiedOnly")]
+ """Only return tweets from Blue-verified authors."""
+
+ card_name: Annotated[str, PropertyInfo(alias="cardName")]
+ """Match the Tweet card name."""
+
cashtags: str
"""Cashtags separated by spaces, commas, or lines."""
@@ -34,12 +40,18 @@ class UserRetrieveMentionsParams(TypedDict, total=False):
exact_phrase: Annotated[str, PropertyInfo(alias="exactPhrase")]
"""Exact phrase to match."""
+ exclude_source: Annotated[str, PropertyInfo(alias="excludeSource")]
+ """Exclude a source application."""
+
exclude_words: Annotated[str, PropertyInfo(alias="excludeWords")]
"""Words or quoted phrases to exclude. Separate with spaces, commas, or lines."""
from_user: Annotated[str, PropertyInfo(alias="fromUser")]
"""Filter by author username."""
+ geocode: str
+ """Match latitude, longitude, and radius."""
+
hashtags: str
"""Hashtags separated by spaces, commas, or lines."""
@@ -49,6 +61,21 @@ class UserRetrieveMentionsParams(TypedDict, total=False):
language: str
"""Language code filter, e.g. en or tr."""
+ max_faves: Annotated[int, PropertyInfo(alias="maxFaves")]
+ """Maximum likes threshold. maxLikes is also accepted."""
+
+ max_id: Annotated[str, PropertyInfo(alias="maxId")]
+ """Return Tweets older than this Tweet ID."""
+
+ max_quotes: Annotated[int, PropertyInfo(alias="maxQuotes")]
+ """Maximum quotes threshold."""
+
+ max_replies: Annotated[int, PropertyInfo(alias="maxReplies")]
+ """Maximum replies threshold."""
+
+ max_retweets: Annotated[int, PropertyInfo(alias="maxRetweets")]
+ """Maximum retweets threshold."""
+
media_type: Annotated[
Literal["images", "videos", "gifs", "media", "links", "none"], PropertyInfo(alias="mediaType")
]
@@ -57,6 +84,9 @@ class UserRetrieveMentionsParams(TypedDict, total=False):
mentioning: str
"""Filter tweets mentioning a username."""
+ min_bookmarks: Annotated[int, PropertyInfo(alias="minBookmarks")]
+ """Minimum bookmark count threshold."""
+
min_faves: Annotated[int, PropertyInfo(alias="minFaves")]
"""Minimum likes threshold."""
@@ -69,6 +99,18 @@ class UserRetrieveMentionsParams(TypedDict, total=False):
min_retweets: Annotated[int, PropertyInfo(alias="minRetweets")]
"""Minimum retweets threshold."""
+ min_views: Annotated[int, PropertyInfo(alias="minViews")]
+ """Minimum view count threshold."""
+
+ native_retweets: Annotated[bool, PropertyInfo(alias="nativeRetweets")]
+ """Only return native reposts."""
+
+ near: str
+ """Match a place name."""
+
+ news: bool
+ """Only return news results."""
+
page_size: Annotated[int, PropertyInfo(alias="pageSize")]
"""Maximum page items (1-100, default 20).
@@ -91,12 +133,21 @@ class UserRetrieveMentionsParams(TypedDict, total=False):
retweets_of_tweet_id: Annotated[str, PropertyInfo(alias="retweetsOfTweetId")]
"""Only retweets of this tweet ID."""
+ safe: bool
+ """Enable the safe-search filter."""
+
since_date: Annotated[Union[str, date], PropertyInfo(alias="sinceDate", format="iso8601")]
"""Start date in YYYY-MM-DD format."""
+ since_id: Annotated[str, PropertyInfo(alias="sinceId")]
+ """Return Tweets newer than this Tweet ID."""
+
since_time: Annotated[str, PropertyInfo(alias="sinceTime")]
"""Unix timestamp - return mentions after this time"""
+ source: str
+ """Match the source application."""
+
to_user: Annotated[str, PropertyInfo(alias="toUser")]
"""Filter replies sent to a username."""
@@ -111,3 +162,9 @@ class UserRetrieveMentionsParams(TypedDict, total=False):
verified_only: Annotated[bool, PropertyInfo(alias="verifiedOnly")]
"""Only return tweets from verified authors."""
+
+ within: str
+ """Set the radius for the near filter."""
+
+ within_time: Annotated[str, PropertyInfo(alias="withinTime")]
+ """Match Tweets inside a recent time window."""
diff --git a/src/x_twitter_scraper/types/x/user_retrieve_replies_params.py b/src/x_twitter_scraper/types/x/user_retrieve_replies_params.py
index fa091ad..a29f21d 100644
--- a/src/x_twitter_scraper/types/x/user_retrieve_replies_params.py
+++ b/src/x_twitter_scraper/types/x/user_retrieve_replies_params.py
@@ -22,6 +22,12 @@ class UserRetrieveRepliesParams(TypedDict, total=False):
Separate with spaces, commas, or lines.
"""
+ blue_verified_only: Annotated[bool, PropertyInfo(alias="blueVerifiedOnly")]
+ """Only return tweets from Blue-verified authors."""
+
+ card_name: Annotated[str, PropertyInfo(alias="cardName")]
+ """Match the Tweet card name."""
+
cashtags: str
"""Cashtags separated by spaces, commas, or lines."""
@@ -29,17 +35,27 @@ class UserRetrieveRepliesParams(TypedDict, total=False):
"""Conversation ID filter."""
cursor: str
- """Pagination cursor for user replies"""
+ """Cursor from the previous response.
+
+ Xquik cursors resume automatic coverage. Existing unprefixed cursors keep legacy
+ standard behavior.
+ """
exact_phrase: Annotated[str, PropertyInfo(alias="exactPhrase")]
"""Exact phrase to match."""
+ exclude_source: Annotated[str, PropertyInfo(alias="excludeSource")]
+ """Exclude a source application."""
+
exclude_words: Annotated[str, PropertyInfo(alias="excludeWords")]
"""Words or quoted phrases to exclude. Separate with spaces, commas, or lines."""
from_user: Annotated[str, PropertyInfo(alias="fromUser")]
"""Filter by author username."""
+ geocode: str
+ """Match latitude, longitude, and radius."""
+
hashtags: str
"""Hashtags separated by spaces, commas, or lines."""
@@ -52,6 +68,21 @@ class UserRetrieveRepliesParams(TypedDict, total=False):
language: str
"""Language code filter, e.g. en or tr."""
+ max_faves: Annotated[int, PropertyInfo(alias="maxFaves")]
+ """Maximum likes threshold. maxLikes is also accepted."""
+
+ max_id: Annotated[str, PropertyInfo(alias="maxId")]
+ """Return Tweets older than this Tweet ID."""
+
+ max_quotes: Annotated[int, PropertyInfo(alias="maxQuotes")]
+ """Maximum quotes threshold."""
+
+ max_replies: Annotated[int, PropertyInfo(alias="maxReplies")]
+ """Maximum replies threshold."""
+
+ max_retweets: Annotated[int, PropertyInfo(alias="maxRetweets")]
+ """Maximum retweets threshold."""
+
media_type: Annotated[
Literal["images", "videos", "gifs", "media", "links", "none"], PropertyInfo(alias="mediaType")
]
@@ -60,6 +91,9 @@ class UserRetrieveRepliesParams(TypedDict, total=False):
mentioning: str
"""Filter tweets mentioning a username."""
+ min_bookmarks: Annotated[int, PropertyInfo(alias="minBookmarks")]
+ """Minimum bookmark count threshold."""
+
min_faves: Annotated[int, PropertyInfo(alias="minFaves")]
"""Minimum likes threshold."""
@@ -72,11 +106,23 @@ class UserRetrieveRepliesParams(TypedDict, total=False):
min_retweets: Annotated[int, PropertyInfo(alias="minRetweets")]
"""Minimum retweets threshold."""
+ min_views: Annotated[int, PropertyInfo(alias="minViews")]
+ """Minimum view count threshold."""
+
+ native_retweets: Annotated[bool, PropertyInfo(alias="nativeRetweets")]
+ """Only return native reposts."""
+
+ near: str
+ """Match a place name."""
+
+ news: bool
+ """Only return news results."""
+
page_size: Annotated[int, PropertyInfo(alias="pageSize")]
- """Maximum page items (1-100, default 20).
+ """Automatic pages accept 1-300 Tweets.
- Source, filters, or credits can reduce results. Continue while has_next_page is
- true. Deprecated limit and count aliases remain accepted.
+ Standard pages keep 1-100. Default 20. Continue while has_next_page is true.
+ Deprecated aliases remain accepted.
"""
quotes: Literal["include", "exclude", "only"]
@@ -94,9 +140,18 @@ class UserRetrieveRepliesParams(TypedDict, total=False):
retweets_of_tweet_id: Annotated[str, PropertyInfo(alias="retweetsOfTweetId")]
"""Only retweets of this tweet ID."""
+ safe: bool
+ """Enable the safe-search filter."""
+
since_date: Annotated[Union[str, date], PropertyInfo(alias="sinceDate", format="iso8601")]
"""Start date in YYYY-MM-DD format."""
+ since_id: Annotated[str, PropertyInfo(alias="sinceId")]
+ """Return Tweets newer than this Tweet ID."""
+
+ source: str
+ """Match the source application."""
+
to_user: Annotated[str, PropertyInfo(alias="toUser")]
"""Filter replies sent to a username."""
@@ -108,3 +163,9 @@ class UserRetrieveRepliesParams(TypedDict, total=False):
verified_only: Annotated[bool, PropertyInfo(alias="verifiedOnly")]
"""Only return tweets from verified authors."""
+
+ within: str
+ """Set the radius for the near filter."""
+
+ within_time: Annotated[str, PropertyInfo(alias="withinTime")]
+ """Match Tweets inside a recent time window."""
diff --git a/src/x_twitter_scraper/types/x/user_retrieve_search_params.py b/src/x_twitter_scraper/types/x/user_retrieve_search_params.py
index 59be296..16d55a8 100644
--- a/src/x_twitter_scraper/types/x/user_retrieve_search_params.py
+++ b/src/x_twitter_scraper/types/x/user_retrieve_search_params.py
@@ -6,7 +6,9 @@
from __future__ import annotations
-from typing_extensions import Required, TypedDict
+from typing_extensions import Required, Annotated, TypedDict
+
+from ..._utils import PropertyInfo
__all__ = ["UserRetrieveSearchParams"]
@@ -15,5 +17,47 @@ class UserRetrieveSearchParams(TypedDict, total=False):
q: Required[str]
"""User search query"""
+ bio_contains: Annotated[str, PropertyInfo(alias="bioContains")]
+ """Match any comma-separated or line-separated bio term, ignoring case."""
+
cursor: str
"""Pagination cursor for user search"""
+
+ has_location: Annotated[bool, PropertyInfo(alias="hasLocation")]
+ """Only return profiles with a location."""
+
+ has_website: Annotated[bool, PropertyInfo(alias="hasWebsite")]
+ """Only return profiles with a website."""
+
+ location_contains: Annotated[str, PropertyInfo(alias="locationContains")]
+ """Match a location substring, ignoring case."""
+
+ max_followers: Annotated[int, PropertyInfo(alias="maxFollowers")]
+ """Maximum follower count. Missing counts pass this maximum."""
+
+ max_following: Annotated[int, PropertyInfo(alias="maxFollowing")]
+ """Maximum following count."""
+
+ max_statuses: Annotated[int, PropertyInfo(alias="maxStatuses")]
+ """Maximum post count. maxPosts is also accepted."""
+
+ min_account_age_days: Annotated[int, PropertyInfo(alias="minAccountAgeDays")]
+ """Minimum account age in whole days."""
+
+ min_followers: Annotated[int, PropertyInfo(alias="minFollowers")]
+ """Minimum follower count. Filtering happens before billing."""
+
+ min_following: Annotated[int, PropertyInfo(alias="minFollowing")]
+ """Minimum following count."""
+
+ min_statuses: Annotated[int, PropertyInfo(alias="minStatuses")]
+ """Minimum post count. minPosts is also accepted."""
+
+ username_contains: Annotated[str, PropertyInfo(alias="usernameContains")]
+ """Match a username substring, ignoring case."""
+
+ verified_only: Annotated[bool, PropertyInfo(alias="verifiedOnly")]
+ """Only return verified profiles."""
+
+ verified_type: Annotated[str, PropertyInfo(alias="verifiedType")]
+ """Match the verification type exactly, ignoring case."""
diff --git a/src/x_twitter_scraper/types/x/user_retrieve_tweets_params.py b/src/x_twitter_scraper/types/x/user_retrieve_tweets_params.py
index d2faa4f..7dd315c 100644
--- a/src/x_twitter_scraper/types/x/user_retrieve_tweets_params.py
+++ b/src/x_twitter_scraper/types/x/user_retrieve_tweets_params.py
@@ -22,6 +22,12 @@ class UserRetrieveTweetsParams(TypedDict, total=False):
Separate with spaces, commas, or lines.
"""
+ blue_verified_only: Annotated[bool, PropertyInfo(alias="blueVerifiedOnly")]
+ """Only return tweets from Blue-verified authors."""
+
+ card_name: Annotated[str, PropertyInfo(alias="cardName")]
+ """Match the Tweet card name."""
+
cashtags: str
"""Cashtags separated by spaces, commas, or lines."""
@@ -29,17 +35,27 @@ class UserRetrieveTweetsParams(TypedDict, total=False):
"""Conversation ID filter."""
cursor: str
- """Pagination cursor for user tweets"""
+ """Cursor from the previous response.
+
+ Xquik cursors resume automatic coverage. Existing unprefixed cursors keep legacy
+ standard behavior.
+ """
exact_phrase: Annotated[str, PropertyInfo(alias="exactPhrase")]
"""Exact phrase to match."""
+ exclude_source: Annotated[str, PropertyInfo(alias="excludeSource")]
+ """Exclude a source application."""
+
exclude_words: Annotated[str, PropertyInfo(alias="excludeWords")]
"""Words or quoted phrases to exclude. Separate with spaces, commas, or lines."""
from_user: Annotated[str, PropertyInfo(alias="fromUser")]
"""Filter by author username."""
+ geocode: str
+ """Match latitude, longitude, and radius."""
+
hashtags: str
"""Hashtags separated by spaces, commas, or lines."""
@@ -55,6 +71,21 @@ class UserRetrieveTweetsParams(TypedDict, total=False):
language: str
"""Language code filter, e.g. en or tr."""
+ max_faves: Annotated[int, PropertyInfo(alias="maxFaves")]
+ """Maximum likes threshold. maxLikes is also accepted."""
+
+ max_id: Annotated[str, PropertyInfo(alias="maxId")]
+ """Return Tweets older than this Tweet ID."""
+
+ max_quotes: Annotated[int, PropertyInfo(alias="maxQuotes")]
+ """Maximum quotes threshold."""
+
+ max_replies: Annotated[int, PropertyInfo(alias="maxReplies")]
+ """Maximum replies threshold."""
+
+ max_retweets: Annotated[int, PropertyInfo(alias="maxRetweets")]
+ """Maximum retweets threshold."""
+
media_type: Annotated[
Literal["images", "videos", "gifs", "media", "links", "none"], PropertyInfo(alias="mediaType")
]
@@ -63,6 +94,9 @@ class UserRetrieveTweetsParams(TypedDict, total=False):
mentioning: str
"""Filter tweets mentioning a username."""
+ min_bookmarks: Annotated[int, PropertyInfo(alias="minBookmarks")]
+ """Minimum bookmark count threshold."""
+
min_faves: Annotated[int, PropertyInfo(alias="minFaves")]
"""Minimum likes threshold."""
@@ -75,11 +109,23 @@ class UserRetrieveTweetsParams(TypedDict, total=False):
min_retweets: Annotated[int, PropertyInfo(alias="minRetweets")]
"""Minimum retweets threshold."""
+ min_views: Annotated[int, PropertyInfo(alias="minViews")]
+ """Minimum view count threshold."""
+
+ native_retweets: Annotated[bool, PropertyInfo(alias="nativeRetweets")]
+ """Only return native reposts."""
+
+ near: str
+ """Match a place name."""
+
+ news: bool
+ """Only return news results."""
+
page_size: Annotated[int, PropertyInfo(alias="pageSize")]
- """Maximum page items (1-100, default 20).
+ """Automatic pages accept 1-300 Tweets.
- Source, filters, or credits can reduce results. Continue while has_next_page is
- true. Deprecated limit and count aliases remain accepted.
+ Standard pages keep 1-100. Default 20. Continue while has_next_page is true.
+ Deprecated aliases remain accepted.
"""
quotes: Literal["include", "exclude", "only"]
@@ -97,9 +143,18 @@ class UserRetrieveTweetsParams(TypedDict, total=False):
retweets_of_tweet_id: Annotated[str, PropertyInfo(alias="retweetsOfTweetId")]
"""Only retweets of this tweet ID."""
+ safe: bool
+ """Enable the safe-search filter."""
+
since_date: Annotated[Union[str, date], PropertyInfo(alias="sinceDate", format="iso8601")]
"""Start date in YYYY-MM-DD format."""
+ since_id: Annotated[str, PropertyInfo(alias="sinceId")]
+ """Return Tweets newer than this Tweet ID."""
+
+ source: str
+ """Match the source application."""
+
to_user: Annotated[str, PropertyInfo(alias="toUser")]
"""Filter replies sent to a username."""
@@ -111,3 +166,9 @@ class UserRetrieveTweetsParams(TypedDict, total=False):
verified_only: Annotated[bool, PropertyInfo(alias="verifiedOnly")]
"""Only return tweets from verified authors."""
+
+ within: str
+ """Set the radius for the near filter."""
+
+ within_time: Annotated[str, PropertyInfo(alias="withinTime")]
+ """Match Tweets inside a recent time window."""
diff --git a/src/x_twitter_scraper/types/x/user_retrieve_verified_followers_params.py b/src/x_twitter_scraper/types/x/user_retrieve_verified_followers_params.py
index 7840646..4e6f09c 100644
--- a/src/x_twitter_scraper/types/x/user_retrieve_verified_followers_params.py
+++ b/src/x_twitter_scraper/types/x/user_retrieve_verified_followers_params.py
@@ -6,7 +6,7 @@
from __future__ import annotations
-from typing_extensions import Annotated, TypedDict
+from typing_extensions import Literal, Annotated, TypedDict
from ..._utils import PropertyInfo
@@ -14,13 +14,73 @@
class UserRetrieveVerifiedFollowersParams(TypedDict, total=False):
+ after: str
+ """Legacy cursor alias. Prefer cursor."""
+
+ bio_contains: Annotated[str, PropertyInfo(alias="bioContains")]
+ """Match any comma-separated or line-separated bio term, ignoring case."""
+
cursor: str
- """Pagination cursor for verified followers"""
+ """Cursor from the previous response.
+
+ Xquik cursors resume automatic coverage. Existing unprefixed cursors keep legacy
+ standard behavior.
+ """
+
+ has_location: Annotated[bool, PropertyInfo(alias="hasLocation")]
+ """Only return profiles with a location."""
+
+ has_website: Annotated[bool, PropertyInfo(alias="hasWebsite")]
+ """Only return profiles with a website."""
+
+ limit: int
+ """Legacy page-size alias outside explicit coverage mode.
+
+ Coverage accepts 1-10000. Prefer pageSize.
+ """
+
+ location_contains: Annotated[str, PropertyInfo(alias="locationContains")]
+ """Match a location substring, ignoring case."""
+
+ max_followers: Annotated[int, PropertyInfo(alias="maxFollowers")]
+ """Maximum follower count. Missing counts pass this maximum."""
+
+ max_following: Annotated[int, PropertyInfo(alias="maxFollowing")]
+ """Maximum following count."""
+
+ max_statuses: Annotated[int, PropertyInfo(alias="maxStatuses")]
+ """Maximum post count. maxPosts is also accepted."""
+
+ min_account_age_days: Annotated[int, PropertyInfo(alias="minAccountAgeDays")]
+ """Minimum account age in whole days."""
+
+ min_followers: Annotated[int, PropertyInfo(alias="minFollowers")]
+ """Minimum follower count. Filtering happens before billing."""
+
+ min_following: Annotated[int, PropertyInfo(alias="minFollowing")]
+ """Minimum following count."""
+
+ min_statuses: Annotated[int, PropertyInfo(alias="minStatuses")]
+ """Minimum post count. minPosts is also accepted."""
+
+ mode: Literal["standard", "coverage"]
+ """Omit mode for resumable maximum coverage.
+
+ Standard keeps legacy pagination. Coverage returns diagnostics once and rejects
+ cursors.
+ """
page_size: Annotated[int, PropertyInfo(alias="pageSize")]
- """Maximum user profiles requested from this page (20-200, default 200).
+ """Maximum user profiles: automatic 300; standard 200.
- The response can contain fewer profiles because the source returned fewer or
- remaining credits cover fewer results. Keep requesting next_cursor while
- has_next_page is true. The deprecated limit and count aliases remain accepted.
+ Sources return fewer profiles. Continue with has_next_page.
"""
+
+ username_contains: Annotated[str, PropertyInfo(alias="usernameContains")]
+ """Match a username substring, ignoring case."""
+
+ verified_only: Annotated[bool, PropertyInfo(alias="verifiedOnly")]
+ """Only return verified profiles."""
+
+ verified_type: Annotated[str, PropertyInfo(alias="verifiedType")]
+ """Match the verification type exactly, ignoring case."""
diff --git a/src/x_twitter_scraper/types/x/user_retrieve_verified_followers_response.py b/src/x_twitter_scraper/types/x/user_retrieve_verified_followers_response.py
new file mode 100644
index 0000000..c1fb892
--- /dev/null
+++ b/src/x_twitter_scraper/types/x/user_retrieve_verified_followers_response.py
@@ -0,0 +1,81 @@
+# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+from typing import List, Union, Optional
+from typing_extensions import Literal, TypeAlias
+
+from pydantic import Field as FieldInfo
+
+from ..._models import BaseModel
+from ..shared.paginated_users import PaginatedUsers
+
+__all__ = [
+ "UserRetrieveVerifiedFollowersResponse",
+ "UserListCoverageResponse",
+ "UserListCoverageResponseDiagnostic",
+ "UserListCoverageResponseDiagnosticStrategy",
+]
+
+
+class UserListCoverageResponseDiagnosticStrategy(BaseModel):
+ duplicate_count: int = FieldInfo(alias="duplicateCount")
+
+ pages_fetched: int = FieldInfo(alias="pagesFetched")
+
+ stop_reason: Literal[
+ "cursor_failure", "deadline", "exhausted", "failed", "page_limit", "result_limit", "stalled"
+ ] = FieldInfo(alias="stopReason")
+
+ strategy: int
+
+ unique_added: int = FieldInfo(alias="uniqueAdded")
+
+
+class UserListCoverageResponseDiagnostic(BaseModel):
+ """Coverage evidence across parallel relationship strategies."""
+
+ complete: bool
+ """True when every strategy exhausted its source."""
+
+ cursor_failure_count: int = FieldInfo(alias="cursorFailureCount")
+
+ deadline_reached: bool = FieldInfo(alias="deadlineReached")
+
+ duplicate_count: int = FieldInfo(alias="duplicateCount")
+
+ failed_strategy_count: int = FieldInfo(alias="failedStrategyCount")
+
+ malformed_count: int = FieldInfo(alias="malformedCount")
+
+ pages_fetched: int = FieldInfo(alias="pagesFetched")
+
+ response_truncated: bool = FieldInfo(alias="responseTruncated")
+ """Whether credits or the requested limit reduced output."""
+
+ result_limit_reached: bool = FieldInfo(alias="resultLimitReached")
+
+ returned_users: int = FieldInfo(alias="returnedUsers")
+
+ stalled_strategy_count: int = FieldInfo(alias="stalledStrategyCount")
+
+ strategies: List[UserListCoverageResponseDiagnosticStrategy]
+
+ strategy_count: int = FieldInfo(alias="strategyCount")
+
+ unique_users: int = FieldInfo(alias="uniqueUsers")
+
+
+class UserListCoverageResponse(PaginatedUsers):
+ """Paginated user profiles.
+
+ No-mode follower, following, and verified follower requests merge independent views automatically. Response fields, page size, aliases, filters, and per-returned-profile billing stay unchanged. Existing unprefixed cursors retain legacy behavior. Follow next_cursor while has_next_page is true.
+ """
+
+ diagnostic: UserListCoverageResponseDiagnostic
+ """Coverage evidence across parallel relationship strategies."""
+
+ has_next_page: Optional[Literal[False]] = None # type: ignore
+
+ next_cursor: Optional[Literal[""]] = None # type: ignore
+
+
+UserRetrieveVerifiedFollowersResponse: TypeAlias = Union[PaginatedUsers, UserListCoverageResponse]
diff --git a/src/x_twitter_scraper/types/x/x_account.py b/src/x_twitter_scraper/types/x/x_account.py
index 01ffda7..b920864 100644
--- a/src/x_twitter_scraper/types/x/x_account.py
+++ b/src/x_twitter_scraper/types/x/x_account.py
@@ -25,13 +25,11 @@ class XAccount(BaseModel):
created_at: datetime = FieldInfo(alias="createdAt")
health: Literal["healthy", "locked", "needsReauth", "recovering", "suspended", "temporaryIssue"]
- """Derived connection health.
+ """Derived health.
- `healthy` = ready to use. `needsReauth` = user must submit fresh credentials.
- `locked` = X locked the account; unlock on x.com first. `suspended` = X banned
- the account. `recovering` = cooldown ended; the account can reconnect on its
- next use. `temporaryIssue` = temporary connection problem; wait before the next
- use.
+ `healthy` is ready. `needsReauth` needs credentials. `locked` must be unlocked
+ on X. `suspended` is banned. `recovering` can reconnect. Wait before using
+ `temporaryIssue`.
"""
status: str
diff --git a/tests/api_resources/support/test_attachments.py b/tests/api_resources/support/test_attachments.py
new file mode 100644
index 0000000..60ccb93
--- /dev/null
+++ b/tests/api_resources/support/test_attachments.py
@@ -0,0 +1,176 @@
+# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+from __future__ import annotations
+
+import os
+from typing import Any, cast
+
+import httpx
+import pytest
+from respx import MockRouter
+
+from x_twitter_scraper import XTwitterScraper, AsyncXTwitterScraper
+from x_twitter_scraper._response import (
+ BinaryAPIResponse,
+ AsyncBinaryAPIResponse,
+ StreamedBinaryAPIResponse,
+ AsyncStreamedBinaryAPIResponse,
+)
+
+base_url = os.environ.get("TEST_API_BASE_URL", "http://127.0.0.1:4010")
+
+
+class TestAttachments:
+ parametrize = pytest.mark.parametrize("client", [False, True], indirect=True, ids=["loose", "strict"])
+
+ @parametrize
+ @pytest.mark.respx(base_url=base_url)
+ def test_method_download(self, client: XTwitterScraper, respx_mock: MockRouter) -> None:
+ respx_mock.get("/support/attachments/att_a1b2c3d4e5f6a1b2c3d4e5f6").mock(
+ return_value=httpx.Response(200, json={"foo": "bar"})
+ )
+ attachment = client.support.attachments.download(
+ id="att_a1b2c3d4e5f6a1b2c3d4e5f6",
+ )
+ assert attachment.is_closed
+ assert attachment.json() == {"foo": "bar"}
+ assert cast(Any, attachment.is_closed) is True
+ assert isinstance(attachment, BinaryAPIResponse)
+
+ @parametrize
+ @pytest.mark.respx(base_url=base_url)
+ def test_method_download_with_all_params(self, client: XTwitterScraper, respx_mock: MockRouter) -> None:
+ respx_mock.get("/support/attachments/att_a1b2c3d4e5f6a1b2c3d4e5f6").mock(
+ return_value=httpx.Response(200, json={"foo": "bar"})
+ )
+ attachment = client.support.attachments.download(
+ id="att_a1b2c3d4e5f6a1b2c3d4e5f6",
+ range="bytes=0-1048575",
+ )
+ assert attachment.is_closed
+ assert attachment.json() == {"foo": "bar"}
+ assert cast(Any, attachment.is_closed) is True
+ assert isinstance(attachment, BinaryAPIResponse)
+
+ @parametrize
+ @pytest.mark.respx(base_url=base_url)
+ def test_raw_response_download(self, client: XTwitterScraper, respx_mock: MockRouter) -> None:
+ respx_mock.get("/support/attachments/att_a1b2c3d4e5f6a1b2c3d4e5f6").mock(
+ return_value=httpx.Response(200, json={"foo": "bar"})
+ )
+
+ attachment = client.support.attachments.with_raw_response.download(
+ id="att_a1b2c3d4e5f6a1b2c3d4e5f6",
+ )
+
+ assert attachment.is_closed is True
+ assert attachment.http_request.headers.get("X-Stainless-Lang") == "python"
+ assert attachment.json() == {"foo": "bar"}
+ assert isinstance(attachment, BinaryAPIResponse)
+
+ @parametrize
+ @pytest.mark.respx(base_url=base_url)
+ def test_streaming_response_download(self, client: XTwitterScraper, respx_mock: MockRouter) -> None:
+ respx_mock.get("/support/attachments/att_a1b2c3d4e5f6a1b2c3d4e5f6").mock(
+ return_value=httpx.Response(200, json={"foo": "bar"})
+ )
+ with client.support.attachments.with_streaming_response.download(
+ id="att_a1b2c3d4e5f6a1b2c3d4e5f6",
+ ) as attachment:
+ assert not attachment.is_closed
+ assert attachment.http_request.headers.get("X-Stainless-Lang") == "python"
+
+ assert attachment.json() == {"foo": "bar"}
+ assert cast(Any, attachment.is_closed) is True
+ assert isinstance(attachment, StreamedBinaryAPIResponse)
+
+ assert cast(Any, attachment.is_closed) is True
+
+ @parametrize
+ @pytest.mark.respx(base_url=base_url)
+ def test_path_params_download(self, client: XTwitterScraper) -> None:
+ with pytest.raises(ValueError, match=r"Expected a non-empty value for `id` but received ''"):
+ client.support.attachments.with_raw_response.download(
+ id="",
+ )
+
+
+class TestAsyncAttachments:
+ parametrize = pytest.mark.parametrize(
+ "async_client", [False, True, {"http_client": "aiohttp"}], indirect=True, ids=["loose", "strict", "aiohttp"]
+ )
+
+ @parametrize
+ @pytest.mark.respx(base_url=base_url)
+ async def test_method_download(self, async_client: AsyncXTwitterScraper, respx_mock: MockRouter) -> None:
+ respx_mock.get("/support/attachments/att_a1b2c3d4e5f6a1b2c3d4e5f6").mock(
+ return_value=httpx.Response(200, json={"foo": "bar"})
+ )
+ attachment = await async_client.support.attachments.download(
+ id="att_a1b2c3d4e5f6a1b2c3d4e5f6",
+ )
+ assert attachment.is_closed
+ assert await attachment.json() == {"foo": "bar"}
+ assert cast(Any, attachment.is_closed) is True
+ assert isinstance(attachment, AsyncBinaryAPIResponse)
+
+ @parametrize
+ @pytest.mark.respx(base_url=base_url)
+ async def test_method_download_with_all_params(
+ self, async_client: AsyncXTwitterScraper, respx_mock: MockRouter
+ ) -> None:
+ respx_mock.get("/support/attachments/att_a1b2c3d4e5f6a1b2c3d4e5f6").mock(
+ return_value=httpx.Response(200, json={"foo": "bar"})
+ )
+ attachment = await async_client.support.attachments.download(
+ id="att_a1b2c3d4e5f6a1b2c3d4e5f6",
+ range="bytes=0-1048575",
+ )
+ assert attachment.is_closed
+ assert await attachment.json() == {"foo": "bar"}
+ assert cast(Any, attachment.is_closed) is True
+ assert isinstance(attachment, AsyncBinaryAPIResponse)
+
+ @parametrize
+ @pytest.mark.respx(base_url=base_url)
+ async def test_raw_response_download(self, async_client: AsyncXTwitterScraper, respx_mock: MockRouter) -> None:
+ respx_mock.get("/support/attachments/att_a1b2c3d4e5f6a1b2c3d4e5f6").mock(
+ return_value=httpx.Response(200, json={"foo": "bar"})
+ )
+
+ attachment = await async_client.support.attachments.with_raw_response.download(
+ id="att_a1b2c3d4e5f6a1b2c3d4e5f6",
+ )
+
+ assert attachment.is_closed is True
+ assert attachment.http_request.headers.get("X-Stainless-Lang") == "python"
+ assert await attachment.json() == {"foo": "bar"}
+ assert isinstance(attachment, AsyncBinaryAPIResponse)
+
+ @parametrize
+ @pytest.mark.respx(base_url=base_url)
+ async def test_streaming_response_download(
+ self, async_client: AsyncXTwitterScraper, respx_mock: MockRouter
+ ) -> None:
+ respx_mock.get("/support/attachments/att_a1b2c3d4e5f6a1b2c3d4e5f6").mock(
+ return_value=httpx.Response(200, json={"foo": "bar"})
+ )
+ async with async_client.support.attachments.with_streaming_response.download(
+ id="att_a1b2c3d4e5f6a1b2c3d4e5f6",
+ ) as attachment:
+ assert not attachment.is_closed
+ assert attachment.http_request.headers.get("X-Stainless-Lang") == "python"
+
+ assert await attachment.json() == {"foo": "bar"}
+ assert cast(Any, attachment.is_closed) is True
+ assert isinstance(attachment, AsyncStreamedBinaryAPIResponse)
+
+ assert cast(Any, attachment.is_closed) is True
+
+ @parametrize
+ @pytest.mark.respx(base_url=base_url)
+ async def test_path_params_download(self, async_client: AsyncXTwitterScraper) -> None:
+ with pytest.raises(ValueError, match=r"Expected a non-empty value for `id` but received ''"):
+ await async_client.support.attachments.with_raw_response.download(
+ id="",
+ )
diff --git a/tests/api_resources/test_events.py b/tests/api_resources/test_events.py
index a857097..2855501 100644
--- a/tests/api_resources/test_events.py
+++ b/tests/api_resources/test_events.py
@@ -75,6 +75,7 @@ def test_method_list_with_all_params(self, client: XTwitterScraper) -> None:
event = client.events.list(
cursor="cursor",
event_type="tweet.new",
+ keyword_monitor_id="keywordMonitorId",
limit=1,
monitor_id="monitorId",
)
@@ -162,6 +163,7 @@ async def test_method_list_with_all_params(self, async_client: AsyncXTwitterScra
event = await async_client.events.list(
cursor="cursor",
event_type="tweet.new",
+ keyword_monitor_id="keywordMonitorId",
limit=1,
monitor_id="monitorId",
)
diff --git a/tests/api_resources/test_extractions.py b/tests/api_resources/test_extractions.py
index 7a0c0d5..6474d1d 100644
--- a/tests/api_resources/test_extractions.py
+++ b/tests/api_resources/test_extractions.py
@@ -21,7 +21,7 @@
ExtractionRetrieveResponse,
ExtractionEstimateCostResponse,
)
-from x_twitter_scraper._utils import parse_date
+from x_twitter_scraper._utils import parse_date, parse_datetime
from x_twitter_scraper._response import (
BinaryAPIResponse,
AsyncBinaryAPIResponse,
@@ -49,7 +49,11 @@ def test_method_retrieve_with_all_params(self, client: XTwitterScraper) -> None:
extraction = client.extractions.retrieve(
id="id",
cursor="cursor",
+ field_style="source",
+ include_raw=True,
limit=1,
+ output_mode="compact",
+ output_preset="nested",
)
assert_matches_type(ExtractionRetrieveResponse, extraction, path=["response"])
@@ -141,42 +145,104 @@ def test_method_estimate_cost_with_all_params(self, client: XTwitterScraper) ->
tool_type="follower_explorer",
advanced_query="min_faves:100",
any_words="ChatGPT AI model",
+ bio_contains="bioContains",
+ blue_verified_only=True,
bounding_box="-74.1 40.6 -73.9 40.8",
+ card_name="cardName",
cashtags="$TSLA $NVDA",
+ collection_strategy="auto",
conversation_id="1234567890",
+ dedupe_across_targets=True,
+ dedupe_mode="none",
exact_phrase="artificial intelligence",
+ exclude_original_author=True,
+ exclude_source="excludeSource",
exclude_words="spam",
from_user="nasa",
+ geocode="geocode",
hashtags="#AI startups",
+ has_location=True,
+ has_media_only=True,
+ has_website=True,
+ include_original_post=True,
+ include_search_terms=True,
+ include_target_metadata=True,
in_reply_to_tweet_id="1234567890",
language="en",
list_id="1234567890",
+ location_contains="locationContains",
+ max_depth=1,
+ max_followers=0,
+ max_following=0,
+ max_id="maxId",
+ max_items_per_target=1,
+ max_likes=0,
+ max_pages_per_target=1,
+ max_posts=0,
+ max_quotes=0,
+ max_replies=0,
+ max_retweets=0,
media_type="images",
mentioning="example_user",
+ min_account_age_days=0,
+ min_bookmarks=0,
min_faves=10,
+ min_followers=0,
+ min_following=0,
+ min_posts=0,
min_quotes=2,
min_replies=3,
min_retweets=5,
+ min_views=0,
+ native_retweets=True,
+ near="near",
+ news=True,
+ overlap_mode=True,
place="96683cc9126741d1",
place_country="US",
point_radius="-73.99 40.73 25mi",
+ query_type="Latest",
quotes="include",
quotes_of_tweet_id="1234567890",
+ relation_targets=[
+ {
+ "relation": "community_members",
+ "value": "x",
+ }
+ ],
replies="include",
results_limit=1000,
retweets="exclude",
retweets_of_tweet_id="1234567890",
+ safe=True,
+ scope="all",
+ search_queries=["string"],
search_query="AI trends 2025",
since_date=parse_date("2025-01-01"),
+ since_id="sinceId",
+ since_time=parse_datetime("2019-12-27T18:11:19.117Z"),
+ sort="relevance",
+ source="source",
+ start_cursor="x",
target_community_id="1500000000000000000",
+ target_community_ids=["string"],
target_list_id="1234567890",
+ target_list_ids=["string"],
+ targets=["string"],
target_space_id="1vOGwMdBqpwGB",
target_tweet_id="1234567890",
+ target_tweet_ids=["string"],
target_username="elonmusk",
+ target_usernames=["string"],
to_user="openai",
until_date=parse_date("2025-12-31"),
+ until_time=parse_datetime("2019-12-27T18:11:19.117Z"),
url="example.com",
+ username_contains="usernameContains",
verified_only=False,
+ verified_type="verifiedType",
+ within="within",
+ within_time="withinTime",
)
assert_matches_type(ExtractionEstimateCostResponse, extraction, path=["response"])
@@ -219,6 +285,37 @@ def test_method_export_results(self, client: XTwitterScraper, respx_mock: MockRo
assert cast(Any, extraction.is_closed) is True
assert isinstance(extraction, BinaryAPIResponse)
+ @parametrize
+ @pytest.mark.respx(base_url=base_url)
+ def test_method_export_results_with_all_params(self, client: XTwitterScraper, respx_mock: MockRouter) -> None:
+ respx_mock.get("/extractions/id/export").mock(return_value=httpx.Response(200, json={"foo": "bar"}))
+ extraction = client.extractions.export_results(
+ id="id",
+ format="csv",
+ has_description=True,
+ has_location=True,
+ has_media=True,
+ lang="lang",
+ max_followers=0,
+ max_following=0,
+ max_posts=0,
+ min_followers=0,
+ min_following=0,
+ min_likes=0,
+ min_posts=0,
+ min_replies=0,
+ min_retweets=0,
+ min_views=0,
+ search="search",
+ since_date=parse_date("2019-12-27"),
+ until_date=parse_date("2019-12-27"),
+ verified=True,
+ )
+ assert extraction.is_closed
+ assert extraction.json() == {"foo": "bar"}
+ assert cast(Any, extraction.is_closed) is True
+ assert isinstance(extraction, BinaryAPIResponse)
+
@parametrize
@pytest.mark.respx(base_url=base_url)
def test_raw_response_export_results(self, client: XTwitterScraper, respx_mock: MockRouter) -> None:
@@ -273,44 +370,107 @@ def test_method_run(self, client: XTwitterScraper) -> None:
def test_method_run_with_all_params(self, client: XTwitterScraper) -> None:
extraction = client.extractions.run(
tool_type="follower_explorer",
+ dry_run=True,
advanced_query="min_faves:100",
any_words="ChatGPT AI model",
+ bio_contains="bioContains",
+ blue_verified_only=True,
bounding_box="-74.1 40.6 -73.9 40.8",
+ card_name="cardName",
cashtags="$TSLA $NVDA",
+ collection_strategy="auto",
conversation_id="1234567890",
+ dedupe_across_targets=True,
+ dedupe_mode="none",
exact_phrase="artificial intelligence",
+ exclude_original_author=True,
+ exclude_source="excludeSource",
exclude_words="spam",
from_user="nasa",
+ geocode="geocode",
hashtags="#AI startups",
+ has_location=True,
+ has_media_only=True,
+ has_website=True,
+ include_original_post=True,
+ include_search_terms=True,
+ include_target_metadata=True,
in_reply_to_tweet_id="1234567890",
language="en",
list_id="1234567890",
+ location_contains="locationContains",
+ max_depth=1,
+ max_followers=0,
+ max_following=0,
+ max_id="maxId",
+ max_items_per_target=1,
+ max_likes=0,
+ max_pages_per_target=1,
+ max_posts=0,
+ max_quotes=0,
+ max_replies=0,
+ max_retweets=0,
media_type="images",
mentioning="example_user",
+ min_account_age_days=0,
+ min_bookmarks=0,
min_faves=10,
+ min_followers=0,
+ min_following=0,
+ min_posts=0,
min_quotes=2,
min_replies=3,
min_retweets=5,
+ min_views=0,
+ native_retweets=True,
+ near="near",
+ news=True,
+ overlap_mode=True,
place="96683cc9126741d1",
place_country="US",
point_radius="-73.99 40.73 25mi",
+ query_type="Latest",
quotes="include",
quotes_of_tweet_id="1234567890",
+ relation_targets=[
+ {
+ "relation": "community_members",
+ "value": "x",
+ }
+ ],
replies="include",
results_limit=1000,
retweets="exclude",
retweets_of_tweet_id="1234567890",
+ safe=True,
+ scope="all",
+ search_queries=["string"],
search_query="AI trends 2025",
since_date=parse_date("2025-01-01"),
+ since_id="sinceId",
+ since_time=parse_datetime("2019-12-27T18:11:19.117Z"),
+ sort="relevance",
+ source="source",
+ start_cursor="x",
target_community_id="1500000000000000000",
+ target_community_ids=["string"],
target_list_id="1234567890",
+ target_list_ids=["string"],
+ targets=["string"],
target_space_id="1vOGwMdBqpwGB",
target_tweet_id="1234567890",
+ target_tweet_ids=["string"],
target_username="elonmusk",
+ target_usernames=["string"],
to_user="openai",
until_date=parse_date("2025-12-31"),
+ until_time=parse_datetime("2019-12-27T18:11:19.117Z"),
url="example.com",
+ username_contains="usernameContains",
verified_only=False,
+ verified_type="verifiedType",
+ within="within",
+ within_time="withinTime",
)
assert_matches_type(ExtractionRunResponse, extraction, path=["response"])
@@ -360,7 +520,11 @@ async def test_method_retrieve_with_all_params(self, async_client: AsyncXTwitter
extraction = await async_client.extractions.retrieve(
id="id",
cursor="cursor",
+ field_style="source",
+ include_raw=True,
limit=1,
+ output_mode="compact",
+ output_preset="nested",
)
assert_matches_type(ExtractionRetrieveResponse, extraction, path=["response"])
@@ -452,42 +616,104 @@ async def test_method_estimate_cost_with_all_params(self, async_client: AsyncXTw
tool_type="follower_explorer",
advanced_query="min_faves:100",
any_words="ChatGPT AI model",
+ bio_contains="bioContains",
+ blue_verified_only=True,
bounding_box="-74.1 40.6 -73.9 40.8",
+ card_name="cardName",
cashtags="$TSLA $NVDA",
+ collection_strategy="auto",
conversation_id="1234567890",
+ dedupe_across_targets=True,
+ dedupe_mode="none",
exact_phrase="artificial intelligence",
+ exclude_original_author=True,
+ exclude_source="excludeSource",
exclude_words="spam",
from_user="nasa",
+ geocode="geocode",
hashtags="#AI startups",
+ has_location=True,
+ has_media_only=True,
+ has_website=True,
+ include_original_post=True,
+ include_search_terms=True,
+ include_target_metadata=True,
in_reply_to_tweet_id="1234567890",
language="en",
list_id="1234567890",
+ location_contains="locationContains",
+ max_depth=1,
+ max_followers=0,
+ max_following=0,
+ max_id="maxId",
+ max_items_per_target=1,
+ max_likes=0,
+ max_pages_per_target=1,
+ max_posts=0,
+ max_quotes=0,
+ max_replies=0,
+ max_retweets=0,
media_type="images",
mentioning="example_user",
+ min_account_age_days=0,
+ min_bookmarks=0,
min_faves=10,
+ min_followers=0,
+ min_following=0,
+ min_posts=0,
min_quotes=2,
min_replies=3,
min_retweets=5,
+ min_views=0,
+ native_retweets=True,
+ near="near",
+ news=True,
+ overlap_mode=True,
place="96683cc9126741d1",
place_country="US",
point_radius="-73.99 40.73 25mi",
+ query_type="Latest",
quotes="include",
quotes_of_tweet_id="1234567890",
+ relation_targets=[
+ {
+ "relation": "community_members",
+ "value": "x",
+ }
+ ],
replies="include",
results_limit=1000,
retweets="exclude",
retweets_of_tweet_id="1234567890",
+ safe=True,
+ scope="all",
+ search_queries=["string"],
search_query="AI trends 2025",
since_date=parse_date("2025-01-01"),
+ since_id="sinceId",
+ since_time=parse_datetime("2019-12-27T18:11:19.117Z"),
+ sort="relevance",
+ source="source",
+ start_cursor="x",
target_community_id="1500000000000000000",
+ target_community_ids=["string"],
target_list_id="1234567890",
+ target_list_ids=["string"],
+ targets=["string"],
target_space_id="1vOGwMdBqpwGB",
target_tweet_id="1234567890",
+ target_tweet_ids=["string"],
target_username="elonmusk",
+ target_usernames=["string"],
to_user="openai",
until_date=parse_date("2025-12-31"),
+ until_time=parse_datetime("2019-12-27T18:11:19.117Z"),
url="example.com",
+ username_contains="usernameContains",
verified_only=False,
+ verified_type="verifiedType",
+ within="within",
+ within_time="withinTime",
)
assert_matches_type(ExtractionEstimateCostResponse, extraction, path=["response"])
@@ -530,6 +756,39 @@ async def test_method_export_results(self, async_client: AsyncXTwitterScraper, r
assert cast(Any, extraction.is_closed) is True
assert isinstance(extraction, AsyncBinaryAPIResponse)
+ @parametrize
+ @pytest.mark.respx(base_url=base_url)
+ async def test_method_export_results_with_all_params(
+ self, async_client: AsyncXTwitterScraper, respx_mock: MockRouter
+ ) -> None:
+ respx_mock.get("/extractions/id/export").mock(return_value=httpx.Response(200, json={"foo": "bar"}))
+ extraction = await async_client.extractions.export_results(
+ id="id",
+ format="csv",
+ has_description=True,
+ has_location=True,
+ has_media=True,
+ lang="lang",
+ max_followers=0,
+ max_following=0,
+ max_posts=0,
+ min_followers=0,
+ min_following=0,
+ min_likes=0,
+ min_posts=0,
+ min_replies=0,
+ min_retweets=0,
+ min_views=0,
+ search="search",
+ since_date=parse_date("2019-12-27"),
+ until_date=parse_date("2019-12-27"),
+ verified=True,
+ )
+ assert extraction.is_closed
+ assert await extraction.json() == {"foo": "bar"}
+ assert cast(Any, extraction.is_closed) is True
+ assert isinstance(extraction, AsyncBinaryAPIResponse)
+
@parametrize
@pytest.mark.respx(base_url=base_url)
async def test_raw_response_export_results(
@@ -588,44 +847,107 @@ async def test_method_run(self, async_client: AsyncXTwitterScraper) -> None:
async def test_method_run_with_all_params(self, async_client: AsyncXTwitterScraper) -> None:
extraction = await async_client.extractions.run(
tool_type="follower_explorer",
+ dry_run=True,
advanced_query="min_faves:100",
any_words="ChatGPT AI model",
+ bio_contains="bioContains",
+ blue_verified_only=True,
bounding_box="-74.1 40.6 -73.9 40.8",
+ card_name="cardName",
cashtags="$TSLA $NVDA",
+ collection_strategy="auto",
conversation_id="1234567890",
+ dedupe_across_targets=True,
+ dedupe_mode="none",
exact_phrase="artificial intelligence",
+ exclude_original_author=True,
+ exclude_source="excludeSource",
exclude_words="spam",
from_user="nasa",
+ geocode="geocode",
hashtags="#AI startups",
+ has_location=True,
+ has_media_only=True,
+ has_website=True,
+ include_original_post=True,
+ include_search_terms=True,
+ include_target_metadata=True,
in_reply_to_tweet_id="1234567890",
language="en",
list_id="1234567890",
+ location_contains="locationContains",
+ max_depth=1,
+ max_followers=0,
+ max_following=0,
+ max_id="maxId",
+ max_items_per_target=1,
+ max_likes=0,
+ max_pages_per_target=1,
+ max_posts=0,
+ max_quotes=0,
+ max_replies=0,
+ max_retweets=0,
media_type="images",
mentioning="example_user",
+ min_account_age_days=0,
+ min_bookmarks=0,
min_faves=10,
+ min_followers=0,
+ min_following=0,
+ min_posts=0,
min_quotes=2,
min_replies=3,
min_retweets=5,
+ min_views=0,
+ native_retweets=True,
+ near="near",
+ news=True,
+ overlap_mode=True,
place="96683cc9126741d1",
place_country="US",
point_radius="-73.99 40.73 25mi",
+ query_type="Latest",
quotes="include",
quotes_of_tweet_id="1234567890",
+ relation_targets=[
+ {
+ "relation": "community_members",
+ "value": "x",
+ }
+ ],
replies="include",
results_limit=1000,
retweets="exclude",
retweets_of_tweet_id="1234567890",
+ safe=True,
+ scope="all",
+ search_queries=["string"],
search_query="AI trends 2025",
since_date=parse_date("2025-01-01"),
+ since_id="sinceId",
+ since_time=parse_datetime("2019-12-27T18:11:19.117Z"),
+ sort="relevance",
+ source="source",
+ start_cursor="x",
target_community_id="1500000000000000000",
+ target_community_ids=["string"],
target_list_id="1234567890",
+ target_list_ids=["string"],
+ targets=["string"],
target_space_id="1vOGwMdBqpwGB",
target_tweet_id="1234567890",
+ target_tweet_ids=["string"],
target_username="elonmusk",
+ target_usernames=["string"],
to_user="openai",
until_date=parse_date("2025-12-31"),
+ until_time=parse_datetime("2019-12-27T18:11:19.117Z"),
url="example.com",
+ username_contains="usernameContains",
verified_only=False,
+ verified_type="verifiedType",
+ within="within",
+ within_time="withinTime",
)
assert_matches_type(ExtractionRunResponse, extraction, path=["response"])
diff --git a/tests/api_resources/x/test_communities.py b/tests/api_resources/x/test_communities.py
index 28d92b3..a556d77 100644
--- a/tests/api_resources/x/test_communities.py
+++ b/tests/api_resources/x/test_communities.py
@@ -186,8 +186,22 @@ def test_method_retrieve_members(self, client: XTwitterScraper) -> None:
def test_method_retrieve_members_with_all_params(self, client: XTwitterScraper) -> None:
community = client.x.communities.retrieve_members(
id="id",
+ bio_contains="bioContains",
cursor="cursor",
+ has_location=True,
+ has_website=True,
+ location_contains="locationContains",
+ max_followers=0,
+ max_following=0,
+ max_statuses=0,
+ min_account_age_days=0,
+ min_followers=0,
+ min_following=0,
+ min_statuses=0,
page_size=20,
+ username_contains="usernameContains",
+ verified_only=True,
+ verified_type="verifiedType",
)
assert_matches_type(PaginatedUsers, community, path=["response"])
@@ -238,7 +252,21 @@ def test_method_retrieve_moderators(self, client: XTwitterScraper) -> None:
def test_method_retrieve_moderators_with_all_params(self, client: XTwitterScraper) -> None:
community = client.x.communities.retrieve_moderators(
id="id",
+ bio_contains="bioContains",
cursor="cursor",
+ has_location=True,
+ has_website=True,
+ location_contains="locationContains",
+ max_followers=0,
+ max_following=0,
+ max_statuses=0,
+ min_account_age_days=0,
+ min_followers=0,
+ min_following=0,
+ min_statuses=0,
+ username_contains="usernameContains",
+ verified_only=True,
+ verified_type="verifiedType",
)
assert_matches_type(PaginatedUsers, community, path=["response"])
@@ -491,8 +519,22 @@ async def test_method_retrieve_members(self, async_client: AsyncXTwitterScraper)
async def test_method_retrieve_members_with_all_params(self, async_client: AsyncXTwitterScraper) -> None:
community = await async_client.x.communities.retrieve_members(
id="id",
+ bio_contains="bioContains",
cursor="cursor",
+ has_location=True,
+ has_website=True,
+ location_contains="locationContains",
+ max_followers=0,
+ max_following=0,
+ max_statuses=0,
+ min_account_age_days=0,
+ min_followers=0,
+ min_following=0,
+ min_statuses=0,
page_size=20,
+ username_contains="usernameContains",
+ verified_only=True,
+ verified_type="verifiedType",
)
assert_matches_type(PaginatedUsers, community, path=["response"])
@@ -543,7 +585,21 @@ async def test_method_retrieve_moderators(self, async_client: AsyncXTwitterScrap
async def test_method_retrieve_moderators_with_all_params(self, async_client: AsyncXTwitterScraper) -> None:
community = await async_client.x.communities.retrieve_moderators(
id="id",
+ bio_contains="bioContains",
cursor="cursor",
+ has_location=True,
+ has_website=True,
+ location_contains="locationContains",
+ max_followers=0,
+ max_following=0,
+ max_statuses=0,
+ min_account_age_days=0,
+ min_followers=0,
+ min_following=0,
+ min_statuses=0,
+ username_contains="usernameContains",
+ verified_only=True,
+ verified_type="verifiedType",
)
assert_matches_type(PaginatedUsers, community, path=["response"])
diff --git a/tests/api_resources/x/test_lists.py b/tests/api_resources/x/test_lists.py
index b501e95..a6a3206 100644
--- a/tests/api_resources/x/test_lists.py
+++ b/tests/api_resources/x/test_lists.py
@@ -34,8 +34,22 @@ def test_method_retrieve_followers(self, client: XTwitterScraper) -> None:
def test_method_retrieve_followers_with_all_params(self, client: XTwitterScraper) -> None:
list_ = client.x.lists.retrieve_followers(
id="id",
+ bio_contains="bioContains",
cursor="cursor",
+ has_location=True,
+ has_website=True,
+ location_contains="locationContains",
+ max_followers=0,
+ max_following=0,
+ max_statuses=0,
+ min_account_age_days=0,
+ min_followers=0,
+ min_following=0,
+ min_statuses=0,
page_size=20,
+ username_contains="usernameContains",
+ verified_only=True,
+ verified_type="verifiedType",
)
assert_matches_type(PaginatedUsers, list_, path=["response"])
@@ -86,8 +100,22 @@ def test_method_retrieve_members(self, client: XTwitterScraper) -> None:
def test_method_retrieve_members_with_all_params(self, client: XTwitterScraper) -> None:
list_ = client.x.lists.retrieve_members(
id="id",
+ bio_contains="bioContains",
cursor="cursor",
+ has_location=True,
+ has_website=True,
+ location_contains="locationContains",
+ max_followers=0,
+ max_following=0,
+ max_statuses=0,
+ min_account_age_days=0,
+ min_followers=0,
+ min_following=0,
+ min_statuses=0,
page_size=20,
+ username_contains="usernameContains",
+ verified_only=True,
+ verified_type="verifiedType",
)
assert_matches_type(PaginatedUsers, list_, path=["response"])
@@ -199,8 +227,22 @@ async def test_method_retrieve_followers(self, async_client: AsyncXTwitterScrape
async def test_method_retrieve_followers_with_all_params(self, async_client: AsyncXTwitterScraper) -> None:
list_ = await async_client.x.lists.retrieve_followers(
id="id",
+ bio_contains="bioContains",
cursor="cursor",
+ has_location=True,
+ has_website=True,
+ location_contains="locationContains",
+ max_followers=0,
+ max_following=0,
+ max_statuses=0,
+ min_account_age_days=0,
+ min_followers=0,
+ min_following=0,
+ min_statuses=0,
page_size=20,
+ username_contains="usernameContains",
+ verified_only=True,
+ verified_type="verifiedType",
)
assert_matches_type(PaginatedUsers, list_, path=["response"])
@@ -251,8 +293,22 @@ async def test_method_retrieve_members(self, async_client: AsyncXTwitterScraper)
async def test_method_retrieve_members_with_all_params(self, async_client: AsyncXTwitterScraper) -> None:
list_ = await async_client.x.lists.retrieve_members(
id="id",
+ bio_contains="bioContains",
cursor="cursor",
+ has_location=True,
+ has_website=True,
+ location_contains="locationContains",
+ max_followers=0,
+ max_following=0,
+ max_statuses=0,
+ min_account_age_days=0,
+ min_followers=0,
+ min_following=0,
+ min_statuses=0,
page_size=20,
+ username_contains="usernameContains",
+ verified_only=True,
+ verified_type="verifiedType",
)
assert_matches_type(PaginatedUsers, list_, path=["response"])
diff --git a/tests/api_resources/x/test_tweets.py b/tests/api_resources/x/test_tweets.py
index 6b447d9..7ce7b7c 100644
--- a/tests/api_resources/x/test_tweets.py
+++ b/tests/api_resources/x/test_tweets.py
@@ -17,6 +17,7 @@
from x_twitter_scraper.types.x import (
TweetCreateResponse,
TweetDeleteResponse,
+ TweetSearchResponse,
TweetRetrieveResponse,
TweetGetRepliesResponse,
)
@@ -218,8 +219,22 @@ def test_method_get_favoriters(self, client: XTwitterScraper) -> None:
def test_method_get_favoriters_with_all_params(self, client: XTwitterScraper) -> None:
tweet = client.x.tweets.get_favoriters(
id="id",
+ bio_contains="bioContains",
cursor="cursor",
+ has_location=True,
+ has_website=True,
+ location_contains="locationContains",
+ max_followers=0,
+ max_following=0,
+ max_statuses=0,
+ min_account_age_days=0,
+ min_followers=0,
+ min_following=0,
+ min_statuses=0,
page_size=20,
+ username_contains="usernameContains",
+ verified_only=True,
+ verified_type="verifiedType",
)
assert_matches_type(PaginatedUsers, tweet, path=["response"])
@@ -271,35 +286,54 @@ def test_method_get_quotes_with_all_params(self, client: XTwitterScraper) -> Non
tweet = client.x.tweets.get_quotes(
id="id",
any_words="anyWords",
+ blue_verified_only=True,
+ card_name="cardName",
cashtags="cashtags",
conversation_id="conversationId",
cursor="cursor",
exact_phrase="exactPhrase",
+ exclude_source="excludeSource",
exclude_words="excludeWords",
from_user="fromUser",
+ geocode="geocode",
hashtags="hashtags",
include_replies=True,
in_reply_to_tweet_id="inReplyToTweetId",
language="language",
+ max_faves=0,
+ max_id="maxId",
+ max_quotes=0,
+ max_replies=0,
+ max_retweets=0,
media_type="images",
mentioning="mentioning",
+ min_bookmarks=0,
min_faves=0,
min_quotes=0,
min_replies=0,
min_retweets=0,
+ min_views=0,
+ native_retweets=True,
+ near="near",
+ news=True,
page_size=1,
quotes="include",
quotes_of_tweet_id="quotesOfTweetId",
replies="include",
retweets="include",
retweets_of_tweet_id="retweetsOfTweetId",
+ safe=True,
since_date=parse_date("2019-12-27"),
+ since_id="sinceId",
since_time="sinceTime",
+ source="source",
to_user="toUser",
until_date=parse_date("2019-12-27"),
until_time="untilTime",
url="url",
verified_only=True,
+ within="within",
+ within_time="withinTime",
)
assert_matches_type(PaginatedTweets, tweet, path=["response"])
@@ -351,36 +385,61 @@ def test_method_get_replies_with_all_params(self, client: XTwitterScraper) -> No
tweet = client.x.tweets.get_replies(
id="id",
any_words="anyWords",
+ blue_verified_only=True,
+ card_name="cardName",
cashtags="cashtags",
conversation_id="conversationId",
cursor="cursor",
exact_phrase="exactPhrase",
+ exclude_original_author=True,
+ exclude_source="excludeSource",
exclude_words="excludeWords",
from_user="fromUser",
+ geocode="geocode",
hashtags="hashtags",
+ has_media_only=True,
+ include_original_post=True,
in_reply_to_tweet_id="inReplyToTweetId",
language="language",
limit=1,
+ max_depth=1,
+ max_faves=0,
+ max_id="maxId",
+ max_quotes=0,
+ max_replies=0,
+ max_retweets=0,
media_type="images",
mentioning="mentioning",
+ min_bookmarks=0,
min_faves=0,
min_quotes=0,
min_replies=0,
min_retweets=0,
- mode="complete",
+ min_views=0,
+ mode="standard",
+ native_retweets=True,
+ near="near",
+ news=True,
page_size=1,
quotes="include",
quotes_of_tweet_id="quotesOfTweetId",
replies="include",
retweets="include",
retweets_of_tweet_id="retweetsOfTweetId",
+ safe=True,
+ scope="all",
since_date=parse_date("2019-12-27"),
+ since_id="sinceId",
since_time="sinceTime",
+ sort="relevance",
+ source="source",
to_user="toUser",
until_date=parse_date("2019-12-27"),
until_time="untilTime",
url="url",
verified_only=True,
+ within="within",
+ within_time="withinTime",
)
assert_matches_type(TweetGetRepliesResponse, tweet, path=["response"])
@@ -431,8 +490,22 @@ def test_method_get_retweeters(self, client: XTwitterScraper) -> None:
def test_method_get_retweeters_with_all_params(self, client: XTwitterScraper) -> None:
tweet = client.x.tweets.get_retweeters(
id="id",
+ bio_contains="bioContains",
cursor="cursor",
+ has_location=True,
+ has_website=True,
+ location_contains="locationContains",
+ max_followers=0,
+ max_following=0,
+ max_statuses=0,
+ min_account_age_days=0,
+ min_followers=0,
+ min_following=0,
+ min_statuses=0,
page_size=20,
+ username_contains="usernameContains",
+ verified_only=True,
+ verified_type="verifiedType",
)
assert_matches_type(PaginatedUsers, tweet, path=["response"])
@@ -528,7 +601,7 @@ def test_method_search(self, client: XTwitterScraper) -> None:
tweet = client.x.tweets.search(
q="q",
)
- assert_matches_type(PaginatedTweets, tweet, path=["response"])
+ assert_matches_type(TweetSearchResponse, tweet, path=["response"])
@pytest.mark.skip(reason="Mock server tests are disabled")
@parametrize
@@ -537,24 +610,39 @@ def test_method_search_with_all_params(self, client: XTwitterScraper) -> None:
q="q",
advanced_query="advancedQuery",
any_words="anyWords",
+ blue_verified_only=True,
bounding_box="boundingBox",
+ card_name="cardName",
cashtags="cashtags",
conversation_id="conversationId",
cursor="cursor",
exact_phrase="exactPhrase",
+ exclude_source="excludeSource",
exclude_words="excludeWords",
from_user="fromUser",
+ geocode="geocode",
hashtags="hashtags",
in_reply_to_tweet_id="inReplyToTweetId",
language="language",
- limit=200,
+ limit=1,
list_id="listId",
+ max_faves=0,
+ max_id="maxId",
+ max_quotes=0,
+ max_replies=0,
+ max_retweets=0,
media_type="images",
mentioning="mentioning",
+ min_bookmarks=0,
min_faves=0,
min_quotes=0,
min_replies=0,
min_retweets=0,
+ min_views=0,
+ mode="standard",
+ native_retweets=True,
+ near="near",
+ news=True,
place="place",
place_country="placeCountry",
point_radius="pointRadius",
@@ -564,15 +652,20 @@ def test_method_search_with_all_params(self, client: XTwitterScraper) -> None:
replies="include",
retweets="include",
retweets_of_tweet_id="retweetsOfTweetId",
+ safe=True,
since_date=parse_date("2019-12-27"),
+ since_id="sinceId",
since_time="sinceTime",
+ source="source",
to_user="toUser",
until_date=parse_date("2019-12-27"),
until_time="untilTime",
url="url",
verified_only=True,
+ within="within",
+ within_time="withinTime",
)
- assert_matches_type(PaginatedTweets, tweet, path=["response"])
+ assert_matches_type(TweetSearchResponse, tweet, path=["response"])
@pytest.mark.skip(reason="Mock server tests are disabled")
@parametrize
@@ -584,7 +677,7 @@ def test_raw_response_search(self, client: XTwitterScraper) -> None:
assert response.is_closed is True
assert response.http_request.headers.get("X-Stainless-Lang") == "python"
tweet = response.parse()
- assert_matches_type(PaginatedTweets, tweet, path=["response"])
+ assert_matches_type(TweetSearchResponse, tweet, path=["response"])
@pytest.mark.skip(reason="Mock server tests are disabled")
@parametrize
@@ -596,7 +689,7 @@ def test_streaming_response_search(self, client: XTwitterScraper) -> None:
assert response.http_request.headers.get("X-Stainless-Lang") == "python"
tweet = response.parse()
- assert_matches_type(PaginatedTweets, tweet, path=["response"])
+ assert_matches_type(TweetSearchResponse, tweet, path=["response"])
assert cast(Any, response.is_closed) is True
@@ -796,8 +889,22 @@ async def test_method_get_favoriters(self, async_client: AsyncXTwitterScraper) -
async def test_method_get_favoriters_with_all_params(self, async_client: AsyncXTwitterScraper) -> None:
tweet = await async_client.x.tweets.get_favoriters(
id="id",
+ bio_contains="bioContains",
cursor="cursor",
+ has_location=True,
+ has_website=True,
+ location_contains="locationContains",
+ max_followers=0,
+ max_following=0,
+ max_statuses=0,
+ min_account_age_days=0,
+ min_followers=0,
+ min_following=0,
+ min_statuses=0,
page_size=20,
+ username_contains="usernameContains",
+ verified_only=True,
+ verified_type="verifiedType",
)
assert_matches_type(PaginatedUsers, tweet, path=["response"])
@@ -849,35 +956,54 @@ async def test_method_get_quotes_with_all_params(self, async_client: AsyncXTwitt
tweet = await async_client.x.tweets.get_quotes(
id="id",
any_words="anyWords",
+ blue_verified_only=True,
+ card_name="cardName",
cashtags="cashtags",
conversation_id="conversationId",
cursor="cursor",
exact_phrase="exactPhrase",
+ exclude_source="excludeSource",
exclude_words="excludeWords",
from_user="fromUser",
+ geocode="geocode",
hashtags="hashtags",
include_replies=True,
in_reply_to_tweet_id="inReplyToTweetId",
language="language",
+ max_faves=0,
+ max_id="maxId",
+ max_quotes=0,
+ max_replies=0,
+ max_retweets=0,
media_type="images",
mentioning="mentioning",
+ min_bookmarks=0,
min_faves=0,
min_quotes=0,
min_replies=0,
min_retweets=0,
+ min_views=0,
+ native_retweets=True,
+ near="near",
+ news=True,
page_size=1,
quotes="include",
quotes_of_tweet_id="quotesOfTweetId",
replies="include",
retweets="include",
retweets_of_tweet_id="retweetsOfTweetId",
+ safe=True,
since_date=parse_date("2019-12-27"),
+ since_id="sinceId",
since_time="sinceTime",
+ source="source",
to_user="toUser",
until_date=parse_date("2019-12-27"),
until_time="untilTime",
url="url",
verified_only=True,
+ within="within",
+ within_time="withinTime",
)
assert_matches_type(PaginatedTweets, tweet, path=["response"])
@@ -929,36 +1055,61 @@ async def test_method_get_replies_with_all_params(self, async_client: AsyncXTwit
tweet = await async_client.x.tweets.get_replies(
id="id",
any_words="anyWords",
+ blue_verified_only=True,
+ card_name="cardName",
cashtags="cashtags",
conversation_id="conversationId",
cursor="cursor",
exact_phrase="exactPhrase",
+ exclude_original_author=True,
+ exclude_source="excludeSource",
exclude_words="excludeWords",
from_user="fromUser",
+ geocode="geocode",
hashtags="hashtags",
+ has_media_only=True,
+ include_original_post=True,
in_reply_to_tweet_id="inReplyToTweetId",
language="language",
limit=1,
+ max_depth=1,
+ max_faves=0,
+ max_id="maxId",
+ max_quotes=0,
+ max_replies=0,
+ max_retweets=0,
media_type="images",
mentioning="mentioning",
+ min_bookmarks=0,
min_faves=0,
min_quotes=0,
min_replies=0,
min_retweets=0,
- mode="complete",
+ min_views=0,
+ mode="standard",
+ native_retweets=True,
+ near="near",
+ news=True,
page_size=1,
quotes="include",
quotes_of_tweet_id="quotesOfTweetId",
replies="include",
retweets="include",
retweets_of_tweet_id="retweetsOfTweetId",
+ safe=True,
+ scope="all",
since_date=parse_date("2019-12-27"),
+ since_id="sinceId",
since_time="sinceTime",
+ sort="relevance",
+ source="source",
to_user="toUser",
until_date=parse_date("2019-12-27"),
until_time="untilTime",
url="url",
verified_only=True,
+ within="within",
+ within_time="withinTime",
)
assert_matches_type(TweetGetRepliesResponse, tweet, path=["response"])
@@ -1009,8 +1160,22 @@ async def test_method_get_retweeters(self, async_client: AsyncXTwitterScraper) -
async def test_method_get_retweeters_with_all_params(self, async_client: AsyncXTwitterScraper) -> None:
tweet = await async_client.x.tweets.get_retweeters(
id="id",
+ bio_contains="bioContains",
cursor="cursor",
+ has_location=True,
+ has_website=True,
+ location_contains="locationContains",
+ max_followers=0,
+ max_following=0,
+ max_statuses=0,
+ min_account_age_days=0,
+ min_followers=0,
+ min_following=0,
+ min_statuses=0,
page_size=20,
+ username_contains="usernameContains",
+ verified_only=True,
+ verified_type="verifiedType",
)
assert_matches_type(PaginatedUsers, tweet, path=["response"])
@@ -1106,7 +1271,7 @@ async def test_method_search(self, async_client: AsyncXTwitterScraper) -> None:
tweet = await async_client.x.tweets.search(
q="q",
)
- assert_matches_type(PaginatedTweets, tweet, path=["response"])
+ assert_matches_type(TweetSearchResponse, tweet, path=["response"])
@pytest.mark.skip(reason="Mock server tests are disabled")
@parametrize
@@ -1115,24 +1280,39 @@ async def test_method_search_with_all_params(self, async_client: AsyncXTwitterSc
q="q",
advanced_query="advancedQuery",
any_words="anyWords",
+ blue_verified_only=True,
bounding_box="boundingBox",
+ card_name="cardName",
cashtags="cashtags",
conversation_id="conversationId",
cursor="cursor",
exact_phrase="exactPhrase",
+ exclude_source="excludeSource",
exclude_words="excludeWords",
from_user="fromUser",
+ geocode="geocode",
hashtags="hashtags",
in_reply_to_tweet_id="inReplyToTweetId",
language="language",
- limit=200,
+ limit=1,
list_id="listId",
+ max_faves=0,
+ max_id="maxId",
+ max_quotes=0,
+ max_replies=0,
+ max_retweets=0,
media_type="images",
mentioning="mentioning",
+ min_bookmarks=0,
min_faves=0,
min_quotes=0,
min_replies=0,
min_retweets=0,
+ min_views=0,
+ mode="standard",
+ native_retweets=True,
+ near="near",
+ news=True,
place="place",
place_country="placeCountry",
point_radius="pointRadius",
@@ -1142,15 +1322,20 @@ async def test_method_search_with_all_params(self, async_client: AsyncXTwitterSc
replies="include",
retweets="include",
retweets_of_tweet_id="retweetsOfTweetId",
+ safe=True,
since_date=parse_date("2019-12-27"),
+ since_id="sinceId",
since_time="sinceTime",
+ source="source",
to_user="toUser",
until_date=parse_date("2019-12-27"),
until_time="untilTime",
url="url",
verified_only=True,
+ within="within",
+ within_time="withinTime",
)
- assert_matches_type(PaginatedTweets, tweet, path=["response"])
+ assert_matches_type(TweetSearchResponse, tweet, path=["response"])
@pytest.mark.skip(reason="Mock server tests are disabled")
@parametrize
@@ -1162,7 +1347,7 @@ async def test_raw_response_search(self, async_client: AsyncXTwitterScraper) ->
assert response.is_closed is True
assert response.http_request.headers.get("X-Stainless-Lang") == "python"
tweet = await response.parse()
- assert_matches_type(PaginatedTweets, tweet, path=["response"])
+ assert_matches_type(TweetSearchResponse, tweet, path=["response"])
@pytest.mark.skip(reason="Mock server tests are disabled")
@parametrize
@@ -1174,6 +1359,6 @@ async def test_streaming_response_search(self, async_client: AsyncXTwitterScrape
assert response.http_request.headers.get("X-Stainless-Lang") == "python"
tweet = await response.parse()
- assert_matches_type(PaginatedTweets, tweet, path=["response"])
+ assert_matches_type(TweetSearchResponse, tweet, path=["response"])
assert cast(Any, response.is_closed) is True
diff --git a/tests/api_resources/x/test_users.py b/tests/api_resources/x/test_users.py
index 69db1d2..f663bb4 100644
--- a/tests/api_resources/x/test_users.py
+++ b/tests/api_resources/x/test_users.py
@@ -17,6 +17,9 @@
from x_twitter_scraper.types.x import (
UserRetrieveBatchResponse,
UserRemoveFollowerResponse,
+ UserRetrieveFollowersResponse,
+ UserRetrieveFollowingResponse,
+ UserRetrieveVerifiedFollowersResponse,
)
from x_twitter_scraper.types.shared import UserProfile, PaginatedUsers, PaginatedTweets
@@ -158,7 +161,7 @@ def test_method_retrieve_followers(self, client: XTwitterScraper) -> None:
user = client.x.users.retrieve_followers(
id="id",
)
- assert_matches_type(PaginatedUsers, user, path=["response"])
+ assert_matches_type(UserRetrieveFollowersResponse, user, path=["response"])
@pytest.mark.skip(reason="Mock server tests are disabled")
@parametrize
@@ -166,11 +169,26 @@ def test_method_retrieve_followers_with_all_params(self, client: XTwitterScraper
user = client.x.users.retrieve_followers(
id="id",
after="after",
+ bio_contains="bioContains",
cursor="cursor",
- limit=0,
+ has_location=True,
+ has_website=True,
+ limit=1,
+ location_contains="locationContains",
+ max_followers=0,
+ max_following=0,
+ max_statuses=0,
+ min_account_age_days=0,
+ min_followers=0,
+ min_following=0,
+ min_statuses=0,
+ mode="standard",
page_size=20,
+ username_contains="usernameContains",
+ verified_only=True,
+ verified_type="verifiedType",
)
- assert_matches_type(PaginatedUsers, user, path=["response"])
+ assert_matches_type(UserRetrieveFollowersResponse, user, path=["response"])
@pytest.mark.skip(reason="Mock server tests are disabled")
@parametrize
@@ -182,7 +200,7 @@ def test_raw_response_retrieve_followers(self, client: XTwitterScraper) -> None:
assert response.is_closed is True
assert response.http_request.headers.get("X-Stainless-Lang") == "python"
user = response.parse()
- assert_matches_type(PaginatedUsers, user, path=["response"])
+ assert_matches_type(UserRetrieveFollowersResponse, user, path=["response"])
@pytest.mark.skip(reason="Mock server tests are disabled")
@parametrize
@@ -194,7 +212,7 @@ def test_streaming_response_retrieve_followers(self, client: XTwitterScraper) ->
assert response.http_request.headers.get("X-Stainless-Lang") == "python"
user = response.parse()
- assert_matches_type(PaginatedUsers, user, path=["response"])
+ assert_matches_type(UserRetrieveFollowersResponse, user, path=["response"])
assert cast(Any, response.is_closed) is True
@@ -219,8 +237,22 @@ def test_method_retrieve_followers_you_know(self, client: XTwitterScraper) -> No
def test_method_retrieve_followers_you_know_with_all_params(self, client: XTwitterScraper) -> None:
user = client.x.users.retrieve_followers_you_know(
id="id",
+ bio_contains="bioContains",
cursor="cursor",
+ has_location=True,
+ has_website=True,
+ location_contains="locationContains",
+ max_followers=0,
+ max_following=0,
+ max_statuses=0,
+ min_account_age_days=0,
+ min_followers=0,
+ min_following=0,
+ min_statuses=0,
page_size=20,
+ username_contains="usernameContains",
+ verified_only=True,
+ verified_type="verifiedType",
)
assert_matches_type(PaginatedUsers, user, path=["response"])
@@ -264,7 +296,7 @@ def test_method_retrieve_following(self, client: XTwitterScraper) -> None:
user = client.x.users.retrieve_following(
id="id",
)
- assert_matches_type(PaginatedUsers, user, path=["response"])
+ assert_matches_type(UserRetrieveFollowingResponse, user, path=["response"])
@pytest.mark.skip(reason="Mock server tests are disabled")
@parametrize
@@ -272,11 +304,26 @@ def test_method_retrieve_following_with_all_params(self, client: XTwitterScraper
user = client.x.users.retrieve_following(
id="id",
after="after",
+ bio_contains="bioContains",
cursor="cursor",
- limit=0,
+ has_location=True,
+ has_website=True,
+ limit=1,
+ location_contains="locationContains",
+ max_followers=0,
+ max_following=0,
+ max_statuses=0,
+ min_account_age_days=0,
+ min_followers=0,
+ min_following=0,
+ min_statuses=0,
+ mode="standard",
page_size=20,
+ username_contains="usernameContains",
+ verified_only=True,
+ verified_type="verifiedType",
)
- assert_matches_type(PaginatedUsers, user, path=["response"])
+ assert_matches_type(UserRetrieveFollowingResponse, user, path=["response"])
@pytest.mark.skip(reason="Mock server tests are disabled")
@parametrize
@@ -288,7 +335,7 @@ def test_raw_response_retrieve_following(self, client: XTwitterScraper) -> None:
assert response.is_closed is True
assert response.http_request.headers.get("X-Stainless-Lang") == "python"
user = response.parse()
- assert_matches_type(PaginatedUsers, user, path=["response"])
+ assert_matches_type(UserRetrieveFollowingResponse, user, path=["response"])
@pytest.mark.skip(reason="Mock server tests are disabled")
@parametrize
@@ -300,7 +347,7 @@ def test_streaming_response_retrieve_following(self, client: XTwitterScraper) ->
assert response.http_request.headers.get("X-Stainless-Lang") == "python"
user = response.parse()
- assert_matches_type(PaginatedUsers, user, path=["response"])
+ assert_matches_type(UserRetrieveFollowingResponse, user, path=["response"])
assert cast(Any, response.is_closed) is True
@@ -326,32 +373,51 @@ def test_method_retrieve_likes_with_all_params(self, client: XTwitterScraper) ->
user = client.x.users.retrieve_likes(
id="id",
any_words="anyWords",
+ blue_verified_only=True,
+ card_name="cardName",
cashtags="cashtags",
conversation_id="conversationId",
cursor="cursor",
exact_phrase="exactPhrase",
+ exclude_source="excludeSource",
exclude_words="excludeWords",
from_user="fromUser",
+ geocode="geocode",
hashtags="hashtags",
in_reply_to_tweet_id="inReplyToTweetId",
language="language",
+ max_faves=0,
+ max_id="maxId",
+ max_quotes=0,
+ max_replies=0,
+ max_retweets=0,
media_type="images",
mentioning="mentioning",
+ min_bookmarks=0,
min_faves=0,
min_quotes=0,
min_replies=0,
min_retweets=0,
+ min_views=0,
+ native_retweets=True,
+ near="near",
+ news=True,
page_size=1,
quotes="include",
quotes_of_tweet_id="quotesOfTweetId",
replies="include",
retweets="include",
retweets_of_tweet_id="retweetsOfTweetId",
+ safe=True,
since_date=parse_date("2019-12-27"),
+ since_id="sinceId",
+ source="source",
to_user="toUser",
until_date=parse_date("2019-12-27"),
url="url",
verified_only=True,
+ within="within",
+ within_time="withinTime",
)
assert_matches_type(PaginatedTweets, user, path=["response"])
@@ -403,32 +469,51 @@ def test_method_retrieve_media_with_all_params(self, client: XTwitterScraper) ->
user = client.x.users.retrieve_media(
id="id",
any_words="anyWords",
+ blue_verified_only=True,
+ card_name="cardName",
cashtags="cashtags",
conversation_id="conversationId",
cursor="cursor",
exact_phrase="exactPhrase",
+ exclude_source="excludeSource",
exclude_words="excludeWords",
from_user="fromUser",
+ geocode="geocode",
hashtags="hashtags",
in_reply_to_tweet_id="inReplyToTweetId",
language="language",
+ max_faves=0,
+ max_id="maxId",
+ max_quotes=0,
+ max_replies=0,
+ max_retweets=0,
media_type="images",
mentioning="mentioning",
+ min_bookmarks=0,
min_faves=0,
min_quotes=0,
min_replies=0,
min_retweets=0,
+ min_views=0,
+ native_retweets=True,
+ near="near",
+ news=True,
page_size=1,
quotes="include",
quotes_of_tweet_id="quotesOfTweetId",
replies="include",
retweets="include",
retweets_of_tweet_id="retweetsOfTweetId",
+ safe=True,
since_date=parse_date("2019-12-27"),
+ since_id="sinceId",
+ source="source",
to_user="toUser",
until_date=parse_date("2019-12-27"),
url="url",
verified_only=True,
+ within="within",
+ within_time="withinTime",
)
assert_matches_type(PaginatedTweets, user, path=["response"])
@@ -480,34 +565,53 @@ def test_method_retrieve_mentions_with_all_params(self, client: XTwitterScraper)
user = client.x.users.retrieve_mentions(
id="id",
any_words="anyWords",
+ blue_verified_only=True,
+ card_name="cardName",
cashtags="cashtags",
conversation_id="conversationId",
cursor="cursor",
exact_phrase="exactPhrase",
+ exclude_source="excludeSource",
exclude_words="excludeWords",
from_user="fromUser",
+ geocode="geocode",
hashtags="hashtags",
in_reply_to_tweet_id="inReplyToTweetId",
language="language",
+ max_faves=0,
+ max_id="maxId",
+ max_quotes=0,
+ max_replies=0,
+ max_retweets=0,
media_type="images",
mentioning="mentioning",
+ min_bookmarks=0,
min_faves=0,
min_quotes=0,
min_replies=0,
min_retweets=0,
+ min_views=0,
+ native_retweets=True,
+ near="near",
+ news=True,
page_size=1,
quotes="include",
quotes_of_tweet_id="quotesOfTweetId",
replies="include",
retweets="include",
retweets_of_tweet_id="retweetsOfTweetId",
+ safe=True,
since_date=parse_date("2019-12-27"),
+ since_id="sinceId",
since_time="sinceTime",
+ source="source",
to_user="toUser",
until_date=parse_date("2019-12-27"),
until_time="untilTime",
url="url",
verified_only=True,
+ within="within",
+ within_time="withinTime",
)
assert_matches_type(PaginatedTweets, user, path=["response"])
@@ -559,33 +663,52 @@ def test_method_retrieve_replies_with_all_params(self, client: XTwitterScraper)
user = client.x.users.retrieve_replies(
id="id",
any_words="anyWords",
+ blue_verified_only=True,
+ card_name="cardName",
cashtags="cashtags",
conversation_id="conversationId",
cursor="cursor",
exact_phrase="exactPhrase",
+ exclude_source="excludeSource",
exclude_words="excludeWords",
from_user="fromUser",
+ geocode="geocode",
hashtags="hashtags",
include_parent_tweet=True,
in_reply_to_tweet_id="inReplyToTweetId",
language="language",
+ max_faves=0,
+ max_id="maxId",
+ max_quotes=0,
+ max_replies=0,
+ max_retweets=0,
media_type="images",
mentioning="mentioning",
+ min_bookmarks=0,
min_faves=0,
min_quotes=0,
min_replies=0,
min_retweets=0,
+ min_views=0,
+ native_retweets=True,
+ near="near",
+ news=True,
page_size=1,
quotes="include",
quotes_of_tweet_id="quotesOfTweetId",
replies="include",
retweets="include",
retweets_of_tweet_id="retweetsOfTweetId",
+ safe=True,
since_date=parse_date("2019-12-27"),
+ since_id="sinceId",
+ source="source",
to_user="toUser",
until_date=parse_date("2019-12-27"),
url="url",
verified_only=True,
+ within="within",
+ within_time="withinTime",
)
assert_matches_type(PaginatedTweets, user, path=["response"])
@@ -636,7 +759,21 @@ def test_method_retrieve_search(self, client: XTwitterScraper) -> None:
def test_method_retrieve_search_with_all_params(self, client: XTwitterScraper) -> None:
user = client.x.users.retrieve_search(
q="q",
+ bio_contains="bioContains",
cursor="cursor",
+ has_location=True,
+ has_website=True,
+ location_contains="locationContains",
+ max_followers=0,
+ max_following=0,
+ max_statuses=0,
+ min_account_age_days=0,
+ min_followers=0,
+ min_following=0,
+ min_statuses=0,
+ username_contains="usernameContains",
+ verified_only=True,
+ verified_type="verifiedType",
)
assert_matches_type(PaginatedUsers, user, path=["response"])
@@ -680,34 +817,53 @@ def test_method_retrieve_tweets_with_all_params(self, client: XTwitterScraper) -
user = client.x.users.retrieve_tweets(
id="id",
any_words="anyWords",
+ blue_verified_only=True,
+ card_name="cardName",
cashtags="cashtags",
conversation_id="conversationId",
cursor="cursor",
exact_phrase="exactPhrase",
+ exclude_source="excludeSource",
exclude_words="excludeWords",
from_user="fromUser",
+ geocode="geocode",
hashtags="hashtags",
include_parent_tweet=True,
include_replies=True,
in_reply_to_tweet_id="inReplyToTweetId",
language="language",
+ max_faves=0,
+ max_id="maxId",
+ max_quotes=0,
+ max_replies=0,
+ max_retweets=0,
media_type="images",
mentioning="mentioning",
+ min_bookmarks=0,
min_faves=0,
min_quotes=0,
min_replies=0,
min_retweets=0,
+ min_views=0,
+ native_retweets=True,
+ near="near",
+ news=True,
page_size=1,
quotes="include",
quotes_of_tweet_id="quotesOfTweetId",
replies="include",
retweets="include",
retweets_of_tweet_id="retweetsOfTweetId",
+ safe=True,
since_date=parse_date("2019-12-27"),
+ since_id="sinceId",
+ source="source",
to_user="toUser",
until_date=parse_date("2019-12-27"),
url="url",
verified_only=True,
+ within="within",
+ within_time="withinTime",
)
assert_matches_type(PaginatedTweets, user, path=["response"])
@@ -751,17 +907,34 @@ def test_method_retrieve_verified_followers(self, client: XTwitterScraper) -> No
user = client.x.users.retrieve_verified_followers(
id="id",
)
- assert_matches_type(PaginatedUsers, user, path=["response"])
+ assert_matches_type(UserRetrieveVerifiedFollowersResponse, user, path=["response"])
@pytest.mark.skip(reason="Mock server tests are disabled")
@parametrize
def test_method_retrieve_verified_followers_with_all_params(self, client: XTwitterScraper) -> None:
user = client.x.users.retrieve_verified_followers(
id="id",
+ after="after",
+ bio_contains="bioContains",
cursor="cursor",
+ has_location=True,
+ has_website=True,
+ limit=1,
+ location_contains="locationContains",
+ max_followers=0,
+ max_following=0,
+ max_statuses=0,
+ min_account_age_days=0,
+ min_followers=0,
+ min_following=0,
+ min_statuses=0,
+ mode="standard",
page_size=20,
+ username_contains="usernameContains",
+ verified_only=True,
+ verified_type="verifiedType",
)
- assert_matches_type(PaginatedUsers, user, path=["response"])
+ assert_matches_type(UserRetrieveVerifiedFollowersResponse, user, path=["response"])
@pytest.mark.skip(reason="Mock server tests are disabled")
@parametrize
@@ -773,7 +946,7 @@ def test_raw_response_retrieve_verified_followers(self, client: XTwitterScraper)
assert response.is_closed is True
assert response.http_request.headers.get("X-Stainless-Lang") == "python"
user = response.parse()
- assert_matches_type(PaginatedUsers, user, path=["response"])
+ assert_matches_type(UserRetrieveVerifiedFollowersResponse, user, path=["response"])
@pytest.mark.skip(reason="Mock server tests are disabled")
@parametrize
@@ -785,7 +958,7 @@ def test_streaming_response_retrieve_verified_followers(self, client: XTwitterSc
assert response.http_request.headers.get("X-Stainless-Lang") == "python"
user = response.parse()
- assert_matches_type(PaginatedUsers, user, path=["response"])
+ assert_matches_type(UserRetrieveVerifiedFollowersResponse, user, path=["response"])
assert cast(Any, response.is_closed) is True
@@ -935,7 +1108,7 @@ async def test_method_retrieve_followers(self, async_client: AsyncXTwitterScrape
user = await async_client.x.users.retrieve_followers(
id="id",
)
- assert_matches_type(PaginatedUsers, user, path=["response"])
+ assert_matches_type(UserRetrieveFollowersResponse, user, path=["response"])
@pytest.mark.skip(reason="Mock server tests are disabled")
@parametrize
@@ -943,11 +1116,26 @@ async def test_method_retrieve_followers_with_all_params(self, async_client: Asy
user = await async_client.x.users.retrieve_followers(
id="id",
after="after",
+ bio_contains="bioContains",
cursor="cursor",
- limit=0,
+ has_location=True,
+ has_website=True,
+ limit=1,
+ location_contains="locationContains",
+ max_followers=0,
+ max_following=0,
+ max_statuses=0,
+ min_account_age_days=0,
+ min_followers=0,
+ min_following=0,
+ min_statuses=0,
+ mode="standard",
page_size=20,
+ username_contains="usernameContains",
+ verified_only=True,
+ verified_type="verifiedType",
)
- assert_matches_type(PaginatedUsers, user, path=["response"])
+ assert_matches_type(UserRetrieveFollowersResponse, user, path=["response"])
@pytest.mark.skip(reason="Mock server tests are disabled")
@parametrize
@@ -959,7 +1147,7 @@ async def test_raw_response_retrieve_followers(self, async_client: AsyncXTwitter
assert response.is_closed is True
assert response.http_request.headers.get("X-Stainless-Lang") == "python"
user = await response.parse()
- assert_matches_type(PaginatedUsers, user, path=["response"])
+ assert_matches_type(UserRetrieveFollowersResponse, user, path=["response"])
@pytest.mark.skip(reason="Mock server tests are disabled")
@parametrize
@@ -971,7 +1159,7 @@ async def test_streaming_response_retrieve_followers(self, async_client: AsyncXT
assert response.http_request.headers.get("X-Stainless-Lang") == "python"
user = await response.parse()
- assert_matches_type(PaginatedUsers, user, path=["response"])
+ assert_matches_type(UserRetrieveFollowersResponse, user, path=["response"])
assert cast(Any, response.is_closed) is True
@@ -996,8 +1184,22 @@ async def test_method_retrieve_followers_you_know(self, async_client: AsyncXTwit
async def test_method_retrieve_followers_you_know_with_all_params(self, async_client: AsyncXTwitterScraper) -> None:
user = await async_client.x.users.retrieve_followers_you_know(
id="id",
+ bio_contains="bioContains",
cursor="cursor",
+ has_location=True,
+ has_website=True,
+ location_contains="locationContains",
+ max_followers=0,
+ max_following=0,
+ max_statuses=0,
+ min_account_age_days=0,
+ min_followers=0,
+ min_following=0,
+ min_statuses=0,
page_size=20,
+ username_contains="usernameContains",
+ verified_only=True,
+ verified_type="verifiedType",
)
assert_matches_type(PaginatedUsers, user, path=["response"])
@@ -1041,7 +1243,7 @@ async def test_method_retrieve_following(self, async_client: AsyncXTwitterScrape
user = await async_client.x.users.retrieve_following(
id="id",
)
- assert_matches_type(PaginatedUsers, user, path=["response"])
+ assert_matches_type(UserRetrieveFollowingResponse, user, path=["response"])
@pytest.mark.skip(reason="Mock server tests are disabled")
@parametrize
@@ -1049,11 +1251,26 @@ async def test_method_retrieve_following_with_all_params(self, async_client: Asy
user = await async_client.x.users.retrieve_following(
id="id",
after="after",
+ bio_contains="bioContains",
cursor="cursor",
- limit=0,
+ has_location=True,
+ has_website=True,
+ limit=1,
+ location_contains="locationContains",
+ max_followers=0,
+ max_following=0,
+ max_statuses=0,
+ min_account_age_days=0,
+ min_followers=0,
+ min_following=0,
+ min_statuses=0,
+ mode="standard",
page_size=20,
+ username_contains="usernameContains",
+ verified_only=True,
+ verified_type="verifiedType",
)
- assert_matches_type(PaginatedUsers, user, path=["response"])
+ assert_matches_type(UserRetrieveFollowingResponse, user, path=["response"])
@pytest.mark.skip(reason="Mock server tests are disabled")
@parametrize
@@ -1065,7 +1282,7 @@ async def test_raw_response_retrieve_following(self, async_client: AsyncXTwitter
assert response.is_closed is True
assert response.http_request.headers.get("X-Stainless-Lang") == "python"
user = await response.parse()
- assert_matches_type(PaginatedUsers, user, path=["response"])
+ assert_matches_type(UserRetrieveFollowingResponse, user, path=["response"])
@pytest.mark.skip(reason="Mock server tests are disabled")
@parametrize
@@ -1077,7 +1294,7 @@ async def test_streaming_response_retrieve_following(self, async_client: AsyncXT
assert response.http_request.headers.get("X-Stainless-Lang") == "python"
user = await response.parse()
- assert_matches_type(PaginatedUsers, user, path=["response"])
+ assert_matches_type(UserRetrieveFollowingResponse, user, path=["response"])
assert cast(Any, response.is_closed) is True
@@ -1103,32 +1320,51 @@ async def test_method_retrieve_likes_with_all_params(self, async_client: AsyncXT
user = await async_client.x.users.retrieve_likes(
id="id",
any_words="anyWords",
+ blue_verified_only=True,
+ card_name="cardName",
cashtags="cashtags",
conversation_id="conversationId",
cursor="cursor",
exact_phrase="exactPhrase",
+ exclude_source="excludeSource",
exclude_words="excludeWords",
from_user="fromUser",
+ geocode="geocode",
hashtags="hashtags",
in_reply_to_tweet_id="inReplyToTweetId",
language="language",
+ max_faves=0,
+ max_id="maxId",
+ max_quotes=0,
+ max_replies=0,
+ max_retweets=0,
media_type="images",
mentioning="mentioning",
+ min_bookmarks=0,
min_faves=0,
min_quotes=0,
min_replies=0,
min_retweets=0,
+ min_views=0,
+ native_retweets=True,
+ near="near",
+ news=True,
page_size=1,
quotes="include",
quotes_of_tweet_id="quotesOfTweetId",
replies="include",
retweets="include",
retweets_of_tweet_id="retweetsOfTweetId",
+ safe=True,
since_date=parse_date("2019-12-27"),
+ since_id="sinceId",
+ source="source",
to_user="toUser",
until_date=parse_date("2019-12-27"),
url="url",
verified_only=True,
+ within="within",
+ within_time="withinTime",
)
assert_matches_type(PaginatedTweets, user, path=["response"])
@@ -1180,32 +1416,51 @@ async def test_method_retrieve_media_with_all_params(self, async_client: AsyncXT
user = await async_client.x.users.retrieve_media(
id="id",
any_words="anyWords",
+ blue_verified_only=True,
+ card_name="cardName",
cashtags="cashtags",
conversation_id="conversationId",
cursor="cursor",
exact_phrase="exactPhrase",
+ exclude_source="excludeSource",
exclude_words="excludeWords",
from_user="fromUser",
+ geocode="geocode",
hashtags="hashtags",
in_reply_to_tweet_id="inReplyToTweetId",
language="language",
+ max_faves=0,
+ max_id="maxId",
+ max_quotes=0,
+ max_replies=0,
+ max_retweets=0,
media_type="images",
mentioning="mentioning",
+ min_bookmarks=0,
min_faves=0,
min_quotes=0,
min_replies=0,
min_retweets=0,
+ min_views=0,
+ native_retweets=True,
+ near="near",
+ news=True,
page_size=1,
quotes="include",
quotes_of_tweet_id="quotesOfTweetId",
replies="include",
retweets="include",
retweets_of_tweet_id="retweetsOfTweetId",
+ safe=True,
since_date=parse_date("2019-12-27"),
+ since_id="sinceId",
+ source="source",
to_user="toUser",
until_date=parse_date("2019-12-27"),
url="url",
verified_only=True,
+ within="within",
+ within_time="withinTime",
)
assert_matches_type(PaginatedTweets, user, path=["response"])
@@ -1257,34 +1512,53 @@ async def test_method_retrieve_mentions_with_all_params(self, async_client: Asyn
user = await async_client.x.users.retrieve_mentions(
id="id",
any_words="anyWords",
+ blue_verified_only=True,
+ card_name="cardName",
cashtags="cashtags",
conversation_id="conversationId",
cursor="cursor",
exact_phrase="exactPhrase",
+ exclude_source="excludeSource",
exclude_words="excludeWords",
from_user="fromUser",
+ geocode="geocode",
hashtags="hashtags",
in_reply_to_tweet_id="inReplyToTweetId",
language="language",
+ max_faves=0,
+ max_id="maxId",
+ max_quotes=0,
+ max_replies=0,
+ max_retweets=0,
media_type="images",
mentioning="mentioning",
+ min_bookmarks=0,
min_faves=0,
min_quotes=0,
min_replies=0,
min_retweets=0,
+ min_views=0,
+ native_retweets=True,
+ near="near",
+ news=True,
page_size=1,
quotes="include",
quotes_of_tweet_id="quotesOfTweetId",
replies="include",
retweets="include",
retweets_of_tweet_id="retweetsOfTweetId",
+ safe=True,
since_date=parse_date("2019-12-27"),
+ since_id="sinceId",
since_time="sinceTime",
+ source="source",
to_user="toUser",
until_date=parse_date("2019-12-27"),
until_time="untilTime",
url="url",
verified_only=True,
+ within="within",
+ within_time="withinTime",
)
assert_matches_type(PaginatedTweets, user, path=["response"])
@@ -1336,33 +1610,52 @@ async def test_method_retrieve_replies_with_all_params(self, async_client: Async
user = await async_client.x.users.retrieve_replies(
id="id",
any_words="anyWords",
+ blue_verified_only=True,
+ card_name="cardName",
cashtags="cashtags",
conversation_id="conversationId",
cursor="cursor",
exact_phrase="exactPhrase",
+ exclude_source="excludeSource",
exclude_words="excludeWords",
from_user="fromUser",
+ geocode="geocode",
hashtags="hashtags",
include_parent_tweet=True,
in_reply_to_tweet_id="inReplyToTweetId",
language="language",
+ max_faves=0,
+ max_id="maxId",
+ max_quotes=0,
+ max_replies=0,
+ max_retweets=0,
media_type="images",
mentioning="mentioning",
+ min_bookmarks=0,
min_faves=0,
min_quotes=0,
min_replies=0,
min_retweets=0,
+ min_views=0,
+ native_retweets=True,
+ near="near",
+ news=True,
page_size=1,
quotes="include",
quotes_of_tweet_id="quotesOfTweetId",
replies="include",
retweets="include",
retweets_of_tweet_id="retweetsOfTweetId",
+ safe=True,
since_date=parse_date("2019-12-27"),
+ since_id="sinceId",
+ source="source",
to_user="toUser",
until_date=parse_date("2019-12-27"),
url="url",
verified_only=True,
+ within="within",
+ within_time="withinTime",
)
assert_matches_type(PaginatedTweets, user, path=["response"])
@@ -1413,7 +1706,21 @@ async def test_method_retrieve_search(self, async_client: AsyncXTwitterScraper)
async def test_method_retrieve_search_with_all_params(self, async_client: AsyncXTwitterScraper) -> None:
user = await async_client.x.users.retrieve_search(
q="q",
+ bio_contains="bioContains",
cursor="cursor",
+ has_location=True,
+ has_website=True,
+ location_contains="locationContains",
+ max_followers=0,
+ max_following=0,
+ max_statuses=0,
+ min_account_age_days=0,
+ min_followers=0,
+ min_following=0,
+ min_statuses=0,
+ username_contains="usernameContains",
+ verified_only=True,
+ verified_type="verifiedType",
)
assert_matches_type(PaginatedUsers, user, path=["response"])
@@ -1457,34 +1764,53 @@ async def test_method_retrieve_tweets_with_all_params(self, async_client: AsyncX
user = await async_client.x.users.retrieve_tweets(
id="id",
any_words="anyWords",
+ blue_verified_only=True,
+ card_name="cardName",
cashtags="cashtags",
conversation_id="conversationId",
cursor="cursor",
exact_phrase="exactPhrase",
+ exclude_source="excludeSource",
exclude_words="excludeWords",
from_user="fromUser",
+ geocode="geocode",
hashtags="hashtags",
include_parent_tweet=True,
include_replies=True,
in_reply_to_tweet_id="inReplyToTweetId",
language="language",
+ max_faves=0,
+ max_id="maxId",
+ max_quotes=0,
+ max_replies=0,
+ max_retweets=0,
media_type="images",
mentioning="mentioning",
+ min_bookmarks=0,
min_faves=0,
min_quotes=0,
min_replies=0,
min_retweets=0,
+ min_views=0,
+ native_retweets=True,
+ near="near",
+ news=True,
page_size=1,
quotes="include",
quotes_of_tweet_id="quotesOfTweetId",
replies="include",
retweets="include",
retweets_of_tweet_id="retweetsOfTweetId",
+ safe=True,
since_date=parse_date("2019-12-27"),
+ since_id="sinceId",
+ source="source",
to_user="toUser",
until_date=parse_date("2019-12-27"),
url="url",
verified_only=True,
+ within="within",
+ within_time="withinTime",
)
assert_matches_type(PaginatedTweets, user, path=["response"])
@@ -1528,17 +1854,34 @@ async def test_method_retrieve_verified_followers(self, async_client: AsyncXTwit
user = await async_client.x.users.retrieve_verified_followers(
id="id",
)
- assert_matches_type(PaginatedUsers, user, path=["response"])
+ assert_matches_type(UserRetrieveVerifiedFollowersResponse, user, path=["response"])
@pytest.mark.skip(reason="Mock server tests are disabled")
@parametrize
async def test_method_retrieve_verified_followers_with_all_params(self, async_client: AsyncXTwitterScraper) -> None:
user = await async_client.x.users.retrieve_verified_followers(
id="id",
+ after="after",
+ bio_contains="bioContains",
cursor="cursor",
+ has_location=True,
+ has_website=True,
+ limit=1,
+ location_contains="locationContains",
+ max_followers=0,
+ max_following=0,
+ max_statuses=0,
+ min_account_age_days=0,
+ min_followers=0,
+ min_following=0,
+ min_statuses=0,
+ mode="standard",
page_size=20,
+ username_contains="usernameContains",
+ verified_only=True,
+ verified_type="verifiedType",
)
- assert_matches_type(PaginatedUsers, user, path=["response"])
+ assert_matches_type(UserRetrieveVerifiedFollowersResponse, user, path=["response"])
@pytest.mark.skip(reason="Mock server tests are disabled")
@parametrize
@@ -1550,7 +1893,7 @@ async def test_raw_response_retrieve_verified_followers(self, async_client: Asyn
assert response.is_closed is True
assert response.http_request.headers.get("X-Stainless-Lang") == "python"
user = await response.parse()
- assert_matches_type(PaginatedUsers, user, path=["response"])
+ assert_matches_type(UserRetrieveVerifiedFollowersResponse, user, path=["response"])
@pytest.mark.skip(reason="Mock server tests are disabled")
@parametrize
@@ -1562,7 +1905,7 @@ async def test_streaming_response_retrieve_verified_followers(self, async_client
assert response.http_request.headers.get("X-Stainless-Lang") == "python"
user = await response.parse()
- assert_matches_type(PaginatedUsers, user, path=["response"])
+ assert_matches_type(UserRetrieveVerifiedFollowersResponse, user, path=["response"])
assert cast(Any, response.is_closed) is True
From 99d4b97651b4e2d753f0ff33ecb912859e60d0da Mon Sep 17 00:00:00 2001
From: "stainless-app[bot]"
<142633134+stainless-app[bot]@users.noreply.github.com>
Date: Tue, 11 Aug 2026 21:01:55 +0000
Subject: [PATCH 2/3] release: 0.9.0
---
.release-please-manifest.json | 2 +-
CHANGELOG.md | 8 ++++++++
pyproject.toml | 2 +-
src/x_twitter_scraper/_version.py | 2 +-
4 files changed, 11 insertions(+), 3 deletions(-)
diff --git a/.release-please-manifest.json b/.release-please-manifest.json
index 02f17d9..76d5538 100644
--- a/.release-please-manifest.json
+++ b/.release-please-manifest.json
@@ -1,3 +1,3 @@
{
- ".": "0.8.1"
+ ".": "0.9.0"
}
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 27ee6c4..00b3280 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,5 +1,13 @@
# Changelog
+## 0.9.0 (2026-08-11)
+
+Full Changelog: [v0.8.1...v0.9.0](https://github.com/Xquik-dev/x-twitter-scraper-python/compare/v0.8.1...v0.9.0)
+
+### Features
+
+* **api:** api update ([6001ecb](https://github.com/Xquik-dev/x-twitter-scraper-python/commit/6001ecbc6504d11d83fbebe0a3cffd83713e71bd))
+
## 0.8.1 (2026-08-11)
Full Changelog: [v0.8.0...v0.8.1](https://github.com/Xquik-dev/x-twitter-scraper-python/compare/v0.8.0...v0.8.1)
diff --git a/pyproject.toml b/pyproject.toml
index 05cf4a5..84d9b45 100644
--- a/pyproject.toml
+++ b/pyproject.toml
@@ -1,6 +1,6 @@
[project]
name = "x_twitter_scraper"
-version = "0.8.1"
+version = "0.9.0"
description = "Python library for the Xquik API. Not affiliated with X Corp."
dynamic = ["readme"]
license = "Apache-2.0"
diff --git a/src/x_twitter_scraper/_version.py b/src/x_twitter_scraper/_version.py
index a286438..cf9d3c1 100644
--- a/src/x_twitter_scraper/_version.py
+++ b/src/x_twitter_scraper/_version.py
@@ -5,4 +5,4 @@
# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
__title__ = "x_twitter_scraper"
-__version__ = "0.8.1" # x-release-please-version
+__version__ = "0.9.0" # x-release-please-version
From 79bc3d148c17bf0755219f02590313f30aac03c7 Mon Sep 17 00:00:00 2001
From: kriptoburak
Date: Wed, 12 Aug 2026 00:16:11 +0300
Subject: [PATCH 3/3] fix: load search coverage responses
---
requirements-dev.lock | 4 ++--
scripts/bootstrap | 10 +++-------
src/x_twitter_scraper/types/x/tweet_search_response.py | 7 ++++---
uv.lock | 4 ++--
4 files changed, 11 insertions(+), 14 deletions(-)
diff --git a/requirements-dev.lock b/requirements-dev.lock
index 1a87765..e1fa269 100644
--- a/requirements-dev.lock
+++ b/requirements-dev.lock
@@ -17,7 +17,7 @@ certifi==2026.6.17
# httpx
colorama==0.4.6 ; sys_platform == 'win32'
# via pytest
-coverage==7.15.2
+coverage==7.15.3
dirty-equals==0.11
distro==1.9.0
# via x-twitter-scraper
@@ -76,7 +76,7 @@ pytest-asyncio==1.4.0
pytest-xdist==3.8.0
respx==0.23.1
rich==15.0.0
-ruff==0.15.22
+ruff==0.16.1
sniffio==1.3.1
# via x-twitter-scraper
time-machine==3.2.0
diff --git a/scripts/bootstrap b/scripts/bootstrap
index 3f5de42..a50c91f 100755
--- a/scripts/bootstrap
+++ b/scripts/bootstrap
@@ -12,13 +12,9 @@ if [ -f "Brewfile" ] && [ "$(uname -s)" = "Darwin" ] && [ "${SKIP_BREW:-}" != "1
brew bundle check >/dev/null 2>&1 || {
echo -n "==> Install Homebrew dependencies? (y/N): "
read -r response
- case "$response" in
- [yY][eE][sS]|[yY])
- brew bundle
- ;;
- *)
- ;;
- esac
+ if [[ "$response" =~ ^[Yy]([Ee][Ss])?$ ]]; then
+ brew bundle
+ fi
echo
}
fi
diff --git a/src/x_twitter_scraper/types/x/tweet_search_response.py b/src/x_twitter_scraper/types/x/tweet_search_response.py
index c3e4f1d..9811695 100644
--- a/src/x_twitter_scraper/types/x/tweet_search_response.py
+++ b/src/x_twitter_scraper/types/x/tweet_search_response.py
@@ -9,6 +9,7 @@
from pydantic import Field as FieldInfo
from ..._models import BaseModel
+from ..shared.search_tweet import SearchTweet
from ..shared.paginated_tweets import PaginatedTweets
__all__ = [
@@ -89,6 +90,8 @@ class TweetSearchCoverageResponse(PaginatedTweets):
No-mode search, user Tweet, user reply, and direct reply reads use automatic coverage. Shape, filters, aliases, and billing stay compatible. Unprefixed cursors remain legacy. Follow next_cursor while has_next_page is true. An empty filtered page can still have has_next_page true.
"""
+ tweets: List[SearchTweet]
+
diagnostic: TweetSearchCoverageResponseDiagnostic
"""Coverage evidence across parallel search strategies."""
@@ -97,6 +100,4 @@ class TweetSearchCoverageResponse(PaginatedTweets):
next_cursor: Optional[Literal[""]] = None # type: ignore
-TweetSearchResponse: TypeAlias = Union["PaginatedTweets", TweetSearchCoverageResponse]
-
-from ..shared.paginated_tweets import PaginatedTweets
+TweetSearchResponse: TypeAlias = Union[PaginatedTweets, TweetSearchCoverageResponse]
diff --git a/uv.lock b/uv.lock
index b5eaaf3..38a4afe 100644
--- a/uv.lock
+++ b/uv.lock
@@ -16,7 +16,7 @@ conflicts = [[
]]
[options]
-exclude-newer = "2026-08-04T14:49:36.499926Z"
+exclude-newer = "2026-08-04T21:08:05.009269Z"
exclude-newer-span = "P7D"
[[package]]
@@ -1571,7 +1571,7 @@ wheels = [
[[package]]
name = "x-twitter-scraper"
-version = "0.8.1"
+version = "0.9.0"
source = { editable = "." }
dependencies = [
{ name = "anyio" },