For developers
REST API reference
The same backend powers the REST API and the MCP server. Both speak JSON, both use the same key.
Authentication
Every request must include a bearer token in the Authorization header. Get one in Settings → Developer. The plaintext is shown exactly once on creation — we only store a SHA-256 hash, so we cannot recover lost keys.
Authorization: Bearer fl_live_a1b2c3d4...Tokens are workspace-scoped. Each call resolves the workspace from the key, so the agent never has to send a workspace id.
Rate limits
60 requests per minute per key, with a burst of 30. When you exceed the bucket, the API returns 429 Too Many Requests with a Retry-After header (seconds).
Error format
All non-2xx responses use a consistent shape:
{
"error": {
"code": "validation_error",
"message": "Human-readable explanation",
"issues": { /* optional zod field-level errors */ }
}
}missing_bearer_token— header missinginvalid_api_key— token unknown or malformedkey_revoked— key was revokedrate_limited— 429plan_limit— workspace hit a plan capvalidation_error— body failed schema validationnot_found— resource doesn't exist
GET /api/v1/me
Returns the workspace this key belongs to plus the active plan.
curl https://flowtive.app/api/v1/me \
-H "Authorization: Bearer fl_live_..."
{
"workspace": { "id": "...", "name": "...", "slug": "..." },
"plan": { "id": "pro", "status": "active", "limits": { ... } },
"api_key": { "id": "...", "scopes": [] }
}GET /api/v1/accounts
Lists every connected social account.
{
"accounts": [
{
"id": "...",
"platform": "twitter",
"username": "flowtive",
"display_name": "Flowtive",
"avatar_url": "https://...",
"is_active": true,
"connected_at": "2026-01-15T..."
}
]
}POST /api/v1/posts
Creates a post and either schedules it (when scheduled_at is set) or publishes it immediately. The response contains a per-platform breakdown.
Body
{
"caption": "Required. Used as the default per platform.",
"media_urls": ["https://..."], // optional
"platforms": ["twitter", "linkedin"], // required, 1–9
"scheduled_at": "2026-06-15T14:00:00Z", // optional, ISO 8601
"variants": {
"twitter": { "caption": "...", "hashtags": ["#a"] },
"linkedin": { "caption": "..." }
}
}Response (immediate)
{
"ok": true,
"post_id": "...",
"status": "published", // or "partial" / "failed" / "scheduled"
"scheduled_at": null,
"variants": [
{ "platform": "twitter", "status": "published",
"url": "https://twitter.com/..." },
{ "platform": "linkedin", "status": "published",
"url": "https://linkedin.com/feed/update/..." }
]
}GET /api/v1/posts
List posts, newest first. Cursor-based pagination.
?status=scheduled // optional filter
?limit=20 // 1–100
?cursor=2026-01-... // ISO timestamp from previous next_cursorGET /api/v1/posts/:id
Returns a post + its per-platform variants and the latest analytics snapshot per variant.
DELETE /api/v1/posts/:id
Cancels a scheduled post (sets status to cancelled) or hard-deletes a draft. Already-published posts return 409 already_published; delete those from the platform itself.
POST /api/v1/media
Uploads an asset to the workspace media library. Two flavours:
multipart/form-data
curl -X POST https://flowtive.app/api/v1/media \
-H "Authorization: Bearer fl_live_..." \
-F "file=@./hero.png"JSON (import from URL)
curl -X POST https://flowtive.app/api/v1/media \
-H "Authorization: Bearer fl_live_..." \
-H "Content-Type: application/json" \
-d '{ "url": "https://cdn.example.com/hero.png" }'GET /api/v1/analytics
Aggregated engagement across published posts. Default window is 7 days.
?since=2026-06-01 // ISO date, default = 7 days ago
?until=2026-06-08 // ISO date, default = now
?platform=twitter // optional
?post_id=... // narrow to a single postMCP endpoint
The MCP server speaks JSON-RPC 2.0 over HTTP at POST /api/mcp. Use the same bearer token. Supported methods:
initializetools/listtools/callwithcreate_post / list_posts / get_post / cancel_post / list_accounts / get_analytics / upload_media_url
curl -X POST https://flowtive.app/api/mcp \
-H "Authorization: Bearer fl_live_..." \
-H "Content-Type: application/json" \
-d '{
"jsonrpc": "2.0",
"id": 1,
"method": "tools/call",
"params": {
"name": "create_post",
"arguments": {
"caption": "Hello world",
"platforms": ["bluesky"]
}
}
}'Ready to wire it up?
Create a key, paste it into your agent, and watch it post.