POST/api/v4/social/bulk-posts

Membuat postingan secara massal

Memvalidasi dan mengantrekan hingga 500 postingan media sosial per permintaan, lalu mengembalikan tugas untuk memeriksa hasil per baris secara berkala.

Memerlukan kunci API. Lihat Autentikasi untuk format header dan rotasi kunci.

Parameter

Body

Field bersarang yang ditandai wajib hanya berlaku jika Anda mengirim induknya. Jika induknya opsional dan Anda menghilangkannya, field turunan yang wajib tidak berlaku.

NamaTipeWajibDeskripsi
inputobjectwajibWrapper object. The entire request body must be nested under `input`.
input.postsarray of objectswajibThe rows to create, 1 to 500 of them. Each row is the same object POST /social/posts takes as its `input`; the per-row fields are listed below.
input.namestringopsionalOptional label for the job itself, to identify it in your own logs. Not shown to any audience.
input.posts[].socialProfileIdstringwajibUUID of the brand publishing this row. Rows may target different brands in one request.
input.posts[].namestringwajibInternal name for the post.
input.posts[].platformsarray of stringswajibPlatforms for this row: `FACEBOOK`, `INSTAGRAM`, `TWITTER` (X), `LINKEDIN`, `PINTEREST`. Each must already have a connection on that row's brand.
input.posts[].contentstringwajibThe post body.
input.posts[].actionstringwajib`DRAFT`, `SCHEDULE` (requires a schedule) or `PUBLISH`.
input.posts[].mediaUrlsarray of stringsopsionalPublic https image URLs. Required when the row targets Instagram or Pinterest.
input.posts[].videoUrlsarray of stringsopsionalPublic https video URLs.
input.posts[].linkstringopsionalLink to attach where the platform supports one.
input.posts[].scheduledAtstringopsionalISO-8601 publish instant with an offset. Alternative to `scheduleDate` + `scheduleTime`, never both.
input.posts[].scheduleDatestringopsional`YYYY-MM-DD`, interpreted in that row's brand timezone. Send with `scheduleTime`.
input.posts[].scheduleTimestringopsional`HH:MM`, interpreted in that row's brand timezone. Send with `scheduleDate`.
input.posts[].connectedChannelIdsarray of stringsopsionalRestrict this row to specific connections by ID.
input.posts[].clientReferencestringopsionalYour own identifier for this row, echoed back on the matching job result. The most reliable way to reconcile a batch against your own records.

Contoh permintaan

Body siap tempel. Ganti ID dan nilai placeholder dengan milik Anda.

Request body
{  "input": {    "name": "Autumn campaign load",    "posts": [      {        "socialProfileId": "6f2c9a41-7b0e-4d55-9a2f-3c8e1d47b902",        "name": "Autumn week 1",        "platforms": ["INSTAGRAM", "FACEBOOK"],        "content": "Week one of the autumn collection: the Fairfield oak sideboard, finished by hand in the workshop.",        "mediaUrls": ["https://cdn.example.com/social/autumn-w1.jpg"],        "action": "SCHEDULE",        "scheduleDate": "2026-10-02",        "scheduleTime": "09:30",        "clientReference": "campaign-4471-slot-01"      },      {        "socialProfileId": "6f2c9a41-7b0e-4d55-9a2f-3c8e1d47b902",        "name": "Autumn week 2",        "platforms": ["INSTAGRAM", "FACEBOOK", "LINKEDIN"],        "content": "Week two: the Halcyon armchair. Sixty hours of work, one chair.",        "mediaUrls": ["https://cdn.example.com/social/autumn-w2.jpg"],        "action": "SCHEDULE",        "scheduleDate": "2026-10-09",        "scheduleTime": "09:30",        "clientReference": "campaign-4471-slot-02"      },      {        "socialProfileId": "a90f7c22-5db1-4e83-9f40-2b7c6a1e5d33",        "name": "Eastside autumn teaser",        "platforms": ["INSTAGRAM"],        "content": "Something solid is arriving next week. Stay tuned.",        "mediaUrls": ["https://cdn.example.com/social/eastside-teaser.jpg"],        "action": "SCHEDULE",        "scheduledAt": "2026-10-01T08:00:00-04:00",        "clientReference": "campaign-4471-slot-03"      }    ]  }}

