Channel settings in the API
Each channel takes its own settings object in POST /posts, identified by __type. Call GET /integration-settings/:id for a channel's exact schema; this page lists the fields for every network Studio supports.
Every entry in the posts array of POST /posts has a settings object. Its __type names the network, and the other fields are that network's options: privacy, titles, reply rules and so on. The composer in Studio sets the same fields when you post by hand.
How do settings work?#
- List your channels with
GET /integrations. Each one has anidand anidentifier, such asxorlinkedin-page. - Call
GET /integration-settings/:idfor the channel. It returns the network's rules, maximum length and settings schema. - If a field needs an ID that only the network knows, such as a Discord channel, call
POST /integration-trigger/:idwith the helper'smethodNameand anydatait takes. - Put the fields in
settings, with__typeset to the channel's identifier, and sendPOST /posts.
{
"integration": { "id": "YOUR_CHANNEL_ID" },
"value": [{ "content": "Our new release is out.", "image": [] }],
"settings": { "__type": "x", "who_can_reply_post": "everyone" }
}A field marked required must be present, or a scheduled post is refused with HTTP 400. Drafts are saved without the check. The full request and response shapes are in the OpenAPI description at https://studio.voholabs.com/api/public/v1/openapi.json. See the public API for authentication and the other endpoints.
X#
__type: x
| Field | Type | Notes |
|---|---|---|
who_can_reply_post | string, required | everyone, following, mentionedUsers, subscribers or verified. |
community | string | An X community address, in the form https://x.com/i/communities/1493446837214187523. |
made_with_ai | boolean | Adds X's "made with AI" label. |
paid_partnership | boolean | Adds X's paid partnership label. |
On the free plan, X posts are paid from the wallet when they are scheduled. See X.
LinkedIn and LinkedIn Page#
__type: linkedin for a personal profile, linkedin-page for a company page. Both take the same fields.
| Field | Type | Notes |
|---|---|---|
post_as_images_carousel | boolean | Posts the attached images as a swipeable carousel document instead of an image post. |
carousel_name | string | The carousel document's title. Defaults to slides. |
Instagram#
__type: instagram for Instagram (Facebook Business), instagram-standalone for Instagram (Standalone). Both take the same fields.
| Field | Type | Notes |
|---|---|---|
post_type | string, required | post or story. A video posted as post goes out as a Reel. |
collaborators | array | Accounts to invite as collaborators, as [{ "label": "username" }]. Not used on stories. |
is_trial_reel | boolean | Shares a Reel as a trial, to non-followers first. |
graduation_strategy | string | For trial Reels: MANUAL (you decide) or SS_PERFORMANCE (Instagram shares it with followers if it performs well). Defaults to MANUAL. |
audio | object | Music or an original sound for a Reel: { "id": "...", "audio_volume": 0-100, "video_volume": 0-100 }, plus optional title, artist and image. |
To find audio, call the audioSearch helper on an Instagram (Facebook Business) channel, with q for a search term (empty for trending audio) and type set to music or original_sound.
Facebook Page#
__type: facebook
| Field | Type | Notes |
|---|---|---|
post_type | string | post (the default) or story. A story needs at least one photo or video, and each one is published as its own story. |
url | string | A link to attach to the post. |
text_format_preset_id | string | A Facebook background for a text-only post. It only applies when the post has no media and is no longer than 130 characters. |
Threads#
__type: threads
Threads has no extra settings. Send { "__type": "threads" }. Extra entries in value are posted as replies, forming a thread.
TikTok#
__type: tiktok
| Field | Type | Notes |
|---|---|---|
content_posting_method | string, required | DIRECT_POST to publish, or UPLOAD to send the post to your TikTok inbox to finish in the app. |
privacy_level | string | Required for DIRECT_POST. PUBLIC_TO_EVERYONE, MUTUAL_FOLLOW_FRIENDS, FOLLOWER_OF_CREATOR or SELF_ONLY, limited to what TikTok allows for the account. |
title | string | Up to 90 characters. |
duet | boolean, required | Allow Duets. |
stitch | boolean, required | Allow Stitches. |
comment | boolean, required | Allow comments. |
autoAddMusic | string, required | yes or no. |
brand_organic_toggle | boolean, required | The post promotes your own brand. |
brand_content_toggle | boolean, required | The post is branded content for a third party. Cannot be combined with SELF_ONLY. |
disclose | boolean | Turns on content disclosure. When true, at least one of the two brand toggles must be true. |
video_made_with_ai | boolean | Labels the video as AI-generated. |
The creatorInfo helper returns what TikTok allows for the account right now, including its privacy options. See TikTok.
YouTube#
__type: youtube
| Field | Type | Notes |
|---|---|---|
title | string, required | 2 to 100 characters. |
type | string, required | public, private or unlisted. |
selfDeclaredMadeForKids | string | yes or no. |
thumbnail | object | An image you uploaded first, as { "id": "...", "path": "..." }. |
tags | array | [{ "value": "launch", "label": "launch" }]. All tags together may use up to 500 characters, and a tag with a space counts two more. |
Discord#
__type: discord
| Field | Type | Notes |
|---|---|---|
channel | string, required | The Discord channel ID. Get the list with the channels helper. |
title | string | Forum channels only: the thread title, up to 100 characters. Left empty, the first line of the post is used. |
Sanity#
__type: sanity
| Field | Type | Notes |
|---|---|---|
documentId | string, required | The published ID of the Sanity document, without the drafts. prefix. |
Studio does not copy the article. At the scheduled time it publishes the document's current draft in Sanity. The documents helper lists the documents in the connected dataset, and validateDocument checks one before you schedule it. See Sanity.
Frequently asked questions
- What happens if a setting is wrong?
Studio checks the settings object against the rules for its __type before it accepts a scheduled or immediate post. A missing required field or a value outside the allowed list returns HTTP 400 naming the channel and the problem, and nothing is scheduled. Drafts are saved without this check.
- Where do the IDs for Discord channels or Instagram audio come from?
From the channel's helper tools. Call POST /integration-trigger/:id with the helper's methodName, such as channels for Discord or audioSearch for Instagram.
- Is there a machine-readable description of the API?
Yes. The OpenAPI 3.1 description is at https://studio.voholabs.com/api/public/v1/openapi.json and needs no key.