A REST API for AI video generation through the Virtuals Protocol ACP system. Generate music videos, commercial ads, and personalized narrative videos using AI agents.
The LL API integrates with two main AI agents:
- Luvi Agent: Generates music videos (MV1, MV2) and commercial ads (CA1, CA2)
- Lucien Agent: Creates personalized narrative videos (PNV)
All video generation jobs are processed asynchronously - submit a request, receive a job ID, then poll for completion status.
- Install dependencies:
npm install- Set up environment variables:
cp .env.example .env
# Edit .env with your actual values (see Environment Variables section)- Start development server:
npm run dev- Test the API:
curl http://localhost:3000/Create a .env file with the following required variables:
AGENT_ENTITIY_ID=your_agent_entity_id
AGENT_WALLET_ADDRESS=0x...
WHITELISTED_WALLET_PRIVATE_KEY=0x...AGENT_ENTITIY_ID: ACP agent entity identifierAGENT_WALLET_ADDRESS: Ethereum wallet address (0x format)WHITELISTED_WALLET_PRIVATE_KEY: Private key for wallet operations (0x format)
http://localhost:3000 # Local development
https://ll-production-58c1.up.railway.app # Production
POST /api/luvi/mv1Request Body:
{
"type": "string",
"artstyle": "string",
"narrative": "string",
"avatar_url": "string",
"avatar_name": "string",
"avatar_description": "string",
"webhook_url": "string (optional)"
}POST /api/luvi/mv2Request Body:
{
"type": "string",
"artstyle": "string",
"narrative": "string",
"avatar_url": "string",
"avatar2_url": "string",
"avatar_name": "string",
"avatar2_name": "string",
"avatar_description": "string",
"avatar2_description": "string",
"webhook_url": "string (optional)"
}POST /api/luvi/ca1Request Body:
{
"type": "string",
"artstyle": "string",
"narrative": "string",
"avatar_url": "string",
"avatar_name": "string",
"avatar_description": "string",
"webhook_url": "string (optional)"
}POST /api/luvi/ca2Request Body:
{
"type": "string",
"artstyle": "string",
"narrative": "string",
"avatar_url": "string",
"avatar2_url": "string",
"avatar_name": "string",
"avatar2_name": "string",
"avatar_description": "string",
"avatar2_description": "string",
"webhook_url": "string (optional)"
}POST /api/lucien/pnvRequest Body:
{
"narrative": "string",
"artstyle": "string",
"webhook_url": "string (optional)"
}GET /api/job/{job_id}All API responses follow a standardized format with a boolean success indicator:
Success Response:
{
"success": true,
"data": {
"id": 123,
"status": "pending|completed|failed",
"url": "https://video-url.mp4",
"meta": {
"phase": "negotiation",
"deliverable": "...",
"requirements": {...},
"price": "...",
"memos": [...],
"clientAddress": "0x...",
"providerAddress": "0x..."
}
}
}Error Response:
{
"success": false,
"error": "Job not found"
}- Submit Job: POST to any creation endpoint with required parameters
- Get Job ID: Extract
data.idfrom successful response - Check Status: GET
/api/job/{job_id}to monitor progress - Get Result: When
data.statusis "completed", checkdata.urlfor video URL
The data.status field can have the following values:
pending- Job is in progress (request, negotiation, transaction, or evaluation phases)completed- Job is finished with video URL indata.urlfieldfailed- Job was rejected or expired
You can receive automatic notifications when jobs complete by including a webhook_url in your request:
curl -X POST http://localhost:3000/api/luvi/mv1 \
-H "Content-Type: application/json" \
-d '{
"type": "music_video",
"artstyle": "cinematic",
"narrative": "A singer performs on stage",
"avatar_url": "https://example.com/avatar.jpg",
"avatar_name": "Singer",
"avatar_description": "Talented musician",
"webhook_url": "https://your-app.com/webhook"
}'When the job completes, a POST request will be sent to your webhook URL with this payload:
{
"event": "job.completed",
"success": true,
"data": {
"id": 123,
"status": "completed",
"url": "https://video-url.mp4",
"meta": {
"phase": "completed",
"deliverable": "...",
"requirements": {...},
"price": "...",
"memos": [...],
"clientAddress": "0x...",
"providerAddress": "0x..."
}
}
}