# POST /posts

> Botdoorで、連携済みアカウントへのSNS投稿を作成、予約、またはドライランします。すべてのフィールド、レスポンス、エラーを解説します。

Source: https://docs.botdoor.co/ja/api/posts-create/

1つ以上のアカウントに向けた投稿を作成します。MCPツール：`create_post`。背景：[承認](https://docs.botdoor.co/ja/concepts/approvals/)、[予約](https://docs.botdoor.co/ja/concepts/scheduling/)、[最初のコメントとスレッド](https://docs.botdoor.co/ja/concepts/first-comments-and-threads/)。

```bash
curl -X POST https://botdoor.co/api/v1/posts -H "Authorization: Bearer $BOTDOOR_KEY" -H "Content-Type: application/json" \
  -H "Idempotency-Key: launch-2026-10-12" \
  -d '{"content": "Fresh sourdough at 7am", "accountIds": ["2ae8…"], "mediaIds": ["9b1c…"],
       "scheduledFor": "2026-10-12T07:00:00+11:00", "firstComment": "Order: https://acme.example", "dryRun": true}'
```

## フィールド

| フィールド | 型 | 備考 |
|---|---|---|
| `accountIds` | string[] | 必須。[/accounts](https://docs.botdoor.co/ja/api/accounts/)で取得したID |
| `content` | string | 投稿の本文 |
| `mediaIds` | string[] | [/media](https://docs.botdoor.co/ja/api/media/)で取得したID。複数指定するとカルーセルになります。`mediaId`（文字列1つ）も使えます |
| `dryRun` | boolean | 検証のみ。保存、送信、カウントは一切行われません |
| `scheduledFor` | string | オフセット付きのISO 8601。1年以内の日時。省略すると今すぐ投稿します |
| `requireApproval` | boolean | `true`なら必ず承認を待ちます。`false`でも承認制キーの承認は省略できません |
| `firstComment` | string | 投稿の公開から約10秒後に、同じアカウントから返信します。リンクはここに入れてください |
| `thread` | string[] | 続きの投稿（X、Threads、Bluesky）。`thread[0]`が最初の返信です |
| `firstReply` | string | 要素が1つの`thread`の別名。`thread`とは併用できません |
| `poll` | object | `{options, durationMinutes, question}`。XまたはLinkedIn、メディアなしの場合のみ。`question`はLinkedInのみ |
| `cover` | object | 動画のカバー画像：`{mediaId}`（画像のアップロード）または`{offsetMs}`（フレーム） |
| `tiktokAiGenerated` | boolean | TikTok：AI生成コンテンツとしてラベル付けします |

`Idempotency-Key`ヘッダー：同じキーで再試行しても、二重に投稿されることはありません。

## レスポンス

- `200` ドライラン：`{"dryRun": true, "valid": true, "warnings": [], "requireApproval": true, "wouldPost": {…}}`
- `201` 作成：`{"post": {…}}`。`status`は`needs_approval`、`scheduled`、`publishing`、`published`、`failed`のいずれかです。形式：[GET /posts/{id}](https://docs.botdoor.co/ja/api/posts-read/)。
- `replayed: true`付きの`200`：以前の投稿と同じ`Idempotency-Key`です。

## エラー

| ステータス | コード | 意味 |
|---|---|---|
| 400 | `validation_failed` | フィールドがない、または形式が正しくない。`details.fields`を確認してください |
| 400 | `invalid_date`、`scheduled_in_past`、`scheduled_too_far` | `scheduledFor`が不正 |
| 400 | `media_required` | Instagram、TikTok、YouTube、Pinterestにはメディアが必要 |
| 400 | `thread_unsupported`、`poll_unsupported`、`first_comment_unsupported`、`cover_unsupported` | 投稿先がその機能に対応していない |
| 400 | `tiktok_privacy_conflict`、`tiktok_ai_unsupported` | TikTokの設定が競合している |
| 400 | `upstream_rejected` | SNS側がコンテンツを拒否した |
| 403 | `plan_feature_unavailable`、`post_limit_reached` | プランの制約（X、Freeでは月30件の投稿） |
| 404 | `account_not_found`、`media_not_found` | IDがこのワークスペースに存在しない |
| 409 | `no_accounts_connected`、`account_needs_reconnection` | 先に連携または再連携が必要 |
| 409 | `media_expired` | アップロードから7日以上経過している |
| 409 | `duplicate_content` | 同じ本文をそのアカウントに投稿した直後 |
| 409 | `tiktok_cannot_post` | TikTokによると、クリエイターは現在投稿できない。再試行可能 |
| 422 | `idempotency_key_reused` | 同じキーで異なるボディ |

## よくある質問

### 公開せずに投稿を確認するには？

dryRun: trueを送信します。valid、warnings、そして実際に投稿される内容がそのまま返ります。月間の上限にもカウントされません。

### 投稿がneeds_approvalで止まったのはなぜですか？

キーが承認制であるか、requireApproval: trueを送信したためです。ログイン済みの人間がアプリで承認します。

### 複数のSNSに同時に投稿できますか？

はい。1つの投稿のaccountIdsに複数のIDを指定します。投稿先ごとに個別のステータスが付きます。

### リンクはどこに入れるべきですか？

firstCommentに入れてください。本文がリンクによって不利に扱われるのを避けつつ、リンクを投稿のすぐ下に表示できます。

### scheduledForは自分のタイムゾーンで解釈されますか？

送信したオフセットで解釈されます。+11:00やZのように、必ずオフセットを含めてください。
