TypeScript/JavaScript SDK
Official TypeScript/JavaScript SDK for the Flow API.
Installation
npm install @flowdev/sdk
# or
yarn add @flowdev/sdk
# or
pnpm add @flowdev/sdk
Quick Start
import { Flow } from '@flowdev/sdk';
const flow = new Flow('flow_sk_live_abc12345_xyz789...');
// Create a post
const post = await flow.posts.create({
channelId: 'channel_123',
content: 'Hello from Flow!',
scheduledFor: new Date('2024-12-25T10:00:00Z'),
});
console.log('Post created:', post.id);
Configuration
const flow = new Flow(apiKey, {
baseURL: 'https://api.flow.dev', // default
timeout: 30000, // 30 seconds, default
maxRetries: 3, // default
retryDelay: 1000, // Initial delay in ms, default
});
Posts
List Posts
// List all posts
const posts = await flow.posts.list();
// With filters
const posts = await flow.posts.list({
filter: {
status: 'queued',
channelId: 'channel_123',
},
sort: '-scheduledFor',
page: 1,
perPage: 50,
});
Create Post
// Immediate post
const post = await flow.posts.create({
channelId: 'channel_123',
content: 'Hello!',
});
// Scheduled post
const post = await flow.posts.create({
channelId: 'channel_123',
content: 'Scheduled post',
scheduledFor: new Date('2024-12-25T10:00:00Z'),
mediaKeys: ['media_key_123'], // optional
enableOptimization: true, // optional
}, {
idempotencyKey: 'unique-key-123', // optional
});
Get Post
const post = await flow.posts.get('post_123');
Update Post
// Only works if post is still 'queued'
await flow.posts.update('post_123', {
content: 'Updated content',
scheduledFor: new Date('2024-12-26T10:00:00Z'),
});
Delete Post
await flow.posts.delete('post_123');
Batch Operations
// Batch create
const result = await flow.posts.createBatch({
posts: [
{ channelId: 'channel_123', content: 'Post 1' },
{ channelId: 'channel_123', content: 'Post 2' },
],
});
// Batch update
await flow.posts.updateBatch({
posts: [
{ id: 'post_1', content: 'Updated 1' },
{ id: 'post_2', content: 'Updated 2' },
],
});
// Batch delete
await flow.posts.deleteBatch({
postIds: ['post_1', 'post_2', 'post_3'],
});
Channels
List Channels
const channels = await flow.channels.list();
Create Channel
const channel = await flow.channels.create({
name: 'My Channel',
color: '#3B82F6', // optional
});
Get Channel
const channel = await flow.channels.get('channel_123');
Update Channel
await flow.channels.update('channel_123', {
name: 'Updated Name',
color: '#FF0000',
});
Delete Channel
await flow.channels.delete('channel_123');
Webhooks
List Webhooks
const webhooks = await flow.webhooks.list();
Create Webhook
const { secret } = await flow.webhooks.create({
url: 'https://example.com/webhooks/flow',
events: ['post.delivered', 'post.failed'],
});
console.log('Webhook secret:', secret); // Save this!
Get Webhook
const webhook = await flow.webhooks.get('webhook_123');
Update Webhook
await flow.webhooks.update('webhook_123', {
url: 'https://new-url.com/webhooks/flow',
events: ['post.delivered'],
active: false,
});
Delete Webhook
await flow.webhooks.delete('webhook_123');
Get Deliveries
const deliveries = await flow.webhooks.getDeliveries('webhook_123', {
status: 'failed',
page: 1,
perPage: 50,
});
Test Webhook
await flow.webhooks.test('webhook_123');
API Keys
List API Keys
const keys = await flow.apiKeys.list();
Create API Key
const { apiKey } = await flow.apiKeys.create({
name: 'Production Key',
permissions: ['posts:write', 'channels:read'], // optional
});
console.log('API Key:', apiKey); // Save this!
Get API Key
const key = await flow.apiKeys.get('key_123');
Update API Key
await flow.apiKeys.update('key_123', {
name: 'Updated Name',
});
Delete API Key
await flow.apiKeys.delete('key_123');
Media
Upload Media
const media = await flow.media.upload({
file: fs.readFileSync('image.jpg'),
filename: 'image.jpg',
});
console.log('Media key:', media.key);
Get Media
const url = await flow.media.getUrl('media_key_123');
Delete Media
await flow.media.delete('media_key_123');
Error Handling
import { Flow, FlowError } from '@flowdev/sdk';
try {
const post = await flow.posts.create({
channelId: 'invalid',
content: 'Test',
});
} catch (error) {
if (error instanceof FlowError) {
switch (error.status) {
case 401:
console.error('Authentication failed');
break;
case 403:
console.error('Permission denied');
break;
case 404:
console.error('Resource not found');
break;
case 429:
console.error(`Rate limited. Retry after ${error.retryAfter}s`);
break;
default:
console.error('API error:', error.message);
}
// Access error details
if (error.details) {
error.details.forEach(detail => {
console.error(`${detail.field}: ${detail.message}`);
});
}
}
}
TypeScript Types
All types are exported:
import {
Flow,
Post,
Channel,
Webhook,
ApiKey,
Media,
CreatePostRequest,
UpdatePostRequest,
} from '@flowdev/sdk';
const flow = new Flow(apiKey);
const posts: Post[] = await flow.posts.list();
Advanced Usage
Custom Headers
const post = await flow.posts.create(
{ channelId: 'channel_123', content: 'Hello' },
{
headers: {
'X-Custom-Header': 'value',
},
}
);
Request Interceptors
// Add custom request logic
flow.client.interceptors.request.use(config => {
config.headers['X-Custom-Header'] = 'value';
return config;
});
Response Interceptors
// Handle responses
flow.client.interceptors.response.use(
response => response,
error => {
// Custom error handling
console.error('Request failed:', error);
return Promise.reject(error);
}
);
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 });
}
Monitor Post Status
async function waitForPostDelivery(postId: string) {
while (true) {
const post = await flow.posts.get(postId);
if (post.status === 'done') {
console.log('Post delivered!');
break;
} else if (post.status === 'blocked') {
console.error('Post blocked');
break;
}
await new Promise(resolve => setTimeout(resolve, 5000)); // Wait 5s
}
}
Next Steps
- Read the API Reference Overview
- Check out Python SDK Documentation
- Explore Go SDK Documentation