Respons

200The whole batch validated. A job was queued, poll GET /social/bulk-posts/{bulkJobId} for per-row results.
Response
{  "data": {    "createBulkSocialMediaPosts": {      "success": true,      "error": [],      "job": {        "id": "9b3f18d0-7a26-4c51-8e94-1f0d5c6b7a82",        "status": "QUEUED",        "totalCount": 3,        "processedCount": 0,        "successCount": 0,        "failureCount": 0,        "createdAt": "2026-09-28T14:04:52Z",        "updatedAt": "2026-09-28T14:04:52Z",        "results": []      }    }  }}
200At least one row failed validation, so **nothing was created**. `success` is `false`, no job is returned, and each rejected row is reported with its 0-based `index`.
Response
{  "data": {    "createBulkSocialMediaPosts": {      "success": false,      "error": [        {          "message": "SY95050: Bulk validation failed, no posts were created",          "code": "SY95050",          "contextInfo": null        }      ],      "job": {        "id": null,        "status": "FAILED",        "totalCount": 3,        "processedCount": 0,        "successCount": 0,        "failureCount": 2,        "createdAt": "2026-09-28T14:04:52Z",        "updatedAt": "2026-09-28T14:04:52Z",        "results": [          {            "index": 1,            "clientReference": "campaign-4471-slot-02",            "socialProfileId": "6f2c9a41-7b0e-4d55-9a2f-3c8e1d47b902",            "platforms": ["INSTAGRAM", "FACEBOOK", "LINKEDIN"],            "status": "INVALID",            "socialPostId": null,            "postStatus": null,            "errors": [              {                "message": "SY95045: No connected channel for LINKEDIN on this brand",                "code": "SY95045",                "contextInfo": [{ "key": "platform", "value": "LINKEDIN" }]              }            ]          },          {            "index": 2,            "clientReference": "campaign-4471-slot-03",            "socialProfileId": "a90f7c22-5db1-4e83-9f40-2b7c6a1e5d33",            "platforms": ["INSTAGRAM"],            "status": "INVALID",            "socialPostId": null,            "postStatus": null,            "errors": [              {                "message": "SY95046: scheduledAt must carry a UTC offset",                "code": "SY95046",                "contextInfo": null              }            ]          }        ]      }    }  }}
401Unauthenticated, missing or invalid API key.

Membuat banyak postingan media sosial dalam satu permintaan. Baris dikirim dalam payload permintaan — tanpa unggahan file dan tanpa CSV, hanya array berisi objek yang sama dengan yang diterima POST /social/posts satu per satu. Maksimal 500 baris per permintaan.

Kasus penggunaan: memuat konten untuk satu kuartal dalam satu panggilan. Alat perencanaan Anda memiliki seluruh kalender konten klien. Buat satu baris per slot, tandai masing-masing dengan clientReference Anda sendiri, lalu kirim semuanya sekaligus. Batch tersebut akan berhasil sebagai satu kesatuan atau menunjukkan secara tepat baris mana yang perlu Anda perbaiki. Simpan job.id yang dikembalikan dan periksa GET /social/bulk-posts/{bulkJobId} secara berkala hingga status mencapai status akhir, lalu cocokkan setiap hasil berdasarkan clientReference-nya.

Seluruh batch divalidasi terlebih dahulu

Validasi dilakukan pada setiap baris sebelum apa pun dibuat, dan batch bersifat atomik pada tahap tersebut:

  • Jika ada satu saja baris yang tidak valid, tidak ada apa pun yang dibuat. success bernilai false, SY95050 dikembalikan dalam error, dan setiap baris yang bermasalah muncul dalam job.results[] beserta index-nya yang dimulai dari 0, clientReference-nya, dan alasannya dalam errors[]. Perbaiki baris-baris tersebut dan kirim ulang seluruh batch.
  • Jika setiap baris valid, sebuah tugas dimasukkan ke antrean, success bernilai true, dan Anda mendapatkan job.id. Setiap baris masih dapat gagal di kemudian waktu, ketika platform menolaknya saat publikasi; kegagalan tersebut akan ditampilkan pada tugas, bukan di sini.

