Scheduling Logic
Understanding how SchedPilot interprets dates, timezones, and platform constraints will help you build integrations that publish exactly when and where you intend.
How scheduled_date and timezone Work
When you create a post, you supply a scheduled_date string and an optional timezone. SchedPilot interprets the date in the given timezone and stores it internally as UTC.
Example:
{
"scheduled_date": "2024-06-15 09:00:00",
"timezone": "America/New_York"
}
New York is UTC-4 in summer (Eastern Daylight Time), so this post will be published at 13:00 UTC on June 15, 2024.
Timezone format
Always use IANA timezone names — do not use UTC offset strings.
| Correct | Incorrect |
|---|---|
America/New_York | -04:00 |
Europe/London | BST |
Asia/Tokyo | +09:00 |
Pacific/Auckland | NZST |
A full list of IANA names is available at IANA Time Zone Database or via the Wikipedia timezone list.
Default timezone
If no timezone field is supplied, SchedPilot assumes UTC.
Minimum Scheduling Window
Posts must be scheduled at a point in the future. Submitting a scheduled_date that is in the past or only a few seconds ahead may result in one of two outcomes depending on how close the date is to the current time:
- The post publishes immediately upon saving.
- The publish attempt fails because the scheduler window has already passed.
To avoid ambiguity, always schedule posts at least 5 minutes in the future.
Platform Character Limits
Exceeding a platform's character limit will cause the post to fail at publish time. Validate content length before submitting.
| Platform | Character limit |
|---|---|
| Twitter / X | 280 |
| Bluesky | 300 |
| Threads | 500 |
| 2,200 (caption) | |
| 3,000 | |
| 63,206 |
const MAX_LENGTHS = {
twitter: 280,
bluesky: 300,
threads: 500,
instagram: 2200,
linkedin: 3000,
facebook: 63206,
};
function validateContent(content, platform) {
const limit = MAX_LENGTHS[platform];
if (!limit) return true; // unknown platform, skip check
return content.length <= limit;
}
Image Recommendations by Platform
| Platform | Recommendation |
|---|---|
| Minimum 1:1 (square) ratio recommended. Landscape and portrait are supported but square performs best in the feed. | |
| Twitter / X | Up to 4 images per post. JPEG and PNG preferred. GIFs count as a single media item. |
| 1 image recommended for link posts. Multiple images are supported for carousel-style posts. | |
| Up to 10 images per post. | |
| Bluesky | Up to 4 images per post. |
| Threads | Up to 10 images per post. |
Post Statuses
| Status | Meaning |
|---|---|
scheduled | The post is queued and waiting to be published at scheduled_date. |
posted | The post was successfully published to the platform. |
failed | A publish attempt was made but the platform rejected it or an error occurred. See error_message for details. |
draft | The post has been saved but is not yet scheduled. It will not be published automatically. |
pending_approval | The post is awaiting approval from an admin before it can be scheduled. |
Handling Failed Posts
When a post transitions to failed status, a post.failed webhook event is fired (if webhooks are configured). The error_message field in the payload describes what went wrong.
Common failure reasons and remedies:
| Error message pattern | Likely cause | Remedy |
|---|---|---|
access token has expired | The platform OAuth token has expired | Go to app.schedpilot.com, navigate to the connected account, and reconnect it. |
rate limit exceeded by platform | The social platform throttled the publish request | Wait a few minutes and reschedule the post. |
content violates platform policy | The post text or media was flagged by the platform | Edit the content and reschedule. |
account not found | The connected account was deleted or disconnected | Reconnect the account at app.schedpilot.com. |
Failed posts are not automatically retried. Once you have resolved the underlying issue, reschedule the post via the Create Post endpoint or from the dashboard.