VidGen API v1 Endpoints Webhooks
All systems operational

VidGen API

Generate videos from a single image and an audio file via a simple HTTP API. Submit a job, poll for status, get back a finished video.

Base URL
Auth
X-API-Key

Authentication

Every request to the API (except health checks) must include your API key in the X-API-Key request header. Keep it secret — anyone with the key can submit jobs on your behalf.

Stored only in your browser's localStorage. The "Try it" panels below will use this key automatically.

Quick start

Submit your first job with a single curl command. The response includes the jobId you'll use to poll for status.

curl -X POST https://example.com/api/jobs \
  -H "X-API-Key: $YOUR_API_KEY" \
  -F "image=@portrait.jpg" \
  -F "audio=@voiceover.mp3" \
  -F "webhookUrl=https://your.app/hooks/vidgen"

One job per user at a time. Submitting a new job while a previous one is still PENDING or PROCESSING returns 409. Wait for it to finish or cancel it first.

Endpoints

GET /api/health public

Liveness probe. Returns 200 OK when the API process is up. No authentication required.

Response

{ "status": "ok" }
Try it Live
POST /api/jobs API key

Submit a new video generation job. Send a multipart/form-data request with two files: an image and an audio track. Optionally include a webhookUrl to be notified when the job finishes.

Body (multipart/form-data)

FieldTypeDescription
image requiredfileSingle source image. Accepts image/jpeg, image/png, image/webp. Max 50 MB.
audio requiredfileVoiceover or audio track. Accepts mp3, wav, m4a, ogg. Max 50 MB.
webhookUrl optionalstringHTTPS URL that receives a signed callback when the job completes or fails. See Webhooks.

Response — 201 Created

{
  "message": "Job created",
  "jobId": "clxxxxx0000abcd1234efgh"
}
Try it Live
GET /api/jobs API key

List your jobs in reverse chronological order. Cursor-paginated.

Query parameters

ParamTypeDescription
limit optionalintegerPage size, 1–100. Default 20.
cursor optionalstringThe nextCursor from the previous response. Omit on first page.
status optionalstringFilter to one of PENDING, PROCESSING, COMPLETED, FAILED, CANCELLED.

Response

{
  "jobs": [
    {
      "id": "clxxxxx0000abcd1234efgh",
      "status": "COMPLETED",
      "outputVideo": "https://…/video.mp4",
      "outputShareLink": "https://…/share/…",
      "errorMessage": null,
      "retries": 0,
      "createdAt": "2026-05-07T12:34:56.000Z",
      "updatedAt": "2026-05-07T12:38:11.000Z",
      "webhookUrl": null
    }
  ],
  "pagination": {
    "limit": 20,
    "nextCursor": "clxxxxx0001…",
    "hasNextPage": true
  }
}
Try it Live
GET /api/status/:jobId API key

Fetch the current status of a single job, including progress (0–100) when actively processing.

Path parameters

ParamTypeDescription
jobId requiredstringThe jobId returned when you submitted the job.

Response

{
  "jobId": "clxxxxx0000abcd1234efgh",
  "status": "PROCESSING",
  "progress": 62,
  "outputVideo": null,
  "outputShareLink": null,
  "errorMessage": null,
  "createdAt": "2026-05-07T12:34:56.000Z",
  "updatedAt": "2026-05-07T12:36:08.000Z"
}

Job status values

  • PENDING — queued, not yet picked up
  • PROCESSING — actively rendering; progress reflects an estimate
  • COMPLETED — done; outputVideo is populated
  • FAILED — terminal failure; errorMessage explains why
  • CANCELLED — you cancelled it before it ran
Try it Live
DELETE /api/jobs/:jobId API key

Cancel a job. Only works while the job is still in PENDING state — once a worker picks it up, it can no longer be cancelled.

Response — 200 OK

{ "success": true, "message": "Job cancelled successfully" }
Try it Live

Webhooks

If you supplied a webhookUrl when creating a job, we'll POST a JSON payload to that URL when the job completes or fails. The body looks like the /api/status/:jobId response.

Verifying the signature

Every webhook is signed with HMAC-SHA256 using your account's webhook secret. The signature lives in the X-Webhook-Signature header. Reject any request where the signature doesn't match the body — anyone could otherwise forge events to your endpoint.

// Node.js / Express
import crypto from 'crypto';

app.post('/hooks/vidgen', express.raw({ type: 'application/json' }), (req, res) => {
  const got      = req.header('X-Webhook-Signature') || '';
  const expected = crypto
    .createHmac('sha256', process.env.WEBHOOK_SECRET)
    .update(req.body)
    .digest('hex');

  if (got.length !== expected.length ||
      !crypto.timingSafeEqual(Buffer.from(got), Buffer.from(expected))) {
    return res.status(401).end();
  }

  const event = JSON.parse(req.body.toString());
  // event.status, event.outputVideo, …
  res.sendStatus(200);
});

HTTPS only. The webhookUrl must start with https://. Plain-HTTP URLs are rejected at job creation.

Errors

The API uses standard HTTP status codes. Error responses include a JSON body with an error field describing the problem.

CodeMeaning
400Bad request — missing field, malformed body, or invalid webhookUrl.
401Missing X-API-Key header.
401API key not recognized or has been deactivated.
404The requested job doesn't exist or doesn't belong to you.
409You already have an active job, or the job isn't in a cancellable state.
413Uploaded file exceeded 50 MB.
415Uploaded file's MIME type isn't supported.
429Rate limit exceeded — slow down.
500Server error. Retry with exponential backoff.

Rate limits

Per-IP rate limits, returned over standard RateLimit-* response headers.

ScopeLimit
All /api/*600 requests / minute
POST /api/jobs30 submissions / minute

You're also capped at 1 active job per API key — submitting another while one is PENDING or PROCESSING returns 409.