AgentStack
Browse Sign in
Browse Why AgentStack Sell Docs
Sign in
MCP verified MIT Self-run

Xpoz Python Sdk

mcp-xpozpublic-xpoz-python-sdk · by XPOZpublic

Python SDK for Xpoz — Pythonic access to Twitter/X, Instagram, Reddit & TikTok data for social listening, research, and AI agents. PyPI: xpoz

No reviews yet
0 installs
20 views
0.0% view→install

Install

$ agentstack add mcp-xpozpublic-xpoz-python-sdk

✓ scanned · ✓ verified, works with Claude Code, Cursor, and more.

Security review

✓ Passed

No issues found. Passed automated security review. · v0.1.0 How review works →

  • Prompt-injection patterns
  • Secret / credential exfiltration
  • Dangerous shell & filesystem operations
  • Untrusted network calls
  • Known-malicious package signatures

What it can access

  • Network access Used
  • Filesystem access No
  • Shell / process execution No
  • Environment & secrets Used
  • Dynamic code execution No

From automated source analysis of v0.1.0. “Used” means the capability is present in the source — more access means more to trust, not that it’s unsafe.

View the full security report →

Verified badge

Passed review? Show it. Paste this badge into your README, it links to the public security report.

AgentStack Verified badge Links to your public security report.
[![AgentStack Verified](https://agentstack.voostack.com/badges/verified.svg)](https://agentstack.voostack.com/security/report/mcp-xpozpublic-xpoz-python-sdk)

Reliability & compatibility

Security review passed
0 installs to date
no reviews yet
1mo ago

Declared compatibility

Claude CodeClaude DesktopCursorWindsurf

Compatibility is declared by the source manifest. End-to-end runtime verification is coming, see below.

Preview Execution monitoring

We're building live execution health for every listing: tool-call success rate, median latency, uptime, and last-checked timestamps, measured, not self-reported. It isn't live yet, so we don't show numbers we can't stand behind.

How agent discovery & health will work →
Are you the author of Xpoz Python Sdk? Claim this listing to set pricing, connect Stripe payouts, and keep 70% of every sale.
Sign up to claim

About

Xpoz Python SDK

[](https://pypi.org/project/xpoz/)

Python SDK for the Xpoz social media intelligence platform. Query Twitter/X, Instagram, Reddit, and TikTok data through a simple, Pythonic interface.

Installation

pip install xpoz

Requires Python 3.10+.

Get an API Key

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-here

What is Xpoz?

Xpoz 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.

Features

  • 42 data methods across Twitter, Instagram, Reddit, and TikTok
  • Sync and async clientsXpozClient and AsyncXpozClient
  • Automatic operation polling — long-running queries are abstracted away
  • Response modesResponseType.FAST for quick limited results, PAGING for full pagination, CSV for export
  • Server-side paginationPaginatedResult with next_page(), get_page(n)
  • CSV exportexport_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 APIclient.twitter.*, client.instagram.*, client.reddit.*, client.tiktok.*

Quick Start

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()

Authentication

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)

Trial Access (No Sign-Up Required)

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_type is forced to fast, 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.

Context Manager

# 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())

Pagination

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 URL

Response Modes

Methods that return PaginatedResult support a response_type parameter to control how results are fetched. Import the ResponseType enum:

from xpoz import XpozClient, ResponseType

Fast mode (default)

Returns 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)

Paging mode

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,
)

CSV mode

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()

Supported methods

response_type and limit are available on:

| Platform | Method | | --------- | ----------------------- | | Twitter | search_posts | | Twitter | get_posts_by_author | | Twitter | get_users_by_keywords | | Instagram | search_posts | | Instagram | get_posts_by_user | | Instagram | get_users_by_keywords | | Reddit | 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 |

Field Selection

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.

Query Syntax

The query parameter on all search_* and get_*_by_keywords methods supports a Lucene-style full-text syntax across Twitter, Instagram, and Reddit.

Exact phrase

Wrap in double quotes to require an exact match:

"machine learning"
"climate change"

Keywords (any word)

Space-separated terms without quotes match posts containing any of the words:

AI crypto blockchain

Boolean operators

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

Grouping with parentheses

(AI OR "artificial intelligence") AND ethics
(startup OR entrepreneur) NOT "venture capital"

Combined example

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:, or until: in the query string — use the dedicated parameters (author_username, language, start_date, end_date) instead.

Error Handling

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}")

API Reference

Twitter — client.twitter

get_user(identifier, identifier_type="username", *, fields) -> TwitterUser

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(name, *, limit=None, fields) -> list[TwitterUser]

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_posts_by_ids(post_ids, *, fields, force_latest) -> list[TwitterPost]

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(post_id, *, fields, start_date) -> PaginatedResult[TwitterPost]

Get retweets of a specific post (database only).

retweets = client.twitter.get_retweets("1234567890")
get_quotes(post_id, *, fields, start_date, force_latest) -> PaginatedResult[TwitterPost]

Get quote tweets of a specific post.

quotes = client.twitter.get_quotes("1234567890")
get_comments(post_id, *, fields, start_date, force_latest) -> PaginatedResult[TwitterPost]

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_posts(phrase, *, start_date, end_date) -> int

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")

Instagram — client.instagram

get_user(identifier, identifier_type="username", *, fields) -> InstagramUser
user = client.instagram.get_user("instagram")
print(f"{user.full_name} — {user.follower_count:,} followers")
search_users(name, *, limit=None, fields) -> list[InstagramUser]
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"')
get_posts_by_ids(post_ids, *, fields, force_latest) -> list[InstagramPost]

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")

Reddit — client.reddit

get_user(username, *, fields) -> RedditUser
user = client.reddit.get_user("spez")
print(f"{user.username} — {user.total_karma:,} karma")
search_users(name, *, limit=None, fields) -> list[RedditUser]
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"
)
`getpostwithcomments(postid, *, postfields, commentfields, force_latest) -> RedditPost

Source & license

This open-source MCP server is cataloged on AgentStack and links to its original source — we do not rehost the code.

Install and usage instructions live in the source repository linked above.

Reviews

No reviews yet, be the first.

Versions

  • v0.1.0 Imported from the upstream source.