Python SDK
Official Python client library for RelayAPI. Post to 21 platforms with a few lines of Python.
Official Python SDK for RelayAPI. Post to 21 platforms, manage accounts, upload media, and track analytics.
Setup
Install
pip install relayAuthenticate
from relay import Relay
client = Relay() # reads RELAY_API_KEY from environmentOr pass the key directly:
client = Relay(api_key="rlay_live_...")Get your API key from relayapi.dev under Settings > API Keys.
Quick Examples
Create and Publish a Post
post = client.posts.create(
content="Hello from the Python SDK!",
targets=["acc_twitter_123", "acc_linkedin_456"],
scheduled_at="now",
)
print(f"Post created: {post.id} — status: {post.status}")Schedule a Post
post = client.posts.create(
content="This will go out tomorrow morning",
targets=["twitter", "linkedin"],
scheduled_at="2025-01-15T09:00:00Z",
timezone="America/New_York",
)Save as Draft
post = client.posts.create(
content="Work in progress...",
targets=["instagram"],
scheduled_at="draft",
)List Connected Accounts
accounts = client.accounts.list()
for acc in accounts.data:
print(f"{acc.platform}: {acc.display_name} ({acc.id})")Upload Media
# Get a presigned upload URL
presign = client.media.presign(
filename="photo.jpg",
content_type="image/jpeg",
)
# Upload the file directly to the URL
import httpx
with open("photo.jpg", "rb") as f:
httpx.put(presign.upload_url, content=f.read(), headers={"Content-Type": "image/jpeg"})
# Use the public URL in a post
post = client.posts.create(
content="Check out this photo!",
targets=["instagram"],
media=[{"url": presign.url, "type": "image"}],
scheduled_at="now",
)Cross-Post with Per-Platform Content
post = client.posts.create(
content="Default content for all platforms",
targets=["twitter", "linkedin", "bluesky"],
target_options={
"twitter": {"content": "Short version for Twitter"},
"linkedin": {"content": "Longer professional version for LinkedIn with more context"},
},
scheduled_at="now",
)Get Post Analytics
analytics = client.analytics.retrieve(post_id="post_abc123")
for platform, metrics in analytics.items():
print(f"{platform}: {metrics.impressions} impressions, {metrics.likes} likes")Check Account Health
health = client.accounts.health()
for acc in health:
status = "healthy" if acc.healthy else "needs attention"
print(f"{acc.platform} ({acc.username}): {status}")Error Handling
from relay import Relay, APIError, AuthenticationError, RateLimitError
client = Relay()
try:
post = client.posts.create(
content="Hello!",
targets=["twitter"],
scheduled_at="now",
)
except AuthenticationError:
print("Invalid API key")
except RateLimitError as e:
print(f"Rate limited — retry after {e.retry_after}s")
except APIError as e:
print(f"API error {e.status_code}: {e.message}")Async Usage
The SDK supports async/await with AsyncRelay:
import asyncio
from relay import AsyncRelay
async def main():
client = AsyncRelay()
post = await client.posts.create(
content="Async post!",
targets=["twitter"],
scheduled_at="now",
)
print(f"Posted: {post.id}")
asyncio.run(main())Configuration
| Environment Variable | Description |
|---|---|
RELAY_API_KEY | Your API key (required if not passed to constructor) |
RELAY_BASE_URL | Custom API base URL (default: https://api.relayapi.dev) |
Links
Found something wrong? Help us improve this page.