POST/api/v4/social/bulk-posts

게시물 일괄 생성

한 번의 요청으로 최대 500개의 소셜 게시물을 검증하고 대기열에 추가하며, 행별 결과를 폴링할 수 있는 작업을 반환합니다.

API 키가 필요합니다. 헤더 형식과 키 교체는 인증을 참고하세요.

매개변수

본문

필수로 표시된 중첩 필드는 상위 필드를 보낼 때만 적용됩니다. 상위 필드가 선택 사항이고 이를 생략하면 필수 하위 필드도 적용되지 않습니다.

이름유형필수설명
inputobject필수Wrapper object. The entire request body must be nested under `input`.
input.postsarray of objects필수The 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.namestring선택Optional label for the job itself, to identify it in your own logs. Not shown to any audience.
input.posts[].socialProfileIdstring필수UUID of the brand publishing this row. Rows may target different brands in one request.
input.posts[].namestring필수Internal name for the post.
input.posts[].platformsarray of strings필수Platforms for this row: `FACEBOOK`, `INSTAGRAM`, `TWITTER` (X), `LINKEDIN`, `PINTEREST`. Each must already have a connection on that row's brand.
input.posts[].contentstring필수The post body.
input.posts[].actionstring필수`DRAFT`, `SCHEDULE` (requires a schedule) or `PUBLISH`.
input.posts[].mediaUrlsarray of strings선택Public https image URLs. Required when the row targets Instagram or Pinterest.
input.posts[].videoUrlsarray of strings선택Public https video URLs.
input.posts[].linkstring선택Link to attach where the platform supports one.
input.posts[].scheduledAtstring선택ISO-8601 publish instant with an offset. Alternative to `scheduleDate` + `scheduleTime`, never both.
input.posts[].scheduleDatestring선택`YYYY-MM-DD`, interpreted in that row's brand timezone. Send with `scheduleTime`.
input.posts[].scheduleTimestring선택`HH:MM`, interpreted in that row's brand timezone. Send with `scheduleDate`.
input.posts[].connectedChannelIdsarray of strings선택Restrict this row to specific connections by ID.
input.posts[].clientReferencestring선택Your own identifier for this row, echoed back on the matching job result. The most reliable way to reconcile a batch against your own records.

요청 예시

바로 붙여 넣을 수 있는 본문입니다. 예시 ID와 값을 실제 값으로 바꾸세요.

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"      }    ]  }}

응답

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.

한 번의 요청으로 여러 소셜 게시물을 생성합니다. 행은 요청 페이로드에 포함되어 전송됩니다. 파일 업로드나 CSV 없이, POST /social/posts에서 한 번에 1개씩 받는 것과 동일한 객체의 배열만 사용합니다. 요청당 최대 500개 행까지 가능합니다.

사용 사례: 한 번의 호출로 한 분기 분량의 콘텐츠 불러오기. 사용 중인 기획 도구에 고객의 전체 콘텐츠 일정이 있습니다. 각 일정에 해당하는 행을 만들고, 각 행에 자체 clientReference를 지정한 다음 함께 전송합니다. 배치는 전체가 하나의 단위로 성공하거나, 수정해야 할 행을 정확히 알려 줍니다. 반환된 job.id를 저장하고 status가 최종 상태에 도달할 때까지 GET /social/bulk-posts/{bulkJobId}를 폴링한 다음, 각 결과를 해당 clientReference를 기준으로 대조합니다.

전체 배치를 먼저 검증합니다

무엇이든 생성하기 전에 모든 행을 검증하며, 이 단계에서는 배치를 원자적으로 처리합니다.

  • 하나의 행이라도 유효하지 않으면 아무것도 생성되지 않습니다. success는 false이고, SY95050은 error에 반환되며, 잘못된 각 행은 0부터 시작하는 index, 해당 clientReference, errors[]에 담긴 사유와 함께 job.results[]에 표시됩니다. 해당 행을 수정하고 전체 배치를 다시 전송합니다.
  • 모든 행이 유효하면 작업이 대기열에 추가되고, success는 true이며, job.id를 받습니다. 개별 행은 이후에도 게시 시점에 플랫폼에서 거부하면 실패할 수 있으며, 해당 실패는 여기가 아닌 작업에 표시됩니다.

가능하면 clientReference를 기준으로, 그렇지 않으면 index를 기준으로 대조합니다. 행 자체는 응답에 다시 포함되지 않으므로 이 2개 필드만이 자체 데이터와 연결할 수 있는 수단입니다.

참고 사항.

  • 요청 본문은 반드시 input 객체로 감싸야 하며, 행은 input.posts에 넣어야 합니다.
  • HTTP 상태가 아닌 success를 확인합니다. 배치 전체가 거부되면 HTTP 200이 반환되며, error에 success: false와 SY95050이 포함됩니다.
  • 요청당 최대 500개 행까지 가능합니다. 이보다 큰 배열은 SY95048과 함께 즉시 거부되고 아무것도 생성되지 않으므로, 배열을 나누어 여러 배치로 전송합니다.
  • 각 행의 브랜드는 socialProfileId입니다. brandId는 오직 URL 경로 토큰으로만 사용되며, 이 엔드포인트에는 경로 토큰이 전혀 없습니다.
  • 각 행은 서로 다른 브랜드를 대상으로 할 수 있습니다. 각 행의 platforms는 해당 행의 브랜드를 기준으로 확인하므로, 한 브랜드에는 연결되어 있지만 다른 브랜드에는 연결되어 있지 않은 플랫폼이 있으면 해당 플랫폼이 필요한 행만 실패합니다.
  • 각 행에는 단일 게시물과 동일한 예약 규칙이 적용됩니다. scheduledAt 또는 scheduleDate + scheduleTime 중 하나만 사용하고 둘을 함께 사용해서는 안 되며, scheduleDate / scheduleTime은 해당 행의 브랜드 시간대를 기준으로 해석합니다. 하나의 배치에서 서로 다른 행에 두 형식을 혼용해도 됩니다.
  • 요청 빈도 제한은 행이 아닌 요청에 적용됩니다. 500개 행으로 구성된 배치는 허용 요청 횟수에서 1회를 사용합니다. 요청 빈도 제한을 참고합니다.

쓰기 작업: 실제 계정에서는 실행하지 않았습니다. 표시된 요청과 응답은 API 스키마를 바탕으로 구성되었으며, 이 작업을 실행하면 실제 소셜 계정에 게시됩니다.

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"        }      ]    }  }'