The Architecture
The high-level flow is simple. The devil is in the details (which we cover below).- User connects account (via Connect Flow).
- User uploads content (via Media Upload).
- User picks a date (your UI).
- You send it to us (API call).
- We publish it (our infrastructure).
- We tell you what happened (Webhooks).
Post Status Lifecycle
This is the most important thing to understand. A post is not just “scheduled” or “published”. It goes through a state machine.Status Breakdown
| Status | What It Means | What You Should Show |
|---|---|---|
DRAFT | Saved but not scheduled. No postDate set (or set in the past). | ”Draft” - editable, not going anywhere yet. |
SCHEDULED | Has a future postDate. Waiting in line. | ”Scheduled for Dec 25 at 10:00 AM” |
PROCESSING | We picked it up and are actively publishing it. | ”Publishing…” - spinner time. |
POSTED | Successfully published to the platform. | ”Published” - show the permalink. |
RETRYING | Failed, but we’re going to try again. | ”Retrying…” - don’t panic yet. |
ERROR | Failed after all retries. Dead. | ”Failed” - show the error, offer manual retry. |
REVIEW | Platform needs to review it (mostly TikTok). | ”Under Review” - patience. |
Retry Logic
When a post fails to publish, we don’t give up immediately:- Max retries: 3 attempts
- Backoff: Exponential, starting at 3 minutes
- Between retries: Status is set to
RETRYING - After all retries exhausted: Status becomes
ERROR
REVIEW instead. We periodically re-check and re-attempt publishing.
Manual retry: Users can retry
ERROR posts via the API. This resets the retry counter and re-queues the post. Max 3 manual retries total - we don’t want infinite loops (we’ve seen things).Step 1: Connect Accounts
Before you can schedule anything, the user needs to connect their social accounts. See the Connect Flow guide for the full walkthrough. Quick version: you redirect the user to our OAuth flow, they authorize, we give you asocialAccountId. Done.
Step 2: Import History (Optional but Recommended)
Don’t show an empty calendar. Nobody likes staring at a blank grid wondering if the app is broken. Use the Post History Import to fetch their recent posts and populate the calendar.Step 3: Upload Media
Crucial: Upload media before the user hits “Schedule”. You need theuploadId to create the post.
- Simple Upload - for images and small files. One request, done.
- Resumable Upload - for videos. Three steps (init, push bytes, finalize), but if the upload fails at 99%, you don’t start over.
Pro tip: Always use Resumable Upload for videos. If a 500MB upload fails with Simple Upload, your user has to start over. With Resumable, they don’t. Your users will thank you. Your support inbox will thank you.
Step 4: Create the Post
Here’s where it gets interesting. You can create a post as a draft or schedule it immediately.Schedule for the Future
Save as Draft
Don’t setpostDate, or set the status to DRAFT:
Platform-Specific Data Options
Each platform has its own special fields in thedata object. Here are the highlights:
| Platform | Key Options |
|---|---|
type (REEL, STORY, POST), coverUrl, locationId | |
| TikTok | privacyLevel, allowComment, allowDuet, allowStitch, autoAddMusic |
| YouTube | title (required), privacyStatus, madeForKids (required, legal!), categoryId |
type (REEL, STORY, POST) | |
visibility | |
boardId (required - you can’t pin to thin air), title, link | |
subredditName (required), title (required), flairId | |
| Discord | channelId (required), username, avatarUrl |
| Slack | channelId (required), username, avatarUrl |
| Google Business | topicType, callToActionType, callToActionUrl, event/offer fields |
Step 5: Edit or Cancel
Update a Scheduled Post
OnlyDRAFT and SCHEDULED posts can be updated. Once a post is PROCESSING or beyond, it’s too late.
Delete a Scheduled Post
Soft-deletes the post. Sets status toDELETED.
POSTED, this only deletes it from our system - it does NOT remove it from the social platform. We can’t un-ring that bell.
Step 6: Handle the Results
Scheduling is asynchronous. You send us the post, we queue it, and you find out later what happened. There are two ways to know:Option A: Webhooks (Recommended)
Set up a webhook endpoint and listen for:| Event | Meaning | What To Do |
|---|---|---|
post.published | Post is live | Update UI to “Published”. Show permalink. |
post.failed | Post failed after all retries | Show error to user. Offer manual retry. |
comment.published | First comment posted | Update UI if you show comment status. |
Verify webhook signatures. Don’t trust random POST requests. We sign every webhook with HMAC SHA256. See Webhooks for the verification code.
Option B: Polling
If you can’t use webhooks, you can poll the post status:Error Notifications
If you setsendEmailOnError: true when creating a post, we’ll email the user when their post fails. One less thing for you to build.
Bulk Scheduling
Want to schedule 50 posts at once? Go for it. But be smart about it.Rate Limits
- API rate limits: Multi-layer limits per endpoint and tracker (API key / bearer token / IP fallback): burst
100/1s, short500/10s, minute2000/60s. See Rate Limits. - Platform limits: Each platform has its own daily posting limits per team. Check our Platform Limits for the exact numbers per tier. If you blast 50 TikToks in an hour, TikTok might have opinions.
Best Approach
Best Practices
1. Validate Before Scheduling
Don’t let a user schedule a 10-minute video for an Instagram Story. It will fail. At 3 AM. On Christmas. And they will email you. Check our Platform Limits and validate in your UI before sending anything to us. We validate too, but catching errors early is better for everyone.2. Timezones. Seriously.
We acceptpostDate in UTC only. Convert on your end. Every timezone bug in social media scheduling comes from someone who thought “eh, it’s probably fine” and didn’t convert.
3. First Comment Strategy
Use thecomments array to put hashtags in the first comment instead of the caption. It keeps the post clean and looks more professional.
4. Remember Data Retention
- Imported posts: Deleted after 30 days. Store them if you need them.
- Analytics: Deleted after 30 days. Fetch daily if you’re building reports.
- Webhook events: Deleted after 7 days. Log them on your end.
5. Handle the REVIEW Status
TikTok (and occasionally other platforms) may put posts into a review state instead of publishing immediately. This is normal. Don’t show it as an error - show it as “Under Review” and let us handle it. We periodically re-check and re-attempt publishing.6. Don’t Forget madeForKids on YouTube
This is a legal requirement (COPPA). If the content targets children, you must set madeForKids: true. If you don’t, YouTube will eventually notice, and penalties apply. We expose this field - use it.