postiz

/home/avalon/.hermes/skills/social-media/postiz/SKILL.md · raw

Postiz Social Media Operator

Use this skill when Alex asks Hermes to manage, draft, schedule, publish, or analyze organic social media content through Postiz.

Postiz is open-source/self-hostable. The CLI package is postiz and the audited upstream agent repo was gitroomhq/postiz-agent at commit 1ba8fd4d48a8b9ee6ce1ce2dc5b3bae7bd92dfc5.

Safety posture for Alex

Default to draft-first operation:

  1. Discover connected integrations/accounts.
  2. Prepare content/media.
  3. Create a Postiz draft (-t draft) or show the exact command/JSON that would be used.
  4. Ask Alex for explicit approval before changing a draft to schedule, deleting posts, or publishing anything live.

Do not publish/schedule/delete social posts blindly from Telegram. For destructive or public-facing changes, identify the target Page/account/post ID and summarize exactly what will happen.

Security / privacy notes from audit

Install / verify

npm install -g postiz@2.0.13
postiz --version
postiz auth:status

If using self-hosted Postiz, set the API URL before commands:

export POSTIZ_API_URL=https://postiz.your-domain.com
export POSTIZ_API_KEY=your_api_key_here
postiz auth:status

For persistent Hermes usage, store non-secret config and secrets safely:

Core commands

postiz auth:status
postiz integrations:list
postiz integrations:settings <integration-id>
postiz integrations:trigger <integration-id> <method> -d '{"key":"value"}'
postiz posts:list
postiz analytics:platform <integration-id> -d 30
postiz analytics:post <post-id> -d 30

Media rule — mandatory

Every media file must go through postiz upload first. Do not pass local paths directly to -m or JSON image fields.

Correct:

MEDIA_URL=$(postiz upload /path/to/image-or-video | jq -r '.path')
postiz posts:create \
  -c "Caption" \
  -m "$MEDIA_URL" \
  -s "2026-05-15T19:00:00Z" \
  -t draft \
  -i "<integration-id>"

Wrong:

postiz posts:create -c "Caption" -m /path/to/video.mp4 ...

Why: TikTok, Instagram, YouTube, and other providers often require publicly reachable/trusted URLs. In self-hosted Postiz this upload goes to the storage backend we configure, not to paid Postiz Cloud unless using their hosted product.

Self-hosted Postiz deployment pattern for Alex

For UI/source customizations on the self-hosted instance, see references/self-hosted-ui-customization.md. Key caution: /home/avalon/apps/postiz is deployment config only; the app UI comes from the Docker image, so code changes require an explicit custom-image or upstream-patch strategy with rollback.

Known deployed instance:

If Temporal exits with a dynamic config YAML parse error, check /home/avalon/apps/postiz/dynamicconfig/development-sql.yaml; valid content is:

system.forceSearchAttributesCacheRefreshOnRead:
  - value: true
    constraints: {}

Facebook Page workflow

  1. Confirm Postiz is running and reachable.
  2. Create/configure a Meta app and set the valid OAuth redirect URI to https://postiz.apps.poofc.com/integrations/social/facebook.
  3. Set FACEBOOK_APP_ID and FACEBOOK_APP_SECRET in the Postiz environment and restart Postiz.
  4. In the Postiz web UI, connect provider Facebook Page via Meta OAuth.
  5. Use a Facebook account that has the Page permission needed to create content.
  6. Grant requested Page permissions.
  7. Back in CLI:
postiz integrations:list
FACEBOOK_ID=$(postiz integrations:list | jq -r '.[] | select(.identifier=="facebook" or .identifier=="facebook-page") | .id' | head -1)
postiz integrations:settings "$FACEBOOK_ID"
  1. Create drafts first:
postiz posts:create \
  -c "Draft Facebook Page post text" \
  -s "2026-05-15T19:00:00Z" \
  -t draft \
  -i "$FACEBOOK_ID"
  1. Only after Alex approves:
postiz posts:status <post-id> --status schedule

Instagram/TikTok/YouTube patterns

Always upload media first:

VIDEO_URL=$(postiz upload ./video.mp4 | jq -r '.path')
postiz posts:create -c "Video caption" -m "$VIDEO_URL" -s "2026-05-15T19:00:00Z" -t draft -i "<integration-id>"

For Instagram post type examples, use platform settings only after checking integrations:settings:

postiz integrations:settings <instagram-id>
postiz posts:create \
  -c "Caption #hashtag" \
  -m "$IMAGE_URL" \
  -s "2026-05-15T19:00:00Z" \
  -t draft \
  --settings '{"post_type":"post"}' \
  -i "<instagram-id>"

Analytics and missing release IDs

If analytics returns {"missing": true}, the platform published but did not return a usable post/content ID. Resolve with:

postiz posts:missing <post-id>
postiz posts:connect <post-id> --release-id "<platform-content-id>"
postiz analytics:post <post-id> -d 30

Pitfalls