Social media API from Python
Complete Python guide: install the SDK, connect social accounts via OAuth, post to 7 platforms, schedule with datetime, pull analytics, manage the inbox, and handle webhooks with Flask.
- • Python 3.9+ with pip
- • An Aether account — free, no credit card required
- • At least one connected social profile (Business/Creator accounts for Instagram)
Step 1 — Install the SDK
pip install aetherSet your API key as an environment variable:
# Set your API key in the environment
export AETHER_API_KEY="your_api_key_here"
# Or use a .env file with python-dotenv:
# pip install python-dotenv
# AETHER_API_KEY=your_api_key_hereStep 2 — Instantiate the client
import os
from aether import Aether
client = Aether(api_key=os.environ["AETHER_API_KEY"])
# Verify the connection
profiles = client.profiles.list()
print(f"Connected profiles: {len(profiles.data)}")Step 3 — Connect a social account
Each platform requires OAuth. Aether's Connect Links handle the entire flow — generate a URL, open it in a browser, authenticate on the platform, and the profile appears in your account immediately:
import os
import webbrowser
from aether import Aether
client = Aether(api_key=os.environ["AETHER_API_KEY"])
# Generate an OAuth Connect Link for Instagram
link = client.connect_links.create(
platform="instagram",
# After authentication, Instagram redirects here
redirect_url="https://your-app.com/oauth/callback",
)
print(f"Connect URL: {link.url}")
# Open in the browser so the user can authenticate
webbrowser.open(link.url)
# After OAuth, the profile appears immediately:
profiles = client.profiles.list()
instagram = next(p for p in profiles.data if p.platform == "instagram")
print(f"Connected: {instagram.display_name} ({instagram.id})")
# ig_abc123Step 4 — Post immediately
Pass an array of profile IDs to post to multiple platforms in one call:
import os
from aether import Aether
client = Aether(api_key=os.environ["AETHER_API_KEY"])
# Post immediately to multiple platforms
post = client.posts.create(
text="New release is live — check the changelog 🚀",
profile_ids=[
"ig_abc123", # Instagram
"li_comp789", # LinkedIn
"th_user456", # Threads
],
media_urls=["https://your-cdn.com/release-screenshot.png"],
)
print(post.data.id) # post_abc123
print(post.data.status) # "publishing"Step 5 — Schedule for a future time
Pass scheduled_for as an ISO 8601 string. Python's datetime module makes this straightforward:
import os
from datetime import datetime, timezone, timedelta
from aether import Aether
client = Aether(api_key=os.environ["AETHER_API_KEY"])
# Schedule for tomorrow at 9am UTC
tomorrow_9am = (
datetime.now(timezone.utc).replace(hour=9, minute=0, second=0, microsecond=0)
+ timedelta(days=1)
).isoformat()
post = client.posts.create(
text="Good morning — here's what we shipped this week.",
profile_ids=["ig_abc123", "li_comp789"],
scheduled_for=tomorrow_9am, # "2026-07-16T09:00:00+00:00"
)
print(post.data.status) # "scheduled"
print(post.data.scheduled_for) # 2026-07-16T09:00:00+00:00Per-platform content overrides
Use the overrides dict to write different copy per platform — all in one API call:
# Per-platform overrides — tailor content per profile in one call
post = client.posts.create(
text="Default caption — shown if no override is set for a profile.",
profile_ids=["ig_abc123", "li_comp789", "tt_xyz789"],
overrides={
"ig_abc123": {
"text": "Launch day 🎉 #buildinpublic #saas #startup",
},
"li_comp789": {
"text": (
"Today we shipped a major product update. "
"Here's what changed and what's coming next:"
),
},
"tt_xyz789": {
"text": "we shipped something wild. let me explain 👀",
},
},
)Pull analytics
Account-level and post-level metrics across all platforms:
import os
from aether import Aether
client = Aether(api_key=os.environ["AETHER_API_KEY"])
# Account-level metrics for the last 30 days
metrics = client.analytics.get_account_metrics(
from_date="2026-06-01",
to_date="2026-06-30",
granularity="day",
platform="instagram", # optional — omit for all platforms
)
for point in metrics.data:
print(f"{point.date}: {point.impressions} impressions, {point.engagement} engagements")
# Post-level metrics
post_metrics = client.analytics.get_post_metrics("post_abc123")
for m in post_metrics.data:
print(f"{m.platform}: {m.metric_type} = {m.value}")Read and reply to the inbox
DMs and comments from all platforms in one unified API:
# Read and reply to DMs across all platforms
messages = client.inbox.list(status="unread", limit=20)
for msg in messages.data:
print(f"[{msg.platform}] {msg.sender_name}: {msg.text}")
# Reply to the message
if "pricing" in msg.text.lower():
client.inbox.reply(
message_id=msg.id,
text="Thanks for reaching out! Here's our pricing: https://aetherhq.dev/pricing",
)Handle webhooks with Flask
Build a Flask endpoint to receive real-time publish confirmations and incoming messages. Always verify the HMAC-SHA256 signature:
# Flask webhook handler with HMAC verification
import os
import hmac
import hashlib
from flask import Flask, request, jsonify
app = Flask(__name__)
def verify_signature(body: bytes, signature: str, secret: str) -> bool:
expected = "sha256=" + hmac.new(
secret.encode(), body, hashlib.sha256
).hexdigest()
return hmac.compare_digest(expected, signature)
@app.route("/webhooks/aether", methods=["POST"])
def webhook():
sig = request.headers.get("X-Aether-Signature", "")
if not verify_signature(request.data, sig, os.environ["AETHER_WEBHOOK_SECRET"]):
return jsonify({"error": "Invalid signature"}), 401
payload = request.get_json(force=True)
event = payload.get("event")
data = payload.get("data", {})
if event == "post.published":
print(f"Published on {data['platform']}: {data.get('platformPostUrl')}")
# Update your DB, notify users, etc.
elif event == "post.failed":
print(f"Failed on {data['platform']}: {data['error']['message']}")
# Alert the user, schedule retry, etc.
elif event == "message.created":
print(f"New DM from {data['senderName']} on {data['platform']}")
# Trigger auto-reply flow, alert support team, etc.
return jsonify({"received": True}), 200
if __name__ == "__main__":
app.run(port=5000)Async usage
The SDK ships an AsyncAether client for use with asyncio:
# Async usage with httpx (Aether's Python SDK supports async)
import os
import asyncio
from aether import AsyncAether
async def main():
client = AsyncAether(api_key=os.environ["AETHER_API_KEY"])
# Post to 3 platforms concurrently
post = await client.posts.create(
text="Shipped something new today 🚀",
profile_ids=["ig_abc123", "li_comp789", "th_user456"],
scheduled_for="2026-07-20T09:00:00Z",
)
print(post.data.status)
# Pull analytics while waiting on post confirmation
metrics, profiles = await asyncio.gather(
client.analytics.get_account_metrics(
from_date="2026-07-01",
to_date="2026-07-14",
),
client.profiles.list(),
)
print(f"{len(profiles.data)} profiles, {len(metrics.data)} data points")
asyncio.run(main())- ✓pip install aether + API key setup
- ✓Connecting social accounts via Connect Links
- ✓Immediate and scheduled posting to multiple platforms
- ✓Per-platform content overrides in one call
- ✓Account and post analytics
- ✓Unified inbox read and reply
- ✓Flask webhook receiver with HMAC-SHA256 verification
- ✓Async usage with AsyncAether
Start building
Free API key — 3 connected accounts, all endpoints, no credit card.