/api/v4/social/bulk-postsCrear publicaciones en bloque
Valida y encola hasta 500 publicaciones en redes por solicitud y devuelve un trabajo que puedes consultar periódicamente para ver resultados por fila.
Parámetros
Cuerpo
Un campo anidado marcado como obligatorio solo se aplica cuando envías su campo principal. Si el campo principal es opcional y lo omites, sus campos hijos obligatorios no se aplican.
| Nombre | Tipo | Obligatorio | Descripción |
|---|---|---|---|
| input | object | obligatorio | Wrapper object. The entire request body must be nested under `input`. |
| input.posts | array of objects | obligatorio | 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 | opcional | Optional label for the job itself, to identify it in your own logs. Not shown to any audience. |
| input.posts[].socialProfileId | string | obligatorio | UUID of the brand publishing this row. Rows may target different brands in one request. |
| input.posts[].name | string | obligatorio | Internal name for the post. |
| input.posts[].platforms | array of strings | obligatorio | 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 | obligatorio | The post body. |
| input.posts[].action | string | obligatorio | `DRAFT`, `SCHEDULE` (requires a schedule) or `PUBLISH`. |
| input.posts[].mediaUrls | array of strings | opcional | Public https image URLs. Required when the row targets Instagram or Pinterest. |
| input.posts[].videoUrls | array of strings | opcional | Public https video URLs. |
| input.posts[].link | string | opcional | Link to attach where the platform supports one. |
| input.posts[].scheduledAt | string | opcional | ISO-8601 publish instant with an offset. Alternative to `scheduleDate` + `scheduleTime`, never both. |
| input.posts[].scheduleDate | string | opcional | `YYYY-MM-DD`, interpreted in that row's brand timezone. Send with `scheduleTime`. |
| input.posts[].scheduleTime | string | opcional | `HH:MM`, interpreted in that row's brand timezone. Send with `scheduleDate`. |
| input.posts[].connectedChannelIds | array of strings | opcional | Restrict this row to specific connections by ID. |
| input.posts[].clientReference | string | opcional | 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. |
Solicitud de ejemplo
Cuerpo listo para pegar. Sustituye los ID y valores de ejemplo por los tuyos.
{ "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" } ] }}Respuestas
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.
Crea muchas publicaciones en redes sociales en una sola solicitud. Las filas se envían en el cuerpo de la solicitud: no se sube ningún archivo ni se usa CSV, solo un array de los mismos objetos que POST /social/posts acepta de uno en uno. Hasta 500 filas por solicitud.
Caso de uso: cargar el contenido de un trimestre en una sola llamada. Tu herramienta de planificación tiene todo el calendario de contenido del cliente. Crea una fila por cada espacio del calendario, etiqueta cada una con tu propio clientReference y envíalas juntas. El lote se procesa correctamente como una unidad o te indica exactamente qué filas debes corregir. Guarda el job.id devuelto y consulta periódicamente GET /social/bulk-posts/{bulkJobId} hasta que status alcance un estado final; después, coteja cada resultado mediante su clientReference.
Todo el lote se valida de antemano
Se validan todas las filas antes de crear nada, y el lote es atómico en esa etapa:
- Si alguna fila no es válida, no se crea nada.
successesfalse, se devuelveSY95050enerrory cada fila incorrecta aparece enjob.results[]con suindexcon base 0, suclientReferencey el motivo enerrors[]. Corrige esas filas y vuelve a enviar todo el lote. - Si todas las filas son válidas, se pone un trabajo en cola,
successestruey recibes unjob.id. Las filas individuales aún pueden fallar más adelante, cuando la plataforma las rechace en el momento de la publicación; esto se refleja en el trabajo, no aquí.
Coteja los resultados mediante clientReference cuando puedas y mediante index en los demás casos: las filas en sí no se devuelven, por lo que esos dos campos son el único vínculo con tus propios datos.
Notas.
- El cuerpo de la solicitud debe estar dentro de un objeto
input, con las filas eninput.posts. - Comprueba
success, no el estado HTTP. Un rechazo de todo el lote es unHTTP 200consuccess: falseySY95050enerror. - Máximo de 500 filas por solicitud. Un array más grande se rechaza de inmediato con
SY95048y no se crea nada; divídelo y envía varios lotes. - La marca de cada fila es
socialProfileId.brandIdsolo se usa como token de la ruta de la URL, y esta ruta no tiene ningún token de ruta. - Las filas pueden estar destinadas a marcas diferentes. Los
platformsde cada fila se comprueban con respecto a la marca de esa misma fila, por lo que una plataforma conectada a una marca pero no a otra solo hace que fallen las filas que la necesitan. - Cada fila sigue las mismas reglas de programación que una publicación individual:
scheduledAtoscheduleDate+scheduleTime, nunca ambas opciones, yscheduleDate/scheduleTimese interpretan en la zona horaria de la marca de esa fila. Puedes combinar las dos formas en filas diferentes de un mismo lote. - Los límites de frecuencia se aplican a la solicitud, no a las filas: un lote de 500 filas consume una solicitud de tu cuota. Consulta Límites de frecuencia.
Operación de escritura: no se ha ejecutado en la cuenta real. La solicitud y la respuesta que se muestran se han generado a partir del esquema de la API; al ejecutarse, esta operación publica en cuentas reales de redes sociales.
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" } ] } }'