Social Post Writer
[Live] ·
agent__social-post-writer· Claude Sonnet 4.6
Writes a single social media post for a specific platform and approved calendar slot, producing platform-native copy with hashtags, an engagement hook, and an alt text suggestion — ready for scheduling.
Overview
| Function | Write a single social media post for a specific platform and calendar slot |
| Type | Worker — Content |
| Model | Claude Sonnet 4.6 |
| Queue | agent__social-post-writer |
| Concurrency | 8 |
| Timeout | 3 min |
| Est. cost / task | ~$0.12 |
| Plan | Pro+ |
Triggers
| Trigger type | When | Who initiates |
|---|---|---|
| Activity Planner dispatch | After Social Calendar Planner completes and the calendar is approved — one job enqueued per approved calendar slot | Activity Planner |
| Human on-demand | User clicks “Write post” on a calendar slot in the DM Portal, or uses “Create social post” from the Dashboard social media screen | Tenant admin / DM reviewer |
| Scheduled / cron | Not applicable — post writing is always triggered by an approved calendar slot or a manual request | — |
Input
interface SocialPostWriterInput {
tenantId: string;
campaignId?: string;
platform: 'instagram' | 'linkedin' | 'facebook' | 'x' | 'tiktok';
calendarItem: {
id: string; // CalendarEntry.id from Social Calendar Planner
date: string; // ISO date the post is scheduled for
contentType: 'educational' | 'promotional' | 'engagement' | 'ugc' | 'behind-the-scenes';
format: 'static' | 'reel' | 'story' | 'carousel' | 'text' | 'poll';
topicAngle: string; // the specific hook/angle from the calendar
theme: string; // campaign theme
notesForWriter: string; // detailed writing instructions from Calendar Planner
pinnedEvent?: string;
};
contentBrief?: string; // optional additional context from campaign brief
}Output
interface SocialPostWriterOutput {
bodyText: string; // post caption/copy — platform character limits enforced
hashtags: string[]; // 3–5 niche hashtags (not included in bodyText character count)
emojiUsed: boolean;
platformFormat: string; // e.g. "carousel", "reel", "text post"
characterCount: number; // character count of bodyText (hashtags excluded)
altTextSuggestion: string; // for the primary image/visual — 80–125 chars
engagementHook: string; // the opening 1–2 sentences, isolated for review
}Platform character limits (hard-enforced)
| Platform | Limit |
|---|---|
| X | 280 characters |
| 3,000 characters | |
| 2,200 characters | |
| 63,206 characters (practical max ~500 for engagement) | |
| TikTok | 2,200 characters |
Sample output excerpt
LinkedIn — educational carousel post:
engagementHook:
"Most marketing reports tell you what happened. Almost none of them tell you what to do next.
Here's the framework we use to turn data into decisions in under 20 minutes."
bodyText:
Most marketing reports tell you what happened. Almost none of them tell you what to do next.
Here's the framework we use to turn data into decisions in under 20 minutes.
The problem with most dashboards: they're built to impress, not to act on. Scroll through and
you see numbers. What you don't see is: what's broken, what's working, and where to put next
month's budget.
We call our approach the Three-Question Audit. Before any strategy meeting, we answer:
→ What's our single best-performing channel right now, and why?
→ Where are we losing money we shouldn't be losing?
→ What's the one change that would move the needle most this month?
Slide 2 covers Question 1. Slide 3 covers Question 2. The last slide has the template.
Save this post — you'll want it before your next reporting session.
#MarketingAnalytics #DigitalMarketing #MarketingStrategy
---
hashtags: ["#MarketingAnalytics", "#DigitalMarketing", "#MarketingStrategy"]
characterCount: 891
altTextSuggestion: "Slide 1 of carousel: bold text reading 'The Three-Question Marketing Audit'
on a dark background with a simple framework diagram"
platformFormat: "carousel"How It Works
-
Load platform context and calendar slot. The platform, calendar item (topic angle, content type, format, writer notes), and Client Context File are injected into the system prompt. The agent reads the writer notes carefully — these are the primary brief for this specific post.
-
RAG: duplicate hook check. Query Published Content for recent posts on this platform with similar topic angles or opening hooks. If a near-identical hook was used in the last 30 days, generate a fresh approach before writing the full post.
-
RAG: brand voice examples. Query Client Documents for brand voice examples, key messages, and any mandatory mentions for this topic. These inform the tone and specific language used.
-
RAG: competitor social angles. Query Competitor Research for how competitors have approached this topic on the same platform. The goal is to identify the dominant competitor angle and write something meaningfully different — not to copy.
-
Write the post. Generate body text that opens with the engagement hook (the first 1–2 sentences must stop the scroll), delivers the promised value, and closes with a CTA or engagement prompt appropriate for the content type. Apply platform-specific conventions: hashtag placement, line breaks, emoji, call-to-action style.
-
Select hashtags. Choose 3–5 hashtags that are niche-relevant and have realistic discovery potential. Avoid hashtags with over 20M posts (too broad, no discovery benefit) or under 5K posts (no volume). Never include banned or flagged hashtags.
-
Enforce character limit. Count body text characters (hashtags excluded per platform convention). If over the platform limit, trim the least essential content — never trim the hook or the CTA.
-
Generate metadata. Isolate the engagement hook (first 2 sentences) as a separate field. Generate the alt text suggestion for the primary visual. Return all fields with character count.
System Prompt
You are a social media copywriter for a digital marketing agency. You write social media posts
that actually get read — not posts that look like brand content.
CLIENT CONTEXT:
{{CLIENT_CONTEXT}}
TENANT SETTINGS:
{{TENANT_SETTINGS}}
KNOWLEDGE BASE CONTEXT (recent posts, brand voice examples, competitor angles):
{{RAG_CONTEXT}}
PLATFORM: {{PLATFORM}}
CHARACTER LIMIT: {{CHAR_LIMIT}}
CALENDAR SLOT:
{{BRIEF}}
Your post must:
1. Open with a hook that stops the scroll in the first 2 sentences. Formats that work:
- A specific, surprising statistic
- A counterintuitive statement ("Most [X] advice is wrong. Here's why.")
- A direct question that the audience genuinely wants answered
- A concrete, relatable problem statement
Do NOT open with the brand name or "We're excited to announce..."
2. Deliver on the hook's promise. If the hook asks a question, answer it. If the hook states a
problem, solve it. The reader clicked — reward them.
3. Match the platform's native format:
- LinkedIn: professional insight, frameworks, numbered/bulleted structure for carousels,
first-person narrative for standard posts, line breaks between every 2–3 sentences
- Instagram: visual-first copy, shorter paragraphs, genuine voice, emoji used sparingly
- X: tight, punchy, one idea per tweet. Threads allowed for educational content.
- Facebook: conversational, community-oriented, question-led for engagement posts
- TikTok: write as if the viewer has already pressed play; hook is the spoken first line
4. Match the content type:
- Educational: teach one specific thing. No fluff. Reader should learn something actionable.
- Promotional: lead with the customer benefit, not the product feature. End with a clear CTA.
- Engagement: ask a question the audience will actually want to answer. Be specific.
- Behind-the-scenes: first-person, real, specific. Generic "team photos" are invisible.
5. Stay strictly within the character limit. Count carefully.
6. Use the brand voice described in the client context.
7. Avoid prohibited words from tenant settings.
8. Do not mention competitors by name.
Output as JSON matching the SocialPostWriterOutput schema. Hashtags go in the hashtags[]
array — not embedded in bodyText unless the platform convention requires it (X: inline;
others: appended or separate).Skills Injected
| Skill file | Purpose |
|---|---|
client-context-file.md | Always injected — company, brand voice, audience, key messages |
platform-posting-guide.md | Per-platform character limits, format conventions, optimal posting patterns, hashtag strategy |
social-copywriting-guide.md | Hook writing patterns, content-type-specific CTA formats, engagement optimisation rules |
social-copywriting-guide.md — content
# Social Copywriting Guide
## The Hook: Your Only Job in the First Two Sentences
On every platform, the algorithm decides whether to show more based on the first interaction.
For LinkedIn and Facebook, that's the "see more" threshold. For Instagram and TikTok, it's
whether the viewer pauses or keeps scrolling. For X, it's whether the first line earns a click.
The hook must do one of these things:
1. **Create a knowledge gap** — "Most agencies won't tell you this about ad spend."
2. **Name a specific pain** — "If your email open rate dropped below 20% this year, here's why."
3. **Make a counterintuitive claim** — "Posting more often is probably hurting your reach."
4. **Start mid-action** — "We lost a $60k client last year. Here's what it taught us."
What hooks must never do:
- Start with the brand name or "We are pleased to..."
- Start with a date or a fact the reader already knows
- Ask a question the reader can answer with "no" ("Are you struggling with...?")
## Content Type Playbook
### Educational Posts
- Teach exactly one thing. Not two, not three. One.
- Use a framework, a numbered list, or a before/after structure.
- The last line should be a takeaway, not a sales pitch.
- On LinkedIn: save-worthy content (frameworks, templates, checklists) outperforms opinion pieces.
- CTA options: "Save this for your next campaign", "Share with your team", "What would you add?"
### Promotional Posts
- Lead with the customer outcome, not the product feature.
Bad: "Our new dashboard is now live."
Good: "You can now see exactly where your ad spend is going — in real time."
- One offer per post. Multiple offers split attention.
- CTA is non-negotiable for promotional posts: include it in the last line of the body.
- CTA options: "Book a free audit", "Get started today — link in bio", "DM us [keyword]"
### Engagement Posts
- Ask a question the audience has an opinion about. Vague questions get no answers.
Bad: "What do you think about AI in marketing?"
Good: "Do you think AI-generated content should be disclosed to readers? Yes or no — and why."
- Offer your own answer first. It lowers the barrier for others to respond.
### Behind-the-Scenes
- Specific beats generic. "Our Monday morning team standup" beats "Team culture post".
- A single honest detail is worth more than three polished sentences.
- First-person plural ("We discovered...", "Our team spent three days...") feels more genuine.
## Hashtag Strategy
- 3–5 hashtags per post on Instagram and LinkedIn. Zero on X (inline only). 3–5 on TikTok.
- Mix niche-specific (100K–2M posts) with industry-level (2M–10M posts). Avoid mega-tags.
- Check hashtags are not banned or restricted on the target platform.
- Never use the same hashtag set for every post — vary them by topic.RAG Usage
| Dataset | Query example | When used |
|---|---|---|
| Published Content | "recent [platform] posts about [topic angle]" | Step 2 — duplicate hook check; avoids repeating recent openings or angles |
| Client Documents | "brand voice examples key messages [topic area]" | Step 3 — to source on-brand language and any mandatory mentions |
| Competitor Research | "competitor social content [topic] [platform]" | Step 4 — to identify and differentiate from the dominant competitor angle |
| Website Content | Not typically used for short-form social posts | — |
Tools Required
| Tool | Method | Purpose | Required? |
|---|---|---|---|
rag_search | search | Query tenant knowledge base across Published Content, Client Documents, Competitor Research | Yes |
HITL Gates
Each completed post is submitted for human review in the DM Portal content calendar before scheduling.
- Review type:
content_review - Risk level:
low - Reviewer sees: Post body in a platform-native preview (rendered with line breaks and emoji), character count, hashtags listed separately, alt text suggestion, and the engagement hook isolated for quick scan.
- Approval triggers: Post is staged for scheduling to the connected social media account at the date/time specified in the calendar slot.
- Edit capability: Reviewer can edit body text, adjust hashtags, and change the CTA. Character count updates live. Platform preview re-renders on edit.
- Bulk approval: Reviewer can approve all posts for a platform in a single action from the calendar view. Individual posts can be excluded from bulk approval.
- Rejection triggers: Post is re-generated with reviewer feedback. Feedback is appended to the original calendar slot
notesForWriter.
Guardrails
| Rule | Enforcement |
|---|---|
| Platform character limits enforced | Hard count on bodyText (excluding hashtags); trim if over limit before returning output |
| 3–5 hashtags required | Count check on hashtags[]; fewer than 3 triggers regeneration of hashtag selection |
| No competitor names in body text | String match against known competitor names from Client Context; any match → regenerate |
| No prohibited words from tenant settings | Filter prohibitedWords[] against body text |
engagementHook must be ≤ 2 sentences | Sentence count check; if more than 2 sentences, extract first 2 only |
| Alt text ≤ 125 characters | Character count check; trim if exceeded |
| Hashtags must not be embedded in bodyText (except X) | For non-X platforms, detect any # in body text and move to hashtags[] array |
Tenant Settings Used
| Setting | How it’s used |
|---|---|
brandVoice | Controls tone, formality, emoji usage, and sentence style for every post |
companyName | Used when the brand is mentioned in the post (sparingly — posts are audience-first) |
targetAudience | Shapes the hook approach and assumed knowledge level |
industry | Scopes competitor RAG query to the correct niche |
prohibitedWords[] | Filtered from body text before returning output |
preferredKeywords[] | Agent attempts to naturally include preferred terms in educational and promotional posts |
Cost Profile
| Avg input tokens | ~4,000 (calendar slot + RAG results + skills) |
| Avg output tokens | ~600 (post body + JSON output) |
| Est. cost / task | ~$0.12 |
Error Handling
| Error | Response |
|---|---|
| Platform is not in supported list | Fail job with validation error before any LLM call |
calendarItem.notesForWriter is empty | Proceed with topic angle and content type as the primary brief; log warning “Writer notes were empty — using topic angle only” |
| Body text exceeds character limit after 2 trim attempts | Return trimmed post with warning; flag for reviewer attention |
| RAG returns no Published Content results | Proceed without duplicate check; log “No published content found — all hooks are eligible” |
| RAG returns no Competitor Research results | Proceed without differentiation context; log “No competitor research found” |
hashtags[] count below 3 after generation | Run a targeted hashtag generation pass using topic and platform as input; append results |
| Job exceeds 3-minute timeout | Fail job and re-queue with reduced RAG query set; log timeout event |