Batch Operations
Perform multiple operations in a single API call for better performance and rate limit management.
Why Use Batch Operations?
- Faster: Single request instead of multiple
- Rate limit friendly: Counts as one request
- Atomic: All succeed or all fail
- Efficient: Better for bulk operations
Batch Create Posts
Create multiple posts in a single request:
const result = await flow.posts.createBatch({
posts: [
{
channelId: 'channel_123',
content: 'Post 1',
scheduledFor: new Date('2024-12-25T09:00:00Z'),
},
{
channelId: 'channel_123',
content: 'Post 2',
scheduledFor: new Date('2024-12-25T10:00:00Z'),
},
{
channelId: 'channel_123',
content: 'Post 3',
scheduledFor: new Date('2024-12-25T11:00:00Z'),
},
],
});
console.log(`Created: ${result.summary.successful}`);
console.log(`Failed: ${result.summary.failed}`);
Response Format
{
"results": [
{
"success": true,
"post": {
"id": "post_1",
"channelId": "channel_123",
"content": "Post 1",
"status": "queued"
},
"index": 0
},
{
"success": false,
"error": "Channel not found",
"index": 1
}
],
"summary": {
"total": 3,
"successful": 2,
"failed": 1
}
}
Limits
- Maximum 100 posts per batch
- Each post is validated independently
- Partial success is possible (some succeed, some fail)
Batch Update Posts
Update multiple posts:
const result = await flow.posts.updateBatch({
posts: [
{
id: 'post_1',
content: 'Updated content 1',
},
{
id: 'post_2',
scheduledFor: new Date('2024-12-26T10:00:00Z'),
},
],
});
Note: Only queued posts can be updated.
Batch Delete Posts
Delete multiple posts:
const result = await flow.posts.deleteBatch({
postIds: ['post_1', 'post_2', 'post_3'],
});
Response Format
{
"results": [
{
"success": true,
"postId": "post_1"
},
{
"success": false,
"postId": "post_2",
"error": "Post not found or access denied"
}
],
"summary": {
"total": 3,
"successful": 2,
"failed": 1
}
}
Error Handling
Each item in a batch is processed independently:
const result = await flow.posts.createBatch({
posts: [
{ channelId: 'valid_channel', content: 'Post 1' },
{ channelId: 'invalid_channel', content: 'Post 2' },
{ channelId: 'valid_channel', content: 'Post 3' },
],
});
// Check individual results
result.results.forEach((item, index) => {
if (item.success) {
console.log(`Post ${index} created: ${item.post.id}`);
} else {
console.error(`Post ${index} failed: ${item.error}`);
}
});
// Check summary
if (result.summary.failed > 0) {
console.warn(`${result.summary.failed} posts failed`);
}
Best Practices
1. Validate Before Batching
// Validate posts before sending
const posts = [
{ channelId: 'channel_123', content: 'Post 1' },
{ channelId: 'channel_123', content: 'Post 2' },
];
// Validate each post
for (const post of posts) {
if (!post.channelId || !post.content) {
throw new Error('Invalid post data');
}
}
// Then batch create
const result = await flow.posts.createBatch({ posts });
2. Handle Partial Failures
const result = await flow.posts.createBatch({ posts });
// Retry failed items
const failed = result.results
.filter(r => !r.success)
.map((r, i) => ({ index: r.index, post: posts[r.index] }));
if (failed.length > 0) {
console.log(`Retrying ${failed.length} failed posts`);
// Retry logic...
}
3. Use for Bulk Operations
// Schedule posts for the next week
const posts = [];
for (let i = 0; i < 7; i++) {
const date = new Date();
date.setDate(date.getDate() + i + 1);
date.setHours(9, 0, 0, 0);
posts.push({
channelId: 'channel_123',
content: `Daily post ${i + 1}`,
scheduledFor: date,
});
}
// Create all at once
const result = await flow.posts.createBatch({ posts });
4. Monitor Rate Limits
// Batch operations count as single requests
// Much better for rate limits than individual requests
// ❌ 100 requests (rate limit risk)
for (const post of posts) {
await flow.posts.create(post);
}
// ✅ 1 request (rate limit friendly)
await flow.posts.createBatch({ posts });
Examples
Schedule Weekly Posts
async function scheduleWeeklyPosts(channelId: string, contents: string[]) {
const posts = contents.map((content, index) => {
const date = new Date();
date.setDate(date.getDate() + index + 1);
date.setHours(9, 0, 0, 0);
return {
channelId,
content,
scheduledFor: date,
};
});
return await flow.posts.createBatch({ posts });
}
// Usage
await scheduleWeeklyPosts('channel_123', [
'Monday motivation!',
'Tuesday tips',
'Wednesday wisdom',
'Thursday thoughts',
'Friday fun',
]);
Bulk Update Scheduled Times
async function reschedulePosts(postIds: string[], newTime: Date) {
const updates = postIds.map(id => ({
id,
scheduledFor: newTime,
}));
return await flow.posts.updateBatch({ posts: updates });
}
Clean Up Old Posts
async function cleanupOldPosts(channelId: string, beforeDate: Date) {
// Get old posts
const posts = await flow.posts.list({
filter: {
channelId,
scheduledFor: { lt: beforeDate.getTime() },
status: 'queued',
},
});
// Delete in batches
const postIds = posts.map(p => p.id);
const batchSize = 100;
for (let i = 0; i < postIds.length; i += batchSize) {
const batch = postIds.slice(i, i + batchSize);
await flow.posts.deleteBatch({ postIds: batch });
}
}
Rate Limits
Batch operations are much more rate-limit friendly:
- Individual requests: 100 posts = 100 API calls
- Batch request: 100 posts = 1 API call
This makes batch operations essential for bulk operations.
Limitations
- Maximum batch size: 100 items per batch
- Timeout: Large batches may timeout (split into smaller batches)
- Partial success: Some items may succeed while others fail
- Validation: Each item is validated independently
Next Steps
- Learn about Creating Posts Guide
- Understand Scheduling Guide
- Explore Error Handling Guide