---
name: write-linkedin-post
description: Draft a LinkedIn post in the author's own voice and put it on the CampaignStack content calendar as a draft, for approval, or scheduled. Use when someone wants to write, schedule or line up LinkedIn posts.
---

# Write a LinkedIn post

You write the words with the author; CampaignStack stores, schedules and
publishes them from their connected account. A scheduled post goes public at
its slot with no further step, so scheduling needs the author's yes.

## 1. Author and voice

```
campaignstack_get_accounts
campaignstack_get_identities(filters: {linkedinAccountId}, include: {voice: {}})
```

The voice profile is measured from their real writing: openers, sentence
length, signature and banned phrases, emoji, exemplars per situation. Use the
`linkedin:post` overlay when present, else the core. Write like the
exemplars.

## 2. Ground it

```
campaignstack_get_workspaces(include: {playbook: {}})
campaignstack_get_content(filters: {status: "published"},
  include: {analytics: {fromMs, toMs}})
```

Playbook `identity` and `boundaries` say what the company stands for and
what it never claims. Past posts show what landed and what was already said.

## 3. Draft together

Ask for the one idea, story or opinion. Write one draft (LinkedIn allows
3,000 characters; most good posts use far fewer). Read it back and revise
until the author says it sounds like them. Facts, numbers and names come
from the author.

## 4. Save as draft

```
campaignstack_edit_content(operations: [{op: "create", authorAccountId,
  body, tags?}])
```

Status `draft`, nothing published. Later edits:
`{op: "update", contentId, patch: {body}}`.

## 5. Schedule, with a yes

Name the account and the timing. On an explicit yes:

```
campaignstack_edit_content(operations: [{op: "state", contentId,
  desiredState: "scheduled", autoSchedule: true}])
```

`autoSchedule` takes the next open slot inside the account's daily posting
limit; pass `scheduledAt` (Unix ms) for a fixed time. When a teammate signs
off first, use `desiredState: "pending_approval"`.

Refusals to explain: `CONTENT_DAY_FULL` (that day is at its limit, pick
another) and `CONTENT_NO_CAPACITY` (the account needs 300+ connections to
publish).

## 6. After

`desiredState: "draft"` pulls a scheduled post back before it goes out.
`campaignstack_get_content(ids: [contentId], include: {analytics: {fromMs,
toMs}})` shows how it did.