Cocokkan hasil berdasarkan clientReference jika memungkinkan, dan berdasarkan index jika tidak — baris-baris itu sendiri tidak dikembalikan, sehingga kedua field tersebut adalah satu-satunya penghubung ke data Anda sendiri.

Catatan.

  • Body permintaan harus dibungkus dalam objek input, dengan baris-baris di dalam input.posts.
  • Periksa success, bukan status HTTP. Penolakan seluruh batch berupa HTTP 200 dengan success: false dan SY95050 dalam error.
  • Maksimal 500 baris per permintaan. Array yang lebih besar langsung ditolak dengan SY95048 dan tidak ada apa pun yang dibuat; pecah array tersebut dan kirim dalam beberapa batch.
  • Merek pada setiap baris ditentukan oleh socialProfileId. brandId hanya digunakan sebagai token jalur URL, dan rute ini sama sekali tidak memiliki token jalur.
  • Baris dapat menargetkan merek yang berbeda. platforms pada setiap baris diperiksa terhadap merek pada baris itu sendiri, sehingga platform yang terhubung ke satu merek tetapi tidak ke merek lain hanya menyebabkan kegagalan pada baris yang memerlukannya.
  • Setiap baris mengikuti aturan penjadwalan yang sama dengan satu postingan: scheduledAt atau scheduleDate + scheduleTime, tidak pernah keduanya, dan scheduleDate / scheduleTime dibaca dalam zona waktu merek pada baris tersebut. Kedua bentuk tersebut boleh digunakan pada baris yang berbeda dalam satu batch.
  • Batas laju berlaku untuk permintaan, bukan untuk baris: batch berisi 500 baris menghabiskan satu permintaan dari kuota Anda. Lihat Batas laju.

Operasi tulis: tidak dijalankan pada akun aktif. Permintaan dan respons yang ditampilkan dibuat berdasarkan skema API; operasi ini memublikasikan ke akun media sosial sungguhan saat dijalankan.

Request
curl -X POST 'https://listingsapi.com/api/v4/social/bulk-posts' \  -H "Authorization: API $LISTINGSAPI_KEY" \  -H 'Content-Type: application/json' \  -d '{    "input": {      "name": "Autumn campaign load",      "posts": [        {          "socialProfileId": "6f2c9a41-7b0e-4d55-9a2f-3c8e1d47b902",          "name": "Autumn week 1",          "platforms": [            "INSTAGRAM",            "FACEBOOK"          ],          "content": "Week one of the autumn collection: the Fairfield oak sideboard, finished by hand in the workshop.",          "mediaUrls": [            "https://cdn.example.com/social/autumn-w1.jpg"          ],          "action": "SCHEDULE",          "scheduleDate": "2026-10-02",          "scheduleTime": "09:30",          "clientReference": "campaign-4471-slot-01"        },        {          "socialProfileId": "6f2c9a41-7b0e-4d55-9a2f-3c8e1d47b902",          "name": "Autumn week 2",          "platforms": [            "INSTAGRAM",            "FACEBOOK",            "LINKEDIN"          ],          "content": "Week two: the Halcyon armchair. Sixty hours of work, one chair.",          "mediaUrls": [            "https://cdn.example.com/social/autumn-w2.jpg"          ],          "action": "SCHEDULE",          "scheduleDate": "2026-10-09",          "scheduleTime": "09:30",          "clientReference": "campaign-4471-slot-02"        },        {          "socialProfileId": "a90f7c22-5db1-4e83-9f40-2b7c6a1e5d33",          "name": "Eastside autumn teaser",          "platforms": [            "INSTAGRAM"          ],          "content": "Something solid is arriving next week. Stay tuned.",          "mediaUrls": [            "https://cdn.example.com/social/eastside-teaser.jpg"          ],          "action": "SCHEDULE",          "scheduledAt": "2026-10-01T08:00:00-04:00",          "clientReference": "campaign-4471-slot-03"        }      ]    }  }'