API Reference for LLMs
BLOTATO API REFERENCE
=====================
Base URL: https://backend.blotato.com/v2
Auth Header: blotato-api-key: YOUR_API_KEY
Content-Type: application/json
All creation operations are ASYNC. Submit a request, then poll for status.
Docs: https://help.blotato.com/api/start
OpenAPI: https://help.blotato.com/api/api-reference/openapi-reference
Errors: https://help.blotato.com/support/errors
================================================================================
ENDPOINTS
================================================================================
ACCOUNTS
GET /users/me - Verify API key, get user info
GET /users/me/accounts - List connected social accounts (get accountId)
GET /users/me/accounts/:accountId/subaccounts - Get Facebook/LinkedIn pageId
PUBLISHING
POST /posts - Create/publish a post (30 req/min)
GET /posts/:postSubmissionId - Poll post status (60 req/min)
VISUALS
POST /videos/from-templates - Create visual from template (30 req/min)
GET /videos/creations/:id - Poll visual status
GET /videos/templates - List available templates
DELETE /videos/:id - Delete a video
SOURCES (Content Extraction)
POST /source-resolutions-v3 - Extract content from URL/text (30 req/min)
GET /source-resolutions-v3/:id - Poll source status (60 req/min)
MEDIA
POST /media - Upload media from URL (30 req/min, optional)
================================================================================
STEP 0: GET ACCOUNTS (always do this first)
================================================================================
GET /users/me/accounts
GET /users/me/accounts?platform=twitter (filter by platform)
Response:
{
"items": [
{ "id": "98432", "platform": "twitter", "fullname": "Jane", "username": "jane" }
]
}
For Facebook/LinkedIn, also fetch subaccounts to get pageId:
GET /users/me/accounts/98432/subaccounts
Response:
{
"items": [
{ "id": "123456789", "accountId": "98432", "name": "My Business Page" }
]
}
Use items[].id as target.pageId when publishing to Facebook or LinkedIn.
Pinterest boardId is not available via API. Ask the user for it.
================================================================================
PUBLISHING A POST
================================================================================
POST /posts
Minimal payload (Twitter):
{
"post": {
"accountId": "98432",
"content": {
"text": "Hello world",
"mediaUrls": [],
"platform": "twitter"
},
"target": {
"targetType": "twitter"
}
}
}
RULES:
- content.platform and target.targetType must be set to the same value
- mediaUrls is required. Pass [] for text-only posts. Pass public URLs for media.
- accountId comes from GET /users/me/accounts
- No upload step needed. Pass any public URL in mediaUrls.
Platform-specific target fields:
- twitter: no extra fields
- instagram: mediaType ("reel"|"story"), collaborators, altText, coverImageUrl
- facebook: pageId (REQUIRED, from subaccounts), mediaType, link
- linkedin: pageId (optional, from subaccounts for company pages)
- tiktok: privacyLevel, disabledComments, disabledDuet, disabledStitch,
isBrandedContent, isYourBrand, isAiGenerated (ALL REQUIRED)
- pinterest: boardId (REQUIRED, manual from user), title, altText, link
- threads: replyControl
- bluesky: no extra fields
- youtube: title (REQUIRED), privacyStatus (REQUIRED), shouldNotifySubscribers (REQUIRED)
- webhook: url (REQUIRED)
Response: { "postSubmissionId": "uuid" }
Poll: GET /posts/{postSubmissionId}
Status values: "in-progress" | "published" | "failed"
- published: response includes "publicUrl"
- failed: response includes "errorMessage"
================================================================================
CREATING VISUALS
================================================================================
POST /videos/from-templates
RECOMMENDED: Use "prompt" to describe what you want. Set "inputs" to {}.
AI fills in the template inputs automatically from your prompt.
Do NOT manually construct the "inputs" object unless you have a specific reason.
templateId: Use the bare UUID from the templates list (e.g., "77f65d2b-48cc-4adb-bfbb-5bc86f8c01bd").
Do NOT use the full path format (e.g., "/base/v2/quote-card/.../v1").
CORRECT:
{
"templateId": "77f65d2b-48cc-4adb-bfbb-5bc86f8c01bd",
"inputs": {},
"prompt": "Create 5 motivational quotes about entrepreneurship",
"render": true
}
WRONG (do not manually fill inputs, use prompt instead):
{
"templateId": "77f65d2b-48cc-4adb-bfbb-5bc86f8c01bd",
"inputs": { "text": "Slide 1: ..." },
"render": true
}
Response: { "item": { "id": "vid_123", "status": "queueing" } }
Poll: GET /videos/creations/{id}
Status values: "queueing" | "generating-script" | "script-ready" |
"generating-media" | "media-ready" | "exporting" |
"done" | "creation-from-template-failed"
Terminal states: "done" (success) or "creation-from-template-failed" (failure)
When done: response includes "mediaUrl" and/or "imageUrls"
Use mediaUrl or imageUrls in your publish request's mediaUrls field.
Discover templates: GET /videos/templates?fields=id,name,description,inputs
Template reference: https://help.blotato.com/api/visuals
================================================================================
EXTRACTING CONTENT (SOURCES)
================================================================================
POST /source-resolutions-v3
Body MUST contain a "source" object. Do NOT put fields at the top level.
source.sourceType (REQUIRED, no auto-detection):
- "text" - Transform raw text (uses source.text)
- "article" - Extract from article URL (uses source.url)
- "youtube" - Extract from YouTube URL (uses source.url)
- "twitter" - Extract from Twitter/X URL (uses source.url)
- "tiktok" - Extract from TikTok URL (uses source.url)
- "perplexity-query" - AI web research (uses source.text)
- "audio" - Extract from audio URL (uses source.url)
- "pdf" - Extract from PDF URL (uses source.url)
CORRECT:
{
"source": {
"sourceType": "youtube",
"url": "https://www.youtube.com/watch?v=dQw4w9WgXcQ"
}
}
WRONG (missing "source" wrapper):
{ "sourceType": "youtube", "url": "..." }
Response: { "id": "src_123" }
Poll: GET /source-resolutions-v3/{id}
Status values: "queued" | "processing" | "completed" | "failed"
When completed: response includes "content" and "title"
================================================================================
COMPLETE WORKFLOW (for AI agents)
================================================================================
1. accounts = GET /users/me/accounts
2. sourceId = POST /source-resolutions-v3 { source: { sourceType, url/text } }
3. POLL: GET /source-resolutions-v3/{sourceId} until status = "completed"
4. videoId = POST /videos/from-templates { templateId, prompt, render: true }
5. POLL: GET /videos/creations/{videoId} until status = "done"
6. postId = POST /posts { post: { accountId, content: { text, mediaUrls, platform }, target: { targetType } } }
7. POLL: GET /posts/{postId} until status = "published"
8. DONE: use publicUrl from step 7
================================================================================
RATE LIMITS
================================================================================
POST /posts: 30 requests / minute
GET /posts/:id: 60 requests / minute
POST /videos/from-templates: 30 requests / minute
POST /source-resolutions-v3: 30 requests / minute
GET /source-resolutions-v3/:id: 60 requests / minute
POST /media: 30 requests / minute
GET /users/me/accounts: No limit
GET /users/me: No limit
429 response means rate limit exceeded. Check "message" for retry timing.Last updated