Skip to main content

Documentation Index

Fetch the complete documentation index at: https://docs.signalrooms.xyz/llms.txt

Use this file to discover all available pages before exploring further.

Captions

Status: Current operator how-to. Caption sources are configured on the template’s Set Description toggle and apply to posting runs (Run Mode = Upload) and onboarding runs (Run Mode = Seeding). A caption is the text TikTok posts alongside a video or carousel. The template picks one of four sources: Inline text, TXT file, JSON file, or Sidecar files. This page covers when to pick each, the exact file formats, and how variants get selected.

Turning it on

The Set Description toggle on the template:
  • Off → the TikTok caption field is left empty.
  • On → pick one of the four sources below.
Each template has a “Download example” link next to the field that points at a working example file.

Cheat sheet: which source to pick

                    ┌─ One-or-two variants for all posts   → Inline text

same captions       ├─ 10+ simple captions, no titles      → Text file (.txt)
across all clips ───┤
                    └─ Need titles, need Sequential        → JSON file

unique caption ──→ Sidecar (video: <name>.json,
per file                     carousel: content.json in subfolder)

Option 1. Inline text: multiple captions separated by ;

When to use

A handful of short captions and you don’t want a separate file.

What to set

  • SourceText.
  • Descriptions field → all variants on one line, separated by ;.

Example

First caption #tag1; Second caption with emoji 🎬; Third caption @mention #hot

How variants are picked

Random without repeats: the runner cycles variants randomly, marking each as used. Once every variant is consumed, the cycle restarts.

Pitfalls

  • A literal ; in a caption is treated as a separator, move that caption to a .txt or sidecar instead.
  • Empty blocks between ;; are ignored.

Option 2. Text file: .txt, one caption per line

When to use

10+ descriptions and you’d rather keep them in an external file editable in any text editor.

What to set

  • SourceTXT file.
  • Descriptions file (.txt) → absolute path to a .txt (extension must be .txt; .text, .md, .csv are ignored).

File format

  • Encoding: UTF-8 (BOM supported).
  • Line endings: LF or CRLF (normalized).
  • One line = one caption.
  • Empty lines are ignored.
  • Hashtags and emoji go inline in the caption text, there are no separate fields.

Example

Put your caption here, replace this line with your own text
Add hashtags inline like this #example #replace_me
Emojis work too 🎬, drop them anywhere in the caption
Each line in this file becomes one TikTok caption
Empty lines are ignored, max 2200 characters per caption

How variants are picked

Random without repeats, same as inline text.

Pitfalls

  • Don’t use # for comments, a line starting with # will be posted as a caption with a hashtag.
  • Only .txt is parsed. Renaming a .md to .txt works; pointing at a .md does not.

Option 3. JSON file: {title, description} per post

When to use

  • Carousels need separate titles (TikTok’s Title field).
  • You need sequential ordering (not just random).
  • Content is generated by a pipeline that prefers structured storage.

What to set

  • SourceJSON file.
  • Title+Description file (.json) → absolute path.
  • Selection order:
    • Sequential: items used in order: first, second, third…
    • Random: random without repeats.

File format

The root is an array; each element is an object with two fields:
[
  { "title": "...", "description": "..." },
  { "title": "...", "description": "..." }
]
FieldRequired?Notes
descriptionYesCaption text, ≤ 2200 characters.
titleOptionalIgnored for videos (TikTok has no video title). Filled in for carousels if non-empty; empty/missing leaves the carousel’s Title field untouched.
Any other keys (e.g. _comment) are ignored by the parser, keep inline comments in your file if you like.

Example

[
  {
    "_comment": "This key is ignored by the parser",
    "title": "Put your title here",
    "description": "Put your description here. Replace this with your TikTok caption #hashtag"
  },
  {
    "title": "",
    "description": "Leave title empty if you don't want one. Only the description will be set"
  },
  {
    "title": "Add hashtags inline",
    "description": "Hashtags go inside the description, not a separate field 🎯 #example #replace"
  }
]

