> ## Documentation Index
> Fetch the complete documentation index at: https://docs.postqueen.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# Platform Examples

> A working command for every network, with the settings each one insists on

Every network wants something slightly different. X wants to know who may reply, Reddit wants a
flair decision even when the answer is no, TikTok wants eight fields and refuses a shorter object.
This page has a command you can paste for each of them, and says what that network will reject you
for.

Every example here is ready to run once you have swapped in your own channel id. Nothing on this
page is a sketch.

<Warning>
  **These commands publish.** `-s` takes a real date, and nothing checks that it is in the future:
  a date in the past is accepted and the post goes out on the next pass. The examples use a date a
  week out. If you want to try one safely, add `-t draft` and it lands on your calendar without
  being sent.
</Warning>

## First, your channel ids

Every command below ends with `-i` and a channel id. That id is not the network name and not the
handle, it is the id PostQueen gave the channel when you connected it. Get the list once:

```bash theme={"system"}
postqueen integrations:list
```

```json theme={"system"}
[
  { "id": "c7f3a91e-4b2d-4f8a-9e11-2a6b5c0d7e83", "name": "@yourhandle", "identifier": "x" },
  { "id": "18d40b6c-9a77-4c31-b5e2-77f9de104ab2", "name": "Your Page", "identifier": "linkedin" }
]
```

The `identifier` tells you which network it is. To pull one straight into a variable:

```bash theme={"system"}
X_ID=$(postqueen integrations:list | tail -n +2 | jq -r '.[] | select(.identifier=="x") | .id')
```

Throughout this page, replace `x-id`, `reddit-id` and the rest with the real values.

<Note>
  Not sure what a network accepts? `postqueen integrations:settings <channel-id>` prints its rules,
  character limit and settings schema. [Integrations](/cli/integrations) shows the output.
</Note>

## Checking it worked

After any command on this page:

```bash theme={"system"}
postqueen posts:list
```

Your new post is in the list with a `state`. `QUEUE` means it is waiting for its time, `PUBLISHED`
means it has gone out, `ERROR` means the network refused it. If you see `ERROR`, the reason is on
the post, and [Troubleshooting](/cli/troubleshooting) covers the common ones.

***

## X (Twitter)

### Simple post

```bash theme={"system"}
postqueen posts:create \
  -c "Hello from the terminal" \
  -s "2026-08-01T09:00:00Z" \
  -i "x-id"
```

### Thread

Repeat `-c` once per tweet. `-d` is the delay in **minutes** between them.

```bash theme={"system"}
postqueen posts:create \
  -c "Thread 1/3: Introduction" \
  -c "Thread 2/3: Main point" \
  -c "Thread 3/3: Conclusion" \
  -s "2026-08-01T09:00:00Z" \
  -d 2 \
  -i "x-id"
```

### Reply controls

```bash theme={"system"}
postqueen posts:create \
  -c "Only people I follow can reply to this" \
  -s "2026-08-01T09:00:00Z" \
  --settings '{"who_can_reply_post":"following"}' \
  -i "x-id"
```

`who_can_reply_post` takes one of `everyone`, `following`, `mentionedUsers`, `subscribers` or
`verified`. Leave the setting out and X applies its own default.

***

## Reddit

### Post with a flair

```bash theme={"system"}
# 1. Get available flairs. The subreddit goes in as the /r/ path, not the bare name
postqueen integrations:trigger reddit-id restrictions -d '{"subreddit":"/r/programming"}'

# 2. Post with a flair. Take the id from .output.flairs[] in step 1
postqueen posts:create \
  -c "My post content" \
  -s "2026-08-01T09:00:00Z" \
  --settings '{"subreddit":[{"value":{"subreddit":"/r/programming","title":"Post Title","type":"text","is_flair_required":true,"flair":{"id":"abc123","name":"Discussion"}}}]}' \
  -i "reddit-id"
```

`is_flair_required` is not optional. Leave it out and the call is refused before the post is
created. Say `false` when the subreddit does not need a flair, and drop the `flair` object with it.

`restrictions` answers with an object, not a list: `.output.flairs[]` holds the flairs, and
`.output.is_flair_required` tells you whether the subreddit insists on one. A flair you send needs
both its `id` and its `name`.

### Scripted

```bash theme={"system"}
#!/bin/bash
REDDIT_ID=$(postqueen integrations:list | tail -n +2 | jq -r '.[] | select(.identifier=="reddit") | .id')
FLAIRS=$(postqueen integrations:trigger "$REDDIT_ID" restrictions -d '{"subreddit":"/r/programming"}' | tail -n +2)
FLAIR_ID=$(echo "$FLAIRS" | jq -r '.output.flairs[0].id')
FLAIR_NAME=$(echo "$FLAIRS" | jq -r '.output.flairs[0].name')

postqueen posts:create \
  -c "Automated Reddit post" \
  -s "2026-08-01T09:00:00Z" \
  --settings "{\"subreddit\":[{\"value\":{\"subreddit\":\"/r/programming\",\"title\":\"Post Title\",\"type\":\"text\",\"is_flair_required\":true,\"flair\":{\"id\":\"$FLAIR_ID\",\"name\":\"$FLAIR_NAME\"}}}]}" \
  -i "$REDDIT_ID"
```

