Skip to main content

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:

ParamTypeDescription
platformstringFilter by platform
statusstringscheduled, published, failed
from_dateISO8601Start of date range
to_dateISO8601End 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
FieldTypeRequiredDescription
reel_urlstringOne ofURL to video/audio file
audio_filefileOne ofDirect upload
languagestringNoDefault en
burn_inboolNoBurn 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
FieldTypeRequiredDescription
csv_filefileYesCSV with script, platform, voice_id columns
twin_idstringYesTwin persona to use
platformstringYesTarget 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:

ParamTypeDefaultDescription
platformstringallFilter by platform
daysint30Lookback window
twin_idstringFilter 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

CodeMeaning
400Validation error — check request body
401Missing or invalid API key
403Plan limit reached (e.g. bulk reels > 100 rows)
404Resource not found or soft-deleted
422Schema validation failure
500Server 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.