API reference

Connected accounts

9 endpoints, served at https://orbitwrite.com/api/v1. Each one lists the credentials it accepts, its parameters and every response it can give.

List a workspace's connected channels#

GET/api/v1/connected-accounts

Every channel in the workspace, live and disconnected, in a stable order. Read this rather than deriving channels from a page's own data when you need one channel by id — the caller then doesn't have to already hold the list. Tokens are never returned.

Authentication

An API key or OAuth access token as a bearer token, or a signed-in session.

Query parameters

organizationIdstring

Session callers only — an API key already determines the workspace.

At least 1 character.

Responses

200ConnectedAccountList

The workspace's channels

Response attributes
accountsConnectedAccount[]Required
Child attributes
idstringRequired
platformstringRequired
handlestring | nullRequired

The channel's handle on its platform, as it was at connect time.

displayNamestring | nullRequired
avatarUrlstring | nullRequired
profileUrlstring | nullRequired

The channel's public profile page. Null where the platform has none (Discord, Slack) or the handle can't name one.

needsReconnectbooleanRequired

The platform credentials are dead — the channel can't publish until it's reconnected.

inboxReconnectNeededbooleanRequired

LinkedIn Pages only: the grant predates the comment-read scope the inbox needs (r_organization_social). Publishing works; comments can't be pulled until the Page is reconnected.

defaultSelectedbooleanRequired

Pre-selected when a fresh post is composed.

disconnectedbooleanRequired

Disconnected from the workspace. Disconnecting is a soft revoke so the channel's posts survive, which is why these rows are returned rather than hidden: they still have to be reachable to reconnect or to clear their content.

isPremiumbooleanRequired

X Premium, which raises the composer's character limit from 280 to 25,000.

carouselUnavailablebooleanRequired

A personal Pinterest account. Pinterest keeps carousel Pins for business accounts, so this channel posts one image or one video.

canShareToInstagramboolean | nullRequired

Threads only: whether connect-time probing found the linked Instagram account eligible for cross-sharing. Null when unknown — an older connection, or a probe that failed — which the composer treats as "allow, and let the publish path decide".

autoEngagementDefaultsAutomationDefaults | nullRequired

Stored defaults that seed the composer's auto-engagement panel for this channel; null when never configured.

Child attributes
commentAutoEngagementDefaultSectionRequired
Child attributes
enabledbooleanRequired
entriesAutoEngagementDefaultEntry[]Required
Child attributes
fromAccountIdstringRequired

At least 1 character.

delayMinutesintegerRequired

At least 0.

likeAutoEngagementLikeDefaultSectionRequired
Child attributes
enabledbooleanRequired
entriesobject[]Required
Child attributes
fromAccountIdstringRequired

At least 1 character.

delayMinutesintegerRequired

At least 0.

reactionstring
  • "LIKE"
  • "LOVE"
  • "CELEBRATE"
  • "INSIGHTFUL"
  • "CURIOUS"
  • "SUPPORT"
repostAutoEngagementDefaultSectionRequired
Child attributes
enabledbooleanRequired
entriesAutoEngagementDefaultEntry[]Required
Child attributes
fromAccountIdstringRequired

At least 1 character.

delayMinutesintegerRequired

At least 0.

slackAutoEngagementDefaultSectionRequired
Child attributes
enabledbooleanRequired
entriesAutoEngagementDefaultEntry[]Required
Child attributes
fromAccountIdstringRequired

At least 1 character.

delayMinutesintegerRequired

At least 0.

discordAutoEngagementDefaultSectionRequired
Child attributes
enabledbooleanRequired
entriesAutoEngagementDefaultEntry[]Required
Child attributes
fromAccountIdstringRequired

At least 1 character.

delayMinutesintegerRequired

At least 0.

primaryAccountIdstring | nullRequired

The channel whose content the composer syncs to the others, or null when the workspace hasn't set one.

400Error

Invalid request

Response attributes
errorstringRequired
issuesany[]
401Error

Not signed in

Response attributes
errorstringRequired
issuesany[]
403Error

Not a member of the organization

Response attributes
errorstringRequired
issuesany[]
GET /api/v1/connected-accounts
curl -X GET "https://orbitwrite.com/api/v1/connected-accounts" \
  -H "Authorization: Bearer $ORBITWRITE_API_KEY"
