Octibiz
Demo

Durchsucht Website und Dokumentation gemeinsam. Enter zeigt alle Treffer, Esc schließt.

Social posts

Social posts screen in Octibiz

Overview

Since 0.7 a social post IS a content item. You write it under Content like any other text, and the networks are its targets. It therefore exists only ONCE — before, the same thought lived as a social row and as a blog post side by side, and the two drifted apart. Scheduling, approval, languages and versions come from the editorial system; what this module contributes is the connection to the network.

Posts are written, scheduled and published here. Publishing itself is done by a network adapter — the system knows the posts, the adapter supplies the connection to the network.

A post can be linked to a campaign. It then counts towards that campaign's attribution; without a link it stands on its own.

Due posts are published by a daily run. The run is idempotent and works in batches — a second pass publishes nothing twice.

Paid reach sits next to it: ad campaigns.

Core tasks

Create a post. Write the content, pick the network and the publication time.

Pre-select networks. Under Published on on the content type you list the networks, format included, that a new post already has selected — per brand its connected account. If the brand lacks a network, Connect in the post leads here.

Schedule. The planned time controls when the run picks the post up. Until then it stays editable.

Track the status. Post statuses are configurable, see Marketing settings. On the dashboard upcoming posts can be shown as a widget.

Link a campaign. Optional — it is the bracket that connects the post with sends and attribution.

Instagram: choose feed, carousel or story. In the post, the selected Instagram target under Targets carries the option Format:

  • Feed post (default) — the first image with the text as caption.
  • Carousel — 2 to 10 images of the post to swipe through, in their order, with the text as

caption. With fewer or more images, publishing fails with this reason before anything reaches the network.

  • Story — the first image, without text (stories carry no caption); it disappears after 24

hours.

Instagram shows posts only with an image. If the post (or its Instagram version) has no image, a hint appears at the selected Instagram target. It blocks nothing — the target stays selected, and the hint disappears as soon as the post has an image, even before saving. Without an image, publishing to Instagram fails.

Images from the editor. Images you upload in the post or pick from the file storage go to every network that takes images. LinkedIn, X and Facebook receive the file itself; formats a network does not accept (WebP on LinkedIn and Facebook) are sent as JPEG. Instagram fetches the image through a signed address that expires after two hours and always receives a JPEG version — for WebP and PNG images too. For Instagram the instance must be reachable from the internet (public address in MARKETING_BASE_URL).

Other networks have their own options on the target: YouTube title, visibility and "made for kids", TikTok visibility and switching off comments, duets and stitch. They are saved with the post; via the API as targetOptions on the item ({"<target ULID>": {"format": "carousel"}}), the allowed values are listed in availableTargets[].optionSchema.

Formats per network

Each target has the option Format under Targets. Without a choice the first format of the list applies. What the format needs — media, answers, parts, a PDF — lives in the fields of the post; what only this network wants to know (first comment, playlist, release time) lives on the target.

NetworkFormatsOn the target
InstagramFeed post · carousel (2–10 images or videos) · story (one image or video) · reel (video, 3 s – 15 min)First comment — appears right after the post (not on a story)
FacebookPost · multiple images (2–10) · video · reel (vertical, 3–90 s) · story (image or video)—
LinkedInPost · multiple images (2–20) · video (up to 30 min, 500 MB) · document (PDF to flip through) · poll (2–4 answers of up to 30 characters, question up to 140)Poll duration
XPost · video (up to 140 s) · GIF · thread · poll (2–4 answers of up to 25 characters)Poll duration
YouTubeVideo · Short (vertical, up to 3 min)Thumbnail (JPEG/PNG up to 2 MB) · playlist · release on
TikTokVideo · photo carouselDraft to the TikTok inbox instead of publishing directly

Which field holds what. Images and videos go under Images and videos (chosen from the file storage), in their order. The PDF for LinkedIn goes under Document (PDF). Poll answers go one per line; the text of the post is the question. A thread starts with the text, every further part goes under Further thread parts, separated by a blank line.

Link. The Link field of the post goes to the networks that take links: LinkedIn shows it as an article with a preview when there is no image, Facebook as a link post; on X, and wherever an image is attached, it is appended to the text (X counts every address as 23 characters). Options on the target (text, link) take up to 500 characters.