Pitfalls

  • JSON must be valid. Any syntax error and the source falls back to the legacy .txt / inline text, if defined.
  • Empty array [] → no descriptions → fallback fires.
  • Encoding must be UTF-8.

Option 4. Sidecar: a separate .json next to each media file

When to use

  • Each video or carousel has its own unique caption, and a strict “this caption → this file” binding matters.
  • Content is prepared by an external pipeline that drops a caption next to each clip.
  • In onboarding runs, to avoid mixing up which caption belongs to which clip.

What to set

  • SourceSidecar files.
  • If sidecar is missing → what to do when a file has no sidecar:
    • Skip description (default), leave the TikTok caption empty.
    • Use inline text: fall back to the global Descriptions field.
    • Use global .txt: fall back to the global .txt.
    • Use global .json: fall back to the global .json.

Sidecar file format

Recommended object form:
{
  "title": "Put your title here",
  "description": "Put your description here. Replace this with your TikTok caption #hashtag"
}
An array form is also accepted for backwards compatibility, the first element is used:
[
  { "title": "...", "description": "..." }
]

Where to put the sidecar

Video

A <video_filename>.json in the same folder next to the video:
videos/
├── clip_1.mp4
├── clip_1.json          ← caption for clip_1.mp4
├── clip_2.mov
├── clip_2.json          ← caption for clip_2.mov
└── clip_3.mp4           ← no sidecar, fallback kicks in
For videos, title is always ignored: TikTok doesn’t display a title for videos. The sidecar lives inside the carousel subfolder. Filename is picked by priority (case-insensitive):
  1. content.json
  2. description.json
  3. caption.json
  4. Any first *.json (natural sort).
carousels/
├── 01_summer/
│   ├── 1.jpg
│   ├── 2.jpg
│   ├── 3.jpg
│   └── content.json          ← priority 1
├── 02_promo/
│   ├── photo_a.png
│   ├── photo_b.png
│   └── description.json      ← priority 2
└── 03_lifestyle/
    ├── img1.png
    └── caption.json          ← priority 3
If a subfolder contains multiple .json files and none match the priority list, the first by natural sort wins and a WARNING is logged. Don’t introduce ambiguity, name your file using one of the priority names. Sidecars in flat carousel mode don’t work, there’s no unambiguous way to bind photos to a group. If you need per-carousel captions, switch to subfolder mode.

What happens to the sidecar after publishing

  • Video: <name>.json moves to used/ (or is deleted) together with the video, in sync.
  • Carousel in subfolders: the entire subfolder moves to used/ as a unit; the sidecar inside goes along.

Hashtags, mentions, titles, music: where each lives

WhatWhereNotes
HashtagsInside the description textNo separate field: "My caption #travel #2026"
Mentions @userInside the description textThe runner catches the suggestion popup while typing
TitleJSON / sidecar, title fieldIgnored for videos. Filled in for carousels if non-empty.
MusicSeparate Music card on the templateNot part of the description, see Posting runs.
Multi-language captionsInside the textAny Unicode is supported.

Limits and normalization

  • Maximum 2200 characters per caption (TikTok’s hard cap).
  • Longer captions are truncated to 2200 and a WARNING is logged.
  • A BOM () at the start of a file is stripped automatically.
  • Line endings are normalized (\r\n\n, \r\n).
  • Leading and trailing whitespace is trimmed.

Troubleshooting

SymptomCauseFix
Empty caption on TikTokSidecar missing, fallback = SkipAdd a sidecar, or switch fallback to inline / .txt / .json
Same text in a loopFew inline variants, cycle restartsAdd variants via ; or switch to .txt / .json
Title didn’t appear on a carouseltitle empty or missingAdd a non-empty "title"
Title didn’t appear on a videoExpected, videos have no Title fieldMove text into description
WARNING “Multiple non-priority sidecars”Several .json in a carousel subfolder, none priorityRename the right one to content.json
Caption truncated> 2200 charactersShorten the caption
JSON not parsingBroken syntax or non-UTF-8Validate JSON; check encoding
Sidecar not picked up mid-runCache populates at thread startRestart the thread