Response
{
  "accounts": [
    {
      "id": "string",
      "platform": "string",
      "handle": "string",
      "displayName": "string",
      "avatarUrl": "string",
      "profileUrl": "string",
      "needsReconnect": true,
      "inboxReconnectNeeded": true,
      "defaultSelected": true,
      "disconnected": true,
      "isPremium": true,
      "carouselUnavailable": true,
      "canShareToInstagram": true,
      "autoEngagementDefaults": {
        "comment": {
          "enabled": true,
          "entries": [
            {
              "fromAccountId": "string",
              "delayMinutes": 0
            }
          ]
        },
        "like": {
          "enabled": true,
          "entries": [
            {
              "fromAccountId": "string",
              "delayMinutes": 0,
              "reaction": "LIKE"
            }
          ]
        },
        "repost": {
          "enabled": true,
          "entries": [
            {
              "fromAccountId": "string",
              "delayMinutes": 0
            }
          ]
        },
        "slack": {
          "enabled": true,
          "entries": [
            {
              "fromAccountId": "string",
              "delayMinutes": 0
            }
          ]
        },
        "discord": {
          "enabled": true,
          "entries": [
            {
              "fromAccountId": "string",
              "delayMinutes": 0
            }
          ]
        },
        "shareToInstagram": true
      }
    }
  ],
  "primaryAccountId": "string"
}

Disconnect a social account#

POST/api/v1/connected-accounts/{accountId}/disconnect

Revokes the connection (clears its tokens and drops it out of every live-account query) but KEEPS the account row, so its posts, drafts, published history, analytics, and posting slots survive and reattach if the user reconnects the same handle. Set purgePosts to instead delete the content this channel authored AND remove the channel row itself. Requires account:disconnect.

Authentication

A signed-in session only. The Orbitwrite app calls this; an API key is refused.

Path parameters

accountIdstringRequired

At least 1 character.

Body application/json

purgePostsboolean

Also delete the posts and drafts this channel authored, AND remove the channel from the workspace entirely (nothing is left to reconnect to; connecting the same handle later starts fresh). Deletion is per post ROW, so a draft shared with other channels keeps its other channels' versions and the group itself. Irreversible. Defaults to false — disconnecting keeps content and the channel stays listed for reconnection.

Responses

200ConnectedAccountDisconnectResult

The account was disconnected

Response attributes
okbooleanRequired
deletedPostsintegerRequired
deletedGroupsintegerRequired
deletedCommentsintegerRequired
400Error

Invalid request

Response attributes
errorstringRequired
issuesany[]
401Error

Not signed in

Response attributes
errorstringRequired
issuesany[]
403Error

Not a member of the organization

Response attributes
errorstringRequired
issuesany[]
404Error

The resource does not exist

Response attributes
errorstringRequired
issuesany[]
POST /api/v1/connected-accounts/{accountId}/disconnect
curl -X POST "https://orbitwrite.com/api/v1/connected-accounts/{accountId}/disconnect" \
  -H "Authorization: Bearer $ORBITWRITE_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
  "purgePosts": true
}'
Response
{
  "ok": true,
  "deletedPosts": 0,
  "deletedGroups": 0,
  "deletedComments": 0
}

Make an account the workspace's primary account#

POST/api/v1/connected-accounts/{accountId}/primary

Requires account:update. A disconnected channel is refused (409) — it can't publish, and the primary is what the composer syncs content from.

Authentication

A signed-in session only. The Orbitwrite app calls this; an API key is refused.

Path parameters

accountIdstringRequired

At least 1 character.

Responses

200ConnectedAccountMutationResult

The mutation was applied

Response attributes
okbooleanRequired
400Error

Invalid request

Response attributes
errorstringRequired
issuesany[]
401Error

Not signed in

Response attributes
errorstringRequired
issuesany[]
403Error

Not a member of the organization

Response attributes
errorstringRequired
issuesany[]
404Error

The resource does not exist

Response attributes
errorstringRequired
issuesany[]
409Error

Conflicts with an existing resource

Response attributes
errorstringRequired
issuesany[]
POST /api/v1/connected-accounts/{accountId}/primary
curl -X POST "https://orbitwrite.com/api/v1/connected-accounts/{accountId}/primary" \
  -H "Authorization: Bearer $ORBITWRITE_API_KEY"
Response
{
  "ok": true
}

Toggle whether the account is pre-selected in a fresh composer#

POST/api/v1/connected-accounts/{accountId}/default-selected

Requires account:update.

Authentication

A signed-in session only. The Orbitwrite app calls this; an API key is refused.

