@growthub/cli 0.3.53 → 0.3.54

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (34) hide show
  1. package/assets/worker-kits/growthub-postiz-social-v1/.env.example +18 -0
  2. package/assets/worker-kits/growthub-postiz-social-v1/QUICKSTART.md +136 -0
  3. package/assets/worker-kits/growthub-postiz-social-v1/brands/NEW-CLIENT.md +67 -0
  4. package/assets/worker-kits/growthub-postiz-social-v1/brands/_template/brand-kit.md +120 -0
  5. package/assets/worker-kits/growthub-postiz-social-v1/brands/growthub/brand-kit.md +117 -0
  6. package/assets/worker-kits/growthub-postiz-social-v1/bundles/growthub-postiz-social-v1.json +52 -0
  7. package/assets/worker-kits/growthub-postiz-social-v1/docs/ai-caption-layer.md +118 -0
  8. package/assets/worker-kits/growthub-postiz-social-v1/docs/bullmq-queue-layer.md +157 -0
  9. package/assets/worker-kits/growthub-postiz-social-v1/docs/platform-coverage.md +97 -0
  10. package/assets/worker-kits/growthub-postiz-social-v1/docs/postiz-fork-integration.md +143 -0
  11. package/assets/worker-kits/growthub-postiz-social-v1/examples/analytics-brief-sample.md +125 -0
  12. package/assets/worker-kits/growthub-postiz-social-v1/examples/client-proposal-sample.md +127 -0
  13. package/assets/worker-kits/growthub-postiz-social-v1/examples/content-calendar-sample.md +75 -0
  14. package/assets/worker-kits/growthub-postiz-social-v1/examples/social-campaign-sample.md +104 -0
  15. package/assets/worker-kits/growthub-postiz-social-v1/growthub-meta/README.md +128 -0
  16. package/assets/worker-kits/growthub-postiz-social-v1/growthub-meta/kit-standard.md +113 -0
  17. package/assets/worker-kits/growthub-postiz-social-v1/kit.json +104 -0
  18. package/assets/worker-kits/growthub-postiz-social-v1/output/README.md +56 -0
  19. package/assets/worker-kits/growthub-postiz-social-v1/output-standards.md +127 -0
  20. package/assets/worker-kits/growthub-postiz-social-v1/runtime-assumptions.md +159 -0
  21. package/assets/worker-kits/growthub-postiz-social-v1/setup/check-deps.sh +117 -0
  22. package/assets/worker-kits/growthub-postiz-social-v1/setup/clone-fork.sh +83 -0
  23. package/assets/worker-kits/growthub-postiz-social-v1/setup/verify-env.mjs +99 -0
  24. package/assets/worker-kits/growthub-postiz-social-v1/skills.md +277 -0
  25. package/assets/worker-kits/growthub-postiz-social-v1/templates/analytics-brief.md +123 -0
  26. package/assets/worker-kits/growthub-postiz-social-v1/templates/caption-copy-deck.md +127 -0
  27. package/assets/worker-kits/growthub-postiz-social-v1/templates/client-proposal.md +139 -0
  28. package/assets/worker-kits/growthub-postiz-social-v1/templates/content-calendar.md +65 -0
  29. package/assets/worker-kits/growthub-postiz-social-v1/templates/platform-publishing-plan.md +112 -0
  30. package/assets/worker-kits/growthub-postiz-social-v1/templates/scheduling-manifest.md +83 -0
  31. package/assets/worker-kits/growthub-postiz-social-v1/templates/social-campaign-brief.md +111 -0
  32. package/assets/worker-kits/growthub-postiz-social-v1/validation-checklist.md +79 -0
  33. package/assets/worker-kits/growthub-postiz-social-v1/workers/postiz-social-operator/CLAUDE.md +287 -0
  34. package/package.json +1 -1
