So you want to build a scheduler? You want to be the next Buffer or Hootsuite?
Here is how you do it with bundle.social.
The Architecture
- User connects account (via Connect Flow).
- User uploads content (via Media Upload).
- User picks a date (UI).
- You send it to us (API).
- We publish it (Magic).
- We ping you back (Webhooks).
Step 1: Import History (Optional)
Don’t show an empty calendar. Import their last 10 posts so they feel at home.
See Import Post History.
Crucial: Do this before the user hits “Schedule”.
- Use Simple Upload for images.
- Use Resumable Upload for videos.
Get the uploadId (e.g. upload_123). You need this.
Step 3: Create the Post
Here is the payload to schedule a post for the future.
const payload = {
teamId: 'team_abc',
socialAccountIds: ['instagram_123'],
text: "Scheduled for the future! 🚀",
uploadIds: ['upload_123'],
// THE IMPORTANT PART
scheduledAt: "2026-12-25T10:00:00.000Z", // UTC ISO string
// Platform specifics? We got you.
data: {
INSTAGRAM: {
type: "REEL" // Force it to be a Reel
}
},
// First comment for hashtags
comments: [
{
text: "#growth #mindset #grind",
socialAccountIds: ['instagram_123']
}
]
};
Timezones matter. Always send scheduledAt in UTC. If your user is in Tokyo, convert their “10:00 AM” to UTC before sending it to us. If you don’t, they will be posting at 3 AM and blaming you.
Step 4: Listen for Webhooks
Scheduling is async. We might succeed, or Instagram might reject the video encoding at the last second.
Listen for:
post.published: 🟢 Success. Update your UI to “Published”.
post.failed: 🔴 Failure. Tell the user (and maybe why).
Best Practices
1. Validate First
Don’t let a user schedule a 10-minute video for an Instagram Story. It will fail. Check our Platform Limits and block it in your UI.
2. Handle Rate Limits
If you are building a bulk uploader, respect the rate limits. If you blast 50 posts at once, we might queue them or reject them.
Use the comments array to put hashtags in the first comment. It keeps the caption clean and looks more professional.