*Social Media Manual — [index](../MANUAL.md)*

# 6. Drafts and preview

A **post** is a piece of content aimed at one or more destination accounts. It is created as
a draft, edited through immutable revisions, checked against each platform with a preview,
and only then published (chapter 7) or scheduled (chapter 8).

## Creating a draft

`social_create_draft` with:

| argument | meaning |
|---|---|
| `account_ids[]` | destinations; the caller needs editor or owner on each |
| `text` | up to 10 000 characters; platform limits apply later |
| `media_ids[]` | up to 10 uploaded media (chapter 5) |
| `link` | an http(s) URL to attach |
| `title` | internal label for lists and the calendar; **never published** |
| `options` | platform-specific options, passed through to the provider untouched |
| `note` | revision note, for example who asked for the change |

Nothing is sent. The reply is the `post` at revision 1 with `status: draft`, its `destinations`,
`content` and `revision`.

## Revisions and concurrency

Every change is a new immutable revision. `social_update_draft` requires `post_id` and
`expected_revision`, the revision you last saw, plus any of `text`, `media_ids`, `link`,
`account_ids`, `title`, `options` and a `note`.

If someone else changed the post in the meantime, the call fails with `REVISION_CONFLICT`
and `details.current_revision` / `details.current_text`. Merge your change into the current
text and call again with the new `expected_revision`. Never retry blindly with a higher number.

Editing a post that has already been published makes a new draft revision and returns the post
to `draft`; the live copies are untouched until you publish again or use
`social_update_published_post` (chapter 9).

## Reading and listing

- `social_get_post`: the post with `revisions[]` (who, when, note) and recent `publications[]`.
- `social_list_posts`: newest first, filterable by `account_id` and `status` (`draft`,
  `scheduled`, `published`, `archived`; archived posts appear only when asked for), `limit`
  up to 200.

Post statuses: `draft` (never published, or edited since), `scheduled` (attached to at least
one open calendar slot), `published` (something succeeded and no slot is still pending),
`archived`.

## Archiving

`social_archive_post` removes the post from lists and cancels every upcoming occurrence that
used it. Live copies on the platforms stay as they are; use chapter 9 to take those down.
Archived posts answer `POST_ARCHIVED` to further edits.

## Preview: the dry run

`social_preview_post` with `post_id` runs the current revision against every destination
without sending anything. Reply: `publishable` (true only when every destination is `ok`),
and `destinations[]` each with `account_id`, `platform`, `handle`, `ok`, `errors[]`
(`{code, message}`), `warnings[]` and `rendered` (how the provider will send it, for example
the text after link handling).

Error codes you will see per destination, in the order they are checked:

| code | meaning |
|---|---|
| `ACCOUNT_DISCONNECTED` | the destination was disconnected; edit the post's `account_ids` or reconnect |
| `CAPABILITY_UNSUPPORTED` | the post uses something the platform cannot take: video, several images, a link, or text-only where media is required |
| `TEXT_TOO_LONG` | over the platform's `text_max` (X counts weighted characters) |
| `TOO_MUCH_MEDIA` / `MEDIA_REQUIRED` | outside the platform's `media_min`..`media_max` |
| `MEDIA_UNSUPPORTED` / `MEDIA_TOO_LARGE` | a media type or size the platform rejects (Instagram: JPEG only; per-platform byte limits in chapter 11) |
| `TOO_MANY_HASHTAGS` | Instagram allows 30 |
| `MEDIA_UNAVAILABLE` | referenced media was deleted |

`social_publish_now` runs exactly the same check and refuses with `CONTENT_INVALID`
(`details.errors` lists the problems) when `publishable` would be false. Preview before you
publish, show the user the problems, fix the draft, preview again.

A post that targets several platforms must satisfy all of them at once. When that is not
possible (an Instagram carousel plus a 1 000-character X post), make two posts.
