Voholabs

    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.

    Last updated View as Markdown

    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?#

    1. List your channels with GET /integrations. Each one has an id and an identifier, such as x or linkedin-page.
    2. Call GET /integration-settings/:id for the channel. It returns the network's rules, maximum length and settings schema.
    3. If a field needs an ID that only the network knows, such as a Discord channel, call POST /integration-trigger/:id with the helper's methodName and any data it takes.
    4. Put the fields in settings, with __type set to the channel's identifier, and send POST /posts.
    JSON
    {
      "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

    FieldTypeNotes
    who_can_reply_poststring, requiredeveryone, following, mentionedUsers, subscribers or verified.
    communitystringAn X community address, in the form https://x.com/i/communities/1493446837214187523.
    made_with_aibooleanAdds X's "made with AI" label.
    paid_partnershipbooleanAdds 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.

    FieldTypeNotes
    post_as_images_carouselbooleanPosts the attached images as a swipeable carousel document instead of an image post.
    carousel_namestringThe carousel document's title. Defaults to slides.

    Instagram#

    __type: instagram for Instagram (Facebook Business), instagram-standalone for Instagram (Standalone). Both take the same fields.

    FieldTypeNotes
    post_typestring, requiredpost or story. A video posted as post goes out as a Reel.
    collaboratorsarrayAccounts to invite as collaborators, as [{ "label": "username" }]. Not used on stories.
    is_trial_reelbooleanShares a Reel as a trial, to non-followers first.
    graduation_strategystringFor trial Reels: MANUAL (you decide) or SS_PERFORMANCE (Instagram shares it with followers if it performs well). Defaults to MANUAL.
    audioobjectMusic 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

    FieldTypeNotes
    post_typestringpost (the default) or story. A story needs at least one photo or video, and each one is published as its own story.
    urlstringA link to attach to the post.
    text_format_preset_idstringA 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

    FieldTypeNotes
    content_posting_methodstring, requiredDIRECT_POST to publish, or UPLOAD to send the post to your TikTok inbox to finish in the app.
    privacy_levelstringRequired for DIRECT_POST. PUBLIC_TO_EVERYONE, MUTUAL_FOLLOW_FRIENDS, FOLLOWER_OF_CREATOR or SELF_ONLY, limited to what TikTok allows for the account.
    titlestringUp to 90 characters.
    duetboolean, requiredAllow Duets.
    stitchboolean, requiredAllow Stitches.
    commentboolean, requiredAllow comments.
    autoAddMusicstring, requiredyes or no.
    brand_organic_toggleboolean, requiredThe post promotes your own brand.
    brand_content_toggleboolean, requiredThe post is branded content for a third party. Cannot be combined with SELF_ONLY.
    disclosebooleanTurns on content disclosure. When true, at least one of the two brand toggles must be true.
    video_made_with_aibooleanLabels 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

    FieldTypeNotes
    titlestring, required2 to 100 characters.
    typestring, requiredpublic, private or unlisted.
    selfDeclaredMadeForKidsstringyes or no.
    thumbnailobjectAn image you uploaded first, as { "id": "...", "path": "..." }.
    tagsarray[{ "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

    FieldTypeNotes
    channelstring, requiredThe Discord channel ID. Get the list with the channels helper.
    titlestringForum channels only: the thread title, up to 100 characters. Left empty, the first line of the post is used.

    Sanity#

    __type: sanity

    FieldTypeNotes
    documentIdstring, requiredThe 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.