@@ -0,0 +1,157 @@
1
+ # BullMQ Queue Layer
2
+
3
+ **Scheduling manifest format and queue architecture for Postiz API submission.**
4
+
5
+ ---
6
+
7
+ ## Overview
8
+
9
+ Postiz uses BullMQ (backed by Redis) as its job queue for scheduled post publishing. When this kit generates a scheduling manifest, it produces a JSON file that can be submitted to the Postiz API's bulk scheduling endpoint. The API enqueues each post with a delay calculated from `scheduledAt - now()`.
10
+
11
+ ---
12
+
13
+ ## Scheduling Manifest Format
14
+
15
+ The full JSON format for the scheduling manifest:
16
+
17
+ ```json
18
+ {
19
+ "postizSchedulingManifest": {
20
+ "version": "1.0",
21
+ "workspaceId": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
22
+ "generatedAt": "2026-04-15T10:00:00-05:00",
23
+ "dryRun": false,
24
+ "posts": [
25
+ {
26
+ "postId": "urbancycle-20260420-instagram-001",
27
+ "platform": "instagram",
28
+ "scheduledAt": "2026-04-20T09:00:00-05:00",
29
+ "content": "Building for the long game means planting seeds you won't harvest for years. At Urban Cycle, we're still running routes we mapped in 2021. Where are you building today that you won't see pay off until 2028? Share in the comments — we read every one. #urbanmobility #sustainableliving #cycling",
30
+ "mediaAssets": [
31
+ {
32
+ "type": "image",
33
+ "path": "assets/2026-04-20-instagram-001.jpg",
34
+ "altText": "Urban Cycle team on a community cycling route, morning light"
35
+ }
36
+ ],
37
+ "tags": ["#urbanmobility", "#sustainableliving", "#cycling"],
38
+ "status": "pending"
39
+ }
40
+ ]
41
+ }
42
+ }
43
+ ```
44
+
45
+ ---
46
+
47
+ ## Field Reference
48
+
49
+ | Field | Type | Required | Description |
50
+ |---|---|---|---|
51
+ | `version` | string | Yes | Manifest version — always `"1.0"` for this kit |
52
+ | `workspaceId` | string (UUID) | Yes | Postiz workspace UUID from Settings → Workspace |
53
+ | `generatedAt` | string (ISO 8601) | Yes | Manifest generation timestamp |
54
+ | `dryRun` | boolean | Yes | `true` for agent-only mode (no API submission); `false` for live submission |
55
+ | `posts[].postId` | string | Yes | Unique post identifier — see naming convention below |
56
+ | `posts[].platform` | string | Yes | Postiz platform integration ID (from `docs/platform-coverage.md`) |
57
+ | `posts[].scheduledAt` | string (ISO 8601) | Yes | Target publish timestamp with timezone offset |
58
+ | `posts[].content` | string | Yes | Full caption text (selected A/B/C variant) |
59
+ | `posts[].mediaAssets` | array | No | Media asset references (empty array if text-only post) |
60
+ | `posts[].mediaAssets[].type` | string | Yes | `"image"` \| `"video"` \| `"carousel"` |
61
+ | `posts[].mediaAssets[].path` | string | Yes | Relative path to asset file |
62
+ | `posts[].mediaAssets[].altText` | string | No | Accessibility alt text for images |
63
+ | `posts[].tags` | array | No | Hashtag strings (with `#` prefix) |
64
+ | `posts[].status` | string | Yes | Always `"pending"` in generated manifest |
65
+
66
+ ---
67
+
68
+ ## Post ID Naming Convention
69
+
70
+ ```
71
+ <client-slug>-<YYYYMMDD>-<platform>-<sequence>
72
+ ```
73
+
74
+ | Part | Rule | Example |
75
+ |---|---|---|
76
+ | client-slug | Lowercase, hyphenated, no special chars | `urban-cycle` |
77
+ | YYYYMMDD | Scheduled post date | `20260420` |
78
+ | platform | Postiz platform ID | `instagram` |
79
+ | sequence | 3-digit zero-padded sequence | `001`, `002`, `003` |
80
+
81
+ **Example:** `urban-cycle-20260420-instagram-001`
82
+
83
+ ---
84
+
85
+ ## Timestamp Format
86
+
87
+ All `scheduledAt` values must use ISO 8601 format with explicit timezone offset:
88
+
89
+ ```
90
+ YYYY-MM-DDTHH:MM:SS±HH:MM
91
+ ```
92
+
93
+ **Examples:**
94
+ - `2026-04-20T09:00:00-05:00` — 9am CDT
95
+ - `2026-04-20T09:00:00-04:00` — 9am EDT
96
+ - `2026-04-20T14:00:00Z` — 2pm UTC
97
+
98
+ Never use `Z` for local time unless the workspace timezone is explicitly UTC.
99
+
100
+ ---
101
+
102
+ ## Submission to Postiz API
103
+
104
+ ```bash
105
+ # Submit the scheduling manifest to Postiz bulk scheduling endpoint
106
+ curl -X POST "${POSTIZ_API_URL}/api/v1/posts/bulk" \
107
+ -H "Content-Type: application/json" \
108
+ -H "Authorization: Bearer <jwt-token>" \
109
+ -d @scheduling-manifest.json
110
+
111
+ # Verify queue health after submission
112
+ curl "${POSTIZ_API_URL}/api/v1/queue/health" \
113
+ -H "Authorization: Bearer <jwt-token>"
114
+ ```
115
+
116
+ Obtain the JWT token from Postiz admin UI → Settings → API Keys, or via `POST /api/v1/auth/login`.
117
+
118
+ ---
119
+
120
+ ## Queue Monitoring
121
+
122
+ After submitting the manifest, monitor the BullMQ queue:
123
+
124
+ 1. **Postiz admin UI** → Queue Management: shows pending, active, completed, and failed jobs
125
+ 2. **API endpoint**: `GET /api/v1/queue/health` — returns queue stats
126
+ 3. **Redis CLI** (advanced): `redis-cli monitor` — raw job events
127
+
128
+ ### Job States
129
+
130
+ | State | Meaning |
131
+ |---|---|
132
+ | `waiting` | Job is queued, delay has not expired |
133
+ | `active` | Job is currently being processed (publishing now) |
134
+ | `completed` | Post was published successfully |
135
+ | `failed` | Post failed to publish — check error in admin UI |
136
+ | `delayed` | Job is waiting for `scheduledAt` time |
137
+
138
+ ### Retry Logic
139
+
140
+ Postiz retries failed publish jobs 3 times with exponential backoff by default:
141
+ - Attempt 1: immediately after failure
142
+ - Attempt 2: 5 seconds after first retry
143
+ - Attempt 3: 30 seconds after second retry
144
+
145
+ Failed jobs after 3 attempts are moved to the dead letter queue and visible in the admin UI → Failed Jobs.
146
+
147
+ ---
148
+
149
+ ## Dry-Run Mode
150
+
151
+ When `dryRun: true` in the manifest header:
152
+ - The manifest is produced as a JSON file but is **not submitted to the Postiz API**
153
+ - All `status` fields remain `"pending"`
154
+ - The manifest can be reviewed and submitted manually
155
+ - Use `dryRun: true` in all agent-only mode sessions
156
+
157
+ The agent must set `dryRun: true` automatically when the Postiz API is not reachable or when execution mode is `agent-only`.
@@ -0,0 +1,97 @@
1
+ # Platform Coverage
2
+
3
+ **Supported Postiz integration IDs, format specs, and character limits.**
4
+
5
+ **Frozen at kit creation: 2026-04-15. Update when Postiz adds new platform integrations.**
6
+
7
+ ---
8
+
9
+ ## Platform Reference Table
10
+
11
+ | Platform | Postiz ID | Auth Method | Post Types | Char Limit | Image Spec | Video Spec |
12
+ |---|---|---|---|---|---|---|
13
+ | Instagram | `instagram` | Meta OAuth | image, video, reel, story, carousel | 2,200 | 1080×1080 (square), 1080×1350 (portrait) | 1080×1920 (reels), MP4, ≤90s |
14
+ | LinkedIn | `linkedin` | LinkedIn OAuth | text, image, video, document/carousel | 3,000 | 1200×627, PNG/JPG | MP4, ≤10 min |
15
+ | TikTok | `tiktok` | TikTok OAuth | video only | 2,200 | — | 1080×1920, MP4/MOV, 15s–10min |
16
+ | X (Twitter) | `twitter` | Twitter OAuth 2.0 | text, image, video, thread | 280 | 1200×675, ≤5MB | MP4/MOV, ≤2min 20s |
17
+ | YouTube | `youtube` | Google OAuth | video (long-form), shorts | N/A | Thumbnail: 1280×720 | MP4, any length; Shorts ≤60s, 1080×1920 |
18
+ | Pinterest | `pinterest` | Pinterest OAuth | image, video, idea pin | 500 | 1000×1500 (2:3 ratio) | MP4, 4s–15min |
19
+ | Reddit | `reddit` | Reddit OAuth | text, image, video, link | — subreddit rules | Varies by subreddit | MP4, ≤15min |
20
+ | Facebook | `facebook` | Meta OAuth | text, image, video, reel, story, carousel | 63,206 | 1200×628, PNG/JPG | MP4, ≤240min |
21
+ | Bluesky | `bluesky` | AT Protocol credentials | text, image, video | 300 | Up to 4 images, 1×1 to 3×4 | MP4, ≤60s |
22
+ | Mastodon | `mastodon` | OAuth (instance-specific) | text, image, video, poll | 500 (instance-configurable) | PNG/JPG/GIF/WebP | MP4/WebM/MOV |
23
+ | Slack | `slack` | Slack OAuth | text, image, file | — | PNG/JPG/GIF | MP4 |
24
+ | Telegram | `telegram` | Telegram Bot API token | text, image, video, document | 4,096 | JPEG, ≤10MB | MP4, ≤50MB |
25
+ | Discord | `discord` | Discord Bot token | text, image, video, embed | 2,000 | PNG/JPG/GIF, ≤8MB | MP4, ≤8MB |
26
+ | Threads | `threads` | Meta OAuth | text, image, video | 500 | 1:1 square; 4:5 portrait | MP4, ≤5min |
27
+ | Dribbble | `dribbble` | Dribbble OAuth | image, video | — | PNG/JPG/GIF, ≤30MB | — |
28
+ | Tumblr | `tumblr` | Tumblr OAuth | text, image, video, audio | — | PNG/JPG/GIF | MP4 |
29
+ | Medium | `medium` | Medium OAuth | article (long-form markdown) | — | Embedded images | — |
30
+ | DEV.to | `devto` | DEV API key | article (markdown) | — | Embedded images | — |
31
+ | Hashnode | `hashnode` | Hashnode API key | article (markdown) | — | Embedded images | — |
32
+ | Lemmy | `lemmy` | Lemmy credentials | text, image, link | — | PNG/JPG | — |
33
+ | Nostr | `nostr` | Nostr keypair | text, image | — | URLs (no direct upload) | — |
34
+
35
+ ---
36
+
37
+ ## Platform Selection Guidance
38
+
39
+ ### Audience Demographics (2026 data — update when brand kit specifies more precise data)
40
+
41
+ | Platform | Primary Demographic | Dominant Use Case |
42
+ |---|---|---|
43
+ | Instagram | 18–34 (55% female) | Visual branding, lifestyle, product showcase |
44
+ | LinkedIn | 25–55 (professional) | B2B, thought leadership, hiring |
45
+ | TikTok | 18–34 | Short-form entertainment, product discovery |
46
+ | X/Twitter | 18–49 (male-skewed) | News, opinion, live commentary |
47
+ | YouTube | All ages (18–49 core) | Education, reviews, entertainment |
48
+ | Pinterest | 25–44 (female-skewed 70%) | Discovery, DIY, home, fashion, recipes |
49
+ | Reddit | 18–49 (male-skewed) | Community discussion, niche interests |
50
+ | Facebook | 35–65 | Community groups, local business, events |
51
+ | Bluesky | 18–40 (tech-forward) | Open protocol social, tech and media |
52
+ | Mastodon | 25–45 (tech-forward) | Open source, decentralized, privacy-aware |
53
+ | LinkedIn | — | — |
54
+
55
+ ---
56
+
57
+ ## Post Type Compatibility Matrix
58
+
59
+ | Post Type | instagram | linkedin | tiktok | twitter | youtube | pinterest | reddit | facebook | bluesky |
60
+ |---|---|---|---|---|---|---|---|---|---|
61
+ | Static Image | ✓ | ✓ | ✗ | ✓ | ✗ | ✓ | ✓ | ✓ | ✓ |
62
+ | Video | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ |
63
+ | Carousel / Slides | ✓ | ✓ | ✗ | ✗ | ✗ | ✓ | ✗ | ✓ | ✗ |
64
+ | Text Only | ✗ | ✓ | ✗ | ✓ | ✗ | ✗ | ✓ | ✓ | ✓ |
65
+ | Story | ✓ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✓ | ✗ |
66
+ | Reel / Short | ✓ | ✗ | ✓ | ✗ | ✓ (Shorts) | ✗ | ✗ | ✓ | ✗ |
67
+ | Long-form Article | ✗ | ✓ (newsletter) | ✗ | ✗ | ✗ | ✗ | ✓ | ✗ | ✗ |
68
+
69
+ ---
70
+
71
+ ## Hashtag Best Practices by Platform
72
+
73
+ | Platform | Recommended Count | Strategy |
74
+ |---|---|---|
75
+ | Instagram | 3–5 | Mix niche + medium-volume (avoid over-tagging) |
76
+ | LinkedIn | 3–5 | Professional and industry-specific |
77
+ | TikTok | 3–6 | Mix trending sounds + niche tags |
78
+ | X/Twitter | 1–2 | In-text placement, campaign hashtags |
79
+ | Pinterest | 2–3 | Keyword-based for discoverability |
80
+ | Bluesky | 0–2 | Contextual only, rarely used |
81
+ | Mastodon | 2–4 | CamelCase for accessibility |
82
+ | Reddit | 0 | Subreddit flair instead |
83
+
84
+ ---
85
+
86
+ ## Posting Time Recommendations
87
+
88
+ *Based on general industry data. Override with client's own analytics if available.*
89
+
90
+ | Platform | Weekday Best Times (ET) | Weekend |
91
+ |---|---|---|
92
+ | Instagram | Mon–Fri: 9–11am, 6–8pm | Sat: 10am–12pm |
93
+ | LinkedIn | Tue–Thu: 8–10am, 12pm | Minimal weekend activity |
94
+ | TikTok | Mon–Fri: 7–9am, 7–9pm | Sat–Sun: 11am–1pm |
95
+ | X/Twitter | Mon–Fri: 8–10am, 12–2pm | Limited |
96
+ | Facebook | Tue–Thu: 9am–12pm | Sat: 12–1pm |
97
+ | Pinterest | Sat–Sun: 2–4pm, 8–11pm | All day |
@@ -0,0 +1,143 @@
1
+ # Postiz Fork Integration
2
+
3
+ **How this kit integrates with the Postiz open-source social media platform.**
4
+
5
+ ---
6
+
7
+ ## What Postiz Is
8
+
9
+ [Postiz](https://github.com/gitroomhq/postiz-app) is an open-source, self-hosted social media scheduling and automation platform built on NestJS + Next.js. It supports 28+ social media platforms and ships with a BullMQ job queue, multi-workspace management, AI caption generation, media upload, and a public REST API.
10
+
11
+ GitHub: https://github.com/gitroomhq/postiz-app
12
+ License: MIT
13
+ Stars: ~28,000+ (as of kit creation)
14
+
15
+ ---
16
+
17
+ ## Integration Architecture
18
+
19
+ ```
20
+ growthub-postiz-social-v1 (this kit)
21
+
22
+ ├── workers/postiz-social-operator/CLAUDE.md
23
+ │ Agent operating law — drives campaign planning, caption drafts,
24
+ │ scheduling manifest generation, and analytics briefing
25
+
26
+ ├── setup/clone-fork.sh
27
+ │ Clones gitroomhq/postiz-app → ~/postiz-app
28
+ │ Runs docker compose up -d (starts Postiz + Redis + PostgreSQL)
29
+ │ Waits for API healthcheck at http://localhost:3000/api/healthcheck
30
+
31
+ ├── setup/verify-env.mjs
32
+ │ Checks fork existence, API reachability, POSTIZ_WORKSPACE_ID, ANTHROPIC_API_KEY
33
+
34
+ └── templates/scheduling-manifest.md
35
+ BullMQ-compatible JSON manifest format for bulk post scheduling
36
+ via POST /api/v1/posts/bulk
37
+ ```
38
+
39
+ ---
40
+
41
+ ## Service Topology
42
+
43
+ When running in local-fork mode, Postiz operates as a Docker Compose stack:
44
+
45
+ ```
46
+ postiz-app container (port 3000)
47
+ ├── NestJS API (apps/backend/) ← REST API, BullMQ job scheduler
48
+ └── Next.js Frontend (apps/frontend/) ← Admin UI, calendar view, analytics
49
+
50
+ postiz-redis container (port 6379)
51
+ └── Redis ← BullMQ queue backend, session cache
52
+
53
+ postiz-postgres container (port 5432)
54
+ └── PostgreSQL ← Posts, workspaces, platform credentials, analytics
55
+ ```
56
+
57
+ All services are defined in `docker-compose.yml` at the fork root.
58
+
59
+ ---
60
+
61
+ ## Postiz API — Key Endpoints Used By This Kit
62
+
63
+ | Endpoint | Method | Purpose |
64
+ |---|---|---|
65
+ | `/api/healthcheck` | GET | Verify Postiz is running |
66
+ | `/api/v1/workspace` | GET | Retrieve workspace ID and metadata |
67
+ | `/api/v1/posts/bulk` | POST | Submit scheduling manifest |
68
+ | `/api/v1/posts/{id}` | GET | Verify a scheduled post |
69
+ | `/api/v1/analytics` | GET | Retrieve engagement analytics |
70
+ | `/api/v1/queue/health` | GET | Check BullMQ queue health |
71
+ | `/api/v1/posts/ai/generate` | POST | AI caption generation (Postiz-side) |
72
+
73
+ Authentication is via JWT bearer token. Obtain from Postiz admin UI → Settings → API Keys.
74
+
75
+ ---
76
+
77
+ ## Platform Integration Layer
78
+
79
+ Platform integrations live under `libraries/nestjs-libraries/src/integrations/` in the Postiz repo. Each integration file:
80
+ - Defines the OAuth flow for connecting the platform account
81
+ - Implements `post()` for publishing content
82
+ - Implements `analytics()` for pulling engagement data
83
+ - Declares the integration ID (used as the `platform` field in scheduling manifests)
84
+
85
+ When this kit generates a scheduling manifest, platform IDs must match the integration IDs in the running Postiz instance. See `docs/platform-coverage.md` for the full list.
86
+
87
+ ---
88
+
89
+ ## AI Caption Generation
90
+
91
+ Postiz has its own AI caption generation endpoint (`/api/v1/posts/ai/generate`), activated when `OPENAI_API_KEY` or `ANTHROPIC_API_KEY` is set in the Postiz `.env`. This is **separate** from the agent-side caption drafting in this kit.
92
+
93
+ **This kit's caption workflow:**
94
+ - The `postiz-social-operator` agent drafts A/B/C caption variants using its own reasoning and the AI caption methodology in `docs/ai-caption-layer.md`
95
+ - Postiz's own AI caption feature is available to the user independently in the admin UI
96
+ - The kit does not call the Postiz AI endpoint — it produces its own caption drafts
97
+
98
+ ---
99
+
100
+ ## BullMQ Queue Behavior
101
+
102
+ When a post is submitted to Postiz via `POST /api/v1/posts/bulk`:
103
+
104
+ 1. Postiz validates the payload against the workspace's connected platforms
105
+ 2. Each post is enqueued in BullMQ with a delay calculated from `scheduledAt - now()`
106
+ 3. When the delay expires, BullMQ triggers the `publish-post` job
107
+ 4. The job calls the platform integration's `post()` method
108
+ 5. On success: post marked as `published` in PostgreSQL
109
+ 6. On failure: retried up to 3 times (configurable), then moved to dead letter queue
110
+
111
+ Monitor the queue via Postiz admin UI → Queue Management, or via `GET /api/v1/queue/health`.
112
+
113
+ ---
114
+
115
+ ## Workspace Isolation
116
+
117
+ Postiz supports multiple workspaces. Each workspace has:
118
+ - Its own set of connected platform accounts
119
+ - Its own posting queue
120
+ - Its own analytics data
121
+ - A UUID (`workspaceId`) required in all API calls
122
+
123
+ The `POSTIZ_WORKSPACE_ID` in this kit's `.env` must match the workspace configured in the Postiz admin UI. Get it from Settings → Workspace in the admin UI, or from `GET /api/v1/workspace`.
124
+
125
+ ---
126
+
127
+ ## Inspecting the Fork Before Planning
128
+
129
+ Before generating any campaign or scheduling manifest, inspect the running Postiz instance:
130
+
131
+ ```bash
132
+ # Verify all containers are running
133
+ docker compose ps
134
+
135
+ # Check API health
136
+ curl http://localhost:3000/api/healthcheck
137
+
138
+ # List connected platform integrations (requires auth)
139
+ curl http://localhost:3000/api/v1/integrations \
140
+ -H "Authorization: Bearer <jwt-token>"
141
+ ```
142
+
143
+ Do not generate scheduling manifests for platforms that are not connected and authorized in the Postiz admin UI. Unconnected platform posts will fail at publish time.
@@ -0,0 +1,125 @@
1
+ # Analytics Brief — Sample
2
+
3
+ <!-- Sample: Urban Cycle | Q2 2026 Urban Mobility Month | May 2026 | v1 | 2026-06-01 -->
4
+ <!-- This is a filled example demonstrating the expected format. All metrics are fictitious but realistic. -->
5
+
6
+ ---
7
+
8
+ ## Period Summary
9
+
10
+ | Field | Value |
11
+ |---|---|
12
+ | Client | Urban Cycle |
13
+ | Campaign | Q2 2026 — Urban Mobility Month |
14
+ | Period | 2026-05-01 to 2026-05-31 |
15
+ | Platforms Analyzed | instagram, linkedin, twitter |
16
+ | Total Posts Published | 52 |
17
+ | Data Source | Client-provided platform export (Instagram Insights, LinkedIn Analytics, X Analytics) |
18
+
19
+ ---
20
+
21
+ ## Per-Platform Performance
22
+
23
+ | Platform | Impressions | Reach | Engagement Rate | Follower Growth | Link Clicks | Posts Published |
24
+ |---|---|---|---|---|---|---|
25
+ | instagram | 28,450 | 14,200 | 4.1% | +612 | 487 (bio link) | 22 |
26
+ | linkedin | 9,800 | 6,300 | 2.8% | +94 | 312 (post links) | 12 |
27
+ | twitter | 11,200 | 8,700 | 1.9% | +128 | 156 | 18 |
28
+ | **Totals** | **49,450** | **29,200** | **avg 2.9%** | **+834** | **955** | **52** |
29
+
30
+ *Engagement Rate = (likes + comments + shares + saves) / impressions × 100*
31
+
32
+ ---
33
+
34
+ ## Top 3 Performing Posts
35
+
36
+ ### #1 Best Performing
37
+
38
+ | Attribute | Value |
39
+ |---|---|
40
+ | Post Date | 2026-05-07 |
41
+ | Platform | instagram |
42
+ | Theme Pillar | Community Spotlight |
43
+ | Post Type | Reel |
44
+ | Impressions | 4,230 |
45
+ | Engagement Rate | 8.7% |
46
+ | Caption Preview | "Maria cycles 14km each way to her nursing shift. Every. Single. Day. Here's her route." |
47
+ | Why It Worked | Community Spotlight Reels consistently outperform static images by 2–3x for this account. Maria's human story resonated — 127 saves, 43 comments. Reel format received Explore page placement. |
48
+
49
+ ---
50
+
51
+ ### #2 Best Performing
52
+
53
+ | Attribute | Value |
54
+ |---|---|
55
+ | Post Date | 2026-05-05 |
56
+ | Platform | linkedin |
57
+ | Theme Pillar | Advocacy & Infrastructure |
58
+ | Post Type | Text + image (infographic) |
59
+ | Impressions | 2,800 |
60
+ | Engagement Rate | 5.2% |
61
+ | Caption Preview | "72% of urban commuters cite safety as the #1 barrier to cycling. Yet cities that invest in prot..." |
62
+ | Why It Worked | Bike to Work Day (May 5) created organic interest in cycling safety data. The infographic format drove 47 saves. 12 comments from city planners and transportation professionals — organic reach into LinkedIn's professional niche. |
63
+
64
+ ---
65
+
66
+ ### #3 Best Performing
67
+
68
+ | Attribute | Value |
69
+ |---|---|
70
+ | Post Date | 2026-05-14 |
71
+ | Platform | instagram |
72
+ | Theme Pillar | Gear & Technique |
73
+ | Post Type | Carousel |
74
+ | Impressions | 3,140 |
75
+ | Engagement Rate | 6.1% |
76
+ | Caption Preview | "5 locks that actually work (and 2 that don't). Swipe for the breakdown →" |
77
+ | Why It Worked | Carousel format drove 89 saves — highest save count of the month. "Save this" CTA explicitly requests save behavior. Educational format with opinionated recommendations outperforms generic product posts. |
78
+
79
+ ---
80
+
81
+ ## Bottom 3 Performing Posts
82
+
83
+ | Post Date | Platform | Theme | Engagement Rate | Failure Hypothesis |
84
+ |---|---|---|---|---|
85
+ | 2026-05-20 | twitter | Brand & Behind the Scenes | 0.6% | Brand origin story content underperforms on X — audience wants real-time commentary and opinions, not retrospective narrative. Recommend moving brand storytelling to Instagram only. |
86
+ | 2026-05-13 | instagram | Route Stories | 1.2% | Posted on Victoria Day holiday weekend (May 13) — audience not active. Should have used this slot for a lighter community post or pushed the Route Story to the following Tuesday. |
87
+ | 2026-05-18 | linkedin | Gear & Technique | 0.8% | Gear recommendations are not relevant to LinkedIn's Urban Cycle audience (B2B decision-makers, urban planners). Gear content should stay on Instagram and X. Platform-content mismatch. |
88
+
89
+ ---
90
+
91
+ ## KPI vs. Target Comparison
92
+
93
+ | KPI | Target | Actual | Status |
94
+ |---|---|---|---|
95
+ | Impressions | 25,000 / month | 49,450 | Exceeded (+98%) |
96
+ | Avg Engagement Rate | ≥3.5% Instagram | 4.1% Instagram | Met |
97
+ | Follower Growth | +500 Instagram | +612 Instagram | Exceeded (+22%) |
98
+ | Link Clicks | 300 (bio + LinkedIn) | 955 | Exceeded (+218%) |
99
+ | UGC Posts #UrbanCycleMonth | ≥3 | 7 | Exceeded (+133%) |
100
+
101
+ ---
102
+
103
+ ## Recommendations for Next Period (June)
104
+
105
+ 1. **Increase Reel frequency on Instagram from 1x/week to 3x/week:** Reels account for 38% of total impressions on only 14% of posts. Shifting 2 static image slots to Reels should push Instagram impressions 40–60% higher with the same posting volume.
106
+
107
+ 2. **Shift X/Twitter posting time from 8am to 7:30am ET on weekdays:** Top-performing X posts came at 7:30am on days when the captions were tied to commute timing. Early morning commuter context drove 2.3× more replies than midday posts.
108
+
109
+ 3. **Remove Gear content from LinkedIn:** The two lowest-performing LinkedIn posts were gear recommendations. Replace with Advocacy & Infrastructure content (strongest LinkedIn performer) and bring LinkedIn gear coverage to 0% in June.
110
+
111
+ 4. **Launch a UGC challenge for June:** With 7 UGC posts in May (vs. 3 target), there's clear community enthusiasm. A branded June challenge (#RideWithUrbanCycle) with a weekly rider spotlight will compound community content without increasing production cost.
112
+
113
+ 5. **Test Variant C (question hook) on Instagram Thursday posts:** May analysis shows engagement rate 1.8× higher on posts that opened with a direct question. Currently only 30% of Instagram captions use Variant C. Shift Thursday posts to question-hook format for 4-week A/B test.
114
+
115
+ ---
116
+
117
+ ## Benchmark Comparison
118
+
119
+ | Metric | Urban Cycle Result | Industry Benchmark | Source |
120
+ |---|---|---|---|
121
+ | Instagram engagement rate | 4.1% | 0.83%–1.22% (general); 3.0% for lifestyle/outdoor | Rival IQ 2026 Social Media Benchmark Report |
122
+ | LinkedIn engagement rate | 2.8% | 0.35%–0.50% (company pages) | LinkedIn internal benchmark 2025 |
123
+ | X/Twitter engagement rate | 1.9% | 0.05%–0.09% (general) | Rival IQ 2026 |
124
+
125
+ *Urban Cycle is performing significantly above industry benchmarks across all three platforms. Above-average performance is driven by high-quality visual content, strong community focus, and consistent posting cadence.*
@@ -0,0 +1,127 @@
1
+ # Social Media Campaign Proposal — Sample
2
+
3
+ <!-- Sample: Urban Cycle | Q3 2026 Growth Campaign | v1 | 2026-06-01 -->
4
+ <!-- This is a filled example demonstrating the expected format. Data is fictitious but realistic. -->
5
+
6
+ ---
7
+
8
+ ## Executive Summary
9
+
10
+ Urban Cycle's May 2026 campaign exceeded all KPIs — 4.1% Instagram engagement rate (vs. 1.2% industry average), 49,450 total impressions (vs. 25,000 target), and 955 link clicks. The Q3 2026 proposal expands to 4 platforms (adding TikTok), increases Reel production to 3x/week, and introduces a monthly rider spotlight series that drove Urban Cycle's highest-performing post in May (8.7% engagement rate). Projected outcome: 120,000 monthly impressions and +1,500 followers by end of Q3.
11
+
12
+ ---
13
+
14
+ ## Campaign Overview
15
+
16
+ | Field | Value |
17
+ |---|---|
18
+ | Proposed Campaign Name | Q3 2026 — Ride Every City |
19
+ | Campaign Objective | Community growth + brand awareness + product launch (new route planner app) |
20
+ | Recommended Platforms | instagram, tiktok, linkedin, twitter |
21
+ | Campaign Duration | 90 days (July 1 – September 30, 2026) |
22
+ | Total Posts | 270 posts across 4 platforms |
23
+ | Start Date | 2026-07-01 (proposed) |
24
+
25
+ ---
26
+
27
+ ## Why These Platforms
28
+
29
+ | Platform | Audience Fit | Primary Role in Campaign |
30
+ |---|---|---|
31
+ | instagram | 68% of Urban Cycle's target audience (urban cyclists, 25–40) is active on Instagram. Q2 data confirms 4.1% engagement — highest of any platform tested. | Brand awareness hub — Reels, carousels, community spotlights |
32
+ | tiktok | Urban Cycle's 18–28 secondary audience segment is 3× more active on TikTok than Instagram. Short-form cycling route videos align with TikTok's discovery algorithm. New platform for Urban Cycle — expect 60-day ramp before organic growth signals emerge. | Audience growth, route content, app launch reach |
33
+ | linkedin | B2B pipeline for corporate wellness programs and urban planning partnerships. May LinkedIn posts drove 312 link clicks to the route planner landing page — highest per-platform click rate. | Thought leadership, infrastructure advocacy, B2B pipeline |
34
+ | twitter | Real-time community engagement during commute hours. Urban Cycle's X presence drove 7 UGC posts in May tied to live commute commentary. | Community engagement, newsjacking, advocacy moments |
35
+
36
+ ---
37
+
38
+ ## Content Strategy
39
+
40
+ ### Theme Pillars
41
+
42
+ | Pillar | Description | % of Calendar | Key Formats |
43
+ |---|---|---|---|
44
+ | Route Stories | Real routes, real riders — city-specific commute coverage | 30% | Reels (Instagram + TikTok), route maps on X |
45
+ | App Launch | Route Planner app features, onboarding, user stories | 25% | Carousels (Instagram + LinkedIn), demo videos (TikTok) |
46
+ | Advocacy & Infrastructure | Cycling infrastructure wins and gaps — data-backed | 20% | LinkedIn long-form, Instagram infographics |
47
+ | Rider Spotlight | Weekly spotlight — one real rider per week across all platforms | 15% | Reel (Instagram), short video (TikTok), text post (LinkedIn) |
48
+ | Community & UGC | #RideWithUrbanCycle challenge, poll, community repair night coverage | 10% | Instagram Story, X text, LinkedIn community post |
49
+
50
+ ### Caption Strategy
51
+
52
+ All captions will use A/B/C variant framework. Selection criteria:
53
+ - Route Stories and App Launch → Variant A (direct, factual, product-specific)
54
+ - Rider Spotlight → Variant B (narrative-first)
55
+ - Community and Advocacy → Variant C (question hook for comments)
56
+
57
+ ---
58
+
59
+ ## Deliverables
60
+
61
+ | Deliverable | Format | Cadence |
62
+ |---|---|---|
63
+ | Social Campaign Brief | Markdown | Once (at campaign start) |
64
+ | Content Calendar | Markdown | Monthly refresh (3 deliveries) |
65
+ | Platform Publishing Plan | Markdown | Once (at campaign start) |
66
+ | Caption Copy Deck | Markdown | Monthly (A/B/C per post) |
67
+ | Scheduling Manifest | JSON | Monthly (submitted on approval) |
68
+ | Analytics Brief | Markdown | Monthly (3 deliveries) |
69
+ | Q3 Campaign Wrap Report | Markdown | Once (at campaign end) |
70
+
71
+ ---
72
+
73
+ ## Engagement Tiers
74
+
75
+ ### Tier 1 — Campaign Starter
76
+
77
+ **Scope:** 2 platforms (Instagram + LinkedIn), 3 posts/week each, 30-day calendar per month
78
+
79
+ **Includes:** Campaign Brief, 30-day Content Calendar, Caption Copy Deck (A/B variants), Monthly Analytics Brief
80
+
81
+ **Pricing:** $2,500/month
82
+
83
+ **Best for:** Urban Cycle maintaining current Instagram + LinkedIn presence without TikTok expansion.
84
+
85
+ ---
86
+
87
+ ### Tier 2 — Multi-Platform Growth *(Recommended)*
88
+
89
+ **Scope:** 4 platforms (Instagram + TikTok + LinkedIn + X), 5 posts/week Instagram and TikTok, 3x/week LinkedIn, daily X
90
+
91
+ **Includes:** Full Campaign Brief, 90-day Content Calendar, Platform Publishing Plan, Caption Copy Deck (A/B/C), Scheduling Manifest (Postiz API), 3× Monthly Analytics Briefs
92
+
93
+ **Pricing:** $6,500/month
94
+
95
+ **Best for:** Urban Cycle's Q3 app launch requiring full platform saturation and Reel-first content strategy.
96
+
97
+ ---
98
+
99
+ ### Tier 3 — Full Social Media Operator
100
+
101
+ **Scope:** 5 platforms including Pinterest (Q4 add), Reels 5x/week, weekly UGC challenge management, Postiz multi-workspace scheduling
102
+
103
+ **Includes:** All Tier 2 deliverables + weekly analytics check-in, quarterly strategy review, Pinterest campaign, Postiz Scheduling API management
104
+
105
+ **Pricing:** $11,000/month
106
+
107
+ **Best for:** Urban Cycle treating social media as a primary growth channel with a dedicated content team producing assets.
108
+
109
+ ---
110
+
111
+ ## ROI Projection
112
+
113
+ | Scenario | Baseline Assumptions | Projected Outcome by Sep 30 | Source |
114
+ |---|---|---|---|
115
+ | Conservative (Tier 1) | 2 platforms, 3 posts/week each, avg 2.5% engagement | 60,000 impressions/month; +400 followers/month | Q2 actual data + Rival IQ 2026 benchmark |
116
+ | Mid (Tier 2 — Recommended) | 4 platforms, full cadence, Reel-first Instagram, TikTok launch | 120,000 impressions/month; +1,500 followers/month; 200 app downloads/month attributed to social | Q2 actuals + TikTok Reel discovery coefficient 3.2× |
117
+ | Aggressive (Tier 3) | 5 platforms, daily Reels, UGC challenge, Postiz automation | 200,000 impressions/month; +2,500 followers/month; 500+ app installs attributed | Comparable brand case (Moov cycling app, Q1 2026) |
118
+
119
+ ---
120
+
121
+ ## Next Steps
122
+
123
+ 1. Select engagement tier (Tier 2 recommended based on Q3 app launch goals)
124
+ 2. Approve Q3 Campaign Brief (draft to be shared within 3 business days)
125
+ 3. Complete TikTok brand kit section (currently empty in brand kit)
126
+ 4. Connect Instagram, TikTok, LinkedIn, and X in Postiz admin UI
127
+ 5. Set campaign start date — earliest available: 2026-07-01