To schedule a social media post with an API, send one POST request to `/v1/posts` with the text, a time and a list of target networks. With Preflight that is one call for up to twelve networks, and the request is checked against every network's rules before anything is created. This page has a working example, the fields that matter, and the mistakes that cost an hour.
The smallest request that schedules a post
Create an API key under *Settings, API keys* (every plan has API access, the free one included), then:
``bash curl -X POST https://preflight.social/v1/posts \ -H "Authorization: Bearer sk_live_..." \ -H "Idempotency-Key: 7c9e6679-7425-40de-944b-e07fc1f90ae7" \ -H "Content-Type: application/json" \ -d '{ "content": "New guide is live.", "scheduledAt": "2026-11-10T09:00:00Z", "targets": [ { "platform": "bluesky" }, { "platform": "linkedin" } ] }' ``
A new post comes back with status 201. If the same Idempotency-Key is sent again, the first post comes back with 200 instead of a second one, so a retry after a timeout is safe. The key is 8 to 200 characters and should be unique per post, such as a UUID.
The fields you will actually use
| Field | What it does |
|---|---|
content | The text, up to 64,000 characters. On YouTube it is the description. |
targets | One entry per channel: platform, and accountId when the workspace has several accounts on one network. |
scheduledAt | One instant for every channel, as an ISO time. Up to five minutes in the past counts as now; older is refused with 400 scheduled_in_past. |
scheduledLocal | The same wall-clock time read in each channel's own zone, such as 2026-11-10T09:00. See time zones. |
queue | true puts the post in each channel's next free slot from its posting schedule. |
publishNow and saveAsDraft | Publish at once, or park the post without a time. |
mediaIds | Up to 35 files uploaded earlier through /v1/media, which must be ready. |
tags | Up to 10 tags by name. |
repeat | Publish again every 1 to 365 days, 2 to 52 times in all, with up to nine other wordings. |
options on a target | Per-network settings such as instagram.placement, pinterest.boardId, youtube.title or a different caption for that network. |
Check a post before you send it
POST /v1/posts already runs the check. If a network would refuse the post, you get 422 `validation_failed` with the list of issues and nothing is created. To test without creating anything, use the dry run at POST /v1/platforms/validate. The rules behind it are the ones on the limits pages.
Scopes: give a key only what it needs
A key has scopes. posts:write is enough for a draft, and posts:publish is needed for anything that goes out. A call without the scope gets 403 and the response names the missing one. A key that only reads, with posts:read, cannot publish at all, which is the right key for a dashboard.
Mistakes that cost an hour
- No `Idempotency-Key`. A retried request then creates a second post.
- A time in the past. Older than five minutes is refused. Send
publishNowif you mean now. - A time with no zone.
scheduledAtis an instant; use a trailingZor an offset, or usescheduledLocal. - Media that is not ready. Upload the file first and send its ID only once it is ready.
- Assuming one text fits all. A LinkedIn post of 2,000 characters is refused by Bluesky at 300. Use the per-target
captionoption to give one network its own text, and check the limits on the limits pages.
Get told when it goes out, or fails
Create a webhook under /v1/workspace/webhooks and the post's result is sent to you, instead of polling. If a channel refuses a post, POST /v1/posts/{id}/retry sends it again. The full reference is in the documentation, and the same calls are available to an AI assistant through the MCP server.
Based on Preflight's OpenAPI description, version 2026.10.24.
Questions people ask
- How do I schedule a social media post with an API?
- Send a POST request to /v1/posts with the text, a scheduledAt time and a targets list. Preflight checks it against every network's rules and returns 201 with the new post, or 422 with the issues.
- Is there a free social media scheduling API?
- Yes. Every Preflight plan includes API access, the free plan too. The free plan has three channels and a monthly allowance of publishes.
- How do I stop an API call from posting twice?
- Send an Idempotency-Key header, unique per post. If the same key arrives again, the first post is returned instead of a second one being created.
- Can one API call post to several networks?
- Yes. List each network in targets. All of them share the post's text and time, and each can have its own caption and settings through options.
- Which API key scope do I need to publish?
- posts:publish for anything that goes live. posts:write is enough for a draft, and posts:read cannot publish.