Post with Python

Post to social media
with Python.

Same publish contract as the docs quickstart. From Python that's one requests call. Connect accounts once in the dashboard; your code only sends text, addressing, and optional schedule/media.

Get started free →

Free tier. No card · one API for every network · full MCP access

In shortFrom Python, POST /v1/posts with requests (or httpx). Address a profile; read targets[]. Partial success is normal and failed targets are free.

When this guide is for you

You're already in Python (scripts, backends, notebooks) and want social publishing without Tweepy, LinkedIn SDKs, or Meta Graph clients.

Before you start

Same setup the docs quickstart uses. Do this once:

  1. Sign up at app.postlake.dev and verify your email (unlocks free credits).
  2. On Channels, create a profile (e.g. my-brand) and connect at least one account. Bluesky is the fastest first channel: no app review. Instagram/TikTok/Facebook need each platform's review before API posting.
  3. Account menu → API Keys → create a key (sk_live_…). It shows once; treat it like a password.

Working example in Python

Connect accounts once in the dashboard, then this is the publish call:

import os
import requests

resp = requests.post(
    "https://api.postlake.dev/v1/posts",
    headers={
        "Authorization": f"Bearer {os.environ['POSTLAKE_API_KEY']}",
        "Idempotency-Key": "hello-python-001",  # safe retries
    },
    json={
        "text": "Hello from Python 👋",
        "profile": "my-brand",  # Channels profile name
        # Optional filter (not a selector): only these networks under the profile
        # "platforms": ["bluesky", "linkedin"],
    },
)
resp.raise_for_status()
post = resp.json()
print(post["id"], post["state"])
for t in post["targets"]:
    print(t["platform"], t["state"], t.get("url") or t.get("error"))

Make it work in Python

Tool-specific glue on top of the shared setup above:

  1. Store the key as POSTLAKE_API_KEY (never commit it). Use the profile name from Channels. Same string as in the docs quickstart.
  2. POST with requests (or httpx). Omit platforms to hit every account on the profile; add it only to filter networks.
  3. Always iterate targets[]. A top-level partial state means some networks published and some failed. Check each entry.
  4. On writes, send Idempotency-Key so a retry never double-posts.

Read the response (don't skip this)

You get one Post with an overall state and a targets[] array. One entry per account. Always check each target; partial success is normal.

{
  "id": "post_a1b2c3",
  "state": "partial",
  "targets": [
    { "platform": "bluesky",  "state": "published", "url": "https://bsky.app/…" },
    { "platform": "linkedin", "state": "failed",
      "error": { "type": "invalid_request", "message": "…", "retryable": false } }
  ]
}

Where the post goes

Same rules as the docs. Pick one addressing style:

See Publishing: where to post.

Do more (same API)

Pitfalls specific to this path

Prefer an assistant over Python code? Point it at MCP (https://api.postlake.dev/mcp). Prefer the dashboard? Use Quickstart → No code.

Common questions

How do I post to social media with Python?

Create a key and connect accounts under a profile (docs quickstart). Then POST https://api.postlake.dev/v1/posts with Authorization: Bearer sk_live_… and JSON { "text": "…", "profile": "my-brand" }. Read targets[] in the response.

Do I need a library per social network?

No. One PostLake endpoint covers every connected network. Use requests or httpx only.

How do I schedule from Python?

Add scheduledAt as UTC (trailing Z), or a naive local time plus timezone (IANA, e.g. Europe/London). Credits charge when it fires. See the scheduling docs.

Go deeper in the docs

These guides stay short on purpose. Canonical behaviour lives here:

Also: Media · Errors · MCP · Analytics

Related guides

All guides · Full docs · llms.txt · Markdown

Stuck? The docs are the source of truth, start at Publishing.

Open the dashboard →