<Note>
  One post can target several subreddits: `subreddit` is an array. The comment feature is the
  exception, it only works when you target a single subreddit.
  [Reddit](/providers/reddit) explains why.
</Note>

***

## YouTube

```bash theme={"system"}
# Upload video first
VIDEO_URL=$(postqueen upload video.mp4 | tail -n +2 | jq -r '.path')

postqueen posts:create \
  -c "Video description here" \
  -m "$VIDEO_URL" \
  -s "2026-08-01T09:00:00Z" \
  --settings '{"title":"My Video Title","type":"public","tags":[{"value":"tech","label":"Tech"}]}' \
  -i "youtube-id"
```

`title` and `type` are both required and neither has a default. `type` must be exactly `public`,
`private` or `unlisted`.

<Warning>
  **Tags share a 500-character budget**, counted across all of them together rather than per tag.
  A tag containing a space costs two extra characters, because YouTube wraps it in quotes. Go over
  and the whole post is refused with "The maximum allowed is 500 characters in total for all tags."
</Warning>

`selfDeclaredMadeForKids` (`yes` or `no`) and `thumbnail` are optional.

***

## TikTok

```bash theme={"system"}
# Upload video first
VIDEO_URL=$(postqueen upload video.mp4 | tail -n +2 | jq -r '.path')

postqueen posts:create \
  -c "Check this out! #fyp" \
  -m "$VIDEO_URL" \
  -s "2026-08-01T09:00:00Z" \
  --settings '{"content_posting_method":"DIRECT_POST","privacy_level":"PUBLIC_TO_EVERYONE","duet":true,"stitch":true,"comment":true,"autoAddMusic":"no","brand_content_toggle":false,"brand_organic_toggle":false}' \
  -i "tiktok-id"
```

TikTok is the strictest settings block in the CLI. Eight of these fields are required and there
are no defaults, so a shorter object is refused rather than filled in: `content_posting_method`,
`privacy_level`, `duet`, `stitch`, `comment`, `autoAddMusic`, `brand_content_toggle` and
`brand_organic_toggle`. Only `title` and `video_made_with_ai` are optional.

TikTok applies these settings only when `content_posting_method` is `"DIRECT_POST"`. With
`"UPLOAD"`, which sends the video to the TikTok app inbox instead of publishing it, every setting
except the post content is silently discarded. `duet` and `stitch` apply to video posts only.

<Note>
  An unapproved TikTok app can only post privately. If your posts come back with
  `App not approved for public posting, contact support`, that is TikTok's audit gate rather than
  anything in this command. [TikTok](/providers/tiktok) covers it.
</Note>

***

## Instagram

```bash theme={"system"}
# Upload image first
IMAGE_URL=$(postqueen upload photo.jpg | tail -n +2 | jq -r '.path')

# Regular post
postqueen posts:create \
  -c "Beautiful day! #photography" \
  -m "$IMAGE_URL" \
  -s "2026-08-01T09:00:00Z" \
  --settings '{"post_type":"post"}' \
  -i "instagram-id"
```

### Story

```bash theme={"system"}
postqueen posts:create \
  -c "Story content" \
  -m "$IMAGE_URL" \
  -s "2026-08-01T09:00:00Z" \
  --settings '{"post_type":"story"}' \
  -i "instagram-id"
```

### Reel

A single video with `post_type: "post"` is published as a Reel:

```bash theme={"system"}
postqueen posts:create \
  -c "Reel caption" \
  -m "$VIDEO_URL" \
  -s "2026-08-01T09:00:00Z" \
  --settings '{"post_type":"post"}' \
  -i "instagram-id"
```

### Reel with audio

Search the Instagram audio catalog and attach a track to the Reel
(Facebook Business-linked channels only, and an empty `q` returns trending audio):

```bash theme={"system"}
# Find an audio ID
AUDIO_ID=$(postqueen integrations:trigger instagram-id audioSearch \
  -d '{"q":"summer vibes","type":"music"}' | tail -n +2 | jq -r '.output[0].id')

postqueen posts:create \
  -c "Reel with trending audio" \
  -m "$VIDEO_URL" \
  -s "2026-08-01T09:00:00Z" \
  --settings "{\"post_type\":\"post\",\"audio\":{\"id\":\"$AUDIO_ID\",\"audio_volume\":80,\"video_volume\":20}}" \
  -i "instagram-id"
```

