diff --git a/CHANGELOG.md b/CHANGELOG.md
index 382a31d..f7eebea 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,5 +1,10 @@
# Changelog
+## v1.26.0-sdk.1
+
+- Regenerated from the public API contract (832 to 837 operations). Adds Google Play ratings, Instagram user dataset search/item/facets, and Reddit trending dataset search.
+- Reddit post and comments operations now expose `include_metrics`. The default feed mode costs 1 credit; metrics mode makes one anonymous HTML request and costs 3 credits.
+
## v1.25.0-sdk.1
- Regenerated from the public API contract (836 to 832 operations). Adds Apple Podcasts chart rankings, new releases, and related shows; App Store editorial collections; and the Apple Podcasts shows dataset family. Removes the TCDB endpoints, which no longer exist upstream.
diff --git a/crawlora/client.py b/crawlora/client.py
index 6049311..23645c4 100644
--- a/crawlora/client.py
+++ b/crawlora/client.py
@@ -20,7 +20,7 @@
from .operations import GROUPS, OPERATIONS
DEFAULT_BASE_URL = "https://api.crawlora.net/api/v1"
-VERSION = "1.25.0-sdk.1"
+VERSION = "1.26.0-sdk.1"
DEFAULT_USER_AGENT = f"crawlora-python-sdk/{VERSION}"
DEFAULT_MAX_RETRY_DELAY = 30.0
DEFAULT_RETRY_STATUSES = (408, 409, 425, 429)
diff --git a/crawlora/client.pyi b/crawlora/client.pyi
index 4678584..16731a1 100644
--- a/crawlora/client.pyi
+++ b/crawlora/client.pyi
@@ -3696,6 +3696,21 @@ ModelDatasetsHousingSearchResponse = TypedDict('ModelDatasetsHousingSearchRespon
'total': NotRequired[int],
}, total=False)
+ModelDatasetsInstagramUserFacetResponse = TypedDict('ModelDatasetsInstagramUserFacetResponse', {
+ 'dataset': NotRequired[str],
+ 'facet': NotRequired[str],
+ 'items': NotRequired[list[ModelEsInstagramUserDatasetFacetItem]],
+}, total=False)
+
+ModelDatasetsInstagramUserSearchResponse = TypedDict('ModelDatasetsInstagramUserSearchResponse', {
+ 'dataset': NotRequired[str],
+ 'items': NotRequired[list[ModelEsInstagramUserDatasetItem]],
+ 'page': NotRequired[int],
+ 'page_size': NotRequired[int],
+ 'sort': NotRequired[str],
+ 'total': NotRequired[int],
+}, total=False)
+
ModelDatasetsJobCompaniesResponse = TypedDict('ModelDatasetsJobCompaniesResponse', {
'companies': NotRequired[list[dict[str, Any]]],
'page': NotRequired[int],
@@ -3890,6 +3905,16 @@ ModelDatasetsProductHuntTrendsSearchResponse = TypedDict('ModelDatasetsProductHu
'total': NotRequired[int],
}, total=False)
+ModelDatasetsRedditTrendingSearchResponse = TypedDict('ModelDatasetsRedditTrendingSearchResponse', {
+ 'dataset': NotRequired[str],
+ 'items': NotRequired[list[ModelEsRedditTrendingEntry]],
+ 'page': NotRequired[int],
+ 'page_size': NotRequired[int],
+ 'snapshot_date': NotRequired[str],
+ 'sort': NotRequired[str],
+ 'total': NotRequired[int],
+}, total=False)
+
ModelDatasetsReviewsSearchResponse = TypedDict('ModelDatasetsReviewsSearchResponse', {
'dataset': NotRequired[str],
'items': NotRequired[list[ModelEsAppReview]],
@@ -4269,6 +4294,24 @@ ModelDatasetsHousingMarketsSearchResponseDoc = TypedDict('ModelDatasetsHousingMa
'msg': NotRequired[str],
}, total=False)
+ModelDatasetsInstagramUserResponseDoc = TypedDict('ModelDatasetsInstagramUserResponseDoc', {
+ 'code': NotRequired[int],
+ 'data': NotRequired[ModelEsInstagramUserRecord],
+ 'msg': NotRequired[str],
+}, total=False)
+
+ModelDatasetsInstagramUsersFacetResponseDoc = TypedDict('ModelDatasetsInstagramUsersFacetResponseDoc', {
+ 'code': NotRequired[int],
+ 'data': NotRequired[ModelDatasetsInstagramUserFacetResponse],
+ 'msg': NotRequired[str],
+}, total=False)
+
+ModelDatasetsInstagramUsersSearchResponseDoc = TypedDict('ModelDatasetsInstagramUsersSearchResponseDoc', {
+ 'code': NotRequired[int],
+ 'data': NotRequired[ModelDatasetsInstagramUserSearchResponse],
+ 'msg': NotRequired[str],
+}, total=False)
+
ModelDatasetsJobsCompaniesResponseDoc = TypedDict('ModelDatasetsJobsCompaniesResponseDoc', {
'code': NotRequired[int],
'data': NotRequired[ModelDatasetsJobCompaniesResponse],
@@ -4503,6 +4546,12 @@ ModelDatasetsProducthuntTrendsSearchResponseDoc = TypedDict('ModelDatasetsProduc
'msg': NotRequired[str],
}, total=False)
+ModelDatasetsRedditTrendingSearchResponseDoc = TypedDict('ModelDatasetsRedditTrendingSearchResponseDoc', {
+ 'code': NotRequired[int],
+ 'data': NotRequired[ModelDatasetsRedditTrendingSearchResponse],
+ 'msg': NotRequired[str],
+}, total=False)
+
ModelDatasetsReviewsSearchResponseDoc = TypedDict('ModelDatasetsReviewsSearchResponseDoc', {
'code': NotRequired[int],
'data': NotRequired[ModelDatasetsReviewsSearchResponse],
@@ -5212,6 +5261,7 @@ ModelEsAppRecord = TypedDict('ModelEsAppRecord', {
'currency': NotRequired[str],
'developer': NotRequired[str],
'developer_id': NotRequired[str],
+ 'discovery_sources': NotRequired[list[str]],
'first_seen': NotRequired[str],
'free': NotRequired[bool],
'icon_url': NotRequired[str],
@@ -5443,6 +5493,7 @@ ModelEsChromeExtensionRecord = TypedDict('ModelEsChromeExtensionRecord', {
'description': NotRequired[str],
'developer': NotRequired[str],
'developer_email': NotRequired[str],
+ 'discovery_sources': NotRequired[list[str]],
'first_seen': NotRequired[str],
'has_broad_host_access': NotRequired[bool],
'host_permissions': NotRequired[list[str]],
@@ -5820,6 +5871,55 @@ ModelEsHousingMarketRecord = TypedDict('ModelEsHousingMarketRecord', {
'zip_code': NotRequired[str],
}, total=False)
+ModelEsInstagramUserDatasetFacetItem = TypedDict('ModelEsInstagramUserDatasetFacetItem', {
+ 'count': NotRequired[int],
+ 'value': NotRequired[str],
+}, total=False)
+
+ModelEsInstagramUserDatasetItem = TypedDict('ModelEsInstagramUserDatasetItem', {
+ 'avatar_url': NotRequired[str],
+ 'biography': NotRequired[str],
+ 'category_name': NotRequired[str],
+ 'crawled_at': NotRequired[str],
+ 'created_at': NotRequired[str],
+ 'external_url': NotRequired[str],
+ 'follower_following_ratio': NotRequired[float],
+ 'followers': NotRequired[int],
+ 'following': NotRequired[int],
+ 'full_name': NotRequired[str],
+ 'has_bio': NotRequired[bool],
+ 'has_external_url': NotRequired[bool],
+ 'id': NotRequired[str],
+ 'is_business_account': NotRequired[bool],
+ 'is_verified': NotRequired[bool],
+ 'posts': NotRequired[int],
+ 'schema_version': NotRequired[int],
+ 'source_tier': NotRequired[str],
+ 'username': NotRequired[str],
+}, total=False)
+
+ModelEsInstagramUserRecord = TypedDict('ModelEsInstagramUserRecord', {
+ 'avatar_url': NotRequired[str],
+ 'biography': NotRequired[str],
+ 'category_name': NotRequired[str],
+ 'crawled_at': NotRequired[str],
+ 'created_at': NotRequired[str],
+ 'external_url': NotRequired[str],
+ 'follower_following_ratio': NotRequired[float],
+ 'followers': NotRequired[int],
+ 'following': NotRequired[int],
+ 'full_name': NotRequired[str],
+ 'has_bio': NotRequired[bool],
+ 'has_external_url': NotRequired[bool],
+ 'id': NotRequired[str],
+ 'is_business_account': NotRequired[bool],
+ 'is_verified': NotRequired[bool],
+ 'posts': NotRequired[int],
+ 'schema_version': NotRequired[int],
+ 'source_tier': NotRequired[str],
+ 'username': NotRequired[str],
+}, total=False)
+
ModelEsJobPostingFacets = TypedDict('ModelEsJobPostingFacets', {
'by_department': NotRequired[list[ModelEsFacetItem]],
'by_employment_type': NotRequired[list[ModelEsFacetItem]],
@@ -6190,6 +6290,21 @@ ModelEsProductHuntTrendsFacetItem = TypedDict('ModelEsProductHuntTrendsFacetItem
'value': NotRequired[str],
}, total=False)
+ModelEsRedditTrendingEntry = TypedDict('ModelEsRedditTrendingEntry', {
+ 'author': NotRequired[str],
+ 'crawled_at': NotRequired[str],
+ 'created_utc': NotRequired[int],
+ 'domain': NotRequired[str],
+ 'permalink': NotRequired[str],
+ 'post_id': NotRequired[str],
+ 'post_uid': NotRequired[str],
+ 'rank': NotRequired[int],
+ 'snapshot_date': NotRequired[str],
+ 'subreddit': NotRequired[str],
+ 'title': NotRequired[str],
+ 'url': NotRequired[str],
+}, total=False)
+
ModelEsSecCompanyFacetItem = TypedDict('ModelEsSecCompanyFacetItem', {
'count': NotRequired[int],
'value': NotRequired[str],
@@ -7898,6 +8013,7 @@ ModelGoogleplayApp = TypedDict('ModelGoogleplayApp', {
'is_available_in_play_pass': NotRequired[bool],
'max_installs': NotRequired[int],
'min_installs': NotRequired[int],
+ 'more_by_developer': NotRequired[list[ModelGoogleplayListApp]],
'offers_iap': NotRequired[bool],
'original_price': NotRequired[float],
'preregister': NotRequired[bool],
@@ -7912,6 +8028,7 @@ ModelGoogleplayApp = TypedDict('ModelGoogleplayApp', {
'score': NotRequired[float],
'score_text': NotRequired[str],
'screenshots': NotRequired[list[str]],
+ 'similar_apps': NotRequired[list[ModelGoogleplayListApp]],
'summary': NotRequired[str],
'title': NotRequired[str],
'updated': NotRequired[int],
@@ -7946,11 +8063,36 @@ ModelGoogleplayDataSafetyResult = TypedDict('ModelGoogleplayDataSafetyResult', {
'shared_data': NotRequired[list[ModelGoogleplayDataSafetyEntry]],
}, total=False)
+ModelGoogleplayDeviceRating = TypedDict('ModelGoogleplayDeviceRating', {
+ 'device': NotRequired[str],
+ 'histogram': NotRequired[dict[str, Any]],
+ 'ratings': NotRequired[int],
+ 'reviews': NotRequired[int],
+ 'score': NotRequired[float],
+ 'score_text': NotRequired[str],
+}, total=False)
+
ModelGoogleplayFeature = TypedDict('ModelGoogleplayFeature', {
'description': NotRequired[str],
'title': NotRequired[str],
}, total=False)
+ModelGoogleplayListApp = TypedDict('ModelGoogleplayListApp', {
+ 'app_id': NotRequired[str],
+ 'currency': NotRequired[str],
+ 'developer': NotRequired[str],
+ 'developer_id': NotRequired[str],
+ 'free': NotRequired[bool],
+ 'icon': NotRequired[str],
+ 'price': NotRequired[float],
+ 'price_text': NotRequired[str],
+ 'score': NotRequired[float],
+ 'score_text': NotRequired[str],
+ 'summary': NotRequired[str],
+ 'title': NotRequired[str],
+ 'url': NotRequired[str],
+}, total=False)
+
ModelGoogleplayReview = TypedDict('ModelGoogleplayReview', {
'criterias': NotRequired[list[ModelGoogleplayReviewCriteria]],
'date': NotRequired[str],
@@ -8017,6 +8159,12 @@ ModelGoogleplayPermissionsResultsResponseDoc = TypedDict('ModelGoogleplayPermiss
'msg': NotRequired[str],
}, total=False)
+ModelGoogleplayRatingsResponseDoc = TypedDict('ModelGoogleplayRatingsResponseDoc', {
+ 'code': NotRequired[int],
+ 'data': NotRequired[list[ModelGoogleplayDeviceRating]],
+ 'msg': NotRequired[str],
+}, total=False)
+
ModelGoogleplayReviewsResponseDoc = TypedDict('ModelGoogleplayReviewsResponseDoc', {
'code': NotRequired[int],
'data': NotRequired[ModelGoogleplayReviewsResult],
@@ -12611,6 +12759,7 @@ ModelRedditAuthor = TypedDict('ModelRedditAuthor', {
ModelRedditComment = TypedDict('ModelRedditComment', {
'author': NotRequired[ModelRedditAuthor],
+ 'award_count': NotRequired[int],
'body': NotRequired[str],
'created': NotRequired[str],
'created_utc': NotRequired[int],
@@ -12625,6 +12774,7 @@ ModelRedditComment = TypedDict('ModelRedditComment', {
ModelRedditCommentsResponse = TypedDict('ModelRedditCommentsResponse', {
'comments': NotRequired[list[ModelRedditComment]],
+ 'metrics_source': NotRequired[ModelRedditSourceDetail],
'post': NotRequired[ModelRedditPost],
'source': NotRequired[ModelRedditSourceDetail],
}, total=False)
@@ -12654,10 +12804,13 @@ ModelRedditPagination = TypedDict('ModelRedditPagination', {
ModelRedditPost = TypedDict('ModelRedditPost', {
'author': NotRequired[ModelRedditAuthor],
+ 'award_count': NotRequired[int],
'comment_count': NotRequired[int],
'created': NotRequired[str],
'created_utc': NotRequired[int],
'domain': NotRequired[str],
+ 'estimated_downvotes': NotRequired[int],
+ 'estimated_upvotes': NotRequired[int],
'flair': NotRequired[str],
'id': NotRequired[str],
'is_self': NotRequired[bool],
@@ -12675,9 +12828,11 @@ ModelRedditPost = TypedDict('ModelRedditPost', {
'title': NotRequired[str],
'upvote_ratio': NotRequired[float],
'url': NotRequired[str],
+ 'vote_counts_estimated': NotRequired[bool],
}, total=False)
ModelRedditPostResponse = TypedDict('ModelRedditPostResponse', {
+ 'metrics_source': NotRequired[ModelRedditSourceDetail],
'post': NotRequired[ModelRedditPost],
'source': NotRequired[ModelRedditSourceDetail],
}, total=False)
@@ -21273,6 +21428,67 @@ DatasetsHousingMarketsSearchParams = TypedDict('DatasetsHousingMarketsSearchPara
'page_size': NotRequired[int],
}, total=False)
+DatasetsInstagramUsersFacetsResponse = ModelDatasetsInstagramUsersFacetResponseDoc
+DatasetsInstagramUsersFacetsParams = TypedDict('DatasetsInstagramUsersFacetsParams', {
+ '_response_type': NotRequired[ResponseType],
+ '_timeout': NotRequired[float],
+ '_headers': NotRequired[Mapping[str, str]],
+ 'facet': Required[Literal['is_verified', 'is_business_account', 'has_bio', 'has_external_url', 'category_name', 'source_tier']],
+ 'q': NotRequired[str],
+ 'username': NotRequired[str],
+ 'category_name': NotRequired[str],
+ 'source_tier': NotRequired[str],
+ 'is_verified': NotRequired[bool],
+ 'is_business_account': NotRequired[bool],
+ 'has_bio': NotRequired[bool],
+ 'has_external_url': NotRequired[bool],
+ 'min_followers': NotRequired[int],
+ 'max_followers': NotRequired[int],
+ 'min_ratio': NotRequired[float],
+ 'max_ratio': NotRequired[float],
+ 'created_after': NotRequired[str],
+ 'created_before': NotRequired[str],
+ 'crawled_after': NotRequired[str],
+ 'crawled_before': NotRequired[str],
+ 'sort': NotRequired[Literal['relevance', 'followers_desc', 'followers_asc', 'crawled_at_desc', 'crawled_at_asc', 'created_at_desc', 'created_at_asc']],
+ 'page': NotRequired[int],
+ 'page_size': NotRequired[int],
+}, total=False)
+
+DatasetsInstagramUsersItemResponse = ModelDatasetsInstagramUserResponseDoc
+DatasetsInstagramUsersItemParams = TypedDict('DatasetsInstagramUsersItemParams', {
+ '_response_type': NotRequired[ResponseType],
+ '_timeout': NotRequired[float],
+ '_headers': NotRequired[Mapping[str, str]],
+ 'username': Required[str],
+}, total=False)
+
+DatasetsInstagramUsersSearchResponse = ModelDatasetsInstagramUsersSearchResponseDoc
+DatasetsInstagramUsersSearchParams = TypedDict('DatasetsInstagramUsersSearchParams', {
+ '_response_type': NotRequired[ResponseType],
+ '_timeout': NotRequired[float],
+ '_headers': NotRequired[Mapping[str, str]],
+ 'q': NotRequired[str],
+ 'username': NotRequired[str],
+ 'category_name': NotRequired[str],
+ 'source_tier': NotRequired[str],
+ 'is_verified': NotRequired[bool],
+ 'is_business_account': NotRequired[bool],
+ 'has_bio': NotRequired[bool],
+ 'has_external_url': NotRequired[bool],
+ 'min_followers': NotRequired[int],
+ 'max_followers': NotRequired[int],
+ 'min_ratio': NotRequired[float],
+ 'max_ratio': NotRequired[float],
+ 'created_after': NotRequired[str],
+ 'created_before': NotRequired[str],
+ 'crawled_after': NotRequired[str],
+ 'crawled_before': NotRequired[str],
+ 'sort': NotRequired[Literal['relevance', 'followers_desc', 'followers_asc', 'crawled_at_desc', 'crawled_at_asc', 'created_at_desc', 'created_at_asc']],
+ 'page': NotRequired[int],
+ 'page_size': NotRequired[int],
+}, total=False)
+
DatasetsJobsCompaniesResponse = ModelDatasetsJobsCompaniesResponseDoc
DatasetsJobsCompaniesParams = TypedDict('DatasetsJobsCompaniesParams', {
'_response_type': NotRequired[ResponseType],
@@ -21857,6 +22073,19 @@ DatasetsProducthuntTrendsSearchParams = TypedDict('DatasetsProducthuntTrendsSear
'page_size': NotRequired[int],
}, total=False)
+DatasetsRedditTrendingSearchResponse = ModelDatasetsRedditTrendingSearchResponseDoc
+DatasetsRedditTrendingSearchParams = TypedDict('DatasetsRedditTrendingSearchParams', {
+ '_response_type': NotRequired[ResponseType],
+ '_timeout': NotRequired[float],
+ '_headers': NotRequired[Mapping[str, str]],
+ 'q': NotRequired[str],
+ 'subreddit': NotRequired[str],
+ 'date': NotRequired[str],
+ 'sort': NotRequired[Literal['rank', 'date_desc']],
+ 'page': NotRequired[int],
+ 'page_size': NotRequired[int],
+}, total=False)
+
DatasetsSecCompaniesFacetsResponse = ModelDatasetsSecCompaniesFacetResponseDoc
DatasetsSecCompaniesFacetsParams = TypedDict('DatasetsSecCompaniesFacetsParams', {
'_response_type': NotRequired[ResponseType],
@@ -23220,6 +23449,7 @@ GooglePlayListParams = TypedDict('GooglePlayListParams', {
'_headers': NotRequired[Mapping[str, str]],
'collection': NotRequired[Literal['TOP_FREE', 'TOP_PAID', 'GROSSING', 'NEW_FREE', 'NEW_PAID']],
'category': NotRequired[str],
+ 'device': NotRequired[Literal['phone', 'tablet', 'tv', 'chromebook', 'watch', 'xr', 'car']],
'age': NotRequired[str],
'num': NotRequired[int],
'country': NotRequired[str],
@@ -23238,6 +23468,16 @@ GooglePlayPermissionsParams = TypedDict('GooglePlayPermissionsParams', {
'short': NotRequired[bool],
}, total=False)
+GooglePlayRatingsResponse = ModelGoogleplayRatingsResponseDoc
+GooglePlayRatingsParams = TypedDict('GooglePlayRatingsParams', {
+ '_response_type': NotRequired[ResponseType],
+ '_timeout': NotRequired[float],
+ '_headers': NotRequired[Mapping[str, str]],
+ 'app_id': Required[str],
+ 'country': NotRequired[str],
+ 'lang': NotRequired[str],
+}, total=False)
+
GooglePlayReviewsResponse = ModelGoogleplayReviewsResponseDoc
GooglePlayReviewsParams = TypedDict('GooglePlayReviewsParams', {
'_response_type': NotRequired[ResponseType],
@@ -25509,6 +25749,7 @@ RedditCommentsParams = TypedDict('RedditCommentsParams', {
'sort': NotRequired[Literal['confidence', 'top', 'new', 'controversial', 'old', 'qa']],
'limit': NotRequired[int],
'depth': NotRequired[int],
+ 'include_metrics': NotRequired[bool],
}, total=False)
RedditDomainPostsResponse = ModelRedditDomainPostsResponseDoc
@@ -25529,6 +25770,7 @@ RedditPostParams = TypedDict('RedditPostParams', {
'_timeout': NotRequired[float],
'_headers': NotRequired[Mapping[str, str]],
'id': Required[str],
+ 'include_metrics': NotRequired[bool],
}, total=False)
RedditSearchResponse = ModelRedditSearchResponseDoc
@@ -28365,6 +28607,9 @@ class DatasetsGroup:
def housing_markets_facets(self, **params: Unpack[DatasetsHousingMarketsFacetsParams]) -> DatasetsHousingMarketsFacetsResponse: ...
def housing_markets_item(self, **params: Unpack[DatasetsHousingMarketsItemParams]) -> DatasetsHousingMarketsItemResponse: ...
def housing_markets_search(self, **params: Unpack[DatasetsHousingMarketsSearchParams]) -> DatasetsHousingMarketsSearchResponse: ...
+ def instagram_users_facets(self, **params: Unpack[DatasetsInstagramUsersFacetsParams]) -> DatasetsInstagramUsersFacetsResponse: ...
+ def instagram_users_item(self, **params: Unpack[DatasetsInstagramUsersItemParams]) -> DatasetsInstagramUsersItemResponse: ...
+ def instagram_users_search(self, **params: Unpack[DatasetsInstagramUsersSearchParams]) -> DatasetsInstagramUsersSearchResponse: ...
def jobs_companies(self, **params: Unpack[DatasetsJobsCompaniesParams]) -> DatasetsJobsCompaniesResponse: ...
def jobs_company_item(self, **params: Unpack[DatasetsJobsCompanyItemParams]) -> DatasetsJobsCompanyItemResponse: ...
def jobs_facets(self, **params: Unpack[DatasetsJobsFacetsParams]) -> DatasetsJobsFacetsResponse: ...
@@ -28405,6 +28650,7 @@ class DatasetsGroup:
def producthunt_products_search(self, **params: Unpack[DatasetsProducthuntProductsSearchParams]) -> DatasetsProducthuntProductsSearchResponse: ...
def producthunt_trends_facets(self, **params: Unpack[DatasetsProducthuntTrendsFacetsParams]) -> DatasetsProducthuntTrendsFacetsResponse: ...
def producthunt_trends_search(self, **params: Unpack[DatasetsProducthuntTrendsSearchParams]) -> DatasetsProducthuntTrendsSearchResponse: ...
+ def reddit_trending_search(self, **params: Unpack[DatasetsRedditTrendingSearchParams]) -> DatasetsRedditTrendingSearchResponse: ...
def sec_companies_facets(self, **params: Unpack[DatasetsSecCompaniesFacetsParams]) -> DatasetsSecCompaniesFacetsResponse: ...
def sec_companies_financials(self, **params: Unpack[DatasetsSecCompaniesFinancialsParams]) -> DatasetsSecCompaniesFinancialsResponse: ...
def sec_companies_insider(self, **params: Unpack[DatasetsSecCompaniesInsiderParams]) -> DatasetsSecCompaniesInsiderResponse: ...
@@ -28545,6 +28791,7 @@ class GooglePlayGroup:
def developer(self, **params: Unpack[GooglePlayDeveloperParams]) -> GooglePlayDeveloperResponse: ...
def list(self, **params: Unpack[GooglePlayListParams]) -> GooglePlayListResponse: ...
def permissions(self, **params: Unpack[GooglePlayPermissionsParams]) -> GooglePlayPermissionsResponse: ...
+ def ratings(self, **params: Unpack[GooglePlayRatingsParams]) -> GooglePlayRatingsResponse: ...
def reviews(self, **params: Unpack[GooglePlayReviewsParams]) -> GooglePlayReviewsResponse: ...
def search(self, **params: Unpack[GooglePlaySearchParams]) -> GooglePlaySearchResponse: ...
def similar(self, **params: Unpack[GooglePlaySimilarParams]) -> GooglePlaySimilarResponse: ...
@@ -29295,6 +29542,9 @@ OperationId = Literal[
'datasets-housing-markets-facets',
'datasets-housing-markets-item',
'datasets-housing-markets-search',
+ 'datasets-instagram-users-facets',
+ 'datasets-instagram-users-item',
+ 'datasets-instagram-users-search',
'datasets-jobs-companies',
'datasets-jobs-company-item',
'datasets-jobs-facets',
@@ -29335,6 +29585,7 @@ OperationId = Literal[
'datasets-producthunt-products-search',
'datasets-producthunt-trends-facets',
'datasets-producthunt-trends-search',
+ 'datasets-reddit-trending-search',
'datasets-sec-companies-facets',
'datasets-sec-companies-financials',
'datasets-sec-companies-insider',
@@ -29461,6 +29712,7 @@ OperationId = Literal[
'googleplay-developer',
'googleplay-list',
'googleplay-permissions',
+ 'googleplay-ratings',
'googleplay-reviews',
'googleplay-search',
'googleplay-similar',
@@ -32114,6 +32366,42 @@ class CrawloraClient:
retry_predicate: Callable[[int, BaseException | None], bool] | None = ...,
) -> DatasetsHousingMarketsSearchResponse: ...
@overload
+ def operation(
+ self,
+ operation_id: Literal['datasets-instagram-users-facets'],
+ params: DatasetsInstagramUsersFacetsParams,
+ *,
+ response_type: ResponseType = ...,
+ timeout: float | None = ...,
+ headers: Mapping[str, str] | None = ...,
+ retries: int | None = ...,
+ retry_predicate: Callable[[int, BaseException | None], bool] | None = ...,
+ ) -> DatasetsInstagramUsersFacetsResponse: ...
+ @overload
+ def operation(
+ self,
+ operation_id: Literal['datasets-instagram-users-item'],
+ params: DatasetsInstagramUsersItemParams,
+ *,
+ response_type: ResponseType = ...,
+ timeout: float | None = ...,
+ headers: Mapping[str, str] | None = ...,
+ retries: int | None = ...,
+ retry_predicate: Callable[[int, BaseException | None], bool] | None = ...,
+ ) -> DatasetsInstagramUsersItemResponse: ...
+ @overload
+ def operation(
+ self,
+ operation_id: Literal['datasets-instagram-users-search'],
+ params: DatasetsInstagramUsersSearchParams = ...,
+ *,
+ response_type: ResponseType = ...,
+ timeout: float | None = ...,
+ headers: Mapping[str, str] | None = ...,
+ retries: int | None = ...,
+ retry_predicate: Callable[[int, BaseException | None], bool] | None = ...,
+ ) -> DatasetsInstagramUsersSearchResponse: ...
+ @overload
def operation(
self,
operation_id: Literal['datasets-jobs-companies'],
@@ -32594,6 +32882,18 @@ class CrawloraClient:
retry_predicate: Callable[[int, BaseException | None], bool] | None = ...,
) -> DatasetsProducthuntTrendsSearchResponse: ...
@overload
+ def operation(
+ self,
+ operation_id: Literal['datasets-reddit-trending-search'],
+ params: DatasetsRedditTrendingSearchParams = ...,
+ *,
+ response_type: ResponseType = ...,
+ timeout: float | None = ...,
+ headers: Mapping[str, str] | None = ...,
+ retries: int | None = ...,
+ retry_predicate: Callable[[int, BaseException | None], bool] | None = ...,
+ ) -> DatasetsRedditTrendingSearchResponse: ...
+ @overload
def operation(
self,
operation_id: Literal['datasets-sec-companies-facets'],
@@ -34106,6 +34406,18 @@ class CrawloraClient:
retry_predicate: Callable[[int, BaseException | None], bool] | None = ...,
) -> GooglePlayPermissionsResponse: ...
@overload
+ def operation(
+ self,
+ operation_id: Literal['googleplay-ratings'],
+ params: GooglePlayRatingsParams,
+ *,
+ response_type: ResponseType = ...,
+ timeout: float | None = ...,
+ headers: Mapping[str, str] | None = ...,
+ retries: int | None = ...,
+ retry_predicate: Callable[[int, BaseException | None], bool] | None = ...,
+ ) -> GooglePlayRatingsResponse: ...
+ @overload
def operation(
self,
operation_id: Literal['googleplay-reviews'],
@@ -42110,6 +42422,42 @@ class CrawloraClient:
retry_predicate: Callable[[int, BaseException | None], bool] | None = ...,
) -> DatasetsHousingMarketsSearchResponse: ...
@overload
+ def request(
+ self,
+ operation_id: Literal['datasets-instagram-users-facets'],
+ params: DatasetsInstagramUsersFacetsParams,
+ *,
+ response_type: ResponseType = ...,
+ timeout: float | None = ...,
+ headers: Mapping[str, str] | None = ...,
+ retries: int | None = ...,
+ retry_predicate: Callable[[int, BaseException | None], bool] | None = ...,
+ ) -> DatasetsInstagramUsersFacetsResponse: ...
+ @overload
+ def request(
+ self,
+ operation_id: Literal['datasets-instagram-users-item'],
+ params: DatasetsInstagramUsersItemParams,
+ *,
+ response_type: ResponseType = ...,
+ timeout: float | None = ...,
+ headers: Mapping[str, str] | None = ...,
+ retries: int | None = ...,
+ retry_predicate: Callable[[int, BaseException | None], bool] | None = ...,
+ ) -> DatasetsInstagramUsersItemResponse: ...
+ @overload
+ def request(
+ self,
+ operation_id: Literal['datasets-instagram-users-search'],
+ params: DatasetsInstagramUsersSearchParams = ...,
+ *,
+ response_type: ResponseType = ...,
+ timeout: float | None = ...,
+ headers: Mapping[str, str] | None = ...,
+ retries: int | None = ...,
+ retry_predicate: Callable[[int, BaseException | None], bool] | None = ...,
+ ) -> DatasetsInstagramUsersSearchResponse: ...
+ @overload
def request(
self,
operation_id: Literal['datasets-jobs-companies'],
@@ -42590,6 +42938,18 @@ class CrawloraClient:
retry_predicate: Callable[[int, BaseException | None], bool] | None = ...,
) -> DatasetsProducthuntTrendsSearchResponse: ...
@overload
+ def request(
+ self,
+ operation_id: Literal['datasets-reddit-trending-search'],
+ params: DatasetsRedditTrendingSearchParams = ...,
+ *,
+ response_type: ResponseType = ...,
+ timeout: float | None = ...,
+ headers: Mapping[str, str] | None = ...,
+ retries: int | None = ...,
+ retry_predicate: Callable[[int, BaseException | None], bool] | None = ...,
+ ) -> DatasetsRedditTrendingSearchResponse: ...
+ @overload
def request(
self,
operation_id: Literal['datasets-sec-companies-facets'],
@@ -44102,6 +44462,18 @@ class CrawloraClient:
retry_predicate: Callable[[int, BaseException | None], bool] | None = ...,
) -> GooglePlayPermissionsResponse: ...
@overload
+ def request(
+ self,
+ operation_id: Literal['googleplay-ratings'],
+ params: GooglePlayRatingsParams,
+ *,
+ response_type: ResponseType = ...,
+ timeout: float | None = ...,
+ headers: Mapping[str, str] | None = ...,
+ retries: int | None = ...,
+ retry_predicate: Callable[[int, BaseException | None], bool] | None = ...,
+ ) -> GooglePlayRatingsResponse: ...
+ @overload
def request(
self,
operation_id: Literal['googleplay-reviews'],
diff --git a/crawlora/operations.py b/crawlora/operations.py
index 41c3a58..5de3800 100644
--- a/crawlora/operations.py
+++ b/crawlora/operations.py
@@ -4272,6 +4272,105 @@
{'in': 'query', 'name': 'page', 'type': 'integer'},
{'in': 'query', 'name': 'page_size', 'type': 'integer'}],
'security': ['ApiKeyAuth']},
+ 'datasets-instagram-users-facets': {'bodyParam': None,
+ 'bodyRequired': False,
+ 'consumes': ['application/json'],
+ 'formParams': [],
+ 'id': 'datasets-instagram-users-facets',
+ 'method': 'GET',
+ 'paginatable': True,
+ 'path': '/datasets/instagram-users/facets',
+ 'pathParams': [],
+ 'produces': ['application/json'],
+ 'queryParams': [{'enum': ['is_verified',
+ 'is_business_account',
+ 'has_bio',
+ 'has_external_url',
+ 'category_name',
+ 'source_tier'],
+ 'in': 'query',
+ 'name': 'facet',
+ 'required': True,
+ 'type': 'string'},
+ {'in': 'query', 'name': 'q', 'type': 'string'},
+ {'in': 'query', 'name': 'username', 'type': 'string'},
+ {'in': 'query', 'name': 'category_name', 'type': 'string'},
+ {'in': 'query', 'name': 'source_tier', 'type': 'string'},
+ {'in': 'query', 'name': 'is_verified', 'type': 'boolean'},
+ {'in': 'query', 'name': 'is_business_account', 'type': 'boolean'},
+ {'in': 'query', 'name': 'has_bio', 'type': 'boolean'},
+ {'in': 'query', 'name': 'has_external_url', 'type': 'boolean'},
+ {'in': 'query', 'name': 'min_followers', 'type': 'integer'},
+ {'in': 'query', 'name': 'max_followers', 'type': 'integer'},
+ {'in': 'query', 'name': 'min_ratio', 'type': 'number'},
+ {'in': 'query', 'name': 'max_ratio', 'type': 'number'},
+ {'in': 'query', 'name': 'created_after', 'type': 'string'},
+ {'in': 'query', 'name': 'created_before', 'type': 'string'},
+ {'in': 'query', 'name': 'crawled_after', 'type': 'string'},
+ {'in': 'query', 'name': 'crawled_before', 'type': 'string'},
+ {'enum': ['relevance',
+ 'followers_desc',
+ 'followers_asc',
+ 'crawled_at_desc',
+ 'crawled_at_asc',
+ 'created_at_desc',
+ 'created_at_asc'],
+ 'in': 'query',
+ 'name': 'sort',
+ 'type': 'string'},
+ {'in': 'query', 'name': 'page', 'type': 'integer'},
+ {'in': 'query', 'name': 'page_size', 'type': 'integer'}],
+ 'security': ['ApiKeyAuth']},
+ 'datasets-instagram-users-item': {'bodyParam': None,
+ 'bodyRequired': False,
+ 'consumes': ['application/json'],
+ 'formParams': [],
+ 'id': 'datasets-instagram-users-item',
+ 'method': 'GET',
+ 'path': '/datasets/instagram-users/items/{username}',
+ 'pathParams': ['username'],
+ 'produces': ['application/json'],
+ 'queryParams': [],
+ 'security': ['ApiKeyAuth']},
+ 'datasets-instagram-users-search': {'bodyParam': None,
+ 'bodyRequired': False,
+ 'consumes': ['application/json'],
+ 'formParams': [],
+ 'id': 'datasets-instagram-users-search',
+ 'method': 'GET',
+ 'paginatable': True,
+ 'path': '/datasets/instagram-users/search',
+ 'pathParams': [],
+ 'produces': ['application/json'],
+ 'queryParams': [{'in': 'query', 'name': 'q', 'type': 'string'},
+ {'in': 'query', 'name': 'username', 'type': 'string'},
+ {'in': 'query', 'name': 'category_name', 'type': 'string'},
+ {'in': 'query', 'name': 'source_tier', 'type': 'string'},
+ {'in': 'query', 'name': 'is_verified', 'type': 'boolean'},
+ {'in': 'query', 'name': 'is_business_account', 'type': 'boolean'},
+ {'in': 'query', 'name': 'has_bio', 'type': 'boolean'},
+ {'in': 'query', 'name': 'has_external_url', 'type': 'boolean'},
+ {'in': 'query', 'name': 'min_followers', 'type': 'integer'},
+ {'in': 'query', 'name': 'max_followers', 'type': 'integer'},
+ {'in': 'query', 'name': 'min_ratio', 'type': 'number'},
+ {'in': 'query', 'name': 'max_ratio', 'type': 'number'},
+ {'in': 'query', 'name': 'created_after', 'type': 'string'},
+ {'in': 'query', 'name': 'created_before', 'type': 'string'},
+ {'in': 'query', 'name': 'crawled_after', 'type': 'string'},
+ {'in': 'query', 'name': 'crawled_before', 'type': 'string'},
+ {'enum': ['relevance',
+ 'followers_desc',
+ 'followers_asc',
+ 'crawled_at_desc',
+ 'crawled_at_asc',
+ 'created_at_desc',
+ 'created_at_asc'],
+ 'in': 'query',
+ 'name': 'sort',
+ 'type': 'string'},
+ {'in': 'query', 'name': 'page', 'type': 'integer'},
+ {'in': 'query', 'name': 'page_size', 'type': 'integer'}],
+ 'security': ['ApiKeyAuth']},
'datasets-jobs-companies': {'bodyParam': None,
'bodyRequired': False,
'consumes': ['application/json'],
@@ -5377,6 +5476,26 @@
{'in': 'query', 'name': 'page', 'type': 'integer'},
{'in': 'query', 'name': 'page_size', 'type': 'integer'}],
'security': ['ApiKeyAuth']},
+ 'datasets-reddit-trending-search': {'bodyParam': None,
+ 'bodyRequired': False,
+ 'consumes': ['application/json'],
+ 'formParams': [],
+ 'id': 'datasets-reddit-trending-search',
+ 'method': 'GET',
+ 'paginatable': True,
+ 'path': '/datasets/reddit-trending/search',
+ 'pathParams': [],
+ 'produces': ['application/json'],
+ 'queryParams': [{'in': 'query', 'name': 'q', 'type': 'string'},
+ {'in': 'query', 'name': 'subreddit', 'type': 'string'},
+ {'in': 'query', 'name': 'date', 'type': 'string'},
+ {'enum': ['rank', 'date_desc'],
+ 'in': 'query',
+ 'name': 'sort',
+ 'type': 'string'},
+ {'in': 'query', 'name': 'page', 'type': 'integer'},
+ {'in': 'query', 'name': 'page_size', 'type': 'integer'}],
+ 'security': ['ApiKeyAuth']},
'datasets-sec-companies-facets': {'bodyParam': None,
'bodyRequired': False,
'consumes': ['application/json'],
@@ -7856,6 +7975,10 @@
'name': 'collection',
'type': 'string'},
{'in': 'query', 'name': 'category', 'type': 'string'},
+ {'enum': ['phone', 'tablet', 'tv', 'chromebook', 'watch', 'xr', 'car'],
+ 'in': 'query',
+ 'name': 'device',
+ 'type': 'string'},
{'in': 'query', 'name': 'age', 'type': 'string'},
{'in': 'query', 'name': 'num', 'type': 'integer'},
{'in': 'query', 'name': 'country', 'type': 'string'},
@@ -7876,6 +7999,19 @@
{'in': 'query', 'name': 'lang', 'type': 'string'},
{'in': 'query', 'name': 'short', 'type': 'boolean'}],
'security': ['ApiKeyAuth']},
+ 'googleplay-ratings': {'bodyParam': None,
+ 'bodyRequired': False,
+ 'consumes': ['application/json'],
+ 'formParams': [],
+ 'id': 'googleplay-ratings',
+ 'method': 'GET',
+ 'path': '/googleplay/ratings',
+ 'pathParams': [],
+ 'produces': ['application/json'],
+ 'queryParams': [{'in': 'query', 'name': 'app_id', 'required': True, 'type': 'string'},
+ {'in': 'query', 'name': 'country', 'type': 'string'},
+ {'in': 'query', 'name': 'lang', 'type': 'string'}],
+ 'security': ['ApiKeyAuth']},
'googleplay-reviews': {'bodyParam': None,
'bodyRequired': False,
'consumes': ['application/json'],
@@ -11219,7 +11355,8 @@
'name': 'sort',
'type': 'string'},
{'in': 'query', 'name': 'limit', 'type': 'integer'},
- {'in': 'query', 'name': 'depth', 'type': 'integer'}],
+ {'in': 'query', 'name': 'depth', 'type': 'integer'},
+ {'in': 'query', 'name': 'include_metrics', 'type': 'boolean'}],
'security': ['ApiKeyAuth']},
'reddit-domain-posts': {'bodyParam': None,
'bodyRequired': False,
@@ -11250,7 +11387,7 @@
'path': '/reddit/post/{id}',
'pathParams': ['id'],
'produces': ['application/json'],
- 'queryParams': [],
+ 'queryParams': [{'in': 'query', 'name': 'include_metrics', 'type': 'boolean'}],
'security': ['ApiKeyAuth']},
'reddit-search': {'bodyParam': None,
'bodyRequired': False,
@@ -15227,6 +15364,9 @@
'housing_markets_facets': 'datasets-housing-markets-facets',
'housing_markets_item': 'datasets-housing-markets-item',
'housing_markets_search': 'datasets-housing-markets-search',
+ 'instagram_users_facets': 'datasets-instagram-users-facets',
+ 'instagram_users_item': 'datasets-instagram-users-item',
+ 'instagram_users_search': 'datasets-instagram-users-search',
'jobs_companies': 'datasets-jobs-companies',
'jobs_company_item': 'datasets-jobs-company-item',
'jobs_facets': 'datasets-jobs-facets',
@@ -15268,6 +15408,7 @@
'producthunt_products_search': 'datasets-producthunt-products-search',
'producthunt_trends_facets': 'datasets-producthunt-trends-facets',
'producthunt_trends_search': 'datasets-producthunt-trends-search',
+ 'reddit_trending_search': 'datasets-reddit-trending-search',
'sec_companies_facets': 'datasets-sec-companies-facets',
'sec_companies_financials': 'datasets-sec-companies-financials',
'sec_companies_insider': 'datasets-sec-companies-insider',
@@ -15390,6 +15531,7 @@
'developer': 'googleplay-developer',
'list': 'googleplay-list',
'permissions': 'googleplay-permissions',
+ 'ratings': 'googleplay-ratings',
'reviews': 'googleplay-reviews',
'search': 'googleplay-search',
'similar': 'googleplay-similar',
@@ -15879,7 +16021,7 @@
'video': 'youtube-video'},
'zillow': {'autocomplete': 'zillow-autocomplete', 'property': 'zillow-property', 'search': 'zillow-search'}}
-OPERATION_COUNT = 832
+OPERATION_COUNT = 837
class OperationId:
AIRBNB_HOST = 'airbnb-host'
@@ -16047,6 +16189,9 @@ class OperationId:
DATASETS_HOUSING_MARKETS_FACETS = 'datasets-housing-markets-facets'
DATASETS_HOUSING_MARKETS_ITEM = 'datasets-housing-markets-item'
DATASETS_HOUSING_MARKETS_SEARCH = 'datasets-housing-markets-search'
+ DATASETS_INSTAGRAM_USERS_FACETS = 'datasets-instagram-users-facets'
+ DATASETS_INSTAGRAM_USERS_ITEM = 'datasets-instagram-users-item'
+ DATASETS_INSTAGRAM_USERS_SEARCH = 'datasets-instagram-users-search'
DATASETS_JOBS_COMPANIES = 'datasets-jobs-companies'
DATASETS_JOBS_COMPANY_ITEM = 'datasets-jobs-company-item'
DATASETS_JOBS_FACETS = 'datasets-jobs-facets'
@@ -16088,6 +16233,7 @@ class OperationId:
DATASETS_PRODUCTHUNT_PRODUCTS_SEARCH = 'datasets-producthunt-products-search'
DATASETS_PRODUCTHUNT_TRENDS_FACETS = 'datasets-producthunt-trends-facets'
DATASETS_PRODUCTHUNT_TRENDS_SEARCH = 'datasets-producthunt-trends-search'
+ DATASETS_REDDIT_TRENDING_SEARCH = 'datasets-reddit-trending-search'
DATASETS_SEC_COMPANIES_FACETS = 'datasets-sec-companies-facets'
DATASETS_SEC_COMPANIES_FINANCIALS = 'datasets-sec-companies-financials'
DATASETS_SEC_COMPANIES_INSIDER = 'datasets-sec-companies-insider'
@@ -16198,6 +16344,7 @@ class OperationId:
GOOGLE_PLAY_DEVELOPER = 'googleplay-developer'
GOOGLE_PLAY_LIST = 'googleplay-list'
GOOGLE_PLAY_PERMISSIONS = 'googleplay-permissions'
+ GOOGLE_PLAY_RATINGS = 'googleplay-ratings'
GOOGLE_PLAY_REVIEWS = 'googleplay-reviews'
GOOGLE_PLAY_SEARCH = 'googleplay-search'
GOOGLE_PLAY_SIMILAR = 'googleplay-similar'
diff --git a/docs/operations.md b/docs/operations.md
index 6823540..3c75c8d 100644
--- a/docs/operations.md
+++ b/docs/operations.md
@@ -2,7 +2,7 @@
Generated from `openapi/public.json`. Deprecated, admin, and internal operations are excluded from this SDK contract.
-Total operations: `832`
+Total operations: `837`
| Group | SDK method | Operation ID | HTTP | Params | Auth | Response | Notes |
| --- | --- | --- | --- | --- | --- | --- | --- |
@@ -177,6 +177,9 @@ Total operations: `832`
| datasets | `datasets.housing_markets_facets` | `datasets-housing-markets-facets` | `GET /datasets/housing-markets/facets` | `facet` (query Literal['region_type', 'state_code', 'property_type', 'parent_metro', 'parent_metro_code', 'income_vintage', 'is_latest', 'period_begin'] required)
`q` (query str)
`region_type` (query Literal['national', 'metro', 'county', 'city', 'zip'])
`state_code` (query str)
`property_type` (query str)
`parent_metro_code` (query str)
`zip_code` (query str)
`period` (query str)
`latest` (query bool)
`min_median_sale_price` (query float)
`max_median_sale_price` (query float)
`min_median_list_price` (query float)
`max_median_list_price` (query float)
`min_price_to_income` (query float)
`max_price_to_income` (query float)
`min_salary_to_buy` (query int)
`max_salary_to_buy` (query int)
`min_median_dom` (query float)
`max_median_dom` (query float)
`min_inventory` (query int)
`max_inventory` (query int)
`min_homes_sold` (query int) | `ApiKeyAuth` | `DatasetsHousingMarketsFacetsResponse` | |
| datasets | `datasets.housing_markets_item` | `datasets-housing-markets-item` | `GET /datasets/housing-markets/items/{region_type}/{table_id}` | `region_type` (path Literal['national', 'metro', 'county', 'city', 'zip'] required)
`table_id` (path int required)
`period` (query str)
`property_type` (query str)
`history` (query bool) | `ApiKeyAuth` | `DatasetsHousingMarketsItemResponse` | |
| datasets | `datasets.housing_markets_search` | `datasets-housing-markets-search` | `GET /datasets/housing-markets/search` | `q` (query str)
`region_type` (query Literal['national', 'metro', 'county', 'city', 'zip'])
`state_code` (query str)
`property_type` (query str)
`parent_metro_code` (query str)
`zip_code` (query str)
`period` (query str)
`latest` (query bool)
`min_median_sale_price` (query float)
`max_median_sale_price` (query float)
`min_median_list_price` (query float)
`max_median_list_price` (query float)
`min_price_to_income` (query float)
`max_price_to_income` (query float)
`min_salary_to_buy` (query int)
`max_salary_to_buy` (query int)
`min_median_dom` (query float)
`max_median_dom` (query float)
`min_inventory` (query int)
`max_inventory` (query int)
`min_homes_sold` (query int)
`sort` (query Literal['relevance', 'price_desc', 'price_asc', 'list_price_desc', 'list_price_asc', 'price_to_income_desc', 'price_to_income_asc', 'salary_to_buy_desc', 'salary_to_buy_asc', 'dom_asc', 'dom_desc', 'inventory_desc', 'homes_sold_desc', 'period_desc'])
`page` (query int)
`page_size` (query int) | `ApiKeyAuth` | `DatasetsHousingMarketsSearchResponse` | |
+| datasets | `datasets.instagram_users_facets` | `datasets-instagram-users-facets` | `GET /datasets/instagram-users/facets` | `facet` (query Literal['is_verified', 'is_business_account', 'has_bio', 'has_external_url', 'category_name', 'source_tier'] required)
`q` (query str)
`username` (query str)
`category_name` (query str)
`source_tier` (query str)
`is_verified` (query bool)
`is_business_account` (query bool)
`has_bio` (query bool)
`has_external_url` (query bool)
`min_followers` (query int)
`max_followers` (query int)
`min_ratio` (query float)
`max_ratio` (query float)
`created_after` (query str)
`created_before` (query str)
`crawled_after` (query str)
`crawled_before` (query str)
`sort` (query Literal['relevance', 'followers_desc', 'followers_asc', 'crawled_at_desc', 'crawled_at_asc', 'created_at_desc', 'created_at_asc'])
`page` (query int)
`page_size` (query int) | `ApiKeyAuth` | `DatasetsInstagramUsersFacetsResponse` | |
+| datasets | `datasets.instagram_users_item` | `datasets-instagram-users-item` | `GET /datasets/instagram-users/items/{username}` | `username` (path str required) | `ApiKeyAuth` | `DatasetsInstagramUsersItemResponse` | |
+| datasets | `datasets.instagram_users_search` | `datasets-instagram-users-search` | `GET /datasets/instagram-users/search` | `q` (query str)
`username` (query str)
`category_name` (query str)
`source_tier` (query str)
`is_verified` (query bool)
`is_business_account` (query bool)
`has_bio` (query bool)
`has_external_url` (query bool)
`min_followers` (query int)
`max_followers` (query int)
`min_ratio` (query float)
`max_ratio` (query float)
`created_after` (query str)
`created_before` (query str)
`crawled_after` (query str)
`crawled_before` (query str)
`sort` (query Literal['relevance', 'followers_desc', 'followers_asc', 'crawled_at_desc', 'crawled_at_asc', 'created_at_desc', 'created_at_asc'])
`page` (query int)
`page_size` (query int) | `ApiKeyAuth` | `DatasetsInstagramUsersSearchResponse` | |
| datasets | `datasets.jobs_companies` | `datasets-jobs-companies` | `GET /datasets/jobs/companies` | `q` (query str)
`provider` (query Literal['greenhouse', 'lever', 'ashby', 'workday', 'smartrecruiters', 'workable', 'recruitee', 'rippling', 'personio', 'teamtailor', 'oracle', 'ukg', 'icims', 'eightfold', 'gem', 'pinpoint'])
`status` (query Literal['active', 'empty', 'gone', 'blocked', 'pending', 'invalid'])
`min_open_roles` (query int)
`sort` (query Literal['open_desc', 'company_asc', 'crawled_desc'])
`page` (query int)
`page_size` (query int) | `ApiKeyAuth` | `DatasetsJobsCompaniesResponse` | |
| datasets | `datasets.jobs_company_item` | `datasets-jobs-company-item` | `GET /datasets/jobs/companies/{id}` | `id` (path str required) | `ApiKeyAuth` | `DatasetsJobsCompanyItemResponse` | |
| datasets | `datasets.jobs_facets` | `datasets-jobs-facets` | `GET /datasets/jobs/facets` | `size` (query int) | `ApiKeyAuth` | `DatasetsJobsFacetsResponse` | |
@@ -217,6 +220,7 @@ Total operations: `832`
| datasets | `datasets.producthunt_products_search` | `datasets-producthunt-products-search` | `GET /datasets/producthunt-products/search` | `q` (query str)
`topic` (query str)
`maker` (query str)
`launched_after` (query str)
`launched_before` (query str)
`min_votes` (query int)
`min_rating` (query float)
`pricing_type` (query str)
`has_website` (query bool)
`is_online` (query bool)
`sort` (query Literal['relevance', 'votes_desc', 'launched_desc', 'launched_asc', 'rating_desc', 'best_rank_asc'])
`page` (query int)
`page_size` (query int) | `ApiKeyAuth` | `DatasetsProducthuntProductsSearchResponse` | |
| datasets | `datasets.producthunt_trends_facets` | `datasets-producthunt-trends-facets` | `GET /datasets/producthunt-trends/facets` | `facet` (query Literal['topic', 'launch_year'] required)
`group_by` (query Literal['topic_month', 'topic_year', 'topic'])
`topic` (query str)
`launched_after` (query str)
`launched_before` (query str)
`min_votes` (query int)
`min_launches` (query int) | `ApiKeyAuth` | `DatasetsProducthuntTrendsFacetsResponse` | |
| datasets | `datasets.producthunt_trends_search` | `datasets-producthunt-trends-search` | `GET /datasets/producthunt-trends/search` | `group_by` (query Literal['topic_month', 'topic_year', 'topic'])
`topic` (query str)
`launched_after` (query str)
`launched_before` (query str)
`min_votes` (query int)
`min_launches` (query int)
`sort` (query Literal['period_desc', 'period_asc', 'launch_count_desc', 'sum_votes_desc'])
`page` (query int)
`page_size` (query int) | `ApiKeyAuth` | `DatasetsProducthuntTrendsSearchResponse` | |
+| datasets | `datasets.reddit_trending_search` | `datasets-reddit-trending-search` | `GET /datasets/reddit-trending/search` | `q` (query str)
`subreddit` (query str)
`date` (query str)
`sort` (query Literal['rank', 'date_desc'])
`page` (query int)
`page_size` (query int) | `ApiKeyAuth` | `DatasetsRedditTrendingSearchResponse` | |
| datasets | `datasets.sec_companies_facets` | `datasets-sec-companies-facets` | `GET /datasets/sec-companies/facets` | `facet` (query Literal['sic', 'sic_description', 'exchange', 'state_of_incorporation', 'entity_type', 'reporting_currency', 'revenue_band', 'forms_filed'] required)
`q` (query str)
`ticker` (query str)
`sic` (query str)
`exchange` (query str)
`state_of_incorporation` (query str)
`entity_type` (query str)
`reporting_currency` (query str)
`has_financials` (query bool)
`min_revenue` (query float)
`form_filed` (query str) | `ApiKeyAuth` | `DatasetsSecCompaniesFacetsResponse` | |
| datasets | `datasets.sec_companies_financials` | `datasets-sec-companies-financials` | `GET /datasets/sec-companies/financials/{cik}` | `cik` (path str required)
`statement` (query Literal['income', 'balance', 'cash_flow'])
`period` (query Literal['annual', 'quarterly'])
`from` (query int)
`to` (query int)
`limit` (query int) | `ApiKeyAuth` | `DatasetsSecCompaniesFinancialsResponse` | |
| datasets | `datasets.sec_companies_insider` | `datasets-sec-companies-insider` | `GET /datasets/sec-companies/insider/{cik}` | `cik` (path str required)
`from` (query str)
`to` (query str)
`code` (query str)
`limit` (query int) | `ApiKeyAuth` | `DatasetsSecCompaniesInsiderResponse` | |
@@ -339,8 +343,9 @@ Total operations: `832`
| google_play | `google_play.categories` | `googleplay-categories` | `GET /googleplay/categories` | `country` (query str)
`lang` (query str) | `ApiKeyAuth` | `GooglePlayCategoriesResponse` | |
| google_play | `google_play.datasafety` | `googleplay-datasafety` | `GET /googleplay/datasafety` | `app_id` (query str required)
`lang` (query str) | `ApiKeyAuth` | `GooglePlayDatasafetyResponse` | |
| google_play | `google_play.developer` | `googleplay-developer` | `GET /googleplay/developer/{dev_id}` | `dev_id` (path str required)
`num` (query int)
`country` (query str)
`lang` (query str)
`full_detail` (query bool) | `ApiKeyAuth` | `GooglePlayDeveloperResponse` | |
-| google_play | `google_play.list` | `googleplay-list` | `GET /googleplay/list` | `collection` (query Literal['TOP_FREE', 'TOP_PAID', 'GROSSING', 'NEW_FREE', 'NEW_PAID'])
`category` (query str)
`age` (query str)
`num` (query int)
`country` (query str)
`lang` (query str)
`full_detail` (query bool) | `ApiKeyAuth` | `GooglePlayListResponse` | |
+| google_play | `google_play.list` | `googleplay-list` | `GET /googleplay/list` | `collection` (query Literal['TOP_FREE', 'TOP_PAID', 'GROSSING', 'NEW_FREE', 'NEW_PAID'])
`category` (query str)
`device` (query Literal['phone', 'tablet', 'tv', 'chromebook', 'watch', 'xr', 'car'])
`age` (query str)
`num` (query int)
`country` (query str)
`lang` (query str)
`full_detail` (query bool) | `ApiKeyAuth` | `GooglePlayListResponse` | |
| google_play | `google_play.permissions` | `googleplay-permissions` | `GET /googleplay/permissions` | `app_id` (query str required)
`country` (query str)
`lang` (query str)
`short` (query bool) | `ApiKeyAuth` | `GooglePlayPermissionsResponse` | |
+| google_play | `google_play.ratings` | `googleplay-ratings` | `GET /googleplay/ratings` | `app_id` (query str required)
`country` (query str)
`lang` (query str) | `ApiKeyAuth` | `GooglePlayRatingsResponse` | |
| google_play | `google_play.reviews` | `googleplay-reviews` | `GET /googleplay/reviews` | `app_id` (query str required)
`sort` (query Literal['helpfulness', 'newest', 'rating'])
`num` (query int)
`country` (query str)
`lang` (query str)
`paginate` (query bool)
`next_pagination_token` (query str) | `ApiKeyAuth` | `GooglePlayReviewsResponse` | |
| google_play | `google_play.search` | `googleplay-search` | `GET /googleplay/search` | `term` (query str required)
`num` (query int)
`country` (query str)
`lang` (query str)
`full_detail` (query bool)
`price` (query Literal['all', 'free', 'paid']) | `ApiKeyAuth` | `GooglePlaySearchResponse` | |
| google_play | `google_play.similar` | `googleplay-similar` | `GET /googleplay/similar` | `app_id` (query str required)
`num` (query int)
`country` (query str)
`lang` (query str)
`full_detail` (query bool) | `ApiKeyAuth` | `GooglePlaySimilarResponse` | |
@@ -571,9 +576,9 @@ Total operations: `832`
| product_hunt | `product_hunt.makers` | `producthunt-makers` | `GET /producthunt/product/{id}/makers` | `id` (path str required)
`cursor` (query str) | `ApiKeyAuth` | `ProductHuntMakersResponse` | |
| product_hunt | `product_hunt.reviews` | `producthunt-reviews` | `GET /producthunt/product/{id}/reviews` | `id` (path str required) | `ApiKeyAuth` | `ProductHuntReviewsResponse` | |
| product_hunt | `product_hunt.search` | `producthunt-search` | `GET /producthunt/search` | `query` (query str required)
`type` (query Literal['product', 'user', 'launch'])
`page` (query int)
`featured` (query bool)
`topics` (query str) | `ApiKeyAuth` | `ProductHuntSearchResponse` | |
-| reddit | `reddit.comments` | `reddit-comments` | `GET /reddit/comments/{id}` | `id` (path str required)
`sort` (query Literal['confidence', 'top', 'new', 'controversial', 'old', 'qa'])
`limit` (query int)
`depth` (query int) | `ApiKeyAuth` | `RedditCommentsResponse` | |
+| reddit | `reddit.comments` | `reddit-comments` | `GET /reddit/comments/{id}` | `id` (path str required)
`sort` (query Literal['confidence', 'top', 'new', 'controversial', 'old', 'qa'])
`limit` (query int)
`depth` (query int)
`include_metrics` (query bool) | `ApiKeyAuth` | `RedditCommentsResponse` | |
| reddit | `reddit.domain_posts` | `reddit-domain-posts` | `GET /reddit/domain/{domain}/posts` | `domain` (path str required)
`sort` (query Literal['hot', 'new', 'top', 'rising'])
`time` (query Literal['hour', 'day', 'week', 'month', 'year', 'all'])
`limit` (query int)
`after` (query str) | `ApiKeyAuth` | `RedditDomainPostsResponse` | |
-| reddit | `reddit.post` | `reddit-post` | `GET /reddit/post/{id}` | `id` (path str required) | `ApiKeyAuth` | `RedditPostResponse` | |
+| reddit | `reddit.post` | `reddit-post` | `GET /reddit/post/{id}` | `id` (path str required)
`include_metrics` (query bool) | `ApiKeyAuth` | `RedditPostResponse` | |
| reddit | `reddit.search` | `reddit-search` | `GET /reddit/search` | `q` (query str required)
`subreddit` (query str)
`sort` (query Literal['relevance', 'hot', 'new', 'top', 'comments'])
`time` (query Literal['hour', 'day', 'week', 'month', 'year', 'all'])
`limit` (query int)
`after` (query str) | `ApiKeyAuth` | `RedditSearchResponse` | |
| reddit | `reddit.subreddit_about` | `reddit-subreddit-about` | `GET /reddit/subreddit/{subreddit}/about` | `subreddit` (path str required)
`limit` (query int) | `ApiKeyAuth` | `RedditSubredditAboutResponse` | |
| reddit | `reddit.subreddit_comments` | `reddit-subreddit-comments` | `GET /reddit/subreddit/{subreddit}/comments` | `subreddit` (path str required)
`limit` (query int)
`after` (query str) | `ApiKeyAuth` | `RedditSubredditCommentsResponse` | |
diff --git a/docs/recipes.md b/docs/recipes.md
index f026358..75f167c 100644
--- a/docs/recipes.md
+++ b/docs/recipes.md
@@ -36,9 +36,14 @@ Newer platforms are grouped like every other endpoint:
```python
posts = crawlora.reddit.search(q="python", subreddit="programming")
+post_with_metrics = crawlora.reddit.post(id="1v8hy3q", include_metrics=True)
+comments_with_metrics = crawlora.reddit.comments(id="1v8hy3q", include_metrics=True, limit=25)
brand = crawlora.brand.retrieve(domain="stripe.com")
```
+Omit `include_metrics` for the 1-credit feed mode. Set it to `True` for the
+3-credit anonymous HTML mode with public post and comment engagement metrics.
+
## Threads Public Lookups
```python
diff --git a/openapi/public.json b/openapi/public.json
index 4d16f58..b6ca113 100644
--- a/openapi/public.json
+++ b/openapi/public.json
@@ -11878,6 +11878,49 @@
},
"type": "object"
},
+ "datasets.InstagramUserFacetResponse": {
+ "properties": {
+ "dataset": {
+ "type": "string"
+ },
+ "facet": {
+ "type": "string"
+ },
+ "items": {
+ "items": {
+ "$ref": "#/definitions/es.InstagramUserDatasetFacetItem"
+ },
+ "type": "array"
+ }
+ },
+ "type": "object"
+ },
+ "datasets.InstagramUserSearchResponse": {
+ "properties": {
+ "dataset": {
+ "type": "string"
+ },
+ "items": {
+ "items": {
+ "$ref": "#/definitions/es.InstagramUserDatasetItem"
+ },
+ "type": "array"
+ },
+ "page": {
+ "type": "integer"
+ },
+ "page_size": {
+ "type": "integer"
+ },
+ "sort": {
+ "type": "string"
+ },
+ "total": {
+ "type": "integer"
+ }
+ },
+ "type": "object"
+ },
"datasets.JobCompaniesResponse": {
"properties": {
"companies": {
@@ -12433,6 +12476,35 @@
},
"type": "object"
},
+ "datasets.RedditTrendingSearchResponse": {
+ "properties": {
+ "dataset": {
+ "type": "string"
+ },
+ "items": {
+ "items": {
+ "$ref": "#/definitions/es.RedditTrendingEntry"
+ },
+ "type": "array"
+ },
+ "page": {
+ "type": "integer"
+ },
+ "page_size": {
+ "type": "integer"
+ },
+ "snapshot_date": {
+ "type": "string"
+ },
+ "sort": {
+ "type": "string"
+ },
+ "total": {
+ "type": "integer"
+ }
+ },
+ "type": "object"
+ },
"datasets.ReviewsSearchResponse": {
"properties": {
"dataset": {
@@ -13480,6 +13552,54 @@
},
"type": "object"
},
+ "datasets.instagramUserResponseDoc": {
+ "properties": {
+ "code": {
+ "example": 200,
+ "type": "integer"
+ },
+ "data": {
+ "$ref": "#/definitions/es.InstagramUserRecord"
+ },
+ "msg": {
+ "example": "OK",
+ "type": "string"
+ }
+ },
+ "type": "object"
+ },
+ "datasets.instagramUsersFacetResponseDoc": {
+ "properties": {
+ "code": {
+ "example": 200,
+ "type": "integer"
+ },
+ "data": {
+ "$ref": "#/definitions/datasets.InstagramUserFacetResponse"
+ },
+ "msg": {
+ "example": "OK",
+ "type": "string"
+ }
+ },
+ "type": "object"
+ },
+ "datasets.instagramUsersSearchResponseDoc": {
+ "properties": {
+ "code": {
+ "example": 200,
+ "type": "integer"
+ },
+ "data": {
+ "$ref": "#/definitions/datasets.InstagramUserSearchResponse"
+ },
+ "msg": {
+ "example": "OK",
+ "type": "string"
+ }
+ },
+ "type": "object"
+ },
"datasets.jobsCompaniesResponseDoc": {
"properties": {
"code": {
@@ -14105,6 +14225,22 @@
},
"type": "object"
},
+ "datasets.redditTrendingSearchResponseDoc": {
+ "properties": {
+ "code": {
+ "example": 200,
+ "type": "integer"
+ },
+ "data": {
+ "$ref": "#/definitions/datasets.RedditTrendingSearchResponse"
+ },
+ "msg": {
+ "example": "OK",
+ "type": "string"
+ }
+ },
+ "type": "object"
+ },
"datasets.reviewsSearchResponseDoc": {
"properties": {
"code": {
@@ -16317,6 +16453,13 @@
"developer_id": {
"type": "string"
},
+ "discovery_sources": {
+ "description": "DiscoverySources lists the public catalogs that supplied this app ID.",
+ "items": {
+ "type": "string"
+ },
+ "type": "array"
+ },
"first_seen": {
"type": "string"
},
@@ -16336,7 +16479,7 @@
"type": "string"
},
"platforms": {
- "description": "Platforms is the set of Apple device platforms this app is confirmed on,\nusing Apple's own appPlatforms vocabulary: phone, pad, mac, tv, watch,\nvision. Only ever set for Store \"ios\" (Apple's App Store ecosystem);\nabsent/empty on existing docs means \"iPhone catalog, platform not yet\nclassified\" rather than \"phone-only\" — do not treat it as authoritative\nuntil backfilled. Not used for Android.",
+ "description": "Platforms is the set of store-specific device platforms this app is\nconfirmed on. iOS uses Apple's appPlatforms vocabulary (phone, pad, mac,\ntv, watch, vision). Android uses Google Play device-tab/source values\n(phone, tablet, tv, chromebook, watch, xr, car, windows). Empty means the\nrecord has not been classified by platform yet.",
"items": {
"type": "string"
},
@@ -17035,6 +17178,13 @@
"developer_email": {
"type": "string"
},
+ "discovery_sources": {
+ "description": "DiscoverySources lists the public catalogs that supplied this extension ID.",
+ "items": {
+ "type": "string"
+ },
+ "type": "array"
+ },
"first_seen": {
"type": "string"
},
@@ -18248,6 +18398,141 @@
},
"type": "object"
},
+ "es.InstagramUserDatasetFacetItem": {
+ "properties": {
+ "count": {
+ "type": "integer"
+ },
+ "value": {
+ "type": "string"
+ }
+ },
+ "type": "object"
+ },
+ "es.InstagramUserDatasetItem": {
+ "properties": {
+ "avatar_url": {
+ "type": "string"
+ },
+ "biography": {
+ "type": "string"
+ },
+ "category_name": {
+ "type": "string"
+ },
+ "crawled_at": {
+ "type": "string"
+ },
+ "created_at": {
+ "type": "string"
+ },
+ "external_url": {
+ "type": "string"
+ },
+ "follower_following_ratio": {
+ "type": "number"
+ },
+ "followers": {
+ "type": "integer"
+ },
+ "following": {
+ "type": "integer"
+ },
+ "full_name": {
+ "type": "string"
+ },
+ "has_bio": {
+ "type": "boolean"
+ },
+ "has_external_url": {
+ "type": "boolean"
+ },
+ "id": {
+ "type": "string"
+ },
+ "is_business_account": {
+ "type": "boolean"
+ },
+ "is_verified": {
+ "type": "boolean"
+ },
+ "posts": {
+ "type": "integer"
+ },
+ "schema_version": {
+ "type": "integer"
+ },
+ "source_tier": {
+ "type": "string"
+ },
+ "username": {
+ "type": "string"
+ }
+ },
+ "type": "object"
+ },
+ "es.InstagramUserRecord": {
+ "properties": {
+ "avatar_url": {
+ "type": "string"
+ },
+ "biography": {
+ "type": "string"
+ },
+ "category_name": {
+ "type": "string"
+ },
+ "crawled_at": {
+ "type": "string"
+ },
+ "created_at": {
+ "type": "string"
+ },
+ "external_url": {
+ "type": "string"
+ },
+ "follower_following_ratio": {
+ "type": "number"
+ },
+ "followers": {
+ "type": "integer"
+ },
+ "following": {
+ "type": "integer"
+ },
+ "full_name": {
+ "type": "string"
+ },
+ "has_bio": {
+ "type": "boolean"
+ },
+ "has_external_url": {
+ "type": "boolean"
+ },
+ "id": {
+ "type": "string"
+ },
+ "is_business_account": {
+ "type": "boolean"
+ },
+ "is_verified": {
+ "type": "boolean"
+ },
+ "posts": {
+ "type": "integer"
+ },
+ "schema_version": {
+ "type": "integer"
+ },
+ "source_tier": {
+ "type": "string"
+ },
+ "username": {
+ "type": "string"
+ }
+ },
+ "type": "object"
+ },
"es.JobPostingFacets": {
"properties": {
"by_department": {
@@ -19374,6 +19659,47 @@
},
"type": "object"
},
+ "es.RedditTrendingEntry": {
+ "properties": {
+ "author": {
+ "type": "string"
+ },
+ "crawled_at": {
+ "type": "string"
+ },
+ "created_utc": {
+ "type": "integer"
+ },
+ "domain": {
+ "type": "string"
+ },
+ "permalink": {
+ "type": "string"
+ },
+ "post_id": {
+ "type": "string"
+ },
+ "post_uid": {
+ "type": "string"
+ },
+ "rank": {
+ "type": "integer"
+ },
+ "snapshot_date": {
+ "type": "string"
+ },
+ "subreddit": {
+ "type": "string"
+ },
+ "title": {
+ "type": "string"
+ },
+ "url": {
+ "type": "string"
+ }
+ },
+ "type": "object"
+ },
"es.SecCompanyFacetItem": {
"properties": {
"count": {
@@ -24750,6 +25076,12 @@
"example": 100000000,
"type": "integer"
},
+ "more_by_developer": {
+ "items": {
+ "$ref": "#/definitions/googleplay.ListApp"
+ },
+ "type": "array"
+ },
"offers_iap": {
"example": true,
"type": "boolean"
@@ -24812,6 +25144,12 @@
},
"type": "array"
},
+ "similar_apps": {
+ "items": {
+ "$ref": "#/definitions/googleplay.ListApp"
+ },
+ "type": "array"
+ },
"summary": {
"example": "The official app by OpenAI",
"type": "string"
@@ -24920,6 +25258,34 @@
},
"type": "object"
},
+ "googleplay.DeviceRating": {
+ "properties": {
+ "device": {
+ "example": "phone",
+ "type": "string"
+ },
+ "histogram": {
+ "type": "object"
+ },
+ "ratings": {
+ "example": 326809,
+ "type": "integer"
+ },
+ "reviews": {
+ "example": 8946,
+ "type": "integer"
+ },
+ "score": {
+ "example": 4.7,
+ "type": "number"
+ },
+ "score_text": {
+ "example": "4.7",
+ "type": "string"
+ }
+ },
+ "type": "object"
+ },
"googleplay.Feature": {
"properties": {
"description": {
@@ -24933,6 +25299,63 @@
},
"type": "object"
},
+ "googleplay.ListApp": {
+ "properties": {
+ "app_id": {
+ "example": "com.openai.chatgpt",
+ "type": "string"
+ },
+ "currency": {
+ "example": "USD",
+ "type": "string"
+ },
+ "developer": {
+ "example": "OpenAI",
+ "type": "string"
+ },
+ "developer_id": {
+ "example": "7577165439232992817",
+ "type": "string"
+ },
+ "free": {
+ "example": true,
+ "type": "boolean"
+ },
+ "icon": {
+ "example": "https://play-lh.googleusercontent.com/lmG9HlI0awHie0cyBieWXeNjpyXvHPwDBb8MNOVIyp0P8VEh95AiBHtUZSDVR3HLe3A",
+ "type": "string"
+ },
+ "price": {
+ "example": 0,
+ "type": "number"
+ },
+ "price_text": {
+ "example": "FREE",
+ "type": "string"
+ },
+ "score": {
+ "example": 4.8,
+ "type": "number"
+ },
+ "score_text": {
+ "example": "4.8",
+ "type": "string"
+ },
+ "summary": {
+ "example": "The official app by OpenAI",
+ "type": "string"
+ },
+ "title": {
+ "example": "ChatGPT",
+ "type": "string"
+ },
+ "url": {
+ "example": "https://play.google.com/store/apps/details?id=com.openai.chatgpt",
+ "type": "string"
+ }
+ },
+ "type": "object"
+ },
"googleplay.Review": {
"properties": {
"criterias": {
@@ -25132,6 +25555,25 @@
},
"type": "object"
},
+ "googleplay.ratingsResponseDoc": {
+ "properties": {
+ "code": {
+ "example": 200,
+ "type": "integer"
+ },
+ "data": {
+ "items": {
+ "$ref": "#/definitions/googleplay.DeviceRating"
+ },
+ "type": "array"
+ },
+ "msg": {
+ "example": "OK",
+ "type": "string"
+ }
+ },
+ "type": "object"
+ },
"googleplay.reviewsResponseDoc": {
"properties": {
"code": {
@@ -39399,6 +39841,9 @@
"author": {
"$ref": "#/definitions/reddit.Author"
},
+ "award_count": {
+ "type": "integer"
+ },
"body": {
"example": "I agree with this post.",
"type": "string"
@@ -39451,6 +39896,9 @@
},
"type": "array"
},
+ "metrics_source": {
+ "$ref": "#/definitions/reddit.SourceDetail"
+ },
"post": {
"$ref": "#/definitions/reddit.Post"
},
@@ -39542,6 +39990,9 @@
"author": {
"$ref": "#/definitions/reddit.Author"
},
+ "award_count": {
+ "type": "integer"
+ },
"comment_count": {
"type": "integer"
},
@@ -39557,6 +40008,12 @@
"example": "self.OpenAI",
"type": "string"
},
+ "estimated_downvotes": {
+ "type": "integer"
+ },
+ "estimated_upvotes": {
+ "type": "integer"
+ },
"flair": {
"example": "Discussion",
"type": "string"
@@ -39617,12 +40074,18 @@
"url": {
"example": "https://www.reddit.com/r/OpenAI/comments/1abcxyz/openai_discussion_thread/",
"type": "string"
+ },
+ "vote_counts_estimated": {
+ "type": "boolean"
}
},
"type": "object"
},
"reddit.PostResponse": {
"properties": {
+ "metrics_source": {
+ "$ref": "#/definitions/reddit.SourceDetail"
+ },
"post": {
"$ref": "#/definitions/reddit.Post"
},
@@ -76885,170 +77348,591 @@
"ApiKeyAuth": []
}
],
- "summary": "Get a US housing market record from the dataset",
+ "summary": "Get a US housing market record from the dataset",
+ "tags": [
+ "Datasets"
+ ]
+ }
+ },
+ "/datasets/housing-markets/search": {
+ "get": {
+ "consumes": [
+ "application/json"
+ ],
+ "description": "Searches monthly Redfin housing-market statistics per region and property type since 2012, joined to Census ACS income for affordability metrics. region_type enum: `national`, `metro`, `county`, `city`, `zip`. property_type enum: `All Residential`, `Single Family Residential`, `Condo/Co-op`, `Townhouse`, `Multi-Family (2-4 Unit)`, `Single Units Only`. Sort enum: `relevance`, `price_desc`, `price_asc`, `list_price_desc`, `list_price_asc`, `price_to_income_desc`, `price_to_income_asc`, `salary_to_buy_desc`, `salary_to_buy_asc`, `dom_asc`, `dom_desc`, `inventory_desc`, `homes_sold_desc`, `period_desc`. Use `latest=true` for the most recent period per region series.",
+ "operationId": "datasets-housing-markets-search",
+ "parameters": [
+ {
+ "description": "Full-text query over region name and city, max 256 characters",
+ "in": "query",
+ "name": "q",
+ "type": "string"
+ },
+ {
+ "description": "Region level enum: national, metro, county, city, zip",
+ "enum": [
+ "national",
+ "metro",
+ "county",
+ "city",
+ "zip"
+ ],
+ "in": "query",
+ "name": "region_type",
+ "type": "string"
+ },
+ {
+ "description": "Exact two-letter state code filter, e.g. CA",
+ "in": "query",
+ "name": "state_code",
+ "type": "string"
+ },
+ {
+ "description": "Property type enum: All Residential, Single Family Residential, Condo/Co-op, Townhouse, Multi-Family (2-4 Unit), Single Units Only",
+ "in": "query",
+ "name": "property_type",
+ "type": "string"
+ },
+ {
+ "description": "Exact parent metro (CBSA) code filter, e.g. 16980",
+ "in": "query",
+ "name": "parent_metro_code",
+ "type": "string"
+ },
+ {
+ "description": "Exact zip code filter (zip-level rows only), e.g. 60616",
+ "in": "query",
+ "name": "zip_code",
+ "type": "string"
+ },
+ {
+ "description": "Exact period start date filter, YYYY-MM-DD",
+ "in": "query",
+ "name": "period",
+ "type": "string"
+ },
+ {
+ "description": "Filter for the most recent period per region and property type",
+ "in": "query",
+ "name": "latest",
+ "type": "boolean"
+ },
+ {
+ "description": "Minimum median sale price in USD",
+ "in": "query",
+ "name": "min_median_sale_price",
+ "type": "number"
+ },
+ {
+ "description": "Maximum median sale price in USD",
+ "in": "query",
+ "name": "max_median_sale_price",
+ "type": "number"
+ },
+ {
+ "description": "Minimum median list price in USD",
+ "in": "query",
+ "name": "min_median_list_price",
+ "type": "number"
+ },
+ {
+ "description": "Maximum median list price in USD",
+ "in": "query",
+ "name": "max_median_list_price",
+ "type": "number"
+ },
+ {
+ "description": "Minimum price-to-income ratio",
+ "in": "query",
+ "name": "min_price_to_income",
+ "type": "number"
+ },
+ {
+ "description": "Maximum price-to-income ratio",
+ "in": "query",
+ "name": "max_price_to_income",
+ "type": "number"
+ },
+ {
+ "description": "Minimum salary needed to buy in USD per year",
+ "in": "query",
+ "name": "min_salary_to_buy",
+ "type": "integer"
+ },
+ {
+ "description": "Maximum salary needed to buy in USD per year",
+ "in": "query",
+ "name": "max_salary_to_buy",
+ "type": "integer"
+ },
+ {
+ "description": "Minimum median days on market",
+ "in": "query",
+ "name": "min_median_dom",
+ "type": "number"
+ },
+ {
+ "description": "Maximum median days on market",
+ "in": "query",
+ "name": "max_median_dom",
+ "type": "number"
+ },
+ {
+ "description": "Minimum active inventory",
+ "in": "query",
+ "name": "min_inventory",
+ "type": "integer"
+ },
+ {
+ "description": "Maximum active inventory",
+ "in": "query",
+ "name": "max_inventory",
+ "type": "integer"
+ },
+ {
+ "description": "Minimum homes sold in the period",
+ "in": "query",
+ "name": "min_homes_sold",
+ "type": "integer"
+ },
+ {
+ "description": "Sort enum: relevance, price_desc, price_asc, list_price_desc, list_price_asc, price_to_income_desc, price_to_income_asc, salary_to_buy_desc, salary_to_buy_asc, dom_asc, dom_desc, inventory_desc, homes_sold_desc, period_desc",
+ "enum": [
+ "relevance",
+ "price_desc",
+ "price_asc",
+ "list_price_desc",
+ "list_price_asc",
+ "price_to_income_desc",
+ "price_to_income_asc",
+ "salary_to_buy_desc",
+ "salary_to_buy_asc",
+ "dom_asc",
+ "dom_desc",
+ "inventory_desc",
+ "homes_sold_desc",
+ "period_desc"
+ ],
+ "in": "query",
+ "name": "sort",
+ "type": "string"
+ },
+ {
+ "description": "Page number, defaults to 1",
+ "in": "query",
+ "name": "page",
+ "type": "integer"
+ },
+ {
+ "description": "Page size, defaults to 20 and maxes at 100; page * page_size must be <= 10000",
+ "in": "query",
+ "name": "page_size",
+ "type": "integer"
+ }
+ ],
+ "produces": [
+ "application/json"
+ ],
+ "responses": {
+ "200": {
+ "description": "OK",
+ "schema": {
+ "$ref": "#/definitions/datasets.housingMarketsSearchResponseDoc"
+ }
+ },
+ "400": {
+ "description": "Bad Request",
+ "schema": {
+ "$ref": "#/definitions/app.Response"
+ }
+ },
+ "429": {
+ "description": "Too Many Requests",
+ "schema": {
+ "$ref": "#/definitions/app.Response"
+ }
+ },
+ "500": {
+ "description": "Internal Server Error",
+ "schema": {
+ "$ref": "#/definitions/app.Response"
+ }
+ }
+ },
+ "security": [
+ {
+ "ApiKeyAuth": []
+ }
+ ],
+ "summary": "Search the US housing markets dataset",
+ "tags": [
+ "Datasets"
+ ]
+ }
+ },
+ "/datasets/instagram-users/facets": {
+ "get": {
+ "consumes": [
+ "application/json"
+ ],
+ "description": "Returns terms aggregation counts for the Instagram users dataset. Facet enum: `is_verified`, `is_business_account`, `has_bio`, `has_external_url`, `category_name`, `source_tier`.",
+ "operationId": "datasets-instagram-users-facets",
+ "parameters": [
+ {
+ "description": "Facet enum: is_verified, is_business_account, has_bio, has_external_url, category_name, source_tier",
+ "enum": [
+ "is_verified",
+ "is_business_account",
+ "has_bio",
+ "has_external_url",
+ "category_name",
+ "source_tier"
+ ],
+ "in": "query",
+ "name": "facet",
+ "required": true,
+ "type": "string"
+ },
+ {
+ "description": "Full-text query over username, full_name and biography, max 256 characters",
+ "in": "query",
+ "name": "q",
+ "type": "string"
+ },
+ {
+ "description": "Exact username filter (case-insensitive), max 128 characters",
+ "in": "query",
+ "name": "username",
+ "type": "string"
+ },
+ {
+ "description": "Exact category filter (case-insensitive, e.g. Digital Creator), max 128 characters",
+ "in": "query",
+ "name": "category_name",
+ "type": "string"
+ },
+ {
+ "description": "Exact filter for seed tier (e.g. crossref, vertical-hashtags, mention-graph, head-directory)",
+ "in": "query",
+ "name": "source_tier",
+ "type": "string"
+ },
+ {
+ "description": "Filter by the Instagram verification checkmark",
+ "in": "query",
+ "name": "is_verified",
+ "type": "boolean"
+ },
+ {
+ "description": "Filter by business or creator accounts",
+ "in": "query",
+ "name": "is_business_account",
+ "type": "boolean"
+ },
+ {
+ "description": "Filter by a non-empty profile biography",
+ "in": "query",
+ "name": "has_bio",
+ "type": "boolean"
+ },
+ {
+ "description": "Filter by a linked external URL",
+ "in": "query",
+ "name": "has_external_url",
+ "type": "boolean"
+ },
+ {
+ "description": "Minimum follower count",
+ "in": "query",
+ "name": "min_followers",
+ "type": "integer"
+ },
+ {
+ "description": "Maximum follower count",
+ "in": "query",
+ "name": "max_followers",
+ "type": "integer"
+ },
+ {
+ "description": "Minimum follower-to-following ratio",
+ "in": "query",
+ "name": "min_ratio",
+ "type": "number"
+ },
+ {
+ "description": "Maximum follower-to-following ratio",
+ "in": "query",
+ "name": "max_ratio",
+ "type": "number"
+ },
+ {
+ "description": "Accounts created on or after this date (RFC3339 or YYYY-MM-DD)",
+ "in": "query",
+ "name": "created_after",
+ "type": "string"
+ },
+ {
+ "description": "Accounts created on or before this date (RFC3339 or YYYY-MM-DD)",
+ "in": "query",
+ "name": "created_before",
+ "type": "string"
+ },
+ {
+ "description": "Records last refreshed on or after this date (RFC3339 or YYYY-MM-DD)",
+ "in": "query",
+ "name": "crawled_after",
+ "type": "string"
+ },
+ {
+ "description": "Records last refreshed on or before this date (RFC3339 or YYYY-MM-DD)",
+ "in": "query",
+ "name": "crawled_before",
+ "type": "string"
+ },
+ {
+ "description": "Sort enum: relevance, followers_desc, followers_asc, crawled_at_desc, crawled_at_asc, created_at_desc, created_at_asc",
+ "enum": [
+ "relevance",
+ "followers_desc",
+ "followers_asc",
+ "crawled_at_desc",
+ "crawled_at_asc",
+ "created_at_desc",
+ "created_at_asc"
+ ],
+ "in": "query",
+ "name": "sort",
+ "type": "string"
+ },
+ {
+ "description": "Page number, defaults to 1",
+ "in": "query",
+ "name": "page",
+ "type": "integer"
+ },
+ {
+ "description": "Page size, defaults to 20 and maxes at 100; page * page_size must be <= 10000",
+ "in": "query",
+ "name": "page_size",
+ "type": "integer"
+ }
+ ],
+ "produces": [
+ "application/json"
+ ],
+ "responses": {
+ "200": {
+ "description": "OK",
+ "schema": {
+ "$ref": "#/definitions/datasets.instagramUsersFacetResponseDoc"
+ }
+ },
+ "400": {
+ "description": "Bad Request",
+ "schema": {
+ "$ref": "#/definitions/app.Response"
+ }
+ },
+ "429": {
+ "description": "Too Many Requests",
+ "schema": {
+ "$ref": "#/definitions/app.Response"
+ }
+ },
+ "500": {
+ "description": "Internal Server Error",
+ "schema": {
+ "$ref": "#/definitions/app.Response"
+ }
+ }
+ },
+ "security": [
+ {
+ "ApiKeyAuth": []
+ }
+ ],
+ "summary": "Facet the Instagram users dataset",
+ "tags": [
+ "Datasets"
+ ]
+ }
+ },
+ "/datasets/instagram-users/items/{username}": {
+ "get": {
+ "consumes": [
+ "application/json"
+ ],
+ "description": "Returns one Instagram user record by username from dataset id enum value `instagram-users`.",
+ "operationId": "datasets-instagram-users-item",
+ "parameters": [
+ {
+ "description": "Instagram username, with or without a leading @, max 128 characters",
+ "in": "path",
+ "name": "username",
+ "required": true,
+ "type": "string"
+ }
+ ],
+ "produces": [
+ "application/json"
+ ],
+ "responses": {
+ "200": {
+ "description": "OK",
+ "schema": {
+ "$ref": "#/definitions/datasets.instagramUserResponseDoc"
+ }
+ },
+ "400": {
+ "description": "Bad Request",
+ "schema": {
+ "$ref": "#/definitions/app.Response"
+ }
+ },
+ "404": {
+ "description": "Not Found",
+ "schema": {
+ "$ref": "#/definitions/app.Response"
+ }
+ },
+ "429": {
+ "description": "Too Many Requests",
+ "schema": {
+ "$ref": "#/definitions/app.Response"
+ }
+ },
+ "500": {
+ "description": "Internal Server Error",
+ "schema": {
+ "$ref": "#/definitions/app.Response"
+ }
+ }
+ },
+ "security": [
+ {
+ "ApiKeyAuth": []
+ }
+ ],
+ "summary": "Get an Instagram user from the dataset",
"tags": [
"Datasets"
]
}
},
- "/datasets/housing-markets/search": {
+ "/datasets/instagram-users/search": {
"get": {
"consumes": [
"application/json"
],
- "description": "Searches monthly Redfin housing-market statistics per region and property type since 2012, joined to Census ACS income for affordability metrics. region_type enum: `national`, `metro`, `county`, `city`, `zip`. property_type enum: `All Residential`, `Single Family Residential`, `Condo/Co-op`, `Townhouse`, `Multi-Family (2-4 Unit)`, `Single Units Only`. Sort enum: `relevance`, `price_desc`, `price_asc`, `list_price_desc`, `list_price_asc`, `price_to_income_desc`, `price_to_income_asc`, `salary_to_buy_desc`, `salary_to_buy_asc`, `dom_asc`, `dom_desc`, `inventory_desc`, `homes_sold_desc`, `period_desc`. Use `latest=true` for the most recent period per region series.",
- "operationId": "datasets-housing-markets-search",
+ "description": "Searches public Instagram user profiles stored in a search index. Sort enum: `relevance`, `followers_desc`, `followers_asc`, `crawled_at_desc`, `crawled_at_asc`, `created_at_desc`, `created_at_asc`.",
+ "operationId": "datasets-instagram-users-search",
"parameters": [
{
- "description": "Full-text query over region name and city, max 256 characters",
+ "description": "Full-text query over username, full_name and biography, max 256 characters",
"in": "query",
"name": "q",
"type": "string"
},
{
- "description": "Region level enum: national, metro, county, city, zip",
- "enum": [
- "national",
- "metro",
- "county",
- "city",
- "zip"
- ],
- "in": "query",
- "name": "region_type",
- "type": "string"
- },
- {
- "description": "Exact two-letter state code filter, e.g. CA",
- "in": "query",
- "name": "state_code",
- "type": "string"
- },
- {
- "description": "Property type enum: All Residential, Single Family Residential, Condo/Co-op, Townhouse, Multi-Family (2-4 Unit), Single Units Only",
- "in": "query",
- "name": "property_type",
- "type": "string"
- },
- {
- "description": "Exact parent metro (CBSA) code filter, e.g. 16980",
+ "description": "Exact username filter (case-insensitive), max 128 characters",
"in": "query",
- "name": "parent_metro_code",
+ "name": "username",
"type": "string"
},
{
- "description": "Exact zip code filter (zip-level rows only), e.g. 60616",
+ "description": "Exact category filter (case-insensitive, e.g. Digital Creator), max 128 characters",
"in": "query",
- "name": "zip_code",
+ "name": "category_name",
"type": "string"
},
{
- "description": "Exact period start date filter, YYYY-MM-DD",
+ "description": "Exact filter for seed tier (e.g. crossref, vertical-hashtags, mention-graph, head-directory), max 128 characters",
"in": "query",
- "name": "period",
+ "name": "source_tier",
"type": "string"
},
{
- "description": "Filter for the most recent period per region and property type",
+ "description": "Filter by the Instagram verification checkmark",
"in": "query",
- "name": "latest",
+ "name": "is_verified",
"type": "boolean"
},
{
- "description": "Minimum median sale price in USD",
- "in": "query",
- "name": "min_median_sale_price",
- "type": "number"
- },
- {
- "description": "Maximum median sale price in USD",
- "in": "query",
- "name": "max_median_sale_price",
- "type": "number"
- },
- {
- "description": "Minimum median list price in USD",
+ "description": "Filter by business or creator accounts",
"in": "query",
- "name": "min_median_list_price",
- "type": "number"
+ "name": "is_business_account",
+ "type": "boolean"
},
{
- "description": "Maximum median list price in USD",
+ "description": "Filter by a non-empty profile biography",
"in": "query",
- "name": "max_median_list_price",
- "type": "number"
+ "name": "has_bio",
+ "type": "boolean"
},
{
- "description": "Minimum price-to-income ratio",
+ "description": "Filter by a linked external URL",
"in": "query",
- "name": "min_price_to_income",
- "type": "number"
+ "name": "has_external_url",
+ "type": "boolean"
},
{
- "description": "Maximum price-to-income ratio",
+ "description": "Minimum follower count",
"in": "query",
- "name": "max_price_to_income",
- "type": "number"
+ "name": "min_followers",
+ "type": "integer"
},
{
- "description": "Minimum salary needed to buy in USD per year",
+ "description": "Maximum follower count",
"in": "query",
- "name": "min_salary_to_buy",
+ "name": "max_followers",
"type": "integer"
},
{
- "description": "Maximum salary needed to buy in USD per year",
+ "description": "Minimum follower-to-following ratio",
"in": "query",
- "name": "max_salary_to_buy",
- "type": "integer"
+ "name": "min_ratio",
+ "type": "number"
},
{
- "description": "Minimum median days on market",
+ "description": "Maximum follower-to-following ratio",
"in": "query",
- "name": "min_median_dom",
+ "name": "max_ratio",
"type": "number"
},
{
- "description": "Maximum median days on market",
+ "description": "Accounts created on or after this date (RFC3339 or YYYY-MM-DD)",
"in": "query",
- "name": "max_median_dom",
- "type": "number"
+ "name": "created_after",
+ "type": "string"
},
{
- "description": "Minimum active inventory",
+ "description": "Accounts created on or before this date (RFC3339 or YYYY-MM-DD)",
"in": "query",
- "name": "min_inventory",
- "type": "integer"
+ "name": "created_before",
+ "type": "string"
},
{
- "description": "Maximum active inventory",
+ "description": "Records last refreshed on or after this date (RFC3339 or YYYY-MM-DD)",
"in": "query",
- "name": "max_inventory",
- "type": "integer"
+ "name": "crawled_after",
+ "type": "string"
},
{
- "description": "Minimum homes sold in the period",
+ "description": "Records last refreshed on or before this date (RFC3339 or YYYY-MM-DD)",
"in": "query",
- "name": "min_homes_sold",
- "type": "integer"
+ "name": "crawled_before",
+ "type": "string"
},
{
- "description": "Sort enum: relevance, price_desc, price_asc, list_price_desc, list_price_asc, price_to_income_desc, price_to_income_asc, salary_to_buy_desc, salary_to_buy_asc, dom_asc, dom_desc, inventory_desc, homes_sold_desc, period_desc",
+ "description": "Sort enum: relevance, followers_desc, followers_asc, crawled_at_desc, crawled_at_asc, created_at_desc, created_at_asc",
"enum": [
"relevance",
- "price_desc",
- "price_asc",
- "list_price_desc",
- "list_price_asc",
- "price_to_income_desc",
- "price_to_income_asc",
- "salary_to_buy_desc",
- "salary_to_buy_asc",
- "dom_asc",
- "dom_desc",
- "inventory_desc",
- "homes_sold_desc",
- "period_desc"
+ "followers_desc",
+ "followers_asc",
+ "crawled_at_desc",
+ "crawled_at_asc",
+ "created_at_desc",
+ "created_at_asc"
],
"in": "query",
"name": "sort",
@@ -77074,7 +77958,7 @@
"200": {
"description": "OK",
"schema": {
- "$ref": "#/definitions/datasets.housingMarketsSearchResponseDoc"
+ "$ref": "#/definitions/datasets.instagramUsersSearchResponseDoc"
}
},
"400": {
@@ -77101,7 +77985,7 @@
"ApiKeyAuth": []
}
],
- "summary": "Search the US housing markets dataset",
+ "summary": "Search the Instagram users dataset",
"tags": [
"Datasets"
]
@@ -80957,36 +81841,181 @@
"ApiKeyAuth": []
}
],
- "summary": "Get a Product Hunt product from the dataset",
+ "summary": "Get a Product Hunt product from the dataset",
+ "tags": [
+ "Datasets"
+ ]
+ }
+ },
+ "/datasets/producthunt-products/search": {
+ "get": {
+ "consumes": [
+ "application/json"
+ ],
+ "description": "Searches individual Product Hunt launches from the dataset id enum value `producthunt-products` — the searchable launch archive. Each result is one product with its topics, upvotes, ranks and launch history; description/website/twitter_url/pricing/makers are filled in as hydration runs. Sort enum: `relevance`, `votes_desc`, `launched_desc`, `launched_asc`, `rating_desc`, `best_rank_asc`.",
+ "operationId": "datasets-producthunt-products-search",
+ "parameters": [
+ {
+ "description": "Full-text query over product name and tagline, max 256 characters",
+ "in": "query",
+ "name": "q",
+ "type": "string"
+ },
+ {
+ "description": "Exact topic-slug filter, e.g. artificial-intelligence, max 128 characters",
+ "in": "query",
+ "name": "topic",
+ "type": "string"
+ },
+ {
+ "description": "Exact maker-username filter (populated by hydration), max 128 characters",
+ "in": "query",
+ "name": "maker",
+ "type": "string"
+ },
+ {
+ "description": "Lower bound on first-launch date, an ISO-8601 date (YYYY-MM-DD)",
+ "in": "query",
+ "name": "launched_after",
+ "type": "string"
+ },
+ {
+ "description": "Upper bound on first-launch date, an ISO-8601 date (YYYY-MM-DD)",
+ "in": "query",
+ "name": "launched_before",
+ "type": "string"
+ },
+ {
+ "description": "Minimum upvotes, 0 or greater",
+ "in": "query",
+ "name": "min_votes",
+ "type": "integer"
+ },
+ {
+ "description": "Minimum review rating, from 0 through 5 (populated by hydration)",
+ "in": "query",
+ "name": "min_rating",
+ "type": "number"
+ },
+ {
+ "description": "Exact pricing-type filter (populated by hydration), e.g. free, paid, freemium",
+ "in": "query",
+ "name": "pricing_type",
+ "type": "string"
+ },
+ {
+ "description": "Website presence filter (populated by hydration)",
+ "in": "query",
+ "name": "has_website",
+ "type": "boolean"
+ },
+ {
+ "description": "true keeps only products still online, false only retired products",
+ "in": "query",
+ "name": "is_online",
+ "type": "boolean"
+ },
+ {
+ "description": "Sort enum: relevance, votes_desc, launched_desc, launched_asc, rating_desc, best_rank_asc",
+ "enum": [
+ "relevance",
+ "votes_desc",
+ "launched_desc",
+ "launched_asc",
+ "rating_desc",
+ "best_rank_asc"
+ ],
+ "in": "query",
+ "name": "sort",
+ "type": "string"
+ },
+ {
+ "description": "Page number, defaults to 1",
+ "in": "query",
+ "name": "page",
+ "type": "integer"
+ },
+ {
+ "description": "Page size, defaults to 20 and maxes at 100; page * page_size must be <= 10000",
+ "in": "query",
+ "name": "page_size",
+ "type": "integer"
+ }
+ ],
+ "produces": [
+ "application/json"
+ ],
+ "responses": {
+ "200": {
+ "description": "OK",
+ "schema": {
+ "$ref": "#/definitions/datasets.producthuntProductsSearchResponseDoc"
+ }
+ },
+ "400": {
+ "description": "Bad Request",
+ "schema": {
+ "$ref": "#/definitions/app.Response"
+ }
+ },
+ "429": {
+ "description": "Too Many Requests",
+ "schema": {
+ "$ref": "#/definitions/app.Response"
+ }
+ },
+ "500": {
+ "description": "Internal Server Error",
+ "schema": {
+ "$ref": "#/definitions/app.Response"
+ }
+ }
+ },
+ "security": [
+ {
+ "ApiKeyAuth": []
+ }
+ ],
+ "summary": "Search the Product Hunt products dataset",
"tags": [
"Datasets"
]
}
},
- "/datasets/producthunt-products/search": {
+ "/datasets/producthunt-trends/facets": {
"get": {
"consumes": [
"application/json"
],
- "description": "Searches individual Product Hunt launches from the dataset id enum value `producthunt-products` — the searchable launch archive. Each result is one product with its topics, upvotes, ranks and launch history; description/website/twitter_url/pricing/makers are filled in as hydration runs. Sort enum: `relevance`, `votes_desc`, `launched_desc`, `launched_asc`, `rating_desc`, `best_rank_asc`.",
- "operationId": "datasets-producthunt-products-search",
+ "description": "Returns suppressed distribution counts over the Product Hunt trends dataset (dataset id enum value `producthunt-trends`), honoring the same filters as search. Facet enum: `topic`, `launch_year`.",
+ "operationId": "datasets-producthunt-trends-facets",
"parameters": [
{
- "description": "Full-text query over product name and tagline, max 256 characters",
+ "description": "Facet enum: topic, launch_year",
+ "enum": [
+ "topic",
+ "launch_year"
+ ],
"in": "query",
- "name": "q",
+ "name": "facet",
+ "required": true,
"type": "string"
},
{
- "description": "Exact topic-slug filter, e.g. artificial-intelligence, max 128 characters",
+ "description": "Aggregate cell dimension enum: topic_month, topic_year, topic. Defaults to topic_month",
+ "enum": [
+ "topic_month",
+ "topic_year",
+ "topic"
+ ],
"in": "query",
- "name": "topic",
+ "name": "group_by",
"type": "string"
},
{
- "description": "Exact maker-username filter (populated by hydration), max 128 characters",
+ "description": "Exact topic-slug filter, e.g. artificial-intelligence, max 128 characters",
"in": "query",
- "name": "maker",
+ "name": "topic",
"type": "string"
},
{
@@ -81002,59 +82031,15 @@
"type": "string"
},
{
- "description": "Minimum upvotes, 0 or greater",
+ "description": "Minimum product upvotes, 0 or greater",
"in": "query",
"name": "min_votes",
"type": "integer"
},
{
- "description": "Minimum review rating, from 0 through 5 (populated by hydration)",
- "in": "query",
- "name": "min_rating",
- "type": "number"
- },
- {
- "description": "Exact pricing-type filter (populated by hydration), e.g. free, paid, freemium",
- "in": "query",
- "name": "pricing_type",
- "type": "string"
- },
- {
- "description": "Website presence filter (populated by hydration)",
- "in": "query",
- "name": "has_website",
- "type": "boolean"
- },
- {
- "description": "true keeps only products still online, false only retired products",
- "in": "query",
- "name": "is_online",
- "type": "boolean"
- },
- {
- "description": "Sort enum: relevance, votes_desc, launched_desc, launched_asc, rating_desc, best_rank_asc",
- "enum": [
- "relevance",
- "votes_desc",
- "launched_desc",
- "launched_asc",
- "rating_desc",
- "best_rank_asc"
- ],
- "in": "query",
- "name": "sort",
- "type": "string"
- },
- {
- "description": "Page number, defaults to 1",
- "in": "query",
- "name": "page",
- "type": "integer"
- },
- {
- "description": "Page size, defaults to 20 and maxes at 100; page * page_size must be <= 10000",
+ "description": "Minimum launches per bucket; raises the small-cell suppression floor",
"in": "query",
- "name": "page_size",
+ "name": "min_launches",
"type": "integer"
}
],
@@ -81065,7 +82050,7 @@
"200": {
"description": "OK",
"schema": {
- "$ref": "#/definitions/datasets.producthuntProductsSearchResponseDoc"
+ "$ref": "#/definitions/datasets.producthuntTrendsFacetResponseDoc"
}
},
"400": {
@@ -81092,31 +82077,20 @@
"ApiKeyAuth": []
}
],
- "summary": "Search the Product Hunt products dataset",
+ "summary": "Facet the Product Hunt trends dataset",
"tags": [
"Datasets"
]
}
},
- "/datasets/producthunt-trends/facets": {
+ "/datasets/producthunt-trends/search": {
"get": {
"consumes": [
"application/json"
],
- "description": "Returns suppressed distribution counts over the Product Hunt trends dataset (dataset id enum value `producthunt-trends`), honoring the same filters as search. Facet enum: `topic`, `launch_year`.",
- "operationId": "datasets-producthunt-trends-facets",
+ "description": "Returns aggregate Product Hunt launch trends from the dataset id enum value `producthunt-trends`. Aggregate-only: each row is a category-over-time cell (a topic, optionally within a calendar period), reporting launch count, total and average upvotes, average rating and the top product — never an individual product record. Thin cells are suppressed. group_by enum: `topic_month`, `topic_year`, `topic`. Sort enum: `period_desc`, `period_asc`, `launch_count_desc`, `sum_votes_desc`.",
+ "operationId": "datasets-producthunt-trends-search",
"parameters": [
- {
- "description": "Facet enum: topic, launch_year",
- "enum": [
- "topic",
- "launch_year"
- ],
- "in": "query",
- "name": "facet",
- "required": true,
- "type": "string"
- },
{
"description": "Aggregate cell dimension enum: topic_month, topic_year, topic. Defaults to topic_month",
"enum": [
@@ -81153,10 +82127,34 @@
"type": "integer"
},
{
- "description": "Minimum launches per bucket; raises the small-cell suppression floor",
+ "description": "Minimum launches per cell; raises the small-cell suppression floor (never lowered below the built-in minimum)",
"in": "query",
"name": "min_launches",
"type": "integer"
+ },
+ {
+ "description": "Sort enum: period_desc, period_asc, launch_count_desc, sum_votes_desc",
+ "enum": [
+ "period_desc",
+ "period_asc",
+ "launch_count_desc",
+ "sum_votes_desc"
+ ],
+ "in": "query",
+ "name": "sort",
+ "type": "string"
+ },
+ {
+ "description": "Page number, defaults to 1",
+ "in": "query",
+ "name": "page",
+ "type": "integer"
+ },
+ {
+ "description": "Page size, defaults to 20 and maxes at 100; page * page_size must be <= 10000",
+ "in": "query",
+ "name": "page_size",
+ "type": "integer"
}
],
"produces": [
@@ -81166,7 +82164,7 @@
"200": {
"description": "OK",
"schema": {
- "$ref": "#/definitions/datasets.producthuntTrendsFacetResponseDoc"
+ "$ref": "#/definitions/datasets.producthuntTrendsSearchResponseDoc"
}
},
"400": {
@@ -81193,68 +82191,43 @@
"ApiKeyAuth": []
}
],
- "summary": "Facet the Product Hunt trends dataset",
+ "summary": "Search the Product Hunt trends dataset",
"tags": [
"Datasets"
]
}
},
- "/datasets/producthunt-trends/search": {
+ "/datasets/reddit-trending/search": {
"get": {
"consumes": [
"application/json"
],
- "description": "Returns aggregate Product Hunt launch trends from the dataset id enum value `producthunt-trends`. Aggregate-only: each row is a category-over-time cell (a topic, optionally within a calendar period), reporting launch count, total and average upvotes, average rating and the top product — never an individual product record. Thin cells are suppressed. group_by enum: `topic_month`, `topic_year`, `topic`. Sort enum: `period_desc`, `period_asc`, `launch_count_desc`, `sum_votes_desc`.",
- "operationId": "datasets-producthunt-trends-search",
+ "description": "Searches daily snapshots of each tracked subreddit's hot-feed post order, stored in a search index (one document per subreddit × snapshot × rank) so history accumulates. With no `date` the latest snapshot is returned (today's trending); pair `subreddit` with `sort=date_desc` for a subreddit's trending history over time. There is no score or comment-count field — the underlying credential-free scraper does not expose vote counts, so `rank` reflects Reddit's own hot-feed order rather than a locally computed score.",
+ "operationId": "datasets-reddit-trending-search",
"parameters": [
{
- "description": "Aggregate cell dimension enum: topic_month, topic_year, topic. Defaults to topic_month",
- "enum": [
- "topic_month",
- "topic_year",
- "topic"
- ],
+ "description": "Full-text query over the post title, max 256 characters",
"in": "query",
- "name": "group_by",
- "type": "string"
- },
- {
- "description": "Exact topic-slug filter, e.g. artificial-intelligence, max 128 characters",
- "in": "query",
- "name": "topic",
+ "name": "q",
"type": "string"
},
{
- "description": "Lower bound on first-launch date, an ISO-8601 date (YYYY-MM-DD)",
+ "description": "Exact subreddit-name filter, max 128 characters",
"in": "query",
- "name": "launched_after",
+ "name": "subreddit",
"type": "string"
},
{
- "description": "Upper bound on first-launch date, an ISO-8601 date (YYYY-MM-DD)",
+ "description": "Snapshot date filter yyyy-MM-dd; defaults to the latest snapshot",
"in": "query",
- "name": "launched_before",
+ "name": "date",
"type": "string"
},
{
- "description": "Minimum product upvotes, 0 or greater",
- "in": "query",
- "name": "min_votes",
- "type": "integer"
- },
- {
- "description": "Minimum launches per cell; raises the small-cell suppression floor (never lowered below the built-in minimum)",
- "in": "query",
- "name": "min_launches",
- "type": "integer"
- },
- {
- "description": "Sort enum: period_desc, period_asc, launch_count_desc, sum_votes_desc",
+ "description": "Sort enum: rank, date_desc",
"enum": [
- "period_desc",
- "period_asc",
- "launch_count_desc",
- "sum_votes_desc"
+ "rank",
+ "date_desc"
],
"in": "query",
"name": "sort",
@@ -81280,7 +82253,7 @@
"200": {
"description": "OK",
"schema": {
- "$ref": "#/definitions/datasets.producthuntTrendsSearchResponseDoc"
+ "$ref": "#/definitions/datasets.redditTrendingSearchResponseDoc"
}
},
"400": {
@@ -81307,7 +82280,7 @@
"ApiKeyAuth": []
}
],
- "summary": "Search the Product Hunt trends dataset",
+ "summary": "Search the reddit-trending dataset",
"tags": [
"Datasets"
]
@@ -91272,7 +92245,7 @@
"consumes": [
"application/json"
],
- "description": "Returns normalized app metadata from a Google Play details page, including installs, ratings, pricing, version info, developer metadata, media assets, release state, and selected user comments. Defaults: `country=us`, `lang=en`.",
+ "description": "Returns normalized app metadata from a Google Play details page, including installs, ratings, pricing, version info, developer metadata, media assets, release state, selected user comments, and \"More by this developer\" and \"Similar apps\" recommendation rails. For a per-device (phone/tablet/Chromebook) ratings-and-reviews breakdown, see `/googleplay/ratings`. Defaults: `country=us`, `lang=en`.",
"operationId": "googleplay-app",
"parameters": [
{
@@ -91603,6 +92576,22 @@
"type": "string",
"x-example": "TOOLS"
},
+ {
+ "description": "Google Play device tab: phone, tablet, tv, chromebook, watch, xr, car",
+ "enum": [
+ "phone",
+ "tablet",
+ "tv",
+ "chromebook",
+ "watch",
+ "xr",
+ "car"
+ ],
+ "in": "query",
+ "name": "device",
+ "type": "string",
+ "x-example": "tablet"
+ },
{
"description": "Family age range",
"in": "query",
@@ -91769,6 +92758,83 @@
]
}
},
+ "/googleplay/ratings": {
+ "get": {
+ "consumes": [
+ "application/json"
+ ],
+ "description": "Returns the ratings-and-reviews breakdown Google Play shows under the details page's device tabs, one entry each for phone, tablet, and Chromebook. Defaults: `country=us`, `lang=en`.",
+ "operationId": "googleplay-ratings",
+ "parameters": [
+ {
+ "description": "Google Play package name",
+ "in": "query",
+ "name": "app_id",
+ "required": true,
+ "type": "string",
+ "x-example": "com.openai.chatgpt"
+ },
+ {
+ "description": "Two-letter storefront country code",
+ "in": "query",
+ "name": "country",
+ "type": "string",
+ "x-example": "us"
+ },
+ {
+ "description": "Two-letter language code",
+ "in": "query",
+ "name": "lang",
+ "type": "string",
+ "x-example": "en"
+ }
+ ],
+ "produces": [
+ "application/json"
+ ],
+ "responses": {
+ "200": {
+ "description": "OK",
+ "schema": {
+ "$ref": "#/definitions/googleplay.ratingsResponseDoc"
+ }
+ },
+ "400": {
+ "description": "Bad Request",
+ "schema": {
+ "$ref": "#/definitions/app.Response"
+ }
+ },
+ "404": {
+ "description": "Not Found",
+ "schema": {
+ "$ref": "#/definitions/app.Response"
+ }
+ },
+ "429": {
+ "description": "Too Many Requests",
+ "schema": {
+ "$ref": "#/definitions/app.Response"
+ }
+ },
+ "500": {
+ "description": "Internal Server Error",
+ "schema": {
+ "$ref": "#/definitions/app.Response"
+ }
+ }
+ },
+ "security": [
+ {
+ "ApiKeyAuth": []
+ }
+ ],
+ "summary": "Get Google Play ratings by device",
+ "tags": [
+ "GooglePlay"
+ ]
+ }
+ },
"/googleplay/reviews": {
"get": {
"consumes": [
@@ -109077,7 +110143,7 @@
"consumes": [
"application/json"
],
- "description": "Returns a Reddit post with its public comments. A post that exists but has no comments yet returns a 200 response with an empty comments list; a post that does not exist returns 404, and a temporary block or upstream failure returns 503 (retryable) rather than 404. A `503` with a `Retry-After` header means Reddit is temporarily throttling the request; wait that many seconds and retry.",
+ "description": "Returns a Reddit post with its public comments. The default 1-credit mode uses RSS. Set `include_metrics=true` to use the anonymous HTML post page as the sole content request and return the server-rendered comments with public net score and award count plus post engagement metrics for 3 credits. Large threads may expose only an initial comment subset in anonymous HTML. Reddit does not expose per-comment upvote ratios or exact upvote/downvote totals anonymously. A post that exists but has no comments yet returns a 200 response with an empty comments list; a post that does not exist returns 404, and a temporary block or upstream failure returns 503 (retryable) rather than 404.",
"operationId": "reddit-comments",
"parameters": [
{
@@ -109089,7 +110155,7 @@
},
{
"default": "confidence",
- "description": "Accepted for compatibility: confidence, top, new, controversial, old, or qa. Public comment data is flat and may ignore sort.",
+ "description": "Comment order: confidence, top, new, controversial, old, or qa. Applied to the anonymous HTML request when metrics are enabled.",
"enum": [
"confidence",
"top",
@@ -109110,10 +110176,17 @@
},
{
"default": 3,
- "description": "Accepted for compatibility. Public comment data is flat and may ignore depth.",
+ "description": "Maximum flat comment depth returned in metrics mode.",
"in": "query",
"name": "depth",
"type": "integer"
+ },
+ {
+ "default": false,
+ "description": "Include public post and per-comment engagement metrics; costs 3 credits instead of 1",
+ "in": "query",
+ "name": "include_metrics",
+ "type": "boolean"
}
],
"produces": [
@@ -109268,7 +110341,7 @@
"consumes": [
"application/json"
],
- "description": "Returns a normalized public Reddit post entry. A `503` with a `Retry-After` header means Reddit is temporarily throttling the request; wait that many seconds and retry.",
+ "description": "Returns a normalized public Reddit post. The default 1-credit mode uses RSS. Set `include_metrics=true` to use the anonymous HTML post page as the sole content request and return public net score, upvote ratio, comment count, award count, and estimated upvote/downvote totals for 3 credits. Reddit fuzzes voting data, so estimates are approximate; share, repost/crosspost, and view counts are not exposed anonymously.",
"operationId": "reddit-post",
"parameters": [
{
@@ -109277,6 +110350,13 @@
"name": "id",
"required": true,
"type": "string"
+ },
+ {
+ "default": false,
+ "description": "Include public engagement metrics; costs 3 credits instead of 1",
+ "in": "query",
+ "name": "include_metrics",
+ "type": "boolean"
}
],
"produces": [
diff --git a/pyproject.toml b/pyproject.toml
index 162ba39..458d562 100644
--- a/pyproject.toml
+++ b/pyproject.toml
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
[project]
name = "crawlora"
-version = "1.25.0.dev1"
+version = "1.26.0.dev1"
description = "Official Python SDK for the Crawlora web-scraping API: typed grouped and dynamic operation calls for every public endpoint, with retries, pagination, hooks, and an async client."
readme = "README.md"
requires-python = ">=3.10"
diff --git a/tests/test_client.py b/tests/test_client.py
index ed68a8e..908dd53 100644
--- a/tests/test_client.py
+++ b/tests/test_client.py
@@ -267,7 +267,7 @@ def transport(_request, _timeout):
self.assertIs(raised.exception.__cause__, cause)
def test_operation_metadata_count(self):
- self.assertEqual(OPERATION_COUNT, 832)
+ self.assertEqual(OPERATION_COUNT, 837)
def test_deprecated_endpoints_are_not_generated(self):
self.assertFalse(hasattr(CrawloraClient(api_key="api_test", base_url=self.base_url).google, "lens"))
@@ -296,7 +296,7 @@ def test_docs_cover_operations_and_recipes(self):
recipes_doc = root.joinpath("docs", "recipes.md").read_text()
for expected in [
- "Total operations: `832`",
+ "Total operations: `837`",
"`bing-search`",
"`GET /bing/search`",
"`bing.search`",