Schedule via API
Scheduling is one field on the publish call. Same addressing and media as an immediate post. Pass timezone (IANA) with a naive local time, or send UTC with a trailing Z. Invalid media is refused when you schedule, not at fire time.
Get started free →Free tier. No card · one API for every network · full MCP access
You want calendar-style publishing from code or automation without a separate scheduler product.
Same setup the docs quickstart uses. Do this once:
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.sk_live_…). It shows once; treat it like a password.Same call you'd use to publish now, plus scheduledAt (UTC, or a local time with timezone):
curl -X POST https://api.postlake.dev/v1/posts \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: friday-recap-001" \
-d '{
"text": "Friday recap",
"profile": "my-brand",
"scheduledAt": "2026-08-13T07:00:00",
"timezone": "Europe/London"
}'
# Response state should be "scheduled" until fire time.Tool-specific glue on top of the shared setup above:
text + profile / accounts).scheduledAt. UTC with a trailing Z, or a naive local time together with timezone (IANA, e.g. Europe/London).POST /v1/posts/validate first for TikTok photo posts (JPEG/WebP, max 1080×1920; PNG is converted to JPEG with a warning).state: "scheduled". At fire time it moves to processing then published / partial / failed.PATCH /v1/posts/{id} to edit, DELETE /v1/posts/{id} to cancel.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 } }
]
}published: every target succeeded. partial: some published, some failed. failed: none published. processing: still going (async networks like TikTok).Idempotency-Key header on writes so a retry never double-posts.Same rules as the docs. Pick one addressing style:
"profile": "my-brand" posts to every account under that profile (the name on Channels)."platforms": ["bluesky", "linkedin"] narrows that set. It is a filter, not a selector: if you have two Pinterest boards, both match pinterest."accounts": ["acc_…"] for exact channels (copy an id on Channels, or GET /v1/social-accounts).profile? PostLake uses that profile. Multiple profiles and you omit it? You'll get an error that names them.See Publishing: where to post.
state is scheduled: PATCH /v1/posts/{id} or DELETE /v1/posts/{id}. Scheduling docs.media, textOverrides, platformOptions.POST /v1/posts/validate (free) before you queue a week of content.timezone is a 400. Sending local time as UTC (trailing Z, no timezone) still fires at the wrong hour.Prefer an assistant over Scheduling code? Point it at MCP (https://api.postlake.dev/mcp). Prefer the dashboard? Use Quickstart → No code.
POST /v1/posts with scheduledAt. Send UTC with a trailing Z, or a naive local time plus timezone (IANA, e.g. Europe/London). PostLake queues it and publishes at that time. See docs → Scheduling.
ISO-8601. UTC with a trailing Z, or a naive local time together with timezone. Unparseable values and naive times without a zone get a clear 400.
Yes, while state is scheduled: PATCH /v1/posts/{id} to edit, DELETE /v1/posts/{id} to cancel.
These guides stay short on purpose. Canonical behaviour lives here:
Also: Media · Errors · MCP · Analytics
All guides · Full docs · llms.txt · Markdown
Stuck? The docs are the source of truth, start at Scheduling.
Open the dashboard →