Reasons before the date. If the post does not fit the format — a reel without video, a Short in landscape, a video over the length limit, too many images, an answer too long, a release time in the past — the reason shows on the target before you publish. The target is then not called.

Videos. Instagram processes a video first; the target shows Processing until then and is published afterwards — the first comment follows. Facebook and Instagram fetch the video through a signed address; the instance must be reachable from the internet for that. YouTube release: the video is uploaded right away and stays private until YouTube releases it at the chosen time.

TikTok. A draft lands in the TikTok app inbox; finish it there (music, effects) and publish it. A photo carousel is fetched by TikTok through signed addresses — the instance domain must be verified with TikTok for that. If an image or video comes from the AI, the post carries TikTok's AI label.

App only. What a network does not accept through its API — music and trending sounds (Instagram, Facebook, TikTok), live, LinkedIn articles, YouTube community posts — is listed in the format choice with the note app only and cannot be selected. For a TikTok post with music: send it as a draft to the inbox and add the music in the app.

Bundled content types. Post, Carousel, Short video, Story and Video come with their networks and formats preselected — Short video, for example: Instagram reel, TikTok, YouTube Short and Facebook reel; Carousel: Instagram carousel, LinkedIn document, TikTok photo and Facebook with multiple images. Change it under Published on on the content type.

Your changes to the bundled types stay. An update no longer overwrites fields, names or "Published on" of the bundled content types, and it does not recreate a type you deleted. If an update brings new fields (such as Document (PDF), Poll answers, Further thread parts or videos in the media picker), it only adds what is missing — once: a field you remove afterwards does not come back.

Fields in detail

A social post is a content item, not a record of its own. There is no separate administration — social supplies the channels, the post fields come from there.

ElementFromWhat it does
Content typecontentWhat kind of post is created.
Text and mediafields of the content typeThe post itself.
Targetsconnected networksWhere it is published. Several at once are possible.
Per-channel contentfield value per channelThe same field, a different version. That is the point: text for a professional network reads differently from one for an image network — the channel axis sits inside the field value, not in a second administration.
Planned publicationthe content itemWhen the post appears. Until then it sits in the calendar but nowhere public.
Options per target targetOptionson the selected targetWhat only this network wants to know — Instagram format, YouTube title, TikTok visibility. Empty means: the network default. A value the network does not know is rejected.

Connected account

This module's own mask sits under Settings → Social connections. It has exactly one purpose: to decide in whose name the company speaks.

FieldRequiredValues / formatWhat it does
Network provideryeslinkedin, meta (Facebook & Instagram), x, youtube, tiktok, pinterest, threads, google_business (Google Business Profile)Which network is meant. An unknown key is rejected.
Brand brandIdnoone of your brands; empty = the brand-less connectionWhich brand the account stands for. Brand-specific, and that is not a detail: the same instance can serve two brands with two accounts, and the permission social.connection.manage must be held in exactly THAT brand — holding it in another one is not enough.
Account accountIdpartlyone of the offered pages or accounts — the board for Pinterest, the location for Google Business ProfileWhich page publishing runs through. Needed for Meta, where one authorisation can cover several pages: taking the first one automatically would be guessing, and whoever manages three pages then posts publicly to the wrong one. Only an offered account is accepted, never a freely typed identifier.
Ad account adAccountIdpartlyone of the offered ad accountsWhich account spends money. Kept apart from the posting account because it is a second consent: being allowed to publish does not yet mean being allowed to spend budget. Here too: only from the offered ones.

At least one of account and ad account must be set — a call with neither is rejected.

Shown rather than entered:

FieldValues / formatWhat it means
connectedyes/noWhether an authorisation is stored for this network (and this brand).
expiresAttimestamp, empty = no expiry storedWhen the access expires.
expiringSoonyes/noWhether the expiry falls within the next seven days. Networks let access expire — LinkedIn after roughly 60 days, and it does not renew on its own. Without this warning the first to notice is someone wondering why nothing has appeared for a week.
accountslist of pages/accountsWhat the authorisation offers — the choice for account.
adAccountslist of ad accountsWhat the authorisation offers for advertising. Empty means advertising was not granted along with it.
hintslist of hints (key with values), empty = set upWhat the instance still lacks for this network — public address, verified domain for TikTok, LinkedIn API version; only for a connected access. See the section “Checking the setup”.

