Got 200 posts to schedule? Upload a CSV instead of creating every post with a separateDocumentation Index
Fetch the complete documentation index at: https://info.bundle.social/llms.txt
Use this file to discover all available pages before exploring further.
POST /post request.
Each row in the CSV becomes one post. Multiple platforms per row, multiple teams, media referenced by URL - one bad row won’t block the rest.
How it works
This is an asynchronous job, same pattern as Import Post History.- Upload: You send us a CSV file.
- Wait: We process each row in the background.
- Poll: You check if we’re done.
- Results: You get per-row success/failure details.
Step 1: Upload the CSV
Endpoint:POST /api/v1/post-csv-import
.csv and under 100 MB.
Response (201):
Every row in the CSV must include a
teamId, and all referenced teams must belong to the same organization that owns your API key.Step 2: Poll Progress
You have two options: lightweight status or full import details.Status (lightweight)
Endpoint:GET /api/v1/post-csv-import/{importId}/status
Full import details
Endpoint:GET /api/v1/post-csv-import/{importId}
Returns the full import object (same shape as the POST response).
Import history
Endpoint:GET /api/v1/post-csv-import
| Parameter | Type | Default | Description |
|---|---|---|---|
offset | number | 0 | Skip this many records |
limit | number | 10 | How many to return |
{ items, total }, newest first.
Step 3: Row Results
Once the import finishes (or while it’s running), you can inspect individual rows. Endpoint:GET /api/v1/post-csv-import/{importId}/rows
| Parameter | Type | Default | Description |
|---|---|---|---|
status | string | - | Filter by SUCCESS or FAILED |
offset | number | 0 | Skip this many rows |
limit | number | 10 | How many to return |
postId so you can track the created post:
Import Statuses
| Status | Meaning |
|---|---|
PENDING | Queued, processing hasn’t started yet. |
PROCESSING | We’re working through the rows. |
COMPLETED | All rows processed successfully. |
COMPLETED_WITH_ERRORS | Done, but at least one row failed. |
FAILED | The entire import failed (e.g. invalid file). |
RATE_LIMITED | Paused due to platform rate limits. |
CSV Format
Each row is one post. Column names map to post fields:| Column | Required | Description |
|---|---|---|
teamId | Yes | Which team this post belongs to |
title | Yes | Internal post title shown in bundle.social |
postDate | Yes | ISO 8601 date-time with timezone, for example 2026-04-05T10:00:00Z |
status | Yes | DRAFT or SCHEDULED |
socialAccountTypes | Yes | Comma-separated platforms (e.g. INSTAGRAM,TIKTOK,LINKEDIN) |
text | - | Post body text |
*MediaUrls | - | Platform-specific media URLs (e.g. instagramMediaUrls, tiktokMediaUrls) |
/upload.
Use # to separate multiple media URLs or list-like values inside one cell:
Platform Media URL Columns
| Platform | Column |
|---|---|
facebookMediaUrls | |
instagramMediaUrls | |
| TikTok | tiktokMediaUrls |
| YouTube | youtubeMediaUrls |
linkedinMediaUrls | |
pinterestMediaUrls | |
redditMediaUrls | |
| Threads | threadsMediaUrls |
| Twitter / X | twitterMediaUrls |
| Mastodon | mastodonMediaUrls |
| Bluesky | blueskyMediaUrls |
| Discord | discordMediaUrls |
| Slack | slackMediaUrls |
| Google Business | googleBusinessMediaUrls |
Common Platform Columns
| Platform | Columns |
|---|---|
facebookType, facebookText, facebookLink, facebookThumbnail, facebookMediaTitle, facebookNativeScheduleTime | |
instagramType, instagramText, instagramThumbnailOffset, instagramThumbnail, instagramShareToFeed, instagramCollaborators, instagramAutoFitImage, instagramAutoCropImage, instagramTagged, instagramCarouselItems, instagramLocationId, instagramTrialParamsGraduationStrategy, instagramMusicSoundId, instagramMusicSoundVolume, instagramVideoOriginalSoundVolume | |
| TikTok | tiktokType, tiktokText, tiktokThumbnail, tiktokPrivacy, tiktokIsBrandContent, tiktokIsOrganicBrandContent, tiktokDisableComments, tiktokDisableDuet, tiktokDisableStitch, tiktokThumbnailOffset, tiktokIsAiGenerated, tiktokAutoAddMusic, tiktokAutoScale, tiktokUploadToDraft, tiktokPhotoCoverIndex, tiktokMusicSoundId, tiktokMusicSoundVolume, tiktokMusicSoundStart, tiktokMusicSoundEnd, tiktokVideoOriginalSoundVolume |
| YouTube | youtubeType, youtubeTitle, youtubeDescription, youtubeThumbnail, youtubePrivacy, youtubeMadeForKids, youtubeContainsSyntheticMedia, youtubeHasPaidProductPlacement |
linkedinText, linkedinLink, linkedinThumbnail, linkedinMediaTitle, linkedinPrivacy, linkedinHideFromFeed, linkedinDisableReshare | |
pinterestBoardName, pinterestTitle, pinterestDescription, pinterestLink, pinterestThumbnail, pinterestAltText, pinterestNote, pinterestDominantColor | |
redditSubreddit, redditText, redditDescription, redditLink, redditNsfw, redditFlairId | |
| Threads | threadsText |
| Twitter / X | twitterText, twitterReplySettings |
| Mastodon | mastodonText, mastodonPrivacy, mastodonThumbnail, mastodonSpoiler |
| Bluesky | blueskyText, blueskyTags, blueskyLabels, blueskyQuoteUri, blueskyExternalUrl, blueskyExternalTitle, blueskyExternalDescription, blueskyVideoAlt |
| Discord | discordChannelId, discordText, discordUsername, discordAvatarUrl |
| Slack | slackChannelId, slackText, slackUsername, slackAvatarUrl |
| Google Business | googleBusinessText, googleBusinessTopicType, googleBusinessLanguageCode, googleBusinessCallToActionType, googleBusinessCallToActionUrl, googleBusinessEventTitle, googleBusinessEventStartDate, googleBusinessEventEndDate, googleBusinessOfferCouponCode, googleBusinessOfferRedeemOnlineUrl, googleBusinessOfferTermsConditions, googleBusinessAlertType |
TRUE or FALSE. Enum-like columns are case-insensitive in practice because we normalize them to uppercase before validation.
Handling Rate Limits
If the import status goes toRATE_LIMITED, don’t panic. We hit a platform’s posting cap.
- The import pauses automatically.
- Check
rateLimitResetAtfor when it can resume. - We retry automatically - just keep polling.
See also
- Import Post History - same async pattern, but for pulling existing posts from platforms.
- Media Upload - if you prefer uploading media separately before creating posts.
- Rate Limits - posting limits per platform and plan.