Rate Limits & Pricing
API rate limits and monthly posting limits
Rate Limits & Pricing
PostCore has two types of limits: API rate limits and monthly posting limits.
API Rate Limits
Rate limits prevent abuse and ensure fair usage.
| Endpoint Type | Limit | Window | Scope |
|---|---|---|---|
| General API | 100 requests | 15 minutes | Per IP |
| OAuth endpoints | 10 requests | 15 minutes | Per IP |
| Post scheduling | 100 requests | 1 hour | Per API key |
Rate Limit Headers
Every API response includes rate limit information:
X-RateLimit-Limit: 100
X-RateLimit-Remaining: 95
X-RateLimit-Reset: 1704110400| Header | Description |
|---|---|
X-RateLimit-Limit | Total requests allowed in window |
X-RateLimit-Remaining | Requests left in current window |
X-RateLimit-Reset | Unix timestamp when limit resets |
Rate Limit Exceeded
{
"error": "RATE_LIMIT_EXCEEDED",
"message": "Rate limit exceeded. Try again in 243 seconds",
"retry_after": 243
}Status Code: 429 Too Many Requests
Solution: Wait retry_after seconds before making another request.
Platform Rate Limits
Each platform has minimum time between posts to comply with their terms of service:
| Platform | Minimum Interval | Per |
|---|---|---|
| 60 seconds | Profile | |
| Bluesky | 1 second | Profile |
These limits are enforced per profile, not globally.
Example
// You have 2 LinkedIn profiles connected
// Profile A can post at 14:00:00
// Profile B can post at 14:00:00 (same time, different profile)
// Profile A's next post: 14:01:00 (60s later)Rate Limit Error
If you try to schedule posts too close together:
{
"error": "RATE_LIMIT_EXCEEDED",
"message": "LinkedIn requires 60 seconds between posts. Next available: 2025-01-15T14:01:00Z",
"platform": "linkedin",
"next_available": "2025-01-15T14:01:00Z"
}Status Code: 429 Too Many Requests
Use the next_available timestamp for your next post.
Monthly Posting Limits
Your plan determines how many posts you can create per month.
Free Plan
- Cost: $0/month
- Limit: 10 posts/month
- Best for: Testing, personal use, light posting
Pro Plan
- Cost: $15/month (or $156/year for $13/month)
- Limit: 3000 posts/month
- Best for: Businesses, agencies, power users
How Monthly Limits Work
Creation Month Matters
Limits are based on when the post is created, not when it publishes.
// January 1: Create 10 posts scheduled for February
// January usage: 10/10 (limit reached)
// February usage: 0/10 (new month)
// January 31: Downgrade to Free
// February 1: Those 10 posts still publish ✅
// February 1: Cannot create new posts (Free = 10/month limit)Why Creation Month?
This prevents users from:
- Subscribing for one month
- Scheduling thousands of posts for future months
- Canceling immediately
- Getting free posting forever
Checking Your Usage
curl https://api.postcore.dev/posts \
-H "x-api-key: YOUR_API_KEY"Count posts where created_at is in the current month:
const posts = await fetch("https://api.postcore.dev/posts", {
headers: { "x-api-key": apiKey },
}).then((r) => r.json());
const now = new Date();
const thisMonth = posts.filter((p) => {
const created = new Date(p.created_at);
return (
created.getMonth() === now.getMonth() &&
created.getFullYear() === now.getFullYear()
);
});
console.log(`Used ${thisMonth.length} posts this month`);Monthly Limit Exceeded
{
"error": "MONTHLY_LIMIT_EXCEEDED",
"message": "Monthly limit of 10 posts reached",
"limit": 10,
"used": 10,
"resets_at": "2025-02-01T00:00:00Z"
}Status Code: 429 Too Many Requests
Solutions:
- Wait until
resets_at(next month) - Upgrade to Pro
Subscription Changes
Upgrading (Free → Pro)
When you upgrade mid-month:
- Previous posts count toward new Pro limit
- You can immediately create more posts
// January 15: Had 10 posts on Free plan
// January 15: Upgrade to Pro
// New limit: 10/3000 ✅
// Can create 2990 more posts this monthDowngrading (Pro → Free)
When you downgrade:
- All existing posts remain scheduled
- New posts limited to Free plan amount
// Had 50 posts on Pro plan
// Downgrade to Free
// Existing posts: Still scheduled ✅
// New posts: Blocked if over 10 this month ❌Canceling Subscription
When you cancel:
- Pro access continues until end of billing period
- All scheduled posts remain and will publish
- After period ends, monthly limit returns to Free (10/month)
Pricing Breakdown
Monthly Plan
- Price: $15/month
- Billed: Monthly
- Posts: 3000/month
- Cost per post: $0.005
Annual Plan
- Price: $156/year
- Billed: Annually
- Posts: 3000/month (36,000/year)
- Monthly equivalent: $13/month
- Savings: $24/year (13% off)
Best Practices
Monitor Your Usage
Set up alerts when you're close to your limit:
const limit = 10; // or 3000 for Pro
const posts = thisMonthPosts.length;
const remaining = limit - posts;
if (remaining <= 2) {
console.warn(`Only ${remaining} posts left this month!`);
}Batch Scheduling
Schedule multiple posts at once efficiently:
const postsToSchedule = [
{ content: "Post 1", scheduled_for: "2025-01-15T10:00:00Z" },
{ content: "Post 2", scheduled_for: "2025-01-15T10:01:00Z" },
{ content: "Post 3", scheduled_for: "2025-01-15T10:02:00Z" },
];
for (const post of postsToSchedule) {
await fetch("https://api.postcore.dev/posts", {
method: "POST",
headers: {
"x-api-key": apiKey,
"Content-Type": "application/json",
},
body: JSON.stringify({
...post,
platforms: ["linkedin", "bluesky"],
}),
});
}Respect Platform Limits
Use the next_available time from errors:
async function schedulePost(content, platforms, time) {
try {
return await fetch("https://api.postcore.dev/posts", {
method: "POST",
headers: {
"x-api-key": apiKey,
"Content-Type": "application/json",
},
body: JSON.stringify({ content, platforms, scheduled_for: time }),
}).then((r) => r.json());
} catch (error) {
if (error.next_available) {
// Use the suggested time instead
return schedulePost(content, platforms, error.next_available);
}
throw error;
}
}