<Note>
  Instagram fetches your media from a URL rather than accepting the file from PostQueen, so
  `/uploads` has to be reachable over public HTTPS. On a laptop install it will not be, and the post
  fails. [Uploads and Storage](/configuration/uploads) explains the options.
</Note>

***

## LinkedIn

```bash theme={"system"}
postqueen posts:create \
  -c "Professional update on LinkedIn" \
  -s "2026-08-01T09:00:00Z" \
  -i "linkedin-id"
```

Every LinkedIn setting is optional, so the plain command above works as it is.

### Image carousel

```bash theme={"system"}
postqueen posts:create \
  -c "Check out these slides!" \
  -m "https://uploads.postqueen.ai/image1.jpg,https://uploads.postqueen.ai/image2.jpg,https://uploads.postqueen.ai/image3.jpg" \
  -s "2026-08-01T09:00:00Z" \
  --settings '{"post_as_images_carousel":true,"carousel_name":"Q3 highlights"}' \
  -i "linkedin-id"
```

`post_as_images_carousel` turns the images into a document carousel; `carousel_name` is the title
shown on it. Both are optional, and without the first one the images post as an ordinary gallery.

***

## Pinterest

```bash theme={"system"}
# Boards are addressed by id, so look yours up first
postqueen integrations:trigger pinterest-id boards

postqueen posts:create \
  -c "Pin description" \
  -m "$IMAGE_URL" \
  -s "2026-08-01T09:00:00Z" \
  --settings '{"board":"board-id","title":"Pin Title","link":"https://example.com"}' \
  -i "pinterest-id"
```

<Warning>
  **`board` is required and must be the board's id**, not its name. Sending the name is the usual
  reason a Pinterest post is rejected with "Board is required" even though you clearly set one. The
  `boards` trigger above returns `{ id, name }` pairs.
</Warning>

`title` caps at 100 characters. `link` has to be a valid URL if you send it. Both are optional,
as is `dominant_color`.

***

## Discord

```bash theme={"system"}
# Channels are addressed by id too
postqueen integrations:trigger discord-id channels

postqueen posts:create \
  -c "Message to Discord" \
  -s "2026-08-01T09:00:00Z" \
  --settings '{"channel":"channel-id"}' \
  -i "discord-id"
```

`channel` is required and is an id, not the `#name` you see in the sidebar. The `channels` trigger
lists the ones the PostQueen bot can post to; a channel missing from that list is a permissions
question on the Discord side.

***

## Batch scheduling

Schedule several posts across different dates:

```bash theme={"system"}
#!/bin/bash
DATES=("2026-08-01T09:00:00Z" "2026-08-02T09:00:00Z" "2026-08-03T09:00:00Z")
CONTENT=("Monday motivation" "Tuesday tips" "Wednesday wisdom")

for i in "${!DATES[@]}"; do
  postqueen posts:create \
    -c "${CONTENT[$i]}" \
    -s "${DATES[$i]}" \
    -i "x-id"
done
```

## Multi-platform campaign

Post different content per platform in one command using a JSON file:

```bash theme={"system"}
postqueen posts:create --json campaign.json
```

Example `campaign.json`:

```json theme={"system"}
{
  "type": "schedule",
  "date": "2026-08-01T09:00:00.000Z",
  "shortLink": false,
  "tags": [],
  "posts": [
    {
      "integration": { "id": "twitter-123" },
      "value": [{ "content": "Short tweet version", "image": [] }],
      "settings": { "who_can_reply_post": "everyone" }
    },
    {
      "integration": { "id": "linkedin-456" },
      "value": [{ "content": "More detailed LinkedIn post with professional tone", "image": [] }]
    },
    {
      "integration": { "id": "reddit-789" },
      "value": [{ "content": "Reddit post body", "image": [] }],
      "settings": {
        "subreddit": [{ "value": { "subreddit": "programming", "title": "Post Title", "type": "text", "url": "", "is_flair_required": false } }]
      }
    }
  ]
}
```

Every entry in `posts` needs its own `integration.id`, drafts included. The full field reference
for this file is in [Managing Posts](/cli/managing-posts#complex-posts-with-json).

## Next steps

<CardGroup cols={2}>
  <Card title="What the CLI cannot do" icon="circle-minus" href="/cli/limits">
    The gaps, and which surface covers each one
  </Card>

  <Card title="Command reference" icon="terminal" href="/cli/command-reference">
    Every command and flag, including the two that mean different things
  </Card>

  <Card title="Troubleshooting" icon="life-ring" href="/cli/troubleshooting">
    What the errors mean and how to clear them
  </Card>

  <Card title="Provider setup" icon="plug" href="/providers/overview">
    Creating the OAuth app each network needs
  </Card>
</CardGroup>
