@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.
- package/assets/worker-kits/growthub-postiz-social-v1/.env.example +18 -0
- package/assets/worker-kits/growthub-postiz-social-v1/QUICKSTART.md +136 -0
- package/assets/worker-kits/growthub-postiz-social-v1/brands/NEW-CLIENT.md +67 -0
- package/assets/worker-kits/growthub-postiz-social-v1/brands/_template/brand-kit.md +120 -0
- package/assets/worker-kits/growthub-postiz-social-v1/brands/growthub/brand-kit.md +117 -0
- package/assets/worker-kits/growthub-postiz-social-v1/bundles/growthub-postiz-social-v1.json +52 -0
- package/assets/worker-kits/growthub-postiz-social-v1/docs/ai-caption-layer.md +118 -0
- package/assets/worker-kits/growthub-postiz-social-v1/docs/bullmq-queue-layer.md +157 -0
- package/assets/worker-kits/growthub-postiz-social-v1/docs/platform-coverage.md +97 -0
- package/assets/worker-kits/growthub-postiz-social-v1/docs/postiz-fork-integration.md +143 -0
- package/assets/worker-kits/growthub-postiz-social-v1/examples/analytics-brief-sample.md +125 -0
- package/assets/worker-kits/growthub-postiz-social-v1/examples/client-proposal-sample.md +127 -0
- package/assets/worker-kits/growthub-postiz-social-v1/examples/content-calendar-sample.md +75 -0
- package/assets/worker-kits/growthub-postiz-social-v1/examples/social-campaign-sample.md +104 -0
- package/assets/worker-kits/growthub-postiz-social-v1/growthub-meta/README.md +128 -0
- package/assets/worker-kits/growthub-postiz-social-v1/growthub-meta/kit-standard.md +113 -0
- package/assets/worker-kits/growthub-postiz-social-v1/kit.json +104 -0
- package/assets/worker-kits/growthub-postiz-social-v1/output/README.md +56 -0
- package/assets/worker-kits/growthub-postiz-social-v1/output-standards.md +127 -0
- package/assets/worker-kits/growthub-postiz-social-v1/runtime-assumptions.md +159 -0
- package/assets/worker-kits/growthub-postiz-social-v1/setup/check-deps.sh +117 -0
- package/assets/worker-kits/growthub-postiz-social-v1/setup/clone-fork.sh +83 -0
- package/assets/worker-kits/growthub-postiz-social-v1/setup/verify-env.mjs +99 -0
- package/assets/worker-kits/growthub-postiz-social-v1/skills.md +277 -0
- package/assets/worker-kits/growthub-postiz-social-v1/templates/analytics-brief.md +123 -0
- package/assets/worker-kits/growthub-postiz-social-v1/templates/caption-copy-deck.md +127 -0
- package/assets/worker-kits/growthub-postiz-social-v1/templates/client-proposal.md +139 -0
- package/assets/worker-kits/growthub-postiz-social-v1/templates/content-calendar.md +65 -0
- package/assets/worker-kits/growthub-postiz-social-v1/templates/platform-publishing-plan.md +112 -0
- package/assets/worker-kits/growthub-postiz-social-v1/templates/scheduling-manifest.md +83 -0
- package/assets/worker-kits/growthub-postiz-social-v1/templates/social-campaign-brief.md +111 -0
- package/assets/worker-kits/growthub-postiz-social-v1/validation-checklist.md +79 -0
- package/assets/worker-kits/growthub-postiz-social-v1/workers/postiz-social-operator/CLAUDE.md +287 -0
- 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
|