# Post (/api/posts)

## Buat post [#buat-post]

```http
POST /v1/posts
Authorization: Bearer tb_live_xxx
Idempotency-Key: 6f1c2b7e-0d8a-4f7e-9a51-2c1f7b0e9d34
Content-Type: application/json

{
  "content": "Promo akhir pekan 🎉",
  "media_ids": ["0b9d..."],
  "targets": [{ "account_id": "a1.." }, { "account_id": "b2.." }],
  "scheduled_at": "2026-10-15T09:00:00+07:00"
}
```

| Field          | Keterangan                                               |
| -------------- | -------------------------------------------------------- |
| `content`      | Teks post                                                |
| `media_ids`    | Id media dari [upload](/api/media), sesuai urutan tampil |
| `targets`      | Akun tujuan (`account_id` dari `GET /v1/accounts`)       |
| `scheduled_at` | Opsional. Tanpa field ini post langsung diterbitkan      |

Respons `201`:

```json
{
  "id": "p1..",
  "status": "scheduled",
  "scheduled_at": "2026-10-15T02:00:00Z",
  "targets": [
    {
      "id": "t1..",
      "account_id": "a1..",
      "platform": "instagram",
      "status": "pending",
      "permalink": null
    },
    {
      "id": "t2..",
      "account_id": "b2..",
      "platform": "threads",
      "status": "pending",
      "permalink": null
    }
  ]
}
```

Penerbitan berjalan di latar belakang. Cek `GET /v1/posts/{id}`: setiap target berubah menjadi `published` beserta `permalink`, atau `failed` beserta `error_code`.

Satu video di Instagram otomatis terbit sebagai **Reels**. Dua media atau lebih menjadi carousel (Instagram maks 10, Threads maks 20).

## Versi per akun [#versi-per-akun]

Setiap target boleh punya teks dan/atau media sendiri. Field yang tidak dikirim mengikuti versi bersama. `content: ""` berarti sengaja tanpa teks.

```json
{
  "content": "Kopi apa favoritmu?",
  "targets": [
    { "account_id": "th..", "options": { "poll": { "options": ["Tubruk", "Susu"] } } },
    { "account_id": "ig..", "content": "Menu baru minggu ini ☕", "media_ids": ["m1.."] }
  ]
}
```

## Opsi per platform [#opsi-per-platform]

Dikirim di `targets[].options`. Kunci yang tidak dikenal ditolak (`400 invalid_options`).

| Platform  | Opsi                                   | Aturan                                                                                           |
| --------- | -------------------------------------- | ------------------------------------------------------------------------------------------------ |
| Threads   | `thread: string[]`                     | Utas: 1–10 bagian lanjutan, masing-masing ≤ 500 karakter                                         |
| Threads   | `poll: { options: string[] }`          | 2–4 pilihan, 1–25 karakter. Hanya post tanpa media                                               |
| Threads   | `link_attachment: url`                 | Kartu link. Hanya post tanpa media                                                               |
| Threads   | `text_attachment: { text, link_url? }` | Teks panjang ≤ 10.000 karakter. Hanya post tanpa media                                           |
| Threads   | `topic_tag: string`                    | 1–50 karakter, tanpa `.` dan `&`                                                                 |
| Threads   | `reply_control`                        | `everyone`, `accounts_you_follow`, `mentioned_only`, `followers_only`, `parent_post_author_only` |
| Instagram | `format: "feed" \| "story"`            | Story: tepat 1 media, tanpa caption, video 3–60 detik dan ≤ 100 MB                               |
| Instagram | `share_to_feed: boolean`               | Reels saja (default `true`)                                                                      |
| Instagram | `cover_media_id` / `thumb_offset_ms`   | Cover Reels: id gambar, atau frame video dalam milidetik                                         |

Threads membatasi 5 link unik per post (`400 too_many_links`).

## Mengelola post [#mengelola-post]

| Request                       | Fungsi                                                                  |
| ----------------------------- | ----------------------------------------------------------------------- |
| `PATCH /v1/posts/{id}`        | Ubah `content`, `media_ids`, atau `scheduled_at` post yang belum terbit |
| `DELETE /v1/posts/{id}`       | Batalkan post terjadwal                                                 |
| `POST /v1/posts/{id}/publish` | Terbitkan sekarang                                                      |
| `POST /v1/posts/{id}/retry`   | Ulangi akun yang `failed`. Tidak memposting ulang yang sudah terbit     |
| `POST /v1/posts/{id}/remove`  | Hapus dari riwayat Tebar. Post di Instagram/Threads tidak ikut terhapus |

Post yang sudah mulai diterbitkan tidak bisa diubah (`409 post_not_editable`).