Path parameters

accountIdstringRequired

At least 1 character.

Body application/json

defaultSelectedbooleanRequired

Responses

200ConnectedAccountMutationResult

The mutation was applied

Response attributes
okbooleanRequired
400Error

Invalid request

Response attributes
errorstringRequired
issuesany[]
401Error

Not signed in

Response attributes
errorstringRequired
issuesany[]
403Error

Not a member of the organization

Response attributes
errorstringRequired
issuesany[]
404Error

The resource does not exist

Response attributes
errorstringRequired
issuesany[]
POST /api/v1/connected-accounts/{accountId}/default-selected
curl -X POST "https://orbitwrite.com/api/v1/connected-accounts/{accountId}/default-selected" \
  -H "Authorization: Bearer $ORBITWRITE_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
  "defaultSelected": true
}'
Response
{
  "ok": true
}

Read an account's auto-engagement defaults#

GET/api/v1/connected-accounts/{accountId}/automation-defaults

The stored defaults that seed the composer's auto-engagement panel for this account; null when never configured. Any member may read (account:read).

Authentication

A signed-in session only. The Orbitwrite app calls this; an API key is refused.

Path parameters

accountIdstringRequired

At least 1 character.

Responses

200AutomationDefaultsResult

The stored defaults

Response attributes
autoEngagementDefaultsAutomationDefaults | nullRequired

Stored defaults that seed the composer's auto-engagement panel for this channel; null when never configured.

Child attributes
commentAutoEngagementDefaultSectionRequired
Child attributes
enabledbooleanRequired
entriesAutoEngagementDefaultEntry[]Required
Child attributes
fromAccountIdstringRequired

At least 1 character.

delayMinutesintegerRequired

At least 0.

likeAutoEngagementLikeDefaultSectionRequired
Child attributes
enabledbooleanRequired
entriesobject[]Required
Child attributes
fromAccountIdstringRequired

At least 1 character.

delayMinutesintegerRequired

At least 0.

reactionstring
  • "LIKE"
  • "LOVE"
  • "CELEBRATE"
  • "INSIGHTFUL"
  • "CURIOUS"
  • "SUPPORT"
repostAutoEngagementDefaultSectionRequired
Child attributes
enabledbooleanRequired
entriesAutoEngagementDefaultEntry[]Required
Child attributes
fromAccountIdstringRequired

At least 1 character.

delayMinutesintegerRequired

At least 0.

slackAutoEngagementDefaultSectionRequired
Child attributes
enabledbooleanRequired
entriesAutoEngagementDefaultEntry[]Required
Child attributes
fromAccountIdstringRequired

At least 1 character.

delayMinutesintegerRequired

At least 0.

discordAutoEngagementDefaultSectionRequired
Child attributes
enabledbooleanRequired
entriesAutoEngagementDefaultEntry[]Required
Child attributes
fromAccountIdstringRequired

At least 1 character.

delayMinutesintegerRequired

At least 0.

400Error

Invalid request

Response attributes
errorstringRequired
issuesany[]
401Error

Not signed in

Response attributes
errorstringRequired
issuesany[]
403Error

Not a member of the organization

Response attributes
errorstringRequired
issuesany[]
404Error

The resource does not exist

Response attributes
errorstringRequired
issuesany[]
GET /api/v1/connected-accounts/{accountId}/automation-defaults
curl -X GET "https://orbitwrite.com/api/v1/connected-accounts/{accountId}/automation-defaults" \
  -H "Authorization: Bearer $ORBITWRITE_API_KEY"
Response
{
  "autoEngagementDefaults": {
    "comment": {
      "enabled": true,
      "entries": [
        {
          "fromAccountId": "string",
          "delayMinutes": 0
        }
      ]
    },
    "like": {
      "enabled": true,
      "entries": [
        {
          "fromAccountId": "string",
          "delayMinutes": 0,
          "reaction": "LIKE"
        }
      ]
    },
    "repost": {
      "enabled": true,
      "entries": [
        {
          "fromAccountId": "string",
          "delayMinutes": 0
        }
      ]
    },
    "slack": {
      "enabled": true,
      "entries": [
        {
          "fromAccountId": "string",
          "delayMinutes": 0
        }
      ]
    },
    "discord": {
      "enabled": true,
      "entries": [
        {
          "fromAccountId": "string",
          "delayMinutes": 0
        }
      ]
    },
    "shareToInstagram": true
  }
}

