Skip to main content

socialrails

Official Python SDK for the SocialRails API. Schedule and manage social media posts across Twitter/X, LinkedIn, Facebook, Instagram, TikTok, Bluesky, Pinterest, Threads, and YouTube.

Installation

pip install socialrails

Quick start

from socialrails import SocialRails

client = SocialRails(api_key="sr_live_...")

# Create a scheduled post
post = client.posts.create(
    content="Launching our new feature today!",
    platform="twitter",
    scheduled_for="2026-03-15T14:30:00Z",
)
print(post["id"])

client.close()

Async usage

import asyncio
from socialrails import AsyncSocialRails

async def main():
    async with AsyncSocialRails(api_key="sr_live_...") as client:
        post = await client.posts.create(
            content="Hello from async Python!",
            platform="linkedin",
        )
        print(post["id"])

asyncio.run(main())

Configuration

Option Environment variable Description
api_key SOCIALRAILS_API_KEY Your API key (starts with sr_live_). Required.
base_url -- API base URL. Defaults to https://socialrails.com/api/v1.

The constructor checks for the SOCIALRAILS_API_KEY environment variable when no api_key argument is provided:

import os
os.environ["SOCIALRAILS_API_KEY"] = "sr_live_..."

client = SocialRails()  # picks up the env var automatically

API reference

Posts

client.posts.create(...)

Create a new post.

post = client.posts.create(
    content="Check out our blog post!",
    platform="twitter",
    scheduled_for="2026-03-15T14:30:00Z",  # optional
    media=["workspace-id/api-uploads/images/uuid.jpg"],  # optional
    platform_settings={"selectedCommunities": ["12345"]},  # optional
)

Thread support (Twitter and Threads):

post = client.posts.create(
    content="Thread intro",
    platform="twitter",
    thread=["First tweet", "Second tweet", "Third tweet"],
    thread_delay=5,  # minutes between tweets
)

client.posts.list(...)

List posts with optional filters and pagination.

result = client.posts.list(
    status="scheduled",       # draft, scheduled, posted, failed
    platform="twitter",       # filter by platform
    sort="scheduled_for",     # created_at (default) or scheduled_for
    from_date="2026-03-01",   # ISO 8601 date
    to_date="2026-03-31",     # ISO 8601 date
    limit=25,                 # 1-100, default 50
    offset=0,                 # pagination offset
)
# result is a dict: the API returns {"data": [...], "pagination": {...}}
# The SDK unwraps "data", so result is the list of posts when no pagination,
# or the full response dict when pagination is present.

client.posts.get(post_id)

Get a single post by ID.

post = client.posts.get("550e8400-e29b-41d4-a716-446655440000")

client.posts.update(post_id, ...)

Update a draft or scheduled post.

updated = client.posts.update(
    "550e8400-e29b-41d4-a716-446655440000",
    content="Updated content!",
    scheduled_for="2026-03-20T10:00:00Z",
)

client.posts.delete(post_id)

Delete a draft or scheduled post.

result = client.posts.delete("550e8400-e29b-41d4-a716-446655440000")
# {"id": "...", "deleted": True}

client.posts.batch(...)

Create posts across multiple platforms in a single request.

result = client.posts.batch(
    content="Cross-platform announcement!",
    platforms=["twitter", "linkedin", "facebook"],
    scheduled_for="2026-03-15T14:30:00Z",
    platform_content={
        "twitter": "Short version for Twitter!",
        "linkedin": "Detailed professional version for LinkedIn.",
    },
)
print(result["batch_id"])
print(len(result["posts"]))

Analytics

client.analytics.get(...)

Retrieve aggregate or per-post analytics.

# Aggregate analytics for the last 30 days
analytics = client.analytics.get(period="30d")
print(analytics["total_posts"])
print(analytics["by_platform"])

# Filter by platform
analytics = client.analytics.get(platform="twitter", period="7d")

# Per-post analytics
post_analytics = client.analytics.get(post_id="550e8400-...")

Accounts

client.accounts.list()

List all connected social media accounts.

accounts = client.accounts.list()
for account in accounts:
    print(f"{account['provider']}: {account['name']} ({account['status']})")

client.accounts.get_settings(account_id)

Get platform capabilities and default settings for an account.

settings = client.accounts.get_settings("550e8400-...")
print(settings["capabilities"]["character_limit"])
print(settings["available_tools"])

client.accounts.trigger_tool(account_id, tool)

Trigger a platform discovery tool (e.g. list Facebook pages, Pinterest boards).

result = client.accounts.trigger_tool("550e8400-...", "pages")
for page in result["results"]:
    print(page)

AI

client.ai.generate(...)

Generate AI-powered social media content.

result = client.ai.generate(
    prompt="Write a tweet about our new Python SDK launch",
    platform="twitter",
    tone="professional",
)
print(result["content"])

Workspace

client.workspace.get()

Get workspace information including plan limits and current usage.

workspace = client.workspace.get()
print(f"Plan: {workspace['plan']}")
print(f"Posts this month: {workspace['usage']['posts_this_month']}")
print(f"Monthly limit: {workspace['limits']['max_posts_per_month']}")

Media

client.media.upload(file, filename, ...)

Upload a media file via multipart form data.

with open("photo.jpg", "rb") as f:
    media = client.media.upload(f, "photo.jpg")
print(media["key"])  # use this key when creating posts

# Upload a video thumbnail
with open("thumb.jpg", "rb") as f:
    thumb = client.media.upload(f, "thumb.jpg", media_type="thumbnail")

client.media.upload_from_url(url, ...)

Upload media from a remote URL.

media = client.media.upload_from_url(
    "https://example.com/image.jpg",
    media_type="image",
)
print(media["key"])

Webhooks

client.webhooks.list()

List all registered webhooks.

webhooks = client.webhooks.list()
for wh in webhooks:
    print(f"{wh['url']} -> {wh['events']}")

client.webhooks.create(url, events)

Register a new webhook. Returns the signing secret (store it securely).

webhook = client.webhooks.create(
    url="https://example.com/webhook",
    events=["post.published", "post.failed"],
)
print(webhook["id"])
print(webhook["secret"])  # save this -- only shown once

client.webhooks.delete(webhook_id)

Delete a webhook.

result = client.webhooks.delete("550e8400-...")

Error handling

All API errors raise SocialRailsError with message, code, and status attributes:

from socialrails import SocialRails, SocialRailsError

client = SocialRails(api_key="sr_live_...")

try:
    client.posts.create(content="", platform="twitter")
except SocialRailsError as e:
    print(f"Error {e.status}: [{e.code}] {e.message}")
    # Error 400: [BAD_REQUEST] Field "content" is required and must be a string.

Common error codes:

Code Status Description
BAD_REQUEST 400 Invalid request parameters
UNAUTHORIZED 401 Missing or invalid API key
FORBIDDEN 403 API key lacks required scope
NOT_FOUND 404 Resource not found
RATE_LIMITED 429 Too many requests
LIMIT_EXCEEDED 429 Monthly plan limit reached
PAYLOAD_TOO_LARGE 413 Request body or file too large
INTERNAL_ERROR 500 Server error

Context manager

Both clients support context managers for automatic cleanup:

# Sync
with SocialRails(api_key="sr_live_...") as client:
    posts = client.posts.list()

# Async
async with AsyncSocialRails(api_key="sr_live_...") as client:
    posts = await client.posts.list()

Requirements

  • Python 3.8+
  • httpx >= 0.24.0

License

MIT

Metadata

Release files for socialrails 1.0.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for socialrails 1.0.0
File Size Uploaded Provenance Actions
socialrails-1.0.0.tar.gz 11.2 kB Without provenance Details for socialrails-1.0.0.tar.gz

Built distribution (wheel)

Table of built distributions (wheels) for socialrails 1.0.0
File Interpreter ABI Platform Actions
socialrails-1.0.0-py3-none-any.whl Python 3 none any Details for socialrails-1.0.0-py3-none-any.whl

Total release size: 26.2 kB

Release files / socialrails-1.0.0.tar.gz

Download URL socialrails-1.0.0.tar.gz
Size 11.2 kB
Tags Source
SHA-256 checksum
How to use checksums
31bf8adb21ed0a48cacd7271739e313364401ea8bcb10611260fac8068c8f623
BLAKE2b-256 checksum
How to use checksums
13d7d3f785d6c24b7447ae95a03c7395b9386588481e100fef31dd3017d83b89
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.2.0 CPython/3.14.2

Release files / socialrails-1.0.0-py3-none-any.whl

Download URL socialrails-1.0.0-py3-none-any.whl
Size 15.0 kB
Tags Python 3
SHA-256 checksum
How to use checksums
036b36bdb34a7a3c77d0ab32eb09b8837e33929839f5978c2301710450cecec2
BLAKE2b-256 checksum
How to use checksums
1c7f70cf0994fc4a2638aae348cf4603ebfba1035f479b23af9770400c396b1a
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.2.0 CPython/3.14.2

Security for socialrails 1.0.0

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

No provenance found

None of the files in this release were uploaded with provenance metadata.

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

To learn more about protecting yourself from malicious actors, visit our package security documentation.

Release history Release notifications | RSS feed

This release

1.0.0 This release

2 release files No provenance

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page