This reference is generated from the API's own route table. Public routes are listed here; vendor callbacks and service routes are left out. There are 128 operations in 23 groups. Every request needs a key unless the table says No key; see authentication. The machine-readable document is at /openapi.json on the API host.
Posts
POST/v1/bulk/posts/approveApprove up to 100 posts waiting in review and schedule them
Needs a role that approves (owner, admin, reviewer). A key or MCP client also needs the approval switch only the workspace owner sets. Each post is checked and scheduled on its own, so one that no longer fits is reported beside its id.
Needs a write key. Role action: post.approve.
| Body field | Type | Required |
|---|
post_ids | string[] | Yes |
|---|
Errors: invalid_inputunauthorizedforbiddenrate_limitedinternal_error
POST/v1/bulk/posts/deleteDelete up to 100 unscheduled posts or scheduled posts
A post that is live on a platform is not removed there and is refused for that id only.
Needs a write key. Role action: post.create.
| Body field | Type | Required |
|---|
post_ids | string[] | Yes |
|---|
Errors: invalid_inputunauthorizedforbiddenrate_limitedinternal_error
POST/v1/bulk/posts/rescheduleMove up to 100 posts to a new time
Posts are moved in the order given, spacing_min minutes apart, starting at schedule_at. Each post is its own step: one that is refused (a full day, a post already sent) is reported beside its id and the others still move. The answer lists every id.
Needs a write key. Role action: post.create.
| Body field | Type | Required |
|---|
post_ids | string[] | Yes |
|---|
schedule_at | string | Yes |
|---|
spacing_min | integer | No |
|---|
Errors: resultsinvalid_inputhorizonunauthorizedqueue_limitallowance_usedforbiddendaily_caprate_limitedinternal_error
List posts, newest first, with their destinations
Needs a read key. Role action: read.
| Parameter | In | Type | Required |
|---|
limit | query | string | No |
|---|
cursor | query | string | No |
|---|
status | query | string (one of a fixed list) | No |
|---|
platform | query | string (one of a fixed list) | No |
|---|
account_id | query | string | No |
|---|
tag | query | string | No |
|---|
from | query | string | No |
|---|
to | query | string | No |
|---|
Errors: invalid_inputunauthorizedforbiddenrate_limitedinternal_error
Save an unscheduled post, schedule a post or publish now to one or more accounts
Without schedule_at, publish_now or use_next_free_slot the post is saved as an unscheduled post. schedule_at is an ISO 8601 time (no offset means UTC) and wins over use_next_free_slot. A contributor's post goes to review whatever the request asks for, and a test key's post is always a dry run. Idempotency-Key is honored for 24 hours: the same key with the same request returns the first answer, with a different request it is a 409.
Needs a write key. Role action: post.create.
| Parameter | In | Type | Required |
|---|
Idempotency-Key | header | string | No |
|---|
| Body field | Type | Required |
|---|
text | string | No |
|---|
parts | object[] | No |
|---|
accounts | string or object[] | No |
|---|
set_id | string | No |
|---|
signature_id | string or null | No |
|---|
tags | string[] | No |
|---|
publish_now | boolean | No |
|---|
schedule_at | string | No |
|---|
use_next_free_slot | boolean | No |
|---|
late_policy | "skip" | "publish" | No |
|---|
late_window_min | integer | No |
|---|
dry_run | boolean | No |
|---|
review_link | boolean | No |
|---|
Errors: publishedinvalid_inputhorizonunauthorizedqueue_limitallowance_usedsubscription_requiredforbiddenreconnect_neededdaily_capno_free_slotinvalid_for_platformrate_limitedinternal_error
Read one post with the state of each destination
Needs a read key. Role action: read.
| Parameter | In | Type | Required |
|---|
id | path | string | Yes |
|---|
Errors: unauthorizedforbiddennot_foundrate_limitedinternal_error
Change part of a post before it goes out, or move it in time
Send only what changes. parts replaces the post's text and media (destinations with their own text keep it); accounts patches destinations already on the post by account_id, or adds new ones; remove_accounts drops destinations. A scheduled post is taken back to an unscheduled post, changed, validated again and scheduled at the same time, all or nothing. A post that already went out can only move, with move.choice.
Needs a write key. Role action: post.create.
| Parameter | In | Type | Required |
|---|
id | path | string | Yes |
|---|
| Body field | Type | Required |
|---|
parts | object[] | No |
|---|
accounts | object[] | No |
|---|
remove_accounts | string[] | No |
|---|
tags | string[] | No |
|---|
late_policy | "skip" | "publish" | No |
|---|
late_window_min | integer | No |
|---|
schedule_at | string | No |
|---|
publish_now | boolean | No |
|---|
move | object | No |
|---|
Errors: keptinvalid_inputhorizonunauthorizedallowance_usedqueue_limitforbiddennot_founddaily_capreconnect_neededinvalid_for_platformrate_limitedinternal_error
Delete an unscheduled post or cancel a schedule, for every destination or one
A destination that is live on a platform is not removed there. With account_id only that destination goes.
Needs a write key. Role action: post.create.
| Parameter | In | Type | Required |
|---|
id | path | string | Yes |
|---|
account_id | query | string | No |
|---|
Errors: deletedinvalid_inputunauthorizedforbiddennot_foundrate_limitedinternal_error
POST/v1/posts/{id}/approveApprove a post waiting in review and schedule it
Also schedules a post a client already approved through a review link. Needs a role that approves (owner, admin, reviewer). A key or MCP client also needs the approval switch only the workspace owner sets.
Needs a write key. Role action: post.approve.
| Parameter | In | Type | Required |
|---|
id | path | string | Yes |
|---|
Errors: invalid_inputunauthorizedforbiddennot_foundrate_limitedinternal_error
POST/v1/posts/{id}/cancelCancel every destination of a post that has not started
A destination whose publish is in flight is left to finish, and is counted in in_flight.
Needs a write key. Role action: post.create.
| Parameter | In | Type | Required |
|---|
id | path | string | Yes |
|---|
| Body field | Type | Required |
|---|
account_id | string | No |
|---|
Errors: invalid_inputunauthorizedforbiddennot_foundrate_limitedinternal_error
POST/v1/posts/{id}/duplicateCopy a post into a new unscheduled post
Needs a write key. Role action: post.create.
| Parameter | In | Type | Required |
|---|
id | path | string | Yes |
|---|
Errors: unauthorizedforbiddennot_foundrate_limitedinternal_error
POST/v1/posts/{id}/link-liveAttach the live platform post to a destination whose outcome was unknown
Send the platform's own id or the post's address. The destination becomes published and its results are collected from then on.
Needs a write key. Role action: post.publish.
| Parameter | In | Type | Required |
|---|
id | path | string | Yes |
|---|
| Body field | Type | Required |
|---|
account_id | string | Yes |
|---|
platform_post_id | string | No |
|---|
url | string | No |
|---|
Errors: invalid_inputunauthorizedforbiddennot_foundrate_limitedinternal_error
POST/v1/posts/{id}/request-changesSend a post in review back to its author with a note
Needs a write key. Role action: post.approve.
| Parameter | In | Type | Required |
|---|
id | path | string | Yes |
|---|
| Body field | Type | Required |
|---|
text | string | Yes |
|---|
Errors: invalid_inputunauthorizedforbiddennot_foundrate_limitedinternal_error
Send the destinations that failed again, as a new post
Only a destination known not to have published (failed) is retried. A destination in unknown may already be on the platform: check the account, then attach it with link-live or duplicate the post.
Needs a write key. Role action: post.publish.
| Parameter | In | Type | Required |
|---|
id | path | string | Yes |
|---|
Errors: unauthorizedforbiddennot_foundoutcome_unknownrate_limitedinternal_error
POST/v1/posts/{id}/review-linksMake a link a client opens to preview, comment on and approve a post
The link works without a 1Post login, expires after 7 days unless ttl_days says up to 30, and can be revoked. The token is in this response only.
Needs a write key. Role action: reviewlink.create.
| Parameter | In | Type | Required |
|---|
id | path | string | Yes |
|---|
| Body field | Type | Required |
|---|
post_ids | string[] | No |
|---|
ttl_days | integer | No |
|---|
Errors: invalid_inputunauthorizedforbiddennot_foundrate_limitedinternal_error
POST/v1/posts/{id}/submitSend an unscheduled post to review
Needs a write key. Role action: post.create.
| Parameter | In | Type | Required |
|---|
id | path | string | Yes |
|---|
Errors: unauthorizedforbiddennot_foundrate_limitedinternal_error
Schedule up to 500 posts from a spreadsheet
Send the file as text in csv. The header row names the columns: text (required), accounts (account ids, handles or platform names separated by ; or |), scheduled_at (2026-11-02T15:00; no offset is read in the workspace time zone, a Z or +02:00 is exact) or date and time (read in the workspace time zone), media_urls, and link (added to the end of the text). A row without a time is saved as an unscheduled post. A file whose columns are named differently says which is which in columns. Every row is checked against its destinations exactly as a post made by hand: with the default on_error: "abort" nothing is queued if any row is refused, with "skip" the rows that pass are queued. dry_run: true checks everything and keeps nothing (files are not fetched). Files at media_urls are brought into the library (up to 25 different addresses). Publer files import as they are (a Date column holding 2026/11/02 15:00, a Media URL column separated by commas, a Link column), and so do SocialBee files (text, imageUrls, gifUrls, videoUrls, postAtSpecificTime). Hootsuite files have no header row: add the header row scheduled_at,text,link and write the dates as 2026-11-20 09:30. Send an Idempotency-Key to repeat an import safely for 24 hours: the same file returns the posts it made, another file with the same key is a 409.
Needs a write key. Role action: post.create.
| Parameter | In | Type | Required |
|---|
Idempotency-Key | header | string | No |
|---|
| Body field | Type | Required |
|---|
csv | string | Yes |
|---|
columns | object | No |
|---|
default_account_ids | string[] | No |
|---|
on_error | "abort" | "skip" | No |
|---|
dry_run | boolean | No |
|---|
Errors: rowsinvalid_inputunauthorizedplan_limitforbiddenconflictqueuedcommittedrate_limitedinternal_errorprovider_unavailable
DELETE/v1/review-links/{id}Turn a review link off
The link stops working at once for the client. Only the person who made it, an admin or the owner can revoke it.
Needs a write key. Role action: reviewlink.create.
| Parameter | In | Type | Required |
|---|
id | path | string | Yes |
|---|
Errors: revokedunauthorizedforbiddennot_foundrate_limitedinternal_error
Accounts
The connected accounts, with their state
Never carries a token, password, webhook address or signing secret, whatever the role.
Needs a read key. Role action: read.
Errors: unauthorizedforbiddenrate_limitedinternal_error
One connected account
Needs a read key. Role action: read.
| Parameter | In | Type | Required |
|---|
id | path | string | Yes |
|---|
Errors: unauthorizedforbiddennot_foundrate_limitedinternal_error
Disable or enable an account, or change its settings
Disabling keeps the account's history and frees a slot of the plan; enabling again needs no reconnect while the connection is still valid.
Needs a write key. Role action: workspace.manage.
| Parameter | In | Type | Required |
|---|
id | path | string | Yes |
|---|
| Body field | Type | Required |
|---|
disabled | boolean | No |
|---|
settings | object | No |
|---|
Errors: invalid_inputunauthorizedforbiddennot_foundrate_limitedinternal_error
Disconnect an account: its tokens are erased and its queued posts are canceled
The account keeps its history and shows as disabled. Posts already live on the platform are not touched.
Needs a write key. Role action: workspace.manage.
| Parameter | In | Type | Required |
|---|
id | path | string | Yes |
|---|
Errors: disconnectedunauthorizedforbiddennot_foundrate_limitedinternal_error
PATCH/v1/accounts/{id}/nameGive an account your own name; the platform's name is kept
Send name: null to go back to the platform's name.
Needs a write key. Role action: workspace.manage.
| Parameter | In | Type | Required |
|---|
id | path | string | Yes |
|---|
| Body field | Type | Required |
|---|
name | string or null | Yes |
|---|
Errors: invalid_inputunauthorizedforbiddennot_foundrate_limitedinternal_error
POST/v1/accounts/{id}/pickPick the Page, channel, blog or location an account posts to
Needs a write key. Role action: workspace.manage.
| Parameter | In | Type | Required |
|---|
id | path | string | Yes |
|---|
| Body field | Type | Required |
|---|
target_id | string | Yes |
|---|
Errors: invalid_inputunauthorizedforbiddennot_foundrate_limitedinternal_errorprovider_unavailable
POST/v1/accounts/{id}/reconnect-linkMake a link a client opens to connect one broken account again
No 1Post login is needed and scheduled posts stay. It works for this account only, once, for 7 days. Only for an account that is waiting to be reconnected and connects by redirect. The link is in this response only.
Needs a write key. Role action: workspace.manage.
| Parameter | In | Type | Required |
|---|
id | path | string | Yes |
|---|
Errors: unauthorizedforbiddennot_foundrate_limitedinternal_error
GET/v1/accounts/{id}/targetsThe Pages, boards, playlists, locations or blogs an account can post to, and the one picked
Needs a read key. Role action: read.
| Parameter | In | Type | Required |
|---|
id | path | string | Yes |
|---|
Errors: unauthorizedforbiddennot_foundrate_limitedinternal_errorprovider_unavailable
Get the address that connects an account by redirect
Open authorize_url in a browser signed in to the platform. The platform sends the person back to this API's callback and then to the site. The key API form of an invite link.
Needs a write key. Role action: workspace.manage.
| Body field | Type | Required |
|---|
platform | string (one of a fixed list) | Yes |
|---|
instance | string | No |
|---|
account_id | string | No |
|---|
Errors: invalid_inputunauthorizedaccount_limitforbiddenrate_limitedinternal_errorprovider_unavailable
POST/v1/accounts/connect/formConnect an account that uses a password, token or pasted address
For Bluesky (app password), Telegram, Discord, Slack, a webhook address, WordPress, DEV, Hashnode, Lemmy and X with your own keys. The details are checked with the platform, sealed and never shown again.
Needs a write key. Role action: workspace.manage.
| Body field | Type | Required |
|---|
platform | string (one of a fixed list) | Yes |
|---|
fields | object | Yes |
|---|
Errors: invalid_inputunauthorizedaccount_limitforbiddenrate_limitedinternal_errorprovider_unavailable
Make an expiring link a client opens to connect their own account into this workspace
No 1Post login is needed. Only platforms that connect by redirect are offered; the token is in this response only.
Needs a write key. Role action: workspace.manage.
| Body field | Type | Required |
|---|
platform | string (one of a fixed list) or null | No |
|---|
Errors: invalid_inputunauthorizedforbiddenrate_limitedinternal_error
Analytics
The posts of a range with their latest numbers, as CSV text
One row per post, newest first, up to 5,000 rows, with one column per metric. Posts imported from the account's own history are marked "published elsewhere". Cells that would run as a formula in a spreadsheet are written as text. Stored numbers only.
Needs a read key. Role action: read.
| Parameter | In | Type | Required |
|---|
range | query | "7d" | "30d" | "all" | No |
|---|
Errors: invalid_inputunauthorizedforbiddenrate_limitedinternal_error
How many on-demand refreshes are left today
Needs a read key. Role action: read.
Errors: unauthorizedforbiddenrate_limitedinternal_error
POST/v1/analytics/refreshAsk for fresh numbers for one published post
Read at the next collector run. 5 a day per workspace for most destinations, 50 a day on Bluesky and Mastodon, and never on X. Asking again while one is waiting costs nothing.
Needs a write key. Role action: post.create.
| Body field | Type | Required |
|---|
post_id | string | Yes |
|---|
account_id | string | Yes |
|---|
Errors: invalid_inputunauthorizedplan_limitforbiddenrate_limitedinternal_error
Totals per platform, the best posts, and account cards compared with the previous period
Reads stored snapshots only; nothing is fetched from a platform on demand.
Needs a read key. Role action: read.
| Parameter | In | Type | Required |
|---|
range | query | "7d" | "30d" | "all" | No |
|---|
account_id | query | string | No |
|---|
days | query | "7" | "30" | "90" | No |
|---|
Errors: invalid_inputunauthorizedforbiddenrate_limitedinternal_error
Posts imported from an account's own history (published elsewhere)
Up to 90 days back, read when the account was connected. They feed analytics and cannot be scheduled, edited or published again.
Needs a read key. Role action: read.
| Parameter | In | Type | Required |
|---|
limit | query | string | No |
|---|
cursor | query | string | No |
|---|
account_id | query | string | No |
|---|
Errors: invalid_inputunauthorizedforbiddenrate_limitedinternal_error
GET/v1/posts/{id}/analyticsThe stored metric snapshots of each destination of a post
Needs a read key. Role action: read.
| Parameter | In | Type | Required |
|---|
id | path | string | Yes |
|---|
Errors: unauthorizedforbiddennot_foundrate_limitedinternal_error