Authentication
All /api/* endpoints require an API token in the Authorization header.
Authorization: Bearer YOUR_API_TOKEN
Base URL
https://api.lovelybots.com/api
Uses PUBLIC_API_BASE_URL when set, then
PUBLIC_ACTIVE_STORAGE_BASE_URL, then
PUBLIC_APP_BASE_URL, then APP_PROTOCOL + APP_HOST.
Use https://api.lovelybots.com/api for bot and server-to-server calls.
Keep dashboard/login flows on https://lovelybots.com.
Endpoint Reference
POST /api/create accepts a single image field (file upload, URL, or base64) and saves it as a named character visible in /your_characters.
| Method |
Path |
Description |
| POST |
/api/create |
Primary create endpoint. Submits image + script to generate a video. Saves the image as a named character. |
| POST |
/api/videos |
Create alias. Same request/response schema as /api/create. |
| GET |
/api/avatars |
List your saved characters. Filter by name. Returns id for reuse. |
| GET |
/api/avatars/:id |
Get a single saved character by ID. |
| GET |
/api/credits |
Returns remaining video credits and usage totals. |
| GET |
/api/voices |
List available voices with IDs for voice_id. |
| GET |
/api/videos |
Lists videos for the authenticated user. |
| GET |
/api/videos/:id |
Returns one video object. |
| GET |
/api/videos/:id/status |
Poll-ready status payload for generation progress. |
Common Error Response
{
"error": "Error message"
}
Typical statuses:
401 missing/invalid token,
403 IP blocked or quota/plan restriction,
404 video not found,
422 validation/input error,
503 API disabled.
POST /api/create
Create a video with a script and image. The uploaded image is automatically saved as a named character in Your Characters, so you can reuse it later by avatar_id or avatar_name — without re-uploading.
Best output quality: use a clear front-facing portrait in 9:16 orientation (example: 1080x1920).
Input Schema
| Field |
Type |
Required |
Description |
| script |
string |
Yes |
Script text for generation. |
| image |
file or string (URL/base64) |
See note |
Image to use as the avatar presenter. Accepts multipart file upload, http/https URL, or base64/data URL. Required unless you supply avatar_id or avatar_name to reuse an existing saved character. For best quality use a front-facing 9:16 portrait (1080×1920). |
| avatar_name |
string |
No |
Name to give the saved character. When sending an image, the character is saved with this name and visible in /your_characters. If omitted, the AI automatically assigns a name. When used without an image, looks up your existing saved character by this name to reuse it. |
| avatar_id |
string (UUID) |
No |
ID of a previously saved character (from GET /api/avatars). Use this instead of uploading an image again. Takes precedence over avatar_name. |
| gender |
string |
No |
Preferred gender hint (male, female). Speeds up and stabilizes auto voice selection for uploaded images. |
| age |
string |
No |
Optional age hint (young_adult, adult, mature, middle_aged, older) to help auto voice selection. |
| voice_id |
string (UUID) |
No |
Voice to force. If omitted, the API auto-selects a supported voice from the uploaded image plus any provided gender/age hints. Missing voice_id does not fail the request. |
| action_prompt |
string |
No |
Presenter action/performance guidance (e.g. "Smiles warmly and waves"). |
| camera_prompt |
string |
No |
Camera/framing guidance (e.g. "Medium closeup, cinematic lighting"). |
| subtitles |
boolean |
No |
Enable subtitle generation. |
| public |
boolean |
No |
Set to false to keep the video private. Defaults to true (visible on the public feed lovelybots.com/feed). |
Output Schema (201 Created)
| Field |
Type |
Description |
| id |
string (UUID) |
Video ID. Use to poll GET /api/videos/:id. |
| status |
string |
Initial status — always queued on creation. |
| credits_remaining |
integer |
Videos remaining in your plan this month. |
| share_url |
string |
Public shareable page for this video. |
| avatar.id |
string (UUID) |
ID of the saved character. Pass this as avatar_id on future calls to reuse without re-uploading. |
| avatar.name |
string |
Name given to the saved character (as provided or AI-generated). |
Example — Upload new image, name the character
curl -X POST "https://api.lovelybots.com/api/create" \
-H "Authorization: Bearer YOUR_API_TOKEN" \
-F "script=Three launch hooks for this week" \
-F "image=@/absolute/path/to/image_1080x1920.jpg" \
-F "avatar_name=Emma" \
-F "action_prompt=Confident delivery with hand gestures" \
-F "camera_prompt=Medium close-up, slight push-in" \
-F "subtitles=true"
Example — Reuse a saved character by ID
curl -X POST "https://api.lovelybots.com/api/create" \
-H "Authorization: Bearer YOUR_API_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"script": "Welcome back to our weekly sale!",
"avatar_id": "a1b2c3d4-..."
}'
Example — Reuse by name (JSON)
curl -X POST "https://api.lovelybots.com/api/create" \
-H "Authorization: Bearer YOUR_API_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"script": "Check out our summer collection.",
"avatar_name": "Emma",
"action_prompt": "Warm smile, gestures to the side"
}'
Response Example (201)
{
"id": "b6f9a32d-3c53-4a6c-9d8c-2f0f7a1b4cde",
"status": "queued",
"credits_remaining": 12,
"share_url": "https://lovelybots.com/videos/b6f9a32d-.../share/abc123token",
"avatar": {
"id": "a1b2c3d4-5e6f-7890-abcd-ef1234567890",
"name": "Emma"
}
}
GET /api/avatars
List your saved characters. Use this to get the avatar_id for reuse in POST /api/create, or find an avatar by name.
Query Parameters
| Param |
Type |
Description |
| name |
string |
Filter by name (case-insensitive substring match). |
| page |
integer |
Page number. |
| per_page |
integer |
Items per page. Default 20. |
Output Schema
| Field |
Type |
Description |
| avatars[].id |
string (UUID) |
Use as avatar_id in create requests. |
| avatars[].name |
string |
Character name. |
| avatars[].image_url |
string |
Thumbnail URL for the character. |
| avatars[].status |
string |
ready avatars can be reused immediately. |
| pagination |
object |
Standard pagination object. |
# List all your characters
curl "https://api.lovelybots.com/api/avatars" \
-H "Authorization: Bearer YOUR_API_TOKEN"
# Filter by name
curl "https://api.lovelybots.com/api/avatars?name=Emma" \
-H "Authorization: Bearer YOUR_API_TOKEN"
# Get a specific character by ID
curl "https://api.lovelybots.com/api/avatars/a1b2c3d4-5e6f-7890-abcd-ef1234567890" \
-H "Authorization: Bearer YOUR_API_TOKEN"
{
"avatars": [
{
"id": "a1b2c3d4-5e6f-7890-abcd-ef1234567890",
"name": "Emma",
"status": "ready",
"image_url": "https://lovelybots.com/rails/active_storage/...",
"tags": { "gender": "female", "age": ["adult"] },
"created_at": "2026-04-01T10:00:00.000Z"
}
],
"pagination": { "current_page": 1, "total_pages": 1, "total_count": 1 }
}
GET /api/voices
Returns supported voices you can use in voice_id when calling POST /api/create. Only live hume and elevenlabs voices are returned. Filter by gender and age.
Query Parameters
| Param |
Values |
| gender |
male, female |
| age |
young_adult, adult, mature, middle_aged, older |
Output Schema
| Field |
Type |
Description |
| voices |
array[object] |
Available voice entries. |
| voices[].id |
string (UUID) |
Use as voice_id in create requests. |
| voices[].name |
string |
Voice display label. |
| voices[].gender |
string |
male or female. |
| voices[].age |
string |
young_adult, adult, mature, middle_aged, or older. |
| voices[].provider |
string |
hume or elevenlabs. |
{
"voices": [
{
"id": "bbbbbbbb-bbbb-bbbb-bbbb-bbbbbbbbbbbb",
"name": "Amelia (female, young_adult)",
"gender": "female",
"age": "young_adult",
"provider": "elevenlabs"
}
]
}
GET /api/credits
Returns current user credit balances and reset timing.
Output Schema
| Field |
Type |
Description |
| credits.videos_remaining |
integer |
Remaining videos available now. |
| credits.videos_this_month |
integer |
Videos generated in current billing period. |
| credits.videos_created_all_time |
integer |
Lifetime videos generated. |
| credits.next_reset |
datetime or null |
Next credit reset time (ISO8601). |
{
"credits": {
"videos_remaining": 9,
"videos_this_month": 3,
"videos_created_all_time": 42,
"next_reset": "2026-03-01T00:00:00.000Z"
}
}
GET /api/videos
List videos for the authenticated user.
Query Parameters
| Parameter |
Type |
Description |
| status |
string |
Filter by one status: pending, queued, processing, completed, failed. |
| completed |
string |
If true, filters to completed videos. |
| failed |
string |
If true, filters to failed videos. |
| page |
integer |
Page number. |
| per_page |
integer |
Items per page. Default 12. |
Output Schema
| Field |
Type |
Description |
| videos |
array[Video] |
Array of video objects (latest first). |
| pagination.current_page |
integer |
Current page number. |
| pagination.total_pages |
integer |
Total number of pages. |
| pagination.total_count |
integer |
Total matching videos. |
{
"videos": [ { "...": "Video object" } ],
"pagination": {
"current_page": 1,
"total_pages": 4,
"total_count": 40
}
}
GET /api/videos/:id
Returns the polling-friendly summary used by the OpenClaw skill.
| Field |
Type |
Description |
| id |
integer |
Video ID. |
| status |
string |
queued, processing, completed, or failed. |
| share_url |
string |
Public shareable page URL. Always present. |
| credits_remaining |
integer |
Videos remaining on your plan this month. |
| video_url |
string or null |
Playable URL. Present when completed. |
| error |
string or null |
Failure reason. Present when failed. |
{
"id": 4321,
"status": "processing",
"credits_remaining": 12,
"share_url": "https://lovelybots.com/videos/4321/share/abc123token"
}
GET /api/videos/:id/status
Low-level provider status payload with progress and provider job metadata.
| Field |
Type |
Description |
| id |
integer |
Video ID. |
| status |
string |
pending, queued, processing, completed, or failed. |
| job_id |
string or null |
Provider job identifier when available. |
| video_url |
string or null |
Playable URL. Present when completed. |
| thumbnail_url |
string or null |
Thumbnail URL when available. |
| progress |
number, string, or null |
Provider progress indicator. |
| error |
string or null |
Failure reason. Present when failed. |
| created_at |
datetime |
Creation timestamp (ISO8601). |
| completed_at |
datetime or null |
Completion timestamp. |
{
"id": 4321,
"status": "processing",
"job_id": "fal_abc123",
"video_url": null,
"thumbnail_url": null,
"progress": 62,
"error": null,
"created_at": "2026-02-19T20:34:02.127Z",
"completed_at": null
}
Video Object Schema
| Field |
Type |
Description |
| id |
integer |
Video ID. |
| status |
string |
Current status. |
| video_url |
string or null |
Final playable video URL. |
| thumbnail_url |
string or null |
Thumbnail URL. Falls back to placeholder when not generated. |
| share_url |
string |
Public shareable page URL. |
| created_at |
datetime |
Creation timestamp (ISO8601). |
| completed_at |
datetime or null |
Completion timestamp. |
| image.id |
integer or null |
Source image record ID. |
| image.name |
string or null |
Source image display name. |
| image.image_url |
string or null |
Source image URL. |
| voice.id |
integer or null |
Voice ID. |
| voice.name |
string or null |
Voice display name. |