Replace an account's auto-engagement defaults#

PUT/api/v1/connected-accounts/{accountId}/automation-defaults

Replaces the stored defaults wholesale. Requires account:update.

Authentication

A signed-in session only. The Orbitwrite app calls this; an API key is refused.

Path parameters

accountIdstringRequired

At least 1 character.

Body application/json

commentAutoEngagementDefaultSectionRequired
Child attributes
enabledbooleanRequired
entriesAutoEngagementDefaultEntry[]Required
Child attributes
fromAccountIdstringRequired

At least 1 character.

delayMinutesintegerRequired

At least 0.

likeAutoEngagementLikeDefaultSectionRequired
Child attributes
enabledbooleanRequired
entriesobject[]Required
Child attributes
fromAccountIdstringRequired

At least 1 character.

delayMinutesintegerRequired

At least 0.

reactionstring
  • "LIKE"
  • "LOVE"
  • "CELEBRATE"
  • "INSIGHTFUL"
  • "CURIOUS"
  • "SUPPORT"
repostAutoEngagementDefaultSectionRequired
Child attributes
enabledbooleanRequired
entriesAutoEngagementDefaultEntry[]Required
Child attributes
fromAccountIdstringRequired

At least 1 character.

delayMinutesintegerRequired

At least 0.

slackAutoEngagementDefaultSectionRequired
Child attributes
enabledbooleanRequired
entriesAutoEngagementDefaultEntry[]Required
Child attributes
fromAccountIdstringRequired

At least 1 character.

delayMinutesintegerRequired

At least 0.

discordAutoEngagementDefaultSectionRequired
Child attributes
enabledbooleanRequired
entriesAutoEngagementDefaultEntry[]Required
Child attributes
fromAccountIdstringRequired

At least 1 character.

delayMinutesintegerRequired

At least 0.

Responses

200ConnectedAccountMutationResult

The mutation was applied

Response attributes
okbooleanRequired
400Error

Invalid request

Response attributes
errorstringRequired
issuesany[]
401Error

Not signed in

Response attributes
errorstringRequired
issuesany[]
403Error

Not a member of the organization

Response attributes
errorstringRequired
issuesany[]
404Error

The resource does not exist

Response attributes
errorstringRequired
issuesany[]
PUT /api/v1/connected-accounts/{accountId}/automation-defaults
curl -X PUT "https://orbitwrite.com/api/v1/connected-accounts/{accountId}/automation-defaults" \
  -H "Authorization: Bearer $ORBITWRITE_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
  "comment": {
    "enabled": true,
    "entries": [
      {
        "fromAccountId": "string",
        "delayMinutes": 0
      }
    ]
  },
  "like": {
    "enabled": true,
    "entries": [
      {
        "fromAccountId": "string",
        "delayMinutes": 0
      }
    ]
  },
  "repost": {
    "enabled": true,
    "entries": [
      {
        "fromAccountId": "string",
        "delayMinutes": 0
      }
    ]
  },
  "slack": {
    "enabled": true,
    "entries": [
      {
        "fromAccountId": "string",
        "delayMinutes": 0
      }
    ]
  },
  "discord": {
    "enabled": true,
    "entries": [
      {
        "fromAccountId": "string",
        "delayMinutes": 0
      }
    ]
  }
}'
Response
{
  "ok": true
}

Read a TikTok channel's current publishing options#

GET/api/v1/connected-accounts/{accountId}/tiktok/creator-info

Requires account:read. Returns the privacy levels TikTok will accept for this creator, their comment/Duet/Stitch settings, and their own maximum video length. TikTok requires this before every Direct Post and refuses a privacy level it didn't offer, so build the post's options from this response rather than from a hard-coded list — an app still in review is offered SELF_ONLY and nothing else. Never cached: a creator can change these between composing and publishing.

Authentication

An API key or OAuth access token as a bearer token, or a signed-in session.

Path parameters

accountIdstringRequired

At least 1 character.

Responses

200TikTokCreatorInfo

The creator's current publishing options

Response attributes
privacyLevelOptionsstring[]Required
  • "PUBLIC_TO_EVERYONE"
  • "MUTUAL_FOLLOW_FRIENDS"
  • "FOLLOWER_OF_CREATOR"
  • "SELF_ONLY"
commentDisabledbooleanRequired
duetDisabledbooleanRequired
stitchDisabledbooleanRequired
400Error

Invalid request

