Content Workflow Tools
Base URL: https://api.ainative.studio/api/v1/public
End-to-end API suite for AI-powered content creation and distribution. Create twin personas, schedule posts, auto-generate captions, batch-render reels, render avatar videos, and publish to social platforms — all async with task_id polling.
Authentication
All endpoints require an API key:
-H "X-API-Key: sk_..."
Async Pattern
Long-running operations return a task_id. Poll GET /tasks/{task_id} until status is done or error:
{
"task_id": "abc123",
"status": "processing", // queued | processing | done | error
"progress": 42, // 0–100
"result": null // populated when done
}
AI Twin Library
Manage AI twin personas — the identity, voice, and style that drive generated content.
Create a twin
POST /twins
{
"name": "Tech Creator",
"voice_id": "en-US-Neural2-A",
"style_tags": ["casual", "educational"],
"persona_prompt": "You are an engaging tech educator who explains complex topics simply.",
"platform_defaults": {
"tiktok": { "caption_style": "short" },
"instagram": { "caption_style": "hashtag-heavy" }
}
}
Response 201:
{
"id": "645b5b56-f879-4f2f-8ccc-106e8912f522",
"name": "Tech Creator",
"memory_namespace": "twin_645b5b56-f879-4f2f-8ccc-106e8912f522",
"style_tags": ["casual", "educational"],
"created_at": "2026-04-30T02:12:14Z"
}
The memory_namespace is pre-wired to ZeroMemory — store twin-specific context there for personalized generation.
List twins
GET /twins
Get a twin
GET /twins/{twin_id}
Update a twin
PATCH /twins/{twin_id}
Content-Type: application/json
{ "persona_prompt": "Updated persona..." }
Delete a twin (soft delete)
DELETE /twins/{twin_id}
Returns 204 No Content.
Content Calendar
Schedule content for automatic publishing. The publish_scheduled_content Celery Beat task checks every minute and dispatches due items.
Schedule a post
POST /content/calendar
{
"twin_id": "645b5b56-f879-4f2f-8ccc-106e8912f522",
"title": "How AI is changing content creation",
"platform": "instagram",
"scheduled_at": "2026-05-01T10:00:00Z",
"script": "AI is transforming how creators work..."
}
Response 201:
{
"id": "096e3539-8d29-404b-882c-c554e05f1b26",
"title": "How AI is changing content creation",
"platform": "instagram",
"status": "scheduled",
"scheduled_at": "2026-05-01T10:00:00Z"
}
Platform values: instagram, tiktok, linkedin, youtube
List calendar items
GET /content/calendar?platform=instagram&status=scheduled
Query params:
| Param | Type | Description |
|---|---|---|
platform | string | Filter by platform |
status | string | scheduled, published, failed |
from_date | ISO8601 | Start of date range |
to_date | ISO8601 | End of date range |
Get a calendar item
GET /content/calendar/{item_id}
Delete a calendar item
DELETE /content/calendar/{item_id}
Captions
Auto-generate captions from video or audio using Whisper. Returns SRT, VTT, and editable segments. Optional FFmpeg burn-in.
Generate captions
POST /captions/generate
Content-Type: multipart/form-data
| Field | Type | Required | Description |
|---|---|---|---|
reel_url | string | One of | URL to video/audio file |
audio_file | file | One of | Direct upload |
language | string | No | Default en |
burn_in | bool | No | Burn captions into video |
curl -X POST https://api.ainative.studio/api/v1/public/captions/generate \
-H "X-API-Key: sk_..." \
-F "reel_url=https://cdn.example.com/video.mp4" \
-F "language=en"
Response 202:
{
"caption_id": "5bc41d91-867a-4ccb-821a-2b9544c45719",
"task_id": "sync_5bc41d91-867a-4ccb-821a-2b9544c45719",
"status": "queued"
}
Get caption result
GET /captions/{caption_id}
Response:
{
"id": "5bc41d91...",
"status": "done",
"srt": "1\n00:00:00,000 --> 00:00:03,500\nAI is transforming how creators work.\n",
"vtt": "WEBVTT\n\n00:00:00.000 --> 00:00:03.500\nAI is transforming...",
"segments": [
{ "start": 0.0, "end": 3.5, "text": "AI is transforming how creators work." }
]
}
Burn captions into video
POST /captions/{caption_id}/burn-in
Content-Type: application/json
{ "font_size": 24, "font_color": "white", "position": "bottom" }
Returns { "task_id": "...", "status": "queued" } — poll until done, then download from result.output_url.
Bulk Reel Generation
Upload a CSV of scripts and generate reels in parallel using a celery.group() fan-out. Max 100 rows per batch.
Submit a batch
POST /bulk/reels
Content-Type: multipart/form-data
| Field | Type | Required | Description |
|---|---|---|---|
csv_file | file | Yes | CSV with script, platform, voice_id columns |
twin_id | string | Yes | Twin persona to use |
platform | string | Yes | Target platform |
CSV format:
script,platform,voice_id
Hello world!,instagram,en-US
Check out this feature.,tiktok,en-US
curl -X POST https://api.ainative.studio/api/v1/public/bulk/reels \
-H "X-API-Key: sk_..." \
-F "csv_file=@scripts.csv;type=text/csv" \
-F "twin_id=645b5b56-f879-4f2f-8ccc-106e8912f522" \
-F "platform=instagram"
Response 202:
{
"task_id": "dc1b2a5b-ecd7-4fa4-bfd0-48917fcf218a",
"batch_id": "dc1b2a5b-ecd7-4fa4-bfd0-48917fcf218a",
"status": "queued",
"progress": 0,
"total_rows": 50
}
Get batch status
GET /bulk/reels/{batch_id}
Returns per-job progress and individual result_url values when each reel completes.
Avatar Render
Generate talking-head avatar videos via HeyGen. Polls HeyGen's API for up to 5 minutes, then fires a webhook on completion.
Submit a render job
POST /multimodal/avatar/generate
Content-Type: application/json
{
"twin_id": "645b5b56-f879-4f2f-8ccc-106e8912f522",
"script": "Hello! I'm your AI twin. Let's create something amazing.",
"voice_id": "en-US-Neural2-A",
"avatar_id": "heygen_avatar_id_optional"
}
Response 202:
{
"task_id": "b1ebec31-ce3e-45c2-8629-9ac12ff4ea3c",
"celery_task_id": "b1ebec31-ce3e-45c2-8629-9ac12ff4ea3c",
"provider": "heygen",
"status": "queued",
"progress": 0,
"estimated_seconds": 45
}
Get render status
GET /multimodal/avatar/{job_id}
Response when done:
{
"task_id": "b1ebec31...",
"status": "done",
"progress": 100,
"result": {
"video_url": "https://cdn.heygen.com/...",
"duration_seconds": 12,
"credits_billed": 120
}
}
Billing: 10 credits per second of rendered video.
Social Publishing
Connect OAuth accounts and publish content to social platforms.
Connect a platform (OAuth)
GET /social/connect/{platform}?redirect_uri=https://yourapp.com/callback
Redirects to the platform's OAuth flow. Supported: instagram, tiktok, linkedin, youtube.
OAuth callback
GET /social/callback/{platform}?code=...&state=...
Called by the platform after OAuth. Stores encrypted tokens internally.
List connected accounts
GET /social/accounts
[
{ "id": "...", "platform": "instagram", "handle": "@mycreator", "connected_at": "..." }
]
Publish content
POST /social/publish
Content-Type: application/json
{
"platforms": ["instagram", "tiktok"],
"reel_url": "https://cdn.example.com/reel.mp4",
"caption": "Check out my latest video! #AIContent",
"twin_id": "645b5b56-f879-4f2f-8ccc-106e8912f522"
}
Response:
{
"results": [
{ "platform": "instagram", "task_id": "abc123", "status": "queued" },
{ "platform": "tiktok", "task_id": "def456", "status": "queued" }
]
}
Each task_id can be polled via GET /social/publish/{job_id}.
Disconnect a platform
DELETE /social/disconnect/{platform}
Social Analytics
Fetch engagement metrics, audience data, and export reports. Analytics sync every 6 hours via Celery Beat.
Get analytics
GET /analytics/social?platform=instagram&days=30
Query params:
| Param | Type | Default | Description |
|---|---|---|---|
platform | string | all | Filter by platform |
days | int | 30 | Lookback window |
twin_id | string | — | Filter by twin |
Response:
[
{
"platform": "instagram",
"date": "2026-04-29",
"views": 15420,
"likes": 823,
"comments": 94,
"shares": 201,
"followers_gained": 47
}
]
Format is Recharts-compatible — pass directly to <AreaChart data={...}>.
Summary rollup
GET /analytics/social/summary?days=30
Returns totals and deltas across all connected platforms.
Export report
POST /analytics/social/export
Content-Type: application/json
{ "format": "csv", "days": 30, "platform": "instagram" }
Returns a task_id. When done, result.download_url contains a signed S3 URL valid for 1 hour.
Error Codes
| Code | Meaning |
|---|---|
400 | Validation error — check request body |
401 | Missing or invalid API key |
403 | Plan limit reached (e.g. bulk reels > 100 rows) |
404 | Resource not found or soft-deleted |
422 | Schema validation failure |
500 | Server error — retry with exponential backoff |
Frontend Integration
The @ainative/react-sdk doesn't expose useTask directly — build the polling hook with TanStack Query:
import { useQuery } from '@tanstack/react-query';
function useTask<T>(taskId: string | null) {
return useQuery<{ status: string; progress: number; result: T }>({
queryKey: ['task', taskId],
queryFn: () =>
fetch(`https://api.ainative.studio/api/v1/tasks/${taskId}`, {
headers: { 'X-API-Key': process.env.NEXT_PUBLIC_AINATIVE_KEY! },
}).then(r => r.json()),
enabled: !!taskId,
refetchInterval: q =>
q.state.data?.status === 'done' || q.state.data?.status === 'error'
? false
: 2000,
});
}
See the AI Kit Components docs for StreamingMessage and StreamingIndicator to pair with script generation.