Jobs API

Create and manage long-running workflow jobs. Jobs are used for complex operations like video generation that take several minutes to complete.

Endpoints

POST
/api/v1/jobs

Create a new job

GET
/api/v1/jobs

List your jobs

GET
/api/v1/jobs/{id}

Get job status

DELETE
/api/v1/jobs/{id}

Cancel a job

Create a Job

POST
/api/v1/jobs

Request Body

NameTypeDescription
workflowrequiredstringWorkflow slug — canonical names (generate_video, generate_image, lipsync_video, etc.) or DB workflows (house-timelapse)
inputobjectWorkflow-specific input parameters (prompt, model, imageUrl, etc.)
webhookUrlstringURL to receive completion notification

Example Request

curl -X POST https://vydra.ai/api/v1/jobs \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "workflow": "generate_video",
    "input": {
      "prompt": "Aerial drone shot of Manhattan at golden hour",
      "model": "veo3"
    }
  }'
Response (201 Created)json
{
  "id": "550e8400-e29b-41d4-a716-446655440000",
  "status": "running",
  "workflow": "house-timelapse",
  "creditsCharged": 150,
  "createdAt": "2026-01-26T12:00:00.000Z",
  "_links": {
    "self": "https://vydra.ai/api/v1/jobs/550e8400-e29b-41d4-a716-446655440000",
    "status": "https://vydra.ai/api/v1/jobs/550e8400-e29b-41d4-a716-446655440000"
  }
}

List Jobs

GET
/api/v1/jobs

Query Parameters

NameTypeDescription
limitnumberDefault: 20Max results (1-100)
offsetnumberDefault: 0Pagination offset
statusstringFilter by status: pending, running, completed, failed
Examplebash
curl "https://vydra.ai/api/v1/jobs?limit=10&status=completed" \
  -H "Authorization: Bearer YOUR_API_KEY"
Responsejson
{
  "data": [
    {
      "id": "550e8400-e29b-41d4-a716-446655440000",
      "status": "completed",
      "progress": 100,
      "workflowSlug": "house-timelapse",
      "statusMessage": "Video generated successfully",
      "creditsCharged": 150,
      "createdAt": "2026-01-26T12:00:00.000Z",
      "completedAt": "2026-01-26T12:15:00.000Z",
      "output": {
        "videoUrl": "https://pub-xxx.r2.dev/videos/output.mp4"
      }
    }
  ],
  "pagination": {
    "limit": 10,
    "offset": 0,
    "count": 1
  }
}

Get Job Status

GET
/api/v1/jobs/{id}
Examplebash
curl https://vydra.ai/api/v1/jobs/550e8400-e29b-41d4-a716-446655440000 \
  -H "Authorization: Bearer YOUR_API_KEY"

Response States

Pending

{
  "id": "...",
  "status": "pending",
  "progress": 0,
  "statusMessage": "Waiting to start..."
}

Running

{
  "id": "...",
  "status": "running",
  "progress": 45,
  "statusMessage": "Generating video 2 of 3..."
}

Completed

{
  "id": "...",
  "status": "completed",
  "progress": 100,
  "output": {
    "videoUrl": "https://pub-xxx.r2.dev/videos/output.mp4",
    "thumbnailUrl": "https://pub-xxx.r2.dev/videos/thumbnail.jpg"
  }
}

Failed

{
  "id": "...",
  "status": "failed",
  "error": {
    "message": "Processing error",
    "code": "PROCESSING_ERROR"
  },
  "creditsRefunded": 150,
  "refundStatus": "completed"
}

Cancel a Job

DELETE
/api/v1/jobs/{id}
Examplebash
curl -X DELETE https://vydra.ai/api/v1/jobs/550e8400-e29b-41d4-a716-446655440000 \
  -H "Authorization: Bearer YOUR_API_KEY"
Responsejson
{
  "success": true,
  "message": "Job cancelled",
  "refund": {
    "applied": true,
    "creditsRefunded": 150
  }
}

Auto-Refund on Cancel

When you cancel a job, any charged credits are automatically refunded.

Webhooks

Instead of polling for status, provide a webhookUrl to receive notifications when jobs complete.

Webhook Payload (Success)

{
  "jobId": "550e8400-e29b-41d4-a716-446655440000",
  "status": "completed",
  "workflow": "house-timelapse",
  "output": {
    "videoUrl": "https://pub-xxx.r2.dev/videos/output.mp4"
  },
  "completedAt": "2026-01-26T12:15:00.000Z"
}

Webhook Payload (Failure)

{
  "jobId": "550e8400-e29b-41d4-a716-446655440000",
  "status": "failed",
  "workflow": "renovation-timelapse",
  "error": {
    "message": "Processing failed",
    "code": "PROCESSING_ERROR"
  },
  "refund": {
    "applied": true,
    "creditsRefunded": 50
  },
  "completedAt": "2026-01-26T12:15:00.000Z"
}

Job Statuses

StatusDescriptionFinal?
pendingJob created, waiting to startNo
runningJob is actively processingNo
completedJob finished successfullyYes
failedJob encountered an errorYes
cancelledJob was cancelled by userYes

Polling Example

If you can't use webhooks, poll for status:

Polling Implementationjavascript
async function waitForJob(jobId, apiKey, maxWaitMs = 30 * 60 * 1000) {
  const startTime = Date.now();
  const pollInterval = 5000; // 5 seconds
  
  while (Date.now() - startTime < maxWaitMs) {
    const response = await fetch(`https://vydra.ai/api/v1/jobs/${jobId}`, {
      headers: { 'Authorization': `Bearer ${apiKey}` }
    });
    
    const job = await response.json();
    
    console.log(`Status: ${job.status}, Progress: ${job.progress}%`);
    
    if (job.status === 'completed') {
      return job.output;
    }
    
    if (job.status === 'failed') {
      throw new Error(job.error?.message || 'Job failed');
    }
    
    // Wait before next poll
    await new Promise(resolve => setTimeout(resolve, pollInterval));
  }
  
  throw new Error('Job timed out');
}

// Usage
const output = await waitForJob('job-id', 'YOUR_API_KEY');
console.log('Video URL:', output.videoUrl);

Rate Limits

Polling counts against your rate limits. Use webhooks when possible, or poll no more than once every 5 seconds.