Bulk Import
Bulk import lets you push many posts in one upload. The backend parses the CSV, validates per-row, and creates posts spaced at a fixed interval starting from the row's date or — if invalid — now.
Endpoint
POST /api/v1/bulk-posts- Auth + workspace + active subscription required, plus the
posts.bulk_uploadplan feature. - Multipart form-data upload, field name
mediaCsv. - Multer config: in-memory storage, 10 MB max file size, CSV mime type only.
Body fields:
accounts— array of channel IDs to fan out to.mediaCsv— the CSV file.interval— minutes between consecutive posts (>= 1).
CSV format
The expected column order, taken from bulk_template.csv:
Text, Year, Month, Day, Hour (0-23), Minutes, Image URL, Link- Text — caption body. Quoted strings supported; embedded commas escape with backslash and
""for embedded quotes. - Year / Month / Day / Hour / Minutes — schedule components. Month
1–12, Day1–31(with calendar-aware validation), Hour0–23, Minutes0–59. - Image URL — public URL to a media asset (or empty for text-only posts).
- Link — optional URL appended to the post.
The first row is treated as a header if its first column contains the word "text" (case-insensitive).
Validation behavior
- Rows with invalid structure are skipped silently. The endpoint returns an error only if no valid rows remain.
- If the parsed date is invalid (e.g. Feb 30) or in the past, Sosyabot starts from
nowand spaces subsequent posts byintervalminutes. - There is no dry-run mode in the current build.
Template download
GET /api/v1/bulk-posts/templateReturns the canonical bulk_template.csv as an attachment. Use it as a starting point.
Frontend UI
The upload form lives at /app/bulk-posts: pick channels, set the interval, drop a CSV. The submission posts the multipart payload to /api/v1/bulk-posts.
Quoting matters
If your captions contain commas or newlines, wrap them in double quotes and escape inner quotes by doubling them (" → ""). The parser is strict about quote balance.