Skip to main content

Bulk Operations

Two endpoints for working with many posts in one call:

  • POST /v1/posts/bulk — create up to 50 posts in a single request
  • POST /v1/posts/retry-failed — retry every failed destination matching a filter

Both count as one API-rate-limit hit (vs N if you'd called the single-item endpoint in a loop). Per-post posting-rate-limits (POSTS_PER_DAY etc) still apply individually.

Bulk create — POST /v1/posts/bulk

curl -X POST https://app.posteverywhere.ai/api/v1/posts/bulk \
-H "Authorization: Bearer $POSTEVERYWHERE_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"posts": [
{ "content": "Morning post", "account_ids": [123, 456], "scheduled_for": "2026-08-01T09:00:00Z" },
{ "content": "Afternoon post", "account_ids": [123, 456], "scheduled_for": "2026-08-01T14:00:00Z" },
{ "content": "Evening post", "account_ids": [123, 456], "scheduled_for": "2026-08-01T19:00:00Z" }
]
}'

Response

{
"summary": { "total": 3, "succeeded": 2, "failed": 1 },
"results": [
{ "index": 0, "ok": true, "post": { "post_id": "...", ... } },
{ "index": 1, "ok": true, "post": { "post_id": "...", ... } },
{ "index": 2, "ok": false, "error": { "code": "validation_error", "message": "scheduled_for must be in the future" } }
]
}

Partial-success HTTP semantics

  • All succeeded201 Created
  • All failed422 Unprocessable Entity
  • Mixed207 Multi-Status

Always iterate results — don't assume 200 means everything worked.

Limits

  • Max 50 posts per call. Exceeding returns 400 bulk_limit_exceeded.
  • Each post inside the array is validated independently — one bad entry doesn't kill the others.
  • Posts are processed sequentially (not in parallel) to keep posting-rate-limits deterministic.

Bulk retry — POST /v1/posts/retry-failed

Retry every failed destination matching a filter. Avoids the "loop over N failed posts and retry each" anti-pattern.

# Retry every TikTok failure from yesterday
curl -X POST https://app.posteverywhere.ai/api/v1/posts/retry-failed \
-H "Authorization: Bearer $POSTEVERYWHERE_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"platform": "tiktok",
"failed_after": "2026-06-10T00:00:00Z",
"failed_before":"2026-06-11T00:00:00Z"
}'

Filter fields (at least one required)

FieldTypeDescription
post_idsstring[]Up to 200 specific post UUIDs
account_idnumberOnly failures on this social account
platformstringOne of instagram, facebook, x, linkedin, youtube, tiktok, threads, pinterest, bluesky, telegram, discord
failed_afterISO timestampOnly failures with updated_at >= this
failed_beforeISO timestampOnly failures with updated_at <= this
max_attemptsnumberSkip destinations whose attempt_count is already >= this

If no filter is supplied, the endpoint returns 400 no_filter — refusing to retry the entire failure history is intentional.

Response

{
"retried_count": 12,
"destinations": [
{ "destination_id": "...", "post_id": "...", "platform": "tiktok", "new_status": "queued" },
...
],
"message": "12 destinations queued for retry."
}

Retried destinations have their attempts reset to 0, last_error cleared, and scheduled_for set to NOW() for immediate publish.

Use cases

Schedule a 30-day content calendar

const posts = generateContentPlan(30); // 30 post objects
const batches = chunk(posts, 50); // Split into 50-post batches
for (const batch of batches) {
await client.bulkCreatePosts(batch);
}

Resurrect everything that failed during an outage

const outageStart = "2026-05-29T08:00:00Z";
const outageEnd = "2026-05-29T20:30:00Z";

const result = await client.retryFailedPosts({
failed_after: outageStart,
failed_before: outageEnd,
});
console.log(`Retrying ${result.retried_count} destinations`);

Recover one account after reconnecting

// User just reconnected their Instagram. Retry recent IG failures.
await client.retryFailedPosts({
account_id: 5356,
failed_after: "2026-06-08T00:00:00Z",
});