Agent content calendar

Let an agent fill
the calendar.

Round-ups keep sending this job to a calendar app you self-host. That is the wrong default when the agent is the one filling the week. PostLake already queues, timezones, cancels, reschedules, and keeps drafts fail-closed. The dashboard calendar is how a person checks the work. You do not install Postiz to get an agent-driven calendar.

Get started free →

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

In shortPoint Claude or Cursor at the hosted MCP. Ask it to draft a week of posts from a changelog, adapt per network, schedule with timezone, and keep them as drafts until you approve. The dashboard calendar is the review surface. No second scheduler product.

When this guide is for you

You want an agent to fill the content calendar, and a person to review it, without self-hosting Postiz or living in a drag-and-drop UI.

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.

The week, as drafts

Same publish contract as the docs, plus scheduledAt, timezone, and draft: true. Credits do not charge until a draft is published and actually fires.

import os, uuid, requests
from datetime import datetime, timedelta
from zoneinfo import ZoneInfo

HEADERS = {
    "Authorization": f"Bearer {os.environ['POSTLAKE_API_KEY']}",
    "Content-Type": "application/json",
}
ZONE = "Europe/London"

def queue_week(items: list[dict]) -> list[dict]:
    """items: [{text, day_offset}] e.g. day_offset=1 is tomorrow 09:00 local."""
    out = []
    today = datetime.now(ZoneInfo(ZONE)).date()
    for i, item in enumerate(items):
        when = datetime(
            today.year, today.month, today.day, 9, 0, 0
        ) + timedelta(days=item["day_offset"])
        body = {
            "text": item["text"],
            "profile": "my-brand",
            "scheduledAt": when.strftime("%Y-%m-%dT09:00:00"),
            "timezone": ZONE,
            "draft": True,  # nothing ships until you approve
        }
        r = requests.post(
            "https://api.postlake.dev/v1/posts",
            headers={**HEADERS, "Idempotency-Key": f"cal-{today}-slot-{i}"},
            json=body,
        )
        r.raise_for_status()
        post = r.json()
        print(post["id"], post["state"], post.get("scheduledAtLocal"))
        out.append(post)
    return out

# MCP path (no key in chat): connect https://api.postlake.dev/mcp
# then: "Draft 5 posts for this week from the changelog, adapt length
# per platform, schedule them 24h out as drafts, do not publish until I approve."

Make it work

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

  1. Connect accounts under one profile. Bluesky is the fastest smoke test.
  2. Prefer MCP over a pasted key: add https://api.postlake.dev/mcp and approve over OAuth.
  3. Call validate_post (free) before queueing a week, especially for TikTok photos.
  4. Create each slot with scheduledAt, timezone, and draft: true. State should be draft. Cost is zero.
  5. Open the dashboard calendar. Edit, move, or delete. When a slot is right, publish_draft (it keeps the scheduled time unless you clear it).
  6. After they fire, get_analytics / GET /v1/analytics so next week's drafts are not a guess.

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 AI content calendar code? Point it at MCP (https://api.postlake.dev/mcp). Prefer the dashboard? Use Quickstart → No code.

Common questions

How do I let an AI agent run a social media calendar?

Connect PostLake's hosted MCP, ask it to draft and schedule the week with timezone, keep posts as drafts, and review them on the dashboard calendar. You do not need to self-host Postiz for this.

Is PostLake a Postiz alternative for calendars?

If an agent is filling the week: yes. If a person wants to live in a drag-and-drop calendar with RSS and in-app image generation: Postiz is still the better calendar app, and we would rather say so.

What instruction should I give the agent?

Draft 5 posts for this week from the changelog, adapt length per platform, schedule them 24 hours out as drafts, and do not publish until I approve.

Can I cancel or move a slot?

Yes, while it is draft or scheduled: PATCH to change copy or time, DELETE to pull it. Cancelling a scheduled post frees the Idempotency-Key.

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 →