Bulk schedule API
POST /api/content/bulk-schedule schedules many text posts in one call. Send either a rows array or a csv string. Each row becomes its own scheduled post, so every normal check applies per row, including the X allowance and the plan's scheduling gate. One bad row never stops the others.
Bulk scheduling creates text posts only. For media posts, create each one with the Content API.
How do I bulk schedule posts from a CSV with the API?
Send the CSV as a JSON string. The first line is a header row that is skipped, and the column order is fixed.
curl -X POST https://api.socifyr.com/api/content/bulk-schedule \
-H "Authorization: Bearer sk_..." \
-H "Content-Type: application/json" \
-d '{
"csv": "text,connections,scheduledAt,title\n\"Monday tip: batch your content.\",linkedin-mybrand|x-mybrand,2026-12-07T09:00:00Z,\nTuesday release notes,linkedin-mybrand,2026-12-08T09:00:00Z,Release notes"
}'CSV rules, taken from the parser:
- Column order is
text,connections,scheduledAt,title. The header line is required and its contents are ignored. - Quoted fields may contain commas, line breaks and doubled quotes (
""). - In
connections, separate slugs with a space, pipe, comma or semicolon. A pipe is safest inside an unquoted CSV cell. titleis optional.- The bulk endpoint has no timezone field. Give every date an explicit offset or
Z.
How do I bulk schedule with JSON rows instead?
curl -X POST https://api.socifyr.com/api/content/bulk-schedule \
-H "Authorization: Bearer sk_..." \
-H "Content-Type: application/json" \
-d '{
"rows": [
{ "text": "Monday tip: batch your content.", "connections": ["linkedin-mybrand", "x-mybrand"], "scheduledAt": "2026-12-07T09:00:00Z" },
{ "text": "Tuesday release notes", "connections": ["linkedin-mybrand"], "scheduledAt": "2026-12-08T09:00:00Z", "title": "Release notes" }
]
}'What parameters does bulk schedule take?
Send rows or csv. If both are present and rows is not empty, rows is used.
| Field | Type | Required | Constraints |
|---|---|---|---|
rows | array | One of rows or csv | Max 500 items |
csv | string | One of rows or csv | Max 500 000 characters |
Row fields:
| Field | Type | Required | Constraints |
|---|---|---|---|
text | string | Yes | Max 25 000 characters |
connections | string[] | Yes | Slugs. A space- or comma-separated string also works. |
scheduledAt | ISO 8601 string | Yes | Must be in the future |
title | string | No | Max 500 |
What does the bulk schedule response look like?
{
"success": true,
"data": {
"created": 1,
"failed": [
{ "row": 2, "error": "Connection \"linkedin-oldname\" not found or not active. Check your connections page for valid slugs." }
]
}
}row is 1-based and counts data rows, not the header. The call returns HTTP 201 even when some rows failed, so always read failed.
Per-row errors you can expect: text is required, at least one connection is required, scheduledAt is required, scheduledAt must be in the future, unknown or inactive connection slugs, the X allowance being reached, and platform rules.
What errors can the whole request return?
| Status | Cause | Fix |
|---|---|---|
| 400 | Provide "rows" or a non-empty "csv". | Send at least one data row. |
| 400 | A bulk schedule is limited to 500 rows. | Split into batches of 500. |
| 400 | Validation errors on rows | Fix the listed fields. |
| 403 | Scheduling is not available on your current plan... | Check the plan in Limits. |
| 403 | API key "<label>" reached its daily post limit... | Guardrail. Resets at 00:00 UTC. |
Guarded API keys may call this route. For a require-approval key, check the post status afterwards, because posts go through the approval flow. See Drafts and approvals.
Frequently asked questions
Can I attach images in a bulk schedule? Not through this endpoint. It creates text posts. Schedule media posts one at a time with scheduledAt.
Where do I see the posts I scheduled?GET /content?status=pending lists scheduled posts. See the Content API.
Next steps
- Scheduling guide
- Content API
- Webhooks API to hear about results