Response attributes
errorstringRequired
issuesany[]
401Error

Not signed in

Response attributes
errorstringRequired
issuesany[]
403Error

Not a member of the organization

Response attributes
errorstringRequired
issuesany[]
404Error

The resource does not exist

Response attributes
errorstringRequired
issuesany[]
429Error

Rate limit exceeded

Response attributes
errorstringRequired
issuesany[]
502object

TikTok couldn't be reached

Response attributes
errorstringRequired
GET /api/v1/connected-accounts/{accountId}/tiktok/creator-info
curl -X GET "https://orbitwrite.com/api/v1/connected-accounts/{accountId}/tiktok/creator-info" \
  -H "Authorization: Bearer $ORBITWRITE_API_KEY"
Response
{
  "privacyLevelOptions": [
    "PUBLIC_TO_EVERYONE"
  ],
  "commentDisabled": true,
  "duetDisabled": true,
  "stitchDisabled": true,
  "maxVideoPostDurationSec": 0,
  "creatorUsername": "string",
  "creatorNickname": "string",
  "creatorAvatarUrl": "string"
}

List a Pinterest channel's boards#

GET/api/v1/connected-accounts/{accountId}/pinterest/boards

Requires account:read. Returns the boards this Pinterest channel can save a Pin to. A Pin is always created on a board, so a post to Pinterest needs platformOptions.pinterest.boardId set to one of these ids before it can be scheduled or published. Secret boards aren't listed. Never cached.

Authentication

An API key or OAuth access token as a bearer token, or a signed-in session.

Path parameters

accountIdstringRequired

At least 1 character.

Responses

200object

The channel's boards

Response attributes
boardsPinterestBoard[]Required
Child attributes
idstringRequired
namestringRequired
privacystring
imageUrlstring
400Error

Invalid request

Response attributes
errorstringRequired
issuesany[]
401Error

Not signed in

Response attributes
errorstringRequired
issuesany[]
403Error

Not a member of the organization

Response attributes
errorstringRequired
issuesany[]
404Error

The resource does not exist

Response attributes
errorstringRequired
issuesany[]
429Error

Rate limit exceeded

Response attributes
errorstringRequired
issuesany[]
502object

Pinterest couldn't be reached

Response attributes
errorstringRequired
GET /api/v1/connected-accounts/{accountId}/pinterest/boards
curl -X GET "https://orbitwrite.com/api/v1/connected-accounts/{accountId}/pinterest/boards" \
  -H "Authorization: Bearer $ORBITWRITE_API_KEY"
Response
{
  "boards": [
    {
      "id": "string",
      "name": "string",
      "description": "string",
      "privacy": "string",
      "imageUrl": "string"
    }
  ]
}

Create a board on a Pinterest channel#

POST/api/v1/connected-accounts/{accountId}/pinterest/boards

Requires account:update. Creates a public board on this Pinterest channel and returns it, ready to use as platformOptions.pinterest.boardId. The board appears on the account's Pinterest profile immediately. Secret boards can't be created. A name Pinterest won't take (one already in use, for example) is a 400 carrying Pinterest's reason.

Authentication

An API key or OAuth access token as a bearer token, or a signed-in session.

Path parameters

accountIdstringRequired

At least 1 character.

Body application/json

namestringRequired

Between 1 and 50 characters.

descriptionstring

At most 500 characters.

Responses

201object

The new board

Response attributes
boardPinterestBoardRequired
Child attributes
idstringRequired
namestringRequired
privacystring
imageUrlstring
400Error

Invalid request

Response attributes
errorstringRequired
issuesany[]
401Error

Not signed in

Response attributes
errorstringRequired
issuesany[]
403Error

Not a member of the organization

Response attributes
errorstringRequired
issuesany[]
404Error

The resource does not exist

Response attributes
errorstringRequired
issuesany[]
429Error

Rate limit exceeded

Response attributes
errorstringRequired
issuesany[]
502object

Pinterest couldn't be reached

Response attributes
errorstringRequired
POST /api/v1/connected-accounts/{accountId}/pinterest/boards
curl -X POST "https://orbitwrite.com/api/v1/connected-accounts/{accountId}/pinterest/boards" \
  -H "Authorization: Bearer $ORBITWRITE_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
  "name": "string"
}'
Response
{
  "board": {
    "id": "string",
    "name": "string",
    "description": "string",
    "privacy": "string",
    "imageUrl": "string"
  }
}