REST API
A social media API for posting from your own code.
Create drafts and threads, schedule them to Instagram, X, LinkedIn, Facebook, Threads, Bluesky, Telegram, Mastodon, Pinterest, TikTok and Tumblr, upload media and read analytics over a plain JSON API. Keys belong to your organization and reach only the workspaces and actions you choose.
- On Starter, Pro and Business
- Approvals always apply
- Every change logged
- List workspaces
- Find channels
- Create a draft
- Schedule it
Request · Schedule it
POST /posts/0199e1…/schedule
X-Workspace-Id: 0198a2…
{
"revisionId": "0199e2…",
"destinations": [
{ "channelConnectionId": "0198c7…" }
],
"scheduledAt": "2026-10-09T06:00:00Z",
"timezone": "Europe/Istanbul"
}Response
{
"id": "0199e1…",
"status": "SCHEDULED",
"scheduledAt": "2026-10-09T06:00:00.000Z"
}- Endpoints
- 40
- posts, media, channels, analytics, AI
- Permissions
- 15
- in 7 groups, chosen per key
- Rate limit
- 120/min
- per key, 600 per organization
- API keys
- Up to 50
- active per organization
Quickstart
From a key to a scheduled post in four steps.
Base URL: https://api.postivate.com/api/v1. Send the key as a bearer token on every request.
- 1
Create a key
In Postivate, open Organization → Developer → New API key. Pick the workspaces it may reach and a preset like Publisher, then copy the secret. It’s shown once.
Terminalexport POSTIVATE_KEY="pvk_…" export API="https://api.postivate.com/api/v1" - 2
Find the workspace and channel
List the workspaces the key can reach, then the connected channels of the one you want. Workspace requests send its id in X-Workspace-Id.
Terminalcurl "$API/organization/workspaces" \ -H "Authorization: Bearer $POSTIVATE_KEY" curl "$API/channels" \ -H "Authorization: Bearer $POSTIVATE_KEY" \ -H "X-Workspace-Id: <workspace-id>" - 3
Create a draft
One text, or a thread of up to 30 entries, with media and a version per channel if you want. An Idempotency-Key makes a retried request safe.
Terminalcurl -X POST "$API/posts" \ -H "Authorization: Bearer $POSTIVATE_KEY" \ -H "X-Workspace-Id: <workspace-id>" \ -H "Idempotency-Key: cms-entry-4182" \ -H "Content-Type: application/json" \ -d '{ "items": [{ "text": "Pumpkin risotto is back this weekend." }], "destinationConnectionIds": ["<channel-id>"] }' - 4
Schedule it
Schedule the draft’s current revision to its channels. If the workspace requires approval, submit it for approval instead and it goes out once a person approves.
Terminalcurl -X POST "$API/posts/<post-id>/schedule" \ -H "Authorization: Bearer $POSTIVATE_KEY" \ -H "X-Workspace-Id: <workspace-id>" \ -H "Content-Type: application/json" \ -d '{ "revisionId": "<currentRevision.id>", "destinations": [{ "channelConnectionId": "<channel-id>" }], "scheduledAt": "2026-10-09T09:00:00+03:00", "timezone": "Europe/Istanbul" }'
API keys
Keys belong to the organization, not to a person.
A key is your organization’s identity for one integration. It keeps working when its creator leaves the team, and revoking it touches nothing else. Create one per integration, so each can be limited and revoked on its own.
- All workspaces, including new ones, or only the ones you pick
- Start from Read only, Content creator or Publisher, then adjust each permission
- No expiry, 90 days or a year; revoking takes effect immediately
- The secret is shown once and stored only as a hash
New API key
Grant only what it needs.
- Workspacesread
- Postsreadcreateeditschedulepublishdelete
- Mediareadcreatedelete
- Channelsread
- Analyticsread
- Approvalsread
- AIgenerate_textgenerate_image
Approval rules still apply: content created with this key goes through the workspace’s policy, and it can’t approve.
Copy the secret now: it won’t be shown again
pvk_7Hq2Lx9aQe_Vn3kT8wPz1mRb4sYc6uJd0hG5fXq2Le9aCopy
Your rules still apply
The same rules as your team, and a record of everything.
A key does only what its permissions allow, in the workspaces it reaches. If a workspace requires approval, a post scheduled over the API waits until a person approves that exact revision. Everything a key changes, and every request it’s refused, is logged.
- Keys never approve posts, connect channels or touch billing and the team
- Scheduling before approval answers 409 APPROVAL_REQUIRED
- Developer → Activity lists what keys changed and were refused, for 90 days
- Posts created with a key are marked “Created via the API”
Activity
All API keysPOST /posts
Done09:41 · Production automation
POST /posts/:id/submit-for-approval
Done09:41 · Production automation
POST /posts/:id/schedule
Refused09:42 · Production automation · APPROVAL_REQUIRED
POST /posts
Refused10:15 · Reporting · SERVICE_PERMISSION_DENIED
POST /posts/:id/schedule
Done11:02 · Production automation
POST /media/uploads
Done11:02 · Production automation
15 permissions
Grant exactly what an integration needs.
The presets are shortcuts: a key stores its own list, and you can change it any time.
| Permission | Read only | Content creator | Publisher |
|---|---|---|---|
| Workspaces | |||
List workspacesworkspaces:readNames, channels and what’s coming up, within the key’s workspaces. | |||
| Posts | |||
Read posts, calendar and templatesposts:read | |||
Create draftsposts:createFrom text or templates. Drafts are never published on their own. | |||
Edit drafts and submit for approvalposts:edit | |||
Schedule, reschedule and cancelposts:schedule | |||
Publish immediatelyposts:publishStill follows the approval policy. | |||
Delete any postposts:deleteWithout it, only posts it created itself that never went live. | |||
| Media | |||
Read the content librarymedia:read | |||
Upload media and edit tagsmedia:create | |||
Delete any filemedia:deleteWithout it, only files it uploaded itself. | |||
| Channels | |||
List channelschannels:readNames and health, never their credentials. | |||
| Analytics | |||
Read analyticsanalytics:read | |||
| Approvals | |||
Read the approval queueapprovals:read | |||
| AI | |||
Write with AIai:generate_textUses the workspace’s Brand Profile. | |||
Generate imagesai:generate_imageCounts against the organization’s AI image allowance. | |||
Never available to keys: approving posts, connecting channels, workspace settings, billing and the team.
40 endpoints
Everything a key can call.
Paths are relative to https://api.postivate.com/api/v1. Anything inside a workspace also sends X-Workspace-Id.
Organization
No X-Workspace-Id needed. Covers the workspaces the key can reach.
- GET
/organization/workspacesThe workspaces the key can reach, with their channels
workspaces:read
- GET
/organization/overviewCounts, what needs attention and how each workspace is doing
workspaces:readposts:read
- GET
/organization/calendarEvery workspace’s posts in a date range (up to 62 days)
workspaces:readposts:read
- GET
/organization/analyticsAnalytics across workspaces
workspaces:readanalytics:read
Posts
- GET
/postsList posts by group: drafts, pending, scheduled, published, failed
posts:read
- GET
/posts/countsHow many posts are in each group
posts:read
- GET
/posts/:idA post with its revision, destinations, publications and history
posts:read
- POST
/postsCreate a draft: one text or a thread, a version per channel, media
posts:create
- POST
/posts/from-templateCreate a draft from a template, filling its variables
posts:create
- PATCH
/posts/:idEdit a draft (send If-Match to avoid overwriting someone)
posts:edit
- POST
/posts/:id/duplicateCopy a post into a new draft
posts:create
- PATCH
/posts/:id/labelsChange the internal title and tags, in any status
posts:edit
- DELETE
/posts/:idDelete a post; what’s live stays on the networks
- GET
/calendarPosts in a date range
posts:read
Scheduling and publishing
If the workspace requires approval, these wait for a person to approve.
- POST
/posts/:id/scheduleSchedule a revision to channels at a time and time zone
posts:schedule
- POST
/posts/:id/publish-nowPublish a revision to channels right away
posts:publish
- POST
/posts/:id/cancelCancel what hasn’t gone out yet
posts:schedule
- POST
/posts/:id/edit-and-rescheduleCancel what’s queued and turn the post back into a draft
posts:schedule
- POST
/publications/:id/rescheduleMove one channel’s publication to another time
posts:schedule
- POST
/publications/:id/retryTry a failed publication again
posts:schedule
- POST
/posts/:id/fix-failedStart a new draft for the channels that failed
posts:create
Approvals
Keys can read the queue and send posts for review. Only people approve.
- POST
/posts/:id/submit-for-approvalSend the current revision for review, with a note and a requested time
posts:edit
- GET
/approvalsThe approval queue
approvals:read
Templates
- GET
/templatesThe workspace’s post templates
posts:read
- GET
/templates/:idA template with its variables
posts:read
- POST
/templates/:id/renderPreview a template with values filled in
posts:read
Media
- GET
/mediaThe content library, newest first (up to 500)
media:read
- GET
/media/foldersLibrary folders
media:read
- POST
/media/uploadsReserve an upload and get a URL to PUT the file to
media:create
- POST
/media/:id/completeFinish the upload so the file can be processed and used
media:create
- PATCH
/media/:idRename a file or edit its tags
media:create
- DELETE
/media/:idDelete a file it uploaded, or any with media:delete
media:create
Channels and analytics
- GET
/channelsConnected accounts and their status
channels:read
- GET
/channels/:id/healthCheck the connection with the network, refreshing its login if needed
channels:read
- GET
/analytics/overviewTotals and trends for the workspace
analytics:read
- GET
/analytics/channels/:idOne account’s metrics and its posts
analytics:read
AI
- POST
/ai/generateWrite a post, rewrite, translate or adapt it per network, in the Brand Profile’s voice
ai:generate_text
- GET
/ai/ideasSaved content ideas
ai:generate_text
- POST
/ai/ideasGenerate content ideas for a theme
ai:generate_text
- POST
/ai/imagesGenerate an image into the content library
ai:generate_imagemedia:create
Good to know
Details that make integrations reliable.
Retries without duplicates
Send an Idempotency-Key on create, schedule, publish-now and retry. Sending the same request again returns the post instead of doing it twice.
No overwritten edits
Every post carries an etag. Send it back as If-Match when you edit, and a change someone made in the meantime is never overwritten.
Errors you can act on
Every error has a stable code, a message and a request id, like 403 SERVICE_PERMISSION_DENIED with the permission that was missing.
Clear rate limits
120 requests a minute per key and 600 per organization. A 429 tells you when to try again, in Retry-After.
Direct media uploads
Reserve an upload, PUT the file straight to storage, then complete it. Postivate processes it and it’s ready for posts.
Plain JSON over HTTPS
Any language and any HTTP client. Keys are for servers and scripts; the API doesn’t take browser requests from other sites.
REST API FAQ
The Postivate API, answered.
Does Postivate have an API?
Yes. A REST API over HTTPS with JSON, at /api/v1. With an API key you can create drafts and threads, schedule and publish them, upload media, read posts, channels, the approval queue and analytics, and write with AI. API keys are included on the Starter, Pro and Business plans.
How do I authenticate?
Create an API key under Organization → Developer, then send it as a bearer token: Authorization: Bearer pvk_…. Requests about one workspace also send X-Workspace-Id. The secret is shown once; Postivate stores only a hash of it.
What can an API key do?
Exactly the permissions you give it, out of 15 in seven groups (workspaces, posts, media, channels, analytics, approvals and AI), in all of the organization’s workspaces or only the ones you pick. You can start from a preset: Read only, Content creator or Publisher. Billing, the team, connecting channels and approving posts are never available to keys.
Can an API key approve posts or skip approvals?
No. If a workspace requires approval, scheduling or publishing over the API waits until a person approves the exact revision; until then the API answers 409 APPROVAL_REQUIRED. A key can send a post for review, but approving always takes a person.
What are the rate limits?
120 requests a minute per key and 600 per organization. Above that the API answers 429 RATE_LIMITED with a Retry-After header. Each social network’s own limits still apply when posts go out.
How do I avoid creating the same post twice?
Send an Idempotency-Key header with a unique value on POST /posts, POST /posts/from-template, schedule, publish-now and retry. A retried request with the same key returns the post from the first one instead of doing it again.
Can I call the API from a browser?
No. API keys are for servers, scripts and back-office tools, and the API doesn’t accept cross-origin browser requests. To let people work with Postivate from an AI app, connect it over MCP: they sign in as themselves, no key involved.
Who can create and revoke API keys?
Organization owners and admins. Each key shows who created it and when it was last used. Revoking takes effect immediately, and keys can be set to expire after 90 days or a year.
How do I see what a key did?
Under Developer → Activity: every change a key made and every request it was refused, with the endpoint and the error, kept for 90 days. In each workspace the activity log and post history show the key by name.

Your next week of content, planned by Friday.
Connect your channels, invite your team and publish your first post today. 7 days free, no credit card.