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

# 13. Recipes

Call-by-call sequences for the common jobs. Each assumes `social_get_status` has been called
once in the session.

## First connection

1. `social_get_status` → confirm the platform is listed with `oauth` in `connect_methods`.
2. `social_start_connect {platform: "facebook", label: "Shop page"}` → give the user
   `authorize_url`.
3. User approves in the browser, tells you they are done.
4. `social_complete_connect {intent_id}` → `connected[]`. If `INTENT_PENDING`, ask again and
   retry.
5. `social_list_accounts` → note each `account_id`.
6. Offer `social_create_recovery_code` and tell the user to keep the code.

## Post a picture now (owner)

1. `social_upload_media {base64, name: "launch.jpg"}` → `media_id`.
2. `social_create_draft {account_ids: [fb, ig], text: "...", media_ids: [media_id]}` →
   `post_id`, revision 1.
3. `social_preview_post {post_id}` → if `publishable` is false, show the errors, fix with
   `social_update_draft {post_id, expected_revision: 1, ...}`, preview again.
4. `social_publish_now {post_id}` → `publication_id`.
5. After a minute, `social_get_publication {publication_id}` → report each result's `url` or
   `error_message`; keep polling while a result is `pending` with a future `next_attempt_at`.

## Share an account with a colleague

Owner's session:

1. `social_invite_member {account_id, role: "editor", note: "Spring campaign"}` →
   `claim_token`. Show it once; tell the owner to pass it on.

Colleague's session:

2. `social_claim_invitation {claim_token}` → `account`. They can now draft and preview but not
   publish.

## Delegate publishing

Owner's session, after sharing:

- For one post: `social_grant_authorization {account_id, kind: "post", post_id}`.
- For a period: `social_grant_authorization {account_id, kind: "standing",
  member_id, valid_until: "2026-12-31T23:59:59Z", max_uses: 20}`.

Editor's session: `social_publish_now {post_id}` now works; the evidence names the
authorization. The owner can see every grant with `social_list_authorizations` and end one
with `social_revoke_authorization`.

## Weekly schedule with briefs

Owner's session:

1. `social_create_schedule {account_ids: [fb], start: "2026-11-02 09:00",
   timezone: "America/Chicago", frequency: "weekly", weekdays: [1, 4],
   until: "2026-12-31 09:00", brief: "One product highlight with a photo; friendly tone."}`
   → occurrences, all `needs_content`.

Any editor's session, before each slot:

2. `social_list_calendar` → the next `needs_content` slot and its `brief`.
3. Draft and preview a post for the slot's accounts.
4. `social_fill_occurrence {occurrence_id, post_id}` → `ready`.

The slot publishes on its own at 09:00 Chicago time under the owner's schedule authorization.

## Repeat one post on a schedule

`social_create_schedule {account_ids, start, frequency: "daily", interval: 2,
max_occurrences: 5, post_id}`. Every slot is `ready` from the start. To stop early:
`social_update_schedule {schedule_id, action: "cancel"}`.

## Fix a failed delivery

1. `social_get_publication` → find the result with `status: failed` and read `error_code`.
2. `RECONNECT_REQUIRED`: the owner reconnects (first-connection recipe, step 2 onward, same
   platform); then `social_publish_now {post_id, account_ids: [that account]}`.
3. `PLATFORM_REJECTED` or `CONTENT_INVALID`: edit the draft, preview, publish again to that
   account only.
4. `unknown` on Facebook, Instagram or X: ask the user to look at the account before
   republishing; the post may already be up.

## Edit or take down a live post

1. `social_get_published_post {publication_id, account_id}` → `live`, `can_edit`,
   `can_delete`.
2. Facebook text fix: `social_update_published_post {publication_id, account_id, text}`.
3. Instagram or X fix: `social_delete_published_post`, then edit the draft and
   `social_publish_now` to that account.

## Recover after reconnecting the connector

Old session (while it still works): `social_create_recovery_code` → code.
New session, before connecting anything: `social_claim_recovery_code {recovery_code}` →
accounts, drafts and schedules are back.

## Month-end usage for an owner

`social_get_usage {from: "2026-10-01", to: "2026-11-01"}` → `totals.estimated_cost_usd`,
`by_charge`, `by_account`, `by_actor`. Report the estimated cost at list price and what drove
it (a post with a link costs over 13x a plain post on X); name the actors if the account is
shared; mention `unpriced_calls` if it is not 0. The operator splits the platform's actual
invoice by each owner's share.
