Python SDK for the Xpoz social media intelligence platform. Query Twitter/X, Instagram, Reddit, and TikTok data through a simple, Pythonic interface.
pip install xpozRequires Python 3.10+.
Sign up and get your token at https://xpoz.ai/get-token.
Once you have it, pass it directly or set the XPOZ_API_KEY environment variable:
export XPOZ_API_KEY=your-token-hereXpoz provides unified access to social media data across Twitter/X, Instagram, Reddit, and TikTok. The platform indexes billions of posts, user profiles, and engagement metrics — making it possible to search, analyze, and export social media data at scale.
The SDK wraps Xpoz's MCP server, abstracting away transport, authentication, operation polling, and pagination into a clean developer-friendly API.
- 42 data methods across Twitter, Instagram, Reddit, and TikTok
- Sync and async clients —
XpozClientandAsyncXpozClient - Automatic operation polling — long-running queries are abstracted away
- Response modes —
ResponseType.FASTfor quick limited results,PAGINGfor full pagination,CSVfor export - Server-side pagination —
PaginatedResultwithnext_page(),get_page(n) - CSV export —
export_csv()on any paginated result - Field selection — request only the fields you need in Pythonic snake_case
- Pydantic v2 models — fully typed results with autocomplete support
- Namespaced API —
client.twitter.*,client.instagram.*,client.reddit.*,client.tiktok.*
from xpoz import XpozClient
client = XpozClient("your-api-key")
user = client.twitter.get_user("elonmusk")
print(f"{user.name} — {user.followers_count:,} followers")
results = client.twitter.search_posts("artificial intelligence", start_date="2025-01-01")
for tweet in results.data:
print(tweet.text, tweet.like_count)
client.close()Get your API key at https://xpoz.ai/get-token, then use it as follows:
# Pass API key directly
client = XpozClient("your-api-key")
# Or use XPOZ_API_KEY environment variable
import os
os.environ["XPOZ_API_KEY"] = "your-api-key"
client = XpozClient()
# Custom server URL (also reads XPOZ_SERVER_URL env var)
client = XpozClient("your-api-key", server_url="https://xpoz.ai/mcp")
# Custom operation timeout (default: 300 seconds)
client = XpozClient("your-api-key", timeout=600)Want to try the SDK before signing up? Mint a free trial token (no account needed, valid for 5 days):
curl -X POST https://api.xpoz.ai/api/trial/token \
-H "Content-Type: application/json" \
-d '{"source": "sdk"}'
# -> { "success": true, "data": { "accessKey": "TRIAL...", "expiresInSeconds": 432000 }, ... }The source field is required — it identifies where the trial token request came from (e.g. skills, a specific page, sdk, cli).
Then use the returned token (it starts with TRIAL) as your API key:
# Optional: try without your own account
client = XpozClient("TRIAL...") # the token from the curl response above
user = client.twitter.get_user("elonmusk")The trial token is rate-limited and intentionally restricted:
- Read-only data tools only — search and lookup methods across Twitter, Instagram, Reddit, and TikTok. Account, tracking, and operation-management methods are not available and return an upgrade prompt.
- Up to 5 results per call — every response is capped at 5 items.
response_typeis forced tofast, so pagination (PAGING) and CSV export (CSV) are unavailable. - Cached data only — trial reads from the database and does not trigger live on-demand crawling, so the very latest posts may not appear.
For full result limits, pagination, CSV export, and live data, get your own API key.
# Sync — auto-closes on exit
with XpozClient("your-api-key") as client:
user = client.twitter.get_user("elonmusk")
# Async
import asyncio
from xpoz import AsyncXpozClient
async def main():
async with AsyncXpozClient("your-api-key") as client:
user = await client.twitter.get_user("elonmusk")
results = await client.twitter.search_posts("AI")
page2 = await results.next_page()
asyncio.run(main())Methods that return large datasets use server-side pagination (100 items per page). These return a PaginatedResult[T] with built-in helpers:
results = client.twitter.search_posts("AI")
results.data # list[TwitterPost] — current page
results.pagination.total_rows # total matching rows
results.pagination.total_pages # total pages
results.pagination.page_number # current page number
results.pagination.page_size # items per page (100)
results.pagination.results_count # items on current page
results.has_next_page() # bool
# Navigate pages
page2 = results.next_page() # fetch next page
page5 = results.get_page(5) # jump to specific page
# Export to CSV
csv_url = results.export_csv() # returns download URLMethods that return PaginatedResult support a response_type parameter to control how results are fetched. Import the ResponseType enum:
from xpoz import XpozClient, ResponseTypeReturns up to limit results directly — no polling, no pagination. This is the default behavior when response_type is not specified.
results = client.twitter.search_posts(
"bitcoin",
limit=10,
fields=["id", "text", "like_count"]
)
# Equivalent to response_type=ResponseType.FAST
for tweet in results.data:
print(tweet.text)Returns full paginated results (100 items per page). Use this when you need to iterate through all results.
results = client.twitter.search_posts(
"bitcoin",
response_type=ResponseType.PAGING,
)Triggers a server-side CSV export. The result contains no inline data — call export_csv() to get the download URL.
results = client.twitter.search_posts(
"bitcoin",
response_type=ResponseType.CSV,
)
csv_url = results.export_csv()response_type and limit are available on:
| Platform | Method |
|---|---|
search_posts |
|
get_posts_by_author |
|
get_users_by_keywords |
|
search_posts |
|
get_posts_by_user |
|
get_users_by_keywords |
|
search_posts |
|
| TikTok | search_posts |
| TikTok | get_posts_by_user |
| TikTok | get_users_by_keywords |
| TikTok | get_posts_by_hashtags |
| TikTok | get_users_by_hashtags |
| TikTok | get_posts_by_sound |
All methods accept a fields parameter. Use snake_case — the SDK translates to camelCase automatically.
# Only fetch the fields you need (faster + less memory)
results = client.twitter.search_posts(
"AI",
fields=["id", "text", "like_count", "retweet_count", "created_at_date"]
)
user = client.twitter.get_user(
"elonmusk",
fields=["id", "username", "name", "followers_count", "description"]
)Requesting fewer fields significantly improves response time.
The query parameter on all search_* and get_*_by_keywords methods supports a Lucene-style full-text syntax across Twitter, Instagram, and Reddit.
Wrap in double quotes to require an exact match:
"machine learning"
"climate change"
Space-separated terms without quotes match posts containing any of the words:
AI crypto blockchain
Use AND, OR, NOT (case-insensitive). A bare space is treated as OR — be explicit:
"deep learning" AND python
tensorflow OR pytorch
climate NOT politics
(AI OR "artificial intelligence") AND ethics
(startup OR entrepreneur) NOT "venture capital"
results = client.twitter.search_posts(
'("machine learning" OR "deep learning") AND python NOT spam',
start_date="2025-01-01",
language="en",
)Note: Do not use
from:,lang:,since:, oruntil:in the query string — use the dedicated parameters (author_username,language,start_date,end_date) instead.
from xpoz import (
XpozError,
AuthenticationError,
ConnectionError,
OperationTimeoutError,
OperationFailedError,
OperationCancelledError,
NotFoundError,
ValidationError,
)
try:
user = client.twitter.get_user("nonexistent_user_12345")
except OperationFailedError as e:
print(f"Operation {e.operation_id} failed: {e.error}")
except OperationTimeoutError as e:
print(f"Timed out after {e.elapsed_seconds}s")
except AuthenticationError:
print("Invalid API key")
except XpozError as e:
print(f"Xpoz error: {e}")Get a single Twitter user profile.
# By username (default)
user = client.twitter.get_user("elonmusk")
# By numeric ID
user = client.twitter.get_user("44196397", identifier_type="id")Search users by name or username. Returns up to 10 results.
users = client.twitter.search_users("elon")get_user_connections(username, connection_type, *, fields, force_latest) -> PaginatedResult[TwitterUser]
Get followers or following for a user.
followers = client.twitter.get_user_connections("elonmusk", "followers")
following = client.twitter.get_user_connections("elonmusk", "following")get_users_by_keywords(query, *, fields, start_date, end_date, language, force_latest, response_type, limit) -> PaginatedResult[TwitterUser]
Find users who authored posts matching a keyword query. Includes aggregation fields like relevant_tweets_count, relevant_tweets_likes_sum.
users = client.twitter.get_users_by_keywords(
'"machine learning"',
fields=["username", "name", "followers_count", "relevant_tweets_count", "relevant_tweets_likes_sum"]
)Get 1-100 posts by their IDs.
tweets = client.twitter.get_posts_by_ids(["1234567890", "0987654321"])get_posts_by_author(identifier, identifier_type="username", *, fields, start_date, end_date, force_latest, response_type, limit) -> PaginatedResult[TwitterPost]
Get all posts by an author with optional date filtering.
results = client.twitter.get_posts_by_author("elonmusk", start_date="2025-01-01")search_posts(query, *, fields, start_date, end_date, author_username, author_id, language, force_latest, response_type, limit) -> PaginatedResult[TwitterPost]
Full-text search with filters. Supports exact phrases ("machine learning"), boolean operators (AI AND python), and parentheses.
results = client.twitter.search_posts(
'"artificial intelligence" AND ethics',
start_date="2025-01-01",
end_date="2025-06-01",
language="en",
fields=["id", "text", "like_count", "author_username", "created_at_date"]
)Get retweets of a specific post (database only).
retweets = client.twitter.get_retweets("1234567890")Get quote tweets of a specific post.
quotes = client.twitter.get_quotes("1234567890")Get replies to a specific post.
comments = client.twitter.get_comments("1234567890")get_post_interacting_users(post_id, interaction_type, *, fields, force_latest) -> PaginatedResult[TwitterUser]
Get users who interacted with a post. interaction_type: "commenters", "quoters", "retweeters".
commenters = client.twitter.get_post_interacting_users("1234567890", "commenters")Count tweets containing a phrase within a date range.
count = client.twitter.count_posts("bitcoin", start_date="2025-01-01")
print(f"{count:,} tweets mention bitcoin")user = client.instagram.get_user("instagram")
print(f"{user.full_name} — {user.follower_count:,} followers")users = client.instagram.search_users("nasa")get_user_connections(username, connection_type, *, fields, force_latest) -> PaginatedResult[InstagramUser]
followers = client.instagram.get_user_connections("instagram", "followers")get_users_by_keywords(query, *, fields, start_date, end_date, force_latest, response_type, limit) -> PaginatedResult[InstagramUser]
users = client.instagram.get_users_by_keywords('"sustainable fashion"')Post IDs must be in strong_id format: "media_id_user_id" (e.g. "3606450040306139062_4836333238").
posts = client.instagram.get_posts_by_ids(["3606450040306139062_4836333238"])get_posts_by_user(identifier, identifier_type="username", *, fields, start_date, end_date, force_latest, response_type, limit) -> PaginatedResult[InstagramPost]
results = client.instagram.get_posts_by_user("nasa")search_posts(query, *, fields, start_date, end_date, force_latest, response_type, limit) -> PaginatedResult[InstagramPost]
results = client.instagram.search_posts("travel photography")get_comments(post_id, *, fields, start_date, end_date, force_latest) -> PaginatedResult[InstagramComment]
comments = client.instagram.get_comments("3606450040306139062_4836333238")get_post_interacting_users(post_id, interaction_type, *, fields, force_latest) -> PaginatedResult[InstagramUser]
interaction_type: "commenters", "likers".
likers = client.instagram.get_post_interacting_users("3606450040306139062_4836333238", "likers")user = client.reddit.get_user("spez")
print(f"{user.username} — {user.total_karma:,} karma")users = client.reddit.search_users("spez")get_users_by_keywords(query, *, fields, start_date, end_date, subreddit, force_latest) -> PaginatedResult[RedditUser]
users = client.reddit.get_users_by_keywords('"machine learning"', subreddit="MachineLearning")search_posts(query, *, fields, start_date, end_date, sort, time, subreddit, force_latest, response_type, limit) -> PaginatedResult[RedditPost]
sort: "relevance", "hot", "top", "new", "comments". time: "hour", "day", "week", "month", "year", "all".
results = client.reddit.search_posts(
"python tutorial",
subreddit="learnpython",
sort="top",
time="month"
)get_post_with_comments(post_id, *, post_fields, comment_fields, force_latest) -> RedditPostWithComments
Returns a composite object with the post and its paginated comments.
result = client.reddit.get_post_with_comments("abc123")
print(result.post.title)
for comment in result.comments:
print(f" {comment.author_username}: {comment.body[:80]}")search_comments(query, *, fields, start_date, end_date, subreddit) -> PaginatedResult[RedditComment]
comments = client.reddit.search_comments("helpful tip", subreddit="LifeProTips")subs = client.reddit.search_subreddits("machine learning")get_subreddit_with_posts(subreddit_name, *, subreddit_fields, post_fields, force_latest) -> SubredditWithPosts
result = client.reddit.get_subreddit_with_posts("wallstreetbets")
print(f"r/{result.subreddit.display_name} — {result.subreddit.subscribers_count:,} members")
for post in result.posts:
print(f" {post.title} ({post.score} points)")get_subreddits_by_keywords(query, *, fields, start_date, end_date, force_latest) -> PaginatedResult[RedditSubreddit]
subs = client.reddit.get_subreddits_by_keywords("cryptocurrency")user = client.tiktok.get_user("charlidamelio")
print(f"{user.nickname} — {user.follower_count:,} followers")
# By numeric ID
user = client.tiktok.get_user("123456789", identifier_type="id")users = client.tiktok.search_users("charli")
top_five = client.tiktok.search_users("charli", limit=5)get_users_by_keywords(query, *, fields, start_date, end_date, force_latest, response_type, limit) -> PaginatedResult[TiktokUser]
users = client.tiktok.get_users_by_keywords(
'"machine learning"',
response_type=ResponseType.FAST,
limit=20,
)posts = client.tiktok.get_posts_by_ids(["7123456789012345678"])get_posts_by_user(identifier, identifier_type="username", *, fields, start_date, end_date, force_latest, response_type, limit) -> PaginatedResult[TiktokPost]
results = client.tiktok.get_posts_by_user("charlidamelio", start_date="2025-01-01")search_posts(query, *, fields, start_date, end_date, force_latest, response_type, limit) -> PaginatedResult[TiktokPost]
results = client.tiktok.search_posts(
"travel vlog",
start_date="2025-01-01",
response_type=ResponseType.FAST,
limit=30,
)get_posts_by_hashtags(hashtags, *, fields, start_date, end_date, force_latest, response_type, limit) -> PaginatedResult[TiktokPost]
Search posts by hashtags via the indexed hashtags column. Pass bare alphanumeric tags (no leading #). Max 5 hashtags per request; OR semantics across the list.
results = client.tiktok.get_posts_by_hashtags(
["dance", "fyp"],
response_type=ResponseType.FAST,
limit=50,
)get_users_by_hashtags(hashtags, *, fields, start_date, end_date, force_latest, response_type, limit) -> PaginatedResult[TiktokUser]
Find users who authored posts tagged with the given hashtags. Same input rules as get_posts_by_hashtags.
users = client.tiktok.get_users_by_hashtags(
["sustainable_fashion"],
response_type=ResponseType.FAST,
limit=20,
)Search sound/music objects by keyword (title or artist). Pass the returned id to get_posts_by_sound.
sounds = client.tiktok.search_sounds("dance monkey")
sound_id = sounds[0].idget_posts_by_sound(sound_id, *, fields, start_date, end_date, force_latest, response_type, limit) -> PaginatedResult[TiktokPost]
Find posts that use a specific sound via the indexed music_id column. Pass a single numeric sound_id from search_sounds.
results = client.tiktok.get_posts_by_sound(
"7016548364456789012",
response_type=ResponseType.FAST,
limit=50,
)get_comments(post_id, *, fields, start_date, end_date, force_latest) -> PaginatedResult[TiktokComment]
comments = client.tiktok.get_comments("7123456789012345678")Read-only account, plan, and usage information for the authenticated user.
Returns the plan (name + feature limits), billing (period + next renewal; billing is None on the Free plan), and current usage (remaining subscription/extra credits, extra tracked items).
details = client.account.get_account_details()
print(details.plan.name, details.usage.subscription_credits_remaining)Returns time-series usage for credits and export rows. range is one of "today", "7d", "current_month" (default), "lifetime"; granularity is "hour" or "day" (default). For current remaining balances, use get_account_details().
history = client.account.get_credits_usage_history(range="7d", granularity="day")
for bucket in history.credits:
print(bucket.bucket, bucket.total_used)All models are Pydantic v2 BaseModel subclasses with extra="allow" (unknown fields are preserved, not rejected). All fields are optional and default to None.
| Field | Type | Description |
|---|---|---|
id |
str |
Post ID |
text |
str |
Post text content |
author_id |
str |
Author's user ID |
author_username |
str |
Author's username |
like_count |
int |
Number of likes |
retweet_count |
int |
Number of retweets |
reply_count |
int |
Number of replies |
quote_count |
int |
Number of quotes |
impression_count |
int |
Number of impressions |
bookmark_count |
int |
Number of bookmarks |
lang |
str |
Language code |
hashtags |
list[str] |
Hashtags in tweet |
mentions |
list[str] |
Mentioned usernames |
media_urls |
list[str] |
Media attachment URLs |
urls |
list[str] |
URLs in tweet text |
country |
str |
Country (if geo-tagged) |
created_at |
str |
Creation timestamp |
created_at_date |
str |
Creation date (YYYY-MM-DD) |
conversation_id |
str |
Thread conversation ID |
quoted_tweet_id |
str |
ID of quoted tweet |
reply_to_tweet_id |
str |
ID of parent tweet |
possibly_sensitive |
bool |
Sensitive content flag |
is_retweet |
bool |
Whether this is a retweet |
has_birdwatch_notes |
bool |
Has community notes |
birdwatch_notes_id |
str |
Birdwatch note ID |
birdwatch_notes_text |
str |
Birdwatch note text |
birdwatch_notes_url |
str |
Birdwatch note URL |
status |
str |
Tweet status |
| Field | Type | Description |
|---|---|---|
id |
str |
User ID |
username |
str |
Username (handle) |
name |
str |
Display name |
description |
str |
Bio text |
location |
str |
Location string |
verified |
bool |
Verification status |
verified_type |
str |
Verification type |
followers_count |
int |
Number of followers |
following_count |
int |
Number of following |
tweet_count |
int |
Total tweets |
likes_count |
int |
Total likes |
profile_image_url |
str |
Profile picture URL |
created_at |
str |
Account creation timestamp |
account_based_in |
str |
Account location |
| Field | Type | Description |
|---|---|---|
id |
str |
Post ID (strong_id format) |
caption |
str |
Post caption |
username |
str |
Author username |
full_name |
str |
Author display name |
like_count |
int |
Number of likes |
comment_count |
int |
Number of comments |
reshare_count |
int |
Number of reshares |
video_play_count |
int |
Video play count |
media_type |
str |
Media type |
image_url |
str |
Image URL |
video_url |
str |
Video URL |
created_at_date |
str |
Creation date |
gen_ai_chat_with_ai_cta_info |
str |
Gen AI chat CTA info |
has_high_risk_gen_ai_inform_treatment |
bool |
High risk Gen AI treatment flag |
| Field | Type | Description |
|---|---|---|
id |
str |
User ID |
username |
str |
Username |
full_name |
str |
Display name |
biography |
str |
Bio text |
is_private |
bool |
Private account |
is_verified |
bool |
Verified status |
follower_count |
int |
Followers |
following_count |
int |
Following |
media_count |
int |
Total posts |
profile_pic_url |
str |
Profile picture URL |
| Field | Type | Description |
|---|---|---|
id |
str |
Comment ID |
text |
str |
Comment text |
username |
str |
Author username |
parent_post_id |
str |
Parent post ID |
like_count |
int |
Number of likes |
child_comment_count |
int |
Reply count |
created_at_date |
str |
Creation date |
| Field | Type | Description |
|---|---|---|
id |
str |
Post ID |
title |
str |
Post title |
selftext |
str |
Post body text |
author_username |
str |
Author username |
subreddit_name |
str |
Subreddit name |
score |
int |
Net score |
upvotes |
int |
Upvote count |
comments_count |
int |
Comment count |
url |
str |
Post URL |
permalink |
str |
Reddit permalink |
is_self |
bool |
Self post (text only) |
over18 |
bool |
NSFW flag |
created_at_date |
str |
Creation date |
| Field | Type | Description |
|---|---|---|
id |
str |
User ID |
username |
str |
Username |
total_karma |
int |
Total karma |
link_karma |
int |
Link karma |
comment_karma |
int |
Comment karma |
is_gold |
bool |
Reddit Gold status |
is_mod |
bool |
Moderator status |
profile_description |
str |
Profile bio |
created_at_date |
str |
Account creation date |
| Field | Type | Description |
|---|---|---|
id |
str |
Comment ID |
body |
str |
Comment text |
author_username |
str |
Author username |
parent_post_id |
str |
Parent post ID |
score |
int |
Net score |
depth |
int |
Nesting depth |
is_submitter |
bool |
Is OP |
created_at_date |
str |
Creation date |
| Field | Type | Description |
|---|---|---|
id |
str |
Subreddit ID |
display_name |
str |
Subreddit name |
title |
str |
Subreddit title |
public_description |
str |
Short description |
description |
str |
Full description |
subscribers_count |
int |
Subscriber count |
active_user_count |
int |
Active users |
over18 |
bool |
NSFW flag |
created_at_date |
str |
Creation date |
| Field | Type | Description |
|---|---|---|
id |
str |
Post ID |
description |
str |
Post caption/description |
description_language |
str |
Language of description |
user_id |
str |
Author user ID |
username |
str |
Author username |
nickname |
str |
Author display name |
like_count |
int |
Number of likes |
comment_count |
int |
Number of comments |
play_count |
int |
Video play count |
collect_count |
int |
Number of collects/saves |
download_count |
int |
Number of downloads |
forward_count |
int |
Number of forwards/shares |
video_thumbnail |
str |
Thumbnail URL |
video_url |
list[str] |
Array of video URLs |
duration |
int |
Video duration in seconds |
hashtags |
list[str] |
Hashtags in the post |
post_type |
int |
Post type code |
is_private |
bool |
Private post flag |
created_at |
str |
Creation timestamp |
created_at_date |
str |
Creation date (YYYY-MM-DD) |
| Field | Type | Description |
|---|---|---|
id |
str |
User ID |
username |
str |
Username |
nickname |
str |
Display name |
signature |
str |
Bio text |
sec_uid |
str |
Secure user ID |
avatar |
str |
Profile picture URL |
is_private |
bool |
Private account |
is_verified |
bool |
Verified status |
follower_count |
int |
Number of followers |
following_count |
int |
Number of following |
like_count |
int |
Total likes received |
post_count |
int |
Total posts |
language |
str |
Profile language |
region |
str |
Account region |
created_at |
str |
Account creation date |
| Field | Type | Description |
|---|---|---|
id |
str |
Comment ID |
post_id |
str |
Parent post ID |
user_id |
str |
Author user ID |
username |
str |
Author username |
text |
str |
Comment text |
like_count |
int |
Number of likes |
created_at |
str |
Creation timestamp |
created_at_date |
str |
Creation date (YYYY-MM-DD) |
| Field | Type | Description |
|---|---|---|
id |
str |
Sound/music ID |
title |
str |
Sound title |
author |
str |
Sound artist/author |
album |
str |
Album name |
duration |
int |
Duration in seconds |
user_count |
int |
Number of posts using the sound |
is_original |
bool |
Whether the sound is original |
is_commerce_music |
bool |
Whether the sound is commercial |
is_original_sound |
bool |
Whether it is an original sound |
Returned by get_account_details(). All fields are nested models and may be None.
plan: AccountPlan | Nonebilling: AccountBilling | None(Noneon the Free plan)usage: AccountUsage | None
| Field | Type | Description |
|---|---|---|
name |
str |
Plan name |
features |
PlanFeatures | None |
Plan feature limits |
| Field | Type | Description |
|---|---|---|
credits |
int |
Subscription credits per period |
credit_reset_frequency |
str |
How often credits reset |
extra_credit_price |
float |
Price per extra credit |
tracked_items |
int |
Tracked-item allowance |
csv_row_export_limit |
int |
CSV row export limit |
extra_csv_row_price |
float |
Price per extra CSV row |
extra_tracked_item_price |
float |
Price per extra tracked item |
max_rows_per_export |
int |
Max rows per single export |
| Field | Type | Description |
|---|---|---|
billing_period |
str |
"monthly" or "annual" |
next_renewal_date |
str |
Next renewal date |
| Field | Type | Description |
|---|---|---|
subscription_credits_remaining |
int |
Subscription credits remaining |
extra_credits_remaining |
int |
Extra credits remaining |
extra_tracked_items |
int |
Extra tracked items purchased |
Returned by get_credits_usage_history().
| Field | Type | Description |
|---|---|---|
range |
str |
Requested range |
granularity |
str |
Requested granularity |
generated_at |
str |
Timestamp the report was generated |
credits |
list[UsageHistoryBucket] |
Credit usage buckets over time |
export_rows |
list[UsageHistoryBucket] |
Export-rows usage buckets over time |
| Field | Type | Description |
|---|---|---|
bucket |
str |
Bucket timestamp (hour or day) |
subscription_used |
int |
Subscription units used in the bucket |
extra_used |
int |
Extra units used in the bucket |
total_used |
int |
Total units used in the bucket |
extra_purchased |
int |
Extra units purchased in the bucket |
RedditPostWithComments — returned by get_post_with_comments():
post: RedditPostcomments: list[RedditComment]comments_pagination: PaginationInfo | None
SubredditWithPosts — returned by get_subreddit_with_posts():
subreddit: RedditSubredditposts: list[RedditPost]posts_pagination: PaginationInfo | None
| Variable | Description | Default |
|---|---|---|
XPOZ_API_KEY |
API key for authentication | — |
XPOZ_SERVER_URL |
MCP server URL | https://mcp.xpoz.ai/mcp |
Tests hit the live Xpoz API and require a valid API key:
XPOZ_API_KEY=your-api-key pytest tests/ -vTests must run sequentially in a single process to avoid API rate limiting. Do not run multiple pytest processes in parallel.
MIT