Disconnecting removes the secrets of the connection. The app credentials remain — they belong to the installation, not to the connection; see integrations.

Storing the app credentials: in the integrations pick the template of the network (LinkedIn, Meta, X, YouTube, TikTok, Pinterest, Threads, Google Business Profile) and enter client_id (the app ID, stored in plain; TikTok calls it "Client Key") and client_secret (encrypted) from the network's developer console. Register https://<your address>/api/v1/social/public/oauth/callback there as the redirect address. Only then does Connect lead to the network's consent; after consenting you return to this page and choose the page or account.

YouTube and TikTok: for YouTube, Connect obtains a permanent refresh token (Google asks for consent again every time for this) — the connection does not expire. For TikTok the connection lasts one year; the short-lived access token is renewed automatically before every post, and you are warned seven days before the year ends. Both networks review the app before it may publish (Google: upload permission, TikTok: app review) — until then connecting only works with the app's test accounts. Entering a refresh or access token by hand in the integrations remains possible.

Pinterest, Threads and Google Business Profile

Three more networks are connected like the others under Settings → Social connections with Connect. Connecting creates the publishing target; in a post it appears under Targets, on the content type under Published on. What a network does not accept is shown on the target while writing — not at night when the scheduled time arrives.

Pinterest

What goes out: a pin on the chosen board — with one image, with several images (2 to 5, to swipe through) or with a video. The text becomes the description (at most 800 characters), the first line the title. The Pinterest target in the post offers:

OptionWhat it does
Pin title pinTitleOwn title instead of the first line of text (at most 100 characters).
Destination link pinLinkWhere the pin leads, e.g. the product page — with https://.
Image description pinAltTextFor screen readers: what the image shows.

Images go to Pinterest as files (JPEG or PNG; other formats as JPEG) — the instance does not need to be reachable from the internet for this. A video is uploaded, Pinterest processes it, then the pin is created; the cover is the post's first image, otherwise the first frame of the video. Without image and without video the target rejects the post ("Pinterest needs an image or a video"), likewise with more than five images.

Choosing the board: after connecting, the account's boards are listed under Board; if the account has only one, it is already chosen. Without a chosen board nothing goes out.

What you need to set up (once):

  1. Create an app on developers.pinterest.com (business account required) and

request access for the scopes boards:read, pins:read, pins:write, user_accounts:read. Until Pinterest grants standard access, trial access applies (only your own account, pins initially visible only to you).

  1. Register https://<your address>/api/v1/social/public/oauth/callback as the redirect address in the app.
  2. In Octibiz under integrations pick the Pinterest template and enter the app ID

(client_id) and app secret (client_secret).

The sign-in lasts 60 days and renews itself — before every pin and in the daily run before it expires. Only if that fails does the connections page warn seven days ahead.

Threads

What goes out: a post with text (at most 500 characters), with an image, with a video or as a carousel of 2 to 20 images and videos. Threads fetches images and videos itself: files from Octibiz get a signed address that expires after two hours, and videos are delivered in pieces. The instance must therefore be reachable from the internet (public address in MARKETING_BASE_URL); text and external image addresses work without it. Threads processes videos first; publishing follows afterwards.

The Threads target offers Who can reply replyControl: everyone, profiles you follow, or mentioned only.

What you need to set up (once):

  1. In your existing Meta app (the same one as for Facebook and Instagram) add the use case "Threads API" and

enable the permissions threads_basic and threads_content_publish.

  1. Register https://<your address>/api/v1/social/public/oauth/callback there as the redirect address.
  2. Read the Threads app ID and Threads app secret (app settings → basic, Threads section — they differ from the

Meta app ID) and enter them in the integrations under the Threads template as client_id and client_secret.

  1. Until Meta approves the app for the Threads permissions (app review), connecting only works with the app's test

accounts.

Threads is a separate connection: Facebook and Instagram stay connected independently. The token lasts 60 days; Octibiz renews it itself seven days before it expires.

Google Business Profile

What goes out: a post on the chosen location of your business profile (Google Search and Maps) — as an update, offer or event, with the post's first image (Google does not accept video for posts). The target offers:

OptionWhat it does
Post type topicTypeUpdate (default), offer or event.
Title eventTitle, Start eventStart, End eventEndRequired for offers and events. Choose start and end as date with time in the date-time picker; Google receives the time in German time (Europe/Berlin). Through the API as an ISO 8601 timestamp, e.g. 2026-11-14T10:00:00+01:00.
Coupon code couponCode, Redeem link redeemUrl, Terms offerTermsOffers only.
Button callToAction, Button link ctaUrlLearn more, book, order, shop, sign up or call — "call" without a link (the profile's phone number applies). Offers carry no button.

If an offer or event lacks title, start or end, an event ends before it starts, or a button lacks its link, publishing fails with that reason before anything reaches Google. Google fetches the image itself via a signed address — the instance must be reachable from the internet for this.

Choosing the location: after connecting, all locations of all accounts your sign-in can access are listed under Location (name, with the city if needed); if there is only one, it is already chosen.

What you need to set up (once):

  1. In the Google Cloud Console pick a project (the YouTube one will do) and enable

the Business Profile APIs: My Business Account Management API, My Business Business Information API and Google My Business API (posts).

  1. Request access: Google only enables the Business Profile APIs on request (form "Business Profile API access

request"); until then the quota is zero and every call fails.

  1. Create an OAuth client (web application), register https://<your address>/api/v1/social/public/oauth/callback as

the redirect address and add the scope https://www.googleapis.com/auth/business.manage to the consent screen.

  1. In the integrations pick the Google Business Profile template and enter the OAuth

client's client_id and client_secret.

As with YouTube, Connect obtains a permanent refresh token; the connection does not expire.

Checking the setup

Under Settings → Social connections every connected access shows what the instance still lacks for a network — as a hint, not a block: whatever works without the requirement is still published. The same hint appears on the target in the post (state warning).

HintWhyWhat to do
… fetches images and videos from this instance itself (Instagram, Threads), … videos (Facebook), … images (Google Business Profile), … photos (TikTok)These networks do not accept your own media as a file but fetch them through a signed address valid for two hours.Set MARKETING_BASE_URL to the public https:// address of the instance. An address counts as not public without https, with localhost, an internal suffix (.local, .test, .ddev.site …) or a private IP. The form of the address is checked, not a fetch from outside.
TikTok only takes photos from a verified domainTikTok only fetches photos from a domain whose ownership is verified in the TikTok developer portal (URL properties).Verify the domain from MARKETING_BASE_URL in the developer portal, then switch on Domain verified with TikTok under Setup below. Videos work without it.
LinkedIn is expected to switch off API version …LinkedIn releases an API version every month and switches each off after about twelve months. The hint appears 60 days before.Install an update (it brings a current version) or enter a newer LinkedIn API version under Setup (format YYYYMM). The newer of the entry and the update's default applies.

You see Setup below the connections with the permission platform.settings.manage; the same values are also under Settings → System (social.linkedin.api_version, social.tiktok.domain_verified).

Settings & permissions

  • Module module.social for the connections; the posts themselves hang on module.content.
  • social.post.manage — plan and publish posts. Pre-assigned to the role Vertrieb.
  • social.connection.manage — connect and disconnect company accounts. Deliberately a separate

permission: writing posts is day-to-day work, connecting a company account is not.

  • social.brand.all — the cross-brand view of connections and figures.
  • No publishing without a network adapter. Planning works; delivery needs a configured connection.
  • Statuses are maintained under Marketing settings with

marketing.config.manage.

FAQ & troubleshooting

Instagram reports that the image cannot be fetched. Instagram fetches the image from your instance. If it is not reachable from the internet or MARKETING_BASE_URL holds an internal address, the fetch fails. Fix: enter the public address, or put the image somewhere else and use its address in the post.

The post stays scheduled and is never published. Either the time has not been reached yet, or no adapter is configured for that network.

"Instagram carousel needs 2 to 10 images." The carousel format is selected, but the post has fewer than two or more than ten images. Add or remove images, or set the format to Feed post.

The post was published twice. Should not happen: the daily run is idempotent. Check whether the same content was created twice.

"Expires on … — please reconnect." The network's access ends in less than seven days. Reconnect the account before it does — after that no scheduled post appears any more.

Meta posts to the wrong page. Then the wrong page is selected under account. A Meta authorisation often covers several pages; the selection decides which one it is.

I see no analysis for the post. Without a campaign link there is no attribution — and therefore no row in the marketing report.

social.uebersicht · Available from version 0.5.0