POST
/api/v4/social/bulk-posts批量创建帖子
在一次请求中验证最多 500 条社交帖子并将其加入队列,返回一个可轮询的任务,以获取每行的结果。
参数
请求体
标记为必填的嵌套字段仅在您发送其父字段时适用。如果父字段为可选且您省略了它,其必填子字段不适用。
| 名称 | 类型 | 必填 | 描述 |
|---|---|---|---|
| input | object | 必填 | Wrapper object. The entire request body must be nested under `input`. |
| input.posts | array 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.name | string | 可选 | Optional label for the job itself, to identify it in your own logs. Not shown to any audience. |
| input.posts[].socialProfileId | string | 必填 | UUID of the brand publishing this row. Rows may target different brands in one request. |
| input.posts[].name | string | 必填 | Internal name for the post. |
| input.posts[].platforms | array 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[].content | string | 必填 | The post body. |
| input.posts[].action | string | 必填 | `DRAFT`, `SCHEDULE` (requires a schedule) or `PUBLISH`. |
| input.posts[].mediaUrls | array of strings | 可选 | Public https image URLs. Required when the row targets Instagram or Pinterest. |
| input.posts[].videoUrls | array of strings | 可选 | Public https video URLs. |
| input.posts[].link | string | 可选 | Link to attach where the platform supports one. |
| input.posts[].scheduledAt | string | 可选 | ISO-8601 publish instant with an offset. Alternative to `scheduleDate` + `scheduleTime`, never both. |
| input.posts[].scheduleDate | string | 可选 | `YYYY-MM-DD`, interpreted in that row's brand timezone. Send with `scheduleTime`. |
| input.posts[].scheduleTime | string | 可选 | `HH:MM`, interpreted in that row's brand timezone. Send with `scheduleDate`. |
| input.posts[].connectedChannelIds | array of strings | 可选 | Restrict this row to specific connections by ID. |
| input.posts[].clientReference | string | 可选 | 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 和值替换为您自己的。
{ "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.
{ "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`.
{ "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 每次接收的单个对象相同。每次请求最多 500 行。
使用场景:通过一次调用加载一个季度的内容。您的规划工具中已有客户的完整内容日历。为每个排期时段构建一行数据,用您自己的 clientReference 标记每行,然后一起发送。整个批次要么全部成功,要么准确告知您需要修正哪些行。保存返回的 job.id,并轮询 GET /social/bulk-posts/{bulkJobId},直到 status 进入终态,然后根据每个结果的 clientReference 与您的数据逐一核对。
预先验证整个批次
在创建任何内容之前,系统会验证每一行,且批次在此阶段具有原子性:
- 如果任何一行无效,则不会创建任何内容。
success为false,SY95050会在error中返回,每个有问题的行都会出现在job.results[]中,包含其从 0 开始的index、其clientReference,以及errors[]中的原因。修正这些行,然后重新发送整个批次。 - 如果每行都有效,系统会将一个任务加入队列,
success为true,您会获得一个job.id。个别行仍可能在之后发布时因平台拒绝而失败;此类失败会显示在任务中,而不是此处。
尽可能按 clientReference 核对,没有时按 index 核对;系统不会原样返回各行数据,因此这 2 个字段是与您自己的数据建立关联的唯一依据。
注意事项。
- 请求体必须封装在一个
input对象中,各行数据放在input.posts中。 - 检查
success,而不是 HTTP 状态。整个批次被拒绝时,返回的是HTTP 200,其中success: false,error中为SY95050。 - 每次请求最多 500 行。更大的数组会被直接拒绝,返回
SY95048,且不会创建任何内容;请将其拆分为多个批次发送。 - 每行的品牌由
socialProfileId指定。brandId只用作 URL 路径参数,而此路由完全没有路径参数。 - 各行可以面向不同的品牌。系统会根据每行所属的品牌检查该行的
platforms,因此,如果某个平台已连接到一个品牌但未连接到另一个品牌,则只有需要该平台且所属品牌未连接该平台的行会失败。 - 每行遵循与单条帖子相同的排期规则:使用
scheduledAt或scheduleDate+scheduleTime,绝不能同时使用两种形式,且scheduleDate/scheduleTime会按该行所属品牌的时区解析。同一批次中的不同行可以分别使用这两种形式。 - 速率限制针对的是请求,而不是行数:包含 500 行的批次仅消耗您配额中的 1 次请求。请参阅速率限制。
写入操作:未在实际账户中执行。所示请求和响应根据 API schema 构建;实际运行时,会向真实社交账号发布内容。
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" } ] } }'