SDKs
Python SDK
Sync and async clients for the Outfame API. Uses pydantic models for response validation, httpx under the hood for async. Works with Python 3.9+.
| Feature | Details |
|---|---|
| Package | outfame |
| Version | 1.8.0 |
| Python | ≥ 3.9 |
| Async support | Yes (asyncio / httpx) |
| License | MIT |
| Source | github.com/outfame/outfame-python |
Installation
pip install outfame
# or
poetry add outfame
# or
pipenv install outfameQuick start
Synchronous client
import outfame
client = outfame.Client(api_key="sk_live_your_api_key")
# List accounts
accounts = client.accounts.list(platform="instagram")
for account in accounts.data:
print(f"{account.id}: {account.instagram_username} ({account.status})")
# Get analytics
overview = client.analytics.overview("acc_7Gx2kLm9Qr", period="30d")
print(f"Net growth: +{overview.net_growth}")
print(f"Engagement rate: {overview.engagement_rate}%")Async client
import outfame
import asyncio
async def main():
client = outfame.AsyncClient(api_key="sk_live_your_api_key")
# All methods are async
accounts = await client.accounts.list(platform="instagram")
# Parallel requests
tasks = [
client.analytics.overview(acc.id, period="7d")
for acc in accounts.data
]
results = await asyncio.gather(*tasks)
for acc, analytics in zip(accounts.data, results):
print(f"{acc.instagram_username}: +{analytics.net_growth} followers")
await client.close()
asyncio.run(main())Tip — The async client pairs well with FastAPI, Django ASGI, and Sanic.
Accounts
# Create an account
account = client.accounts.create(
instagram_username="new_handle",
platform="instagram",
targeting_config={
"competitor_accounts": ["competitor1", "competitor2"],
"hashtags": ["fitness", "wellness"],
"filters": {
"age_range": {"min": 18, "max": 44},
"language": "en",
"activity_level": "high",
},
},
)
print(f"Created: {account.id} (status: {account.status})")
# Update
updated = client.accounts.update(
"acc_7Gx2kLm9Qr",
targeting_config={
"hashtags": ["fitness", "wellness", "nutrition"],
},
)
# Delete
client.accounts.delete("acc_7Gx2kLm9Qr")
# Pagination
accounts = client.accounts.list(limit=10)
while accounts.has_more:
accounts = client.accounts.list(limit=10, cursor=accounts.next_cursor)
for acc in accounts.data:
print(acc.instagram_username)
# Auto-pagination iterator
for account in client.accounts.list_auto_paging(platform="instagram"):
print(account.instagram_username)Analytics
# Overview
overview = client.analytics.overview("acc_7Gx2kLm9Qr", period="30d")
print(f"Followers gained: {overview.followers_gained}")
print(f"Followers lost: {overview.followers_lost}")
print(f"Net growth: {overview.net_growth}")
# Growth time series
growth = client.analytics.growth("acc_7Gx2kLm9Qr", period="7d", granularity="daily")
for point in growth.data_points:
print(f"{point.date}: {point.followers} (+{point.net})")
# Engagement
engagement = client.analytics.engagement("acc_7Gx2kLm9Qr", period="30d")
for content_type, metrics in engagement.by_content_type.items():
print(f"{content_type}: {metrics.engagement_rate}%")
# Audience
audience = client.analytics.audience("acc_7Gx2kLm9Qr")
print(f"Quality score: {audience.quality_score}")
print(f"Bot percentage: {audience.bot_percentage}%")
# Custom date range
custom = client.analytics.overview(
"acc_7Gx2kLm9Qr",
period="custom",
start_date="2026-01-01",
end_date="2026-01-31",
)Targeting
# Get current config
config = client.targeting.config("acc_7Gx2kLm9Qr")
print(f"Competitors: {config.competitor_accounts}")
# Update targeting
client.targeting.update("acc_7Gx2kLm9Qr", {
"competitor_accounts": ["new_rival_1", "new_rival_2"],
"hashtags": ["travel", "digitalnomad"],
"ai_optimization": {
"enabled": True,
"mode": "aggressive",
"quality_threshold": 0.8,
},
})
# AI suggestions
suggestions = client.targeting.suggestions(
"acc_7Gx2kLm9Qr",
goal="balanced",
include_reasoning=True,
)
print(f"Confidence: {suggestions.confidence}")
for s in suggestions.suggestions.add_competitors:
print(f" Add: @{s.username} (relevance: {s.relevance_score})")
print(f" Reason: {s.reasoning}")Engagement
# Activity log
activities = client.engagement.activity("acc_7Gx2kLm9Qr", type="follow", limit=20)
for act in activities.data:
print(f"{act.type} -> @{act.target_username} ({act.quality_score})")
# Stats
stats = client.engagement.stats("acc_7Gx2kLm9Qr")
print(f"Likes: {stats.actions.likes.performed}/{stats.actions.likes.limit}")
print(f"Follow-back rate: {stats.conversion_rates.follow_to_follow_back:.1%}")
# Pause / Resume
client.engagement.pause("acc_7Gx2kLm9Qr", reason="Vacation")
client.engagement.resume("acc_7Gx2kLm9Qr")Webhooks
# Create
webhook = client.webhooks.create(
url="https://yourapp.com/webhooks/outfame",
events=["account.growth_milestone", "engagement.daily_summary"],
)
signing_secret = webhook.signing_secret # Store securely
# Verify signature (helper)
from outfame.webhooks import verify_signature
is_valid = verify_signature(
payload=request.body,
signature=request.headers["X-Outfame-Signature"],
timestamp=request.headers["X-Outfame-Timestamp"],
secret=signing_secret,
)
# Django example
from django.http import JsonResponse
from django.views.decorators.csrf import csrf_exempt
@csrf_exempt
def webhook_handler(request):
if not verify_signature(
payload=request.body.decode(),
signature=request.headers.get("X-Outfame-Signature", ""),
timestamp=request.headers.get("X-Outfame-Timestamp", ""),
secret=settings.OUTFAME_WEBHOOK_SECRET,
):
return JsonResponse({"error": "Invalid signature"}, status=401)
event = json.loads(request.body)
# Process event...
return JsonResponse({"received": True})
# FastAPI example
from fastapi import FastAPI, Request, HTTPException
app = FastAPI()
@app.post("/webhooks/outfame")
async def handle_webhook(request: Request):
body = await request.body()
if not verify_signature(
payload=body.decode(),
signature=request.headers.get("x-outfame-signature", ""),
timestamp=request.headers.get("x-outfame-timestamp", ""),
secret=os.environ["OUTFAME_WEBHOOK_SECRET"],
):
raise HTTPException(status_code=401)
event = await request.json()
print(f"Received: {event['type']}")
return {"received": True}Error handling
from outfame.exceptions import (
OutfameError,
AuthenticationError,
RateLimitError,
NotFoundError,
ValidationError,
)
try:
account = client.accounts.retrieve("acc_invalid")
except NotFoundError:
print("Account not found")
except RateLimitError as e:
print(f"Rate limited. Retry after {e.retry_after}s")
except AuthenticationError:
print("Invalid API key")
except ValidationError as e:
print(f"Validation errors: {e.errors}")
except OutfameError as e:
print(f"API error: {e.code} - {e.message}")Configuration
| Parameter | Type | Default | Description |
|---|---|---|---|
api_key | str | — | API key. Required unless access_token is set. |
access_token | str | None | OAuth access token. |
base_url | str | https://api.outfame.com/v1 | API base URL. |
timeout | float | 30.0 | Request timeout in seconds. |
max_retries | int | 3 | Automatic retries for transient errors. |
Environment variable
# The SDK automatically reads from OUTFAME_API_KEY
export OUTFAME_API_KEY=sk_live_your_api_key
# Then in Python:
client = outfame.Client() # No api_key argument needed