VEED Lipsync 2.0 API, VEED Fabric 1.0 API, Veed API: Pricing, Documentation

by Veed

VEED provides professional AI video processing capabilities including the Fabric model for video enhancement and intelligent background removal. Through Pixazo's API, developers can implement advanced video processing features that automatically improve video quality and remove backgrounds without green screens. The API is designed for content creators and video platforms needing automated video enhancement at scale.

Get API Key
Veed AI API

Models Version

WELCOME BONUS

Get 10% Cashback on Your First Payment (up to $500)

Add funds and get 10% cashback on your first payment (up to $500).

Claim Your Cashback →

Veed Clean Audio API Documentation

Remove background noise from speech with VEED Clean Audio: send one recording — any audio or video file up to 30 minutes — and get back a cleaned, loudness-normalized 48 kHz mono audio file in FLAC or WAV. Asynchronous: submit returns a request_id; poll the status endpoint until the request is COMPLETED, then download the audio from output.media_url.

POST https://gateway.pixazo.ai/veed-clean-audio/v1/clean-audio

Authentication

All requests require an API key passed via header.

HeaderTypeRequiredDescription
Ocp-Apim-Subscription-KeystringYesYour API subscription key

Audio to Audio - VEED Clean Audio

Request Code

POST https://gateway.pixazo.ai/veed-clean-audio/v1/clean-audio
Content-Type: application/json
Ocp-Apim-Subscription-Key: YOUR_SUBSCRIPTION_KEY

{
  "audio_url": "https://pub-582b7213209642b9b995c96c95a30381.r2.dev/doc-assets/audio/transcribe-sample.wav",
  "output_format": "flac",
  "target_lufs": -19,
  "strength": 0.874
}
import requests

url = "https://gateway.pixazo.ai/veed-clean-audio/v1/clean-audio"
headers = {
    "Content-Type": "application/json",
    "Ocp-Apim-Subscription-Key": "YOUR_SUBSCRIPTION_KEY"
}
data = {
  "audio_url": "https://pub-582b7213209642b9b995c96c95a30381.r2.dev/doc-assets/audio/transcribe-sample.wav",
  "output_format": "flac",
  "target_lufs": -19,
  "strength": 0.874
}

resp = requests.post(url, json=data, headers=headers)
print(resp.json())
const res = await fetch("https://gateway.pixazo.ai/veed-clean-audio/v1/clean-audio", {
  method: "POST",
  headers: {
    "Content-Type": "application/json",
    "Ocp-Apim-Subscription-Key": "YOUR_SUBSCRIPTION_KEY"
  },
  body: JSON.stringify({
  "audio_url": "https://pub-582b7213209642b9b995c96c95a30381.r2.dev/doc-assets/audio/transcribe-sample.wav",
  "output_format": "flac",
  "target_lufs": -19,
  "strength": 0.874
})
});
console.log(await res.json());
curl -X POST 'https://gateway.pixazo.ai/veed-clean-audio/v1/clean-audio' \
  -H 'Content-Type: application/json' \
  -H 'Ocp-Apim-Subscription-Key: YOUR_SUBSCRIPTION_KEY' \
  --data-raw '{"audio_url": "https://pub-582b7213209642b9b995c96c95a30381.r2.dev/doc-assets/audio/transcribe-sample.wav", "output_format": "flac", "target_lufs": -19, "strength": 0.874}'

Output

{
  "request_id": "veed-clean-audio_019dxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
  "status": "QUEUED",
  "polling_url": "https://gateway.pixazo.ai/v2/requests/status/veed-clean-audio_019dxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
}

Webhook (Optional)

Instead of polling, you can receive a Webhook callback when the request reaches a terminal state. Provide a Webhook URL via header on the submit request.

HeaderRequiredDescription
X-Webhook-URLTo enableHTTPS URL to receive the Webhook callback.
X-Webhook-ModeNoterminal (default, one callback on COMPLETED/ERROR) or sync (per-poll callbacks).

Example: enable Webhook

curl -X POST 'https://gateway.pixazo.ai/veed-clean-audio/v1/clean-audio' \
  -H 'Content-Type: application/json' \
  -H 'Ocp-Apim-Subscription-Key: YOUR_SUBSCRIPTION_KEY' \
  -H 'X-Webhook-URL: https://your-server.com/webhook' \
  --data-raw '{"audio_url": "https://pub-582b7213209642b9b995c96c95a30381.r2.dev/doc-assets/audio/transcribe-sample.wav", "output_format": "flac", "target_lufs": -19, "strength": 0.874}'

Callback Payload (success)

{
  "request_id": "veed-clean-audio_019dxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
  "status": "COMPLETED",
  "model_id": "veed-clean-audio",
  "error": null,
  "output": {
    "media_url": [
      "https://pub-582b7213209642b9b995c96c95a30381.r2.dev/v1/{request_id}/output.flac"
    ],
    "media_type": "audio/flac"
  },
  "created_at": "2026-10-06T16:09:09.763Z",
  "completed_at": "2026-10-06 16:10:18"
}

Failure callback shape

{
  "request_id": "veed-clean-audio_019dxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
  "status": "ERROR",
  "model_id": "veed-clean-audio",
  "error": "Description of the failure"
}

Delivery semantics

  • terminal mode: one Webhook callback when the request is COMPLETED or ERROR.
  • sync mode: a Webhook callback on every poll while the request is processing (status PROCESSING), plus the final COMPLETED/ERROR callback.
  • Callbacks are idempotent on request_id — de-duplicate on it.
  • Respond 200 within a few seconds; the Webhook endpoint must be HTTPS.

Request Parameters

ParameterRequiredTypeDefaultAllowed values / rangeDescription
audio_urlYesstring—One audio or video file, up to 30 minutes and 512 MB: a publicly reachable https URL that serves the file itself (no redirects), or a data URI for a small file (a data URI over 50 MB is refused)The recording to clean. Any format ffmpeg can decode — for example WAV, MP3, M4A, AAC, OGG, FLAC, MP4, MOV or WebM. For a video file, its audio track is cleaned; multi-channel audio is mixed down to mono.
output_formatNostring"flac"flac, wavContainer for the cleaned audio, always 48 kHz mono 16-bit. FLAC is lossless at about half the size of WAV. Values are case-sensitive.
target_lufsNonumber or null-19−40 to −8, or nullLoudness target for the output, in LUFS (ITU-R BS.1770 integrated loudness). The true peak is capped at −1.1 dBTP, so a recording with sharp peaks can come out quieter than the target. Send null to skip loudness normalization and keep the input level.
strengthNonumber0.8740 to 1How strongly noise under speech is suppressed: the suppression floor is 1 − strength. Lower values keep more room tone behind the voice; silence between words is always cleaned.

Good to know

  • Each request cleans one recording. batch_size, num_images, number_of_images, n, count are rejected — send one request per file.
  • Send the file as audio_url only; audio_urls and video_url are rejected. For a video, send its URL as audio_url: the audio track is cleaned and returned as an audio file.
  • There is no length field: duration, seconds, num_frames, frames_per_second, music_length_ms are rejected. The billed length is measured from the file.
  • The model takes no prompt. Send every field at the top level of the JSON body; parameters, content, text are rejected.
  • Values are case-sensitive: use flac, not FLAC.
  • When you leave a field out, the defaults apply: flac, a loudness target of −19 LUFS and a strength of 0.874.
  • Only target_lufs accepts null. Omit the other optional fields you do not use — do not send them as null.
  • There is no seed parameter.
  • Webhooks are set with the X-Webhook-URL / X-Webhook-Mode headers; webhook_url and webhook_mode in the JSON body are rejected.

Input Audio

  • Send exactly one file in audio_url: a publicly reachable https URL that serves the file itself (no redirects), or a data URI such as data:audio/wav;base64,.... Use a URL for anything large: a data URI over 50 MB is refused. A list of files is rejected.
  • Any audio or video format ffmpeg can decode works — for example WAV, MP3, M4A, AAC, OGG, FLAC, MP4, MOV or WebM. For a video, its audio track is cleaned and returned as an audio file; the video itself is not returned.
  • Multi-channel audio is mixed down to mono.
  • Up to 30 minutes and 512 MB per file. A longer recording whose file states its length is refused when you submit; split it into shorter segments.
  • The link is checked when you submit: a URL that cannot be downloaded, or that returns a web page or an empty file instead of a recording, is refused at once with a 400 and its hold is released. Large files are fetched when processing starts, so keep the link valid until the request completes.

Example: send the recording as a data URI

{
  "audio_url": "data:audio/wav;base64,UklGRiQAAABXQVZFZm10IBAAAAABAAEA...",
  "output_format": "wav"
}

Output Audio

The cleaned recording is 48 kHz, mono, 16-bit, and the same length as the input, give or take a fraction of a second. Background noise is removed from the speech, and the loudness is normalized — aimed at target_lufs, within a true-peak cap (see Loudness below) — unless you send null.

output_formatFileoutput.media_typeNotes
flacoutput.flacaudio/flacThe default. Lossless, about half the size of WAV.
wavoutput.wavaudio/wavUncompressed PCM.

Loudness

The default target is −19 LUFS integrated, and the true peak is capped at −1.1 dBTP. When the cap is reached first, the output comes out quieter than the target. To keep the original level and skip loudness normalization, send "target_lufs": null:

{
  "audio_url": "https://pub-582b7213209642b9b995c96c95a30381.r2.dev/doc-assets/audio/transcribe-sample.wav",
  "output_format": "wav",
  "target_lufs": null
}

Strength

strength sets how much of the background stays under the voice: at the default 0.874 the noise floor is held about 18 dB down. Lower it to keep more of the room's sound behind the speaker.

Example Request

{
  "audio_url": "https://pub-582b7213209642b9b995c96c95a30381.r2.dev/doc-assets/audio/transcribe-sample.wav",
  "output_format": "flac",
  "target_lufs": -19,
  "strength": 0.874
}

Example Response

{
  "request_id": "veed-clean-audio_019dxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
  "status": "QUEUED",
  "polling_url": "https://gateway.pixazo.ai/v2/requests/status/veed-clean-audio_019dxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
}

Request Headers

HeaderRequiredDescription
Content-TypeYesapplication/json
Ocp-Apim-Subscription-KeyYesYour API subscription key.
X-Webhook-URLNoEnable Webhook callbacks (see Webhook section).
X-Webhook-ModeNoterminal (default) or sync (see Webhook section).

Response Handling

Status CodeMeaning
202Accepted — request queued; returns request_id and polling_url.
400Invalid request — a required field is missing, a value has the wrong type, is out of range or is not one of the allowed values, or the recording could not be downloaded or is longer than 30 minutes. The message says what to fix.
401Unauthorized — missing or invalid subscription key.
402Insufficient balance for the hold this request needs.
429Too many requests.
500Internal server error.

Parameter problems are caught when you submit and returned as a 400, before any hold is placed on your balance. A recording that cannot be downloaded is also refused at submit with a 400, and its hold is released at once. Problems that need the model to run are reported through the status endpoint as status: "ERROR", with a message in error saying what went wrong. Failed requests are not billed — the hold is released in full.

ConditionHow it surfaces
Missing or invalid subscription keysynchronous 401
Balance too low for the holdsynchronous 402
Missing or empty audio_url, or audio_url sent as anything other than a single stringsynchronous 400
An audio_url that cannot be downloaded when you submit, or that returns a web page or an empty file instead of a recording, or a data URI over 50 MB (the hold is released at once)synchronous 400
A recording longer than 30 minutes whose file states its length — for example WAV, FLAC, MP4, MOV or M4A (refused before any hold)synchronous 400
output_format not one of the allowed values (values are case-sensitive)synchronous 400
target_lufs not a number from −40 to −8 (a JSON null is accepted), or strength not a number from 0 to 1 — for example the string "0.5"synchronous 400
batch_size, num_images, number_of_images, n, count (one recording per request)synchronous 400
duration, seconds, num_frames, frames_per_second, music_length_ms (the billed length is measured from the file)synchronous 400
parameters, content, text (no prompt; send the fields at the top level of the JSON body)synchronous 400
audio_urls, video_url (send one file, as audio_url)synchronous 400
webhook_url or webhook_mode in the JSON body (use the X-Webhook-URL / X-Webhook-Mode headers)synchronous 400
A file the model cannot use: no audio track, audio that cannot be decoded, or a file over 512 MBstatus: "ERROR"
A recording longer than 30 minutes whose length could not be read when you submitted itstatus: "ERROR"
A large file the model cannot fetch when processing starts — for example a link that redirects, has expired or is not publicly reachablestatus: "ERROR"

Missing audio_url (synchronous 400)

{
  "error": "Invalid request parameters",
  "message": "'audio_url' is required",
  "violations": [
    "'audio_url' is required"
  ]
}

A value that is not allowed (synchronous 400)

{
  "error": "Invalid request parameters",
  "message": "'output_format' must be one of: \"flac\", \"wav\" (got \"FLAC\")",
  "violations": [
    "'output_format' must be one of: \"flac\", \"wav\" (got \"FLAC\")"
  ]
}

A recording longer than 30 minutes (synchronous 400, no hold)

{
  "error": "Input too long",
  "message": "The source media is 2400s. This API accepts inputs up to 1800s — split it into shorter segments.",
  "max_input_seconds": 1800,
  "input_seconds": 2400
}

A file that cannot be downloaded (synchronous 400, hold released)

{
  "request_id": "veed-clean-audio_019dxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
  "error": "Asset proxy failed",
  "message": "Failed to proxy asset https://example.com/recording.wav: 404 Not Found",
  "failures": [
    {
      "url": "https://example.com/recording.wav",
      "error": "404 Not Found"
    }
  ]
}

Retrieving Results

Poll the status endpoint with the request_id from the submit response until status is COMPLETED or ERROR, then download the audio from output.media_url. Treat any status other than QUEUED, PROCESSING or COMPLETED as a failure. Longer recordings take longer to process.

Endpoint

GET https://gateway.pixazo.ai/v2/requests/status/{request_id}
Ocp-Apim-Subscription-Key: YOUR_SUBSCRIPTION_KEY

cURL example

curl 'https://gateway.pixazo.ai/v2/requests/status/veed-clean-audio_019dxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx' \
  -H 'Ocp-Apim-Subscription-Key: YOUR_SUBSCRIPTION_KEY'

Completed response

{
  "request_id": "veed-clean-audio_019dxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
  "status": "COMPLETED",
  "model_id": "veed-clean-audio",
  "error": null,
  "output": {
    "media_url": [
      "https://pub-582b7213209642b9b995c96c95a30381.r2.dev/v1/{request_id}/output.flac"
    ],
    "media_type": "audio/flac"
  },
  "created_at": "2026-10-06T16:09:09.763Z",
  "completed_at": "2026-10-06 16:10:18"
}

Response Fields

FieldTypeDescription
request_idstringUnique request identifier.
statusstringQUEUED, PROCESSING, COMPLETED or ERROR.
model_idstringThe model that handled the request — veed-clean-audio for this endpoint.
output.media_urlarray of stringsURL of the cleaned audio (one file per request).
output.media_typestringaudio/flac, or audio/wav when output_format is wav.
created_atstringRequest creation timestamp.
completed_atstringCompletion timestamp.
errorstringError message when status is ERROR.
polling_urlstringStatus URL for this request (submit response only).

Status Values & Flow

QUEUED → PROCESSING → COMPLETED (success) or ERROR (failure).

Typical workflow

  1. Send the request to POST https://gateway.pixazo.ai/veed-clean-audio/v1/clean-audio.
  2. Save the request_id from the 202 response.
  3. Poll GET /v2/requests/status/{request_id} every 10 seconds or so, or use a Webhook instead.
  4. When status is COMPLETED, download the audio from output.media_url.

How billing is measured

Billing is measured per minute of input audio: the length of the recording you send, rounded to whole seconds and then up to the next full minute, with a one-minute minimum — a 4-minute 10-second file is billed as 5 minutes, a 20-second file as 1 minute. For a video file, the length of its audio track is billed. output_format, target_lufs and strength do not change the amount.

When you submit, a hold is placed on your balance: for the file's length when the file states it (WAV, FLAC, MP4, MOV, M4A, and MP3 with a length header), otherwise for the 30-minute maximum. When the request completes, the charge is settled to the measured length and the rest of the hold is released. A failed request is not billed — its hold is released in full.

The current rate is shown in the pricing panel on this page.

Veed Clean Audio API Pricing

Billed on the length of the recording you send: rounded to whole seconds, then up to the next full minute, with a one-minute minimum. A video file is billed on its audio track; the output format, loudness target and strength do not change the price.

Your request will cost $0.0125 per minute of input audio.
a 4-minute 10-second recording is billed as 5 minutes; a 20-second clip as 1 minute
2. Veed Lipsync 2.0

Veed Lipsync 2.0 API Documentation

POST https://gateway.pixazo.ai/veed-lipsync-v2/v1/video-to-video/lip-sync

Authentication

All requests require an API key passed via header.

HeaderTypeRequiredDescription
Ocp-Apim-Subscription-KeystringYesYour API subscription key

Video + Audio to Video - VEED Lipsync v2

Request Code

POST https://gateway.pixazo.ai/veed-lipsync-v2/v1/video-to-video/lip-sync
Content-Type: application/json
Cache-Control: no-cache
Ocp-Apim-Subscription-Key: YOUR_SUBSCRIPTION_KEY

{
  "video_url": "https://pub-582b7213209642b9b995c96c95a30381.r2.dev/doc-assets/lipsync/talking-head-17s.mp4",
  "audio_url": "https://pub-582b7213209642b9b995c96c95a30381.r2.dev/test-audio/hg_audio17.mp3"
}
import requests

url = "https://gateway.pixazo.ai/veed-lipsync-v2/v1/video-to-video/lip-sync"
headers = {
    "Content-Type": "application/json",
    "Ocp-Apim-Subscription-Key": "YOUR_SUBSCRIPTION_KEY"
}
payload = {
    "video_url": "https://pub-582b7213209642b9b995c96c95a30381.r2.dev/doc-assets/lipsync/talking-head-17s.mp4",
    "audio_url": "https://pub-582b7213209642b9b995c96c95a30381.r2.dev/test-audio/hg_audio17.mp3"
}

resp = requests.post(url, headers=headers, json=payload)
print(resp.json())  # { "request_id": "...", "status": "QUEUED", "polling_url": "..." }
const res = await fetch("https://gateway.pixazo.ai/veed-lipsync-v2/v1/video-to-video/lip-sync", {
  method: "POST",
  headers: {
    "Content-Type": "application/json",
    "Ocp-Apim-Subscription-Key": "YOUR_SUBSCRIPTION_KEY"
  },
  body: JSON.stringify({
    video_url: "https://pub-582b7213209642b9b995c96c95a30381.r2.dev/doc-assets/lipsync/talking-head-17s.mp4",
    audio_url: "https://pub-582b7213209642b9b995c96c95a30381.r2.dev/test-audio/hg_audio17.mp3"
  })
});
const data = await res.json();
console.log(data); // { request_id, status: "QUEUED", polling_url }
curl -X POST "https://gateway.pixazo.ai/veed-lipsync-v2/v1/video-to-video/lip-sync" \
  -H "Content-Type: application/json" \
  -H "Cache-Control: no-cache" \
  -H "Ocp-Apim-Subscription-Key: YOUR_SUBSCRIPTION_KEY" \
  --data-raw '{
    "video_url": "https://pub-582b7213209642b9b995c96c95a30381.r2.dev/doc-assets/lipsync/talking-head-17s.mp4",
    "audio_url": "https://pub-582b7213209642b9b995c96c95a30381.r2.dev/test-audio/hg_audio17.mp3"
  }'

Output

{
  "request_id": "veed-lipsync-v2_019dxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
  "status": "QUEUED",
  "polling_url": "https://gateway.pixazo.ai/v2/requests/status/veed-lipsync-v2_019dxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
}

Webhook (Optional)

Instead of polling, you can receive a callback when the request reaches a terminal state. Pass the webhook headers on the submit request; the gateway will POST the result to your URL.

HeaderTypeRequiredDescription
X-Webhook-URLstringNoHTTPS URL to receive the callback. Providing it enables webhook delivery.
X-Webhook-ModestringNoterminal (default) fires once on COMPLETED/ERROR; sync fires on each status transition.

Example: enable webhook

curl -X POST "https://gateway.pixazo.ai/veed-lipsync-v2/v1/video-to-video/lip-sync" \
  -H "Content-Type: application/json" \
  -H "Ocp-Apim-Subscription-Key: YOUR_SUBSCRIPTION_KEY" \
  -H "X-Webhook-URL: https://your-server.com/webhooks/pixazo" \
  -H "X-Webhook-Mode: terminal" \
  --data-raw '{ "video_url": "https://pub-582b7213209642b9b995c96c95a30381.r2.dev/doc-assets/lipsync/talking-head-17s.mp4", "audio_url": "https://pub-582b7213209642b9b995c96c95a30381.r2.dev/test-audio/hg_audio17.mp3" }'

Callback Payload (success)

{
  "request_id": "veed-lipsync-v2_019dxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
  "status": "COMPLETED",
  "model_id": "veed-lipsync-v2",
  "output": {
    "media_url": ["https://pub-582b7213209642b9b995c96c95a30381.r2.dev/v1/veed-lipsync-v2_019dxxxx.../output.mp4"],
    "media_type": "video/mp4"
  }
}

Failure callback shape

{
  "request_id": "veed-lipsync-v2_019dxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
  "status": "ERROR",
  "error": "Failed to download the file. Please check if the URL is accessible."
}
  • terminal mode delivers one callback on COMPLETED or ERROR; sync mode delivers on each status transition.
  • Deliveries are keyed by request_id — make your handler idempotent.
  • Respond with HTTP 200 within a few seconds; non-2xx responses are retried.
  • The webhook URL must be HTTPS and publicly reachable.

Request Parameters

ParameterRequiredTypeDefaultAllowed values / rangeDescription
video_urlYesstring——Upload the talking-head video clip whose lips will be re-synced to your audio.
audio_urlYesstring——Upload the audio track to sync the video's lips to.

Content Item Types & Limits

TypeMaxFormat / SizeDescription
video1mp4, mov, webm, m4v, gif · up to 4K · ≤ 10 min · ≤ 5 GBSource video.
audio1mp3, ogg, wav, m4a, aac · ≤ 10 min · ≤ 5 GBVoice / audio track.

Example Request

{
  "video_url": "https://pub-582b7213209642b9b995c96c95a30381.r2.dev/doc-assets/lipsync/talking-head-17s.mp4",
  "audio_url": "https://pub-582b7213209642b9b995c96c95a30381.r2.dev/test-audio/hg_audio17.mp3"
}

Example Response

{
  "request_id": "veed-lipsync-v2_019dxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
  "status": "QUEUED",
  "polling_url": "https://gateway.pixazo.ai/v2/requests/status/veed-lipsync-v2_019dxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
}

Request Headers

HeaderRequiredDescription
Ocp-Apim-Subscription-KeyYesYour API subscription key.
Content-TypeYesMust be application/json.
X-Webhook-URLNoHTTPS callback URL (see Webhook section).

Response Handling

Common status codes returned by the submit endpoint.

Status CodeMeaning
202 AcceptedRequest queued. Returns request_id, status: "QUEUED", and polling_url.
400 Bad RequestInvalid request body or unknown model.
401 UnauthorizedMissing or invalid subscription key.
402 Payment RequiredInsufficient wallet balance.
403 ForbiddenSubscription not permitted to access this API.
429 Too Many RequestsRate limit exceeded.
500 Internal Server ErrorUnexpected gateway error.

Error Responses

Queue-system errors are returned at submit time; generation errors are surfaced via the status endpoint / webhook with status: "ERROR".

// 402 — insufficient balance
{ "error": "Insufficient balance", "message": "Wallet balance is too low for this request." }

// 400 — model not found / invalid body
{ "error": "Model not found", "message": "Model 'veed-lipsync-v2' not found or is disabled" }

// generation failure (via status / webhook)
{ "request_id": "veed-lipsync-v2_019dxxxx...", "status": "ERROR", "error": "Failed to download the input file." }

Retrieving Results

Poll the universal status endpoint to check progress and retrieve results.

Endpoint

GET https://gateway.pixazo.ai/v2/requests/status/{request_id}
Ocp-Apim-Subscription-Key: YOUR_API_KEY

cURL Example

curl -H "Ocp-Apim-Subscription-Key: YOUR_API_KEY" \
  "https://gateway.pixazo.ai/v2/requests/status/veed-lipsync-v2_019dxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"

Response (Completed)

{
  "request_id": "veed-lipsync-v2_019dxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
  "status": "COMPLETED",
  "model_id": "veed-lipsync-v2",
  "error": null,
  "output": {
    "media_url": [
      "https://pub-582b7213209642b9b995c96c95a30381.r2.dev/v1/veed-lipsync-v2_019dxxxx-xxxx/output.mp4"
    ],
    "media_type": "video/mp4"
  },
  "created_at": "2026-03-31T10:00:00.000Z",
  "updated_at": "2026-03-31T10:00:15.000Z",
  "completed_at": "2026-03-31T10:00:15.000Z"
}

Response Fields

FieldTypeDescription
request_idstringUnique identifier for the request.
statusstringQUEUED, PROCESSING, COMPLETED, FAILED, or ERROR.
model_idstringThe model that handled the request (veed-lipsync-v2).
errorstring | nullError message when the request fails; null otherwise.
output.media_urlstring[]Array of URLs to the generated lip-synced MP4 video.
output.media_typestringMIME type of the output (video/mp4).
created_atstringISO-8601 timestamp when the request was created.
completed_atstringISO-8601 timestamp when the request reached a terminal state.
polling_urlstringURL to poll for status (returned on submit).

Status Values & Flow

StatusMeaning
QUEUEDRequest accepted and waiting to be processed.
PROCESSINGThe lip-sync job is running.
COMPLETEDDone — output.media_url contains the synced video.
FAILED / ERRORGeneration failed — see error.

Typical workflow

QUEUED → PROCESSING → COMPLETED (or FAILED / ERROR). Submit the request, then poll GET /v2/requests/status/{request_id} (or use a webhook) until the status is terminal, then download the video from output.media_url.

Veed Lipsync 2.0 API Pricing

Your request will cost $0.07 per second of output video.
1-minute clip = $4.20
3. Veed Fabric 1.0

Veed Fabric 1.0 API Documentation

https://gateway.pixazo.ai/veed-fabric-1-0-api-130/v1/veed-fabric-1-0-api-request

Authentication

All requests require an API key passed via header.

Header Type Required Description
Ocp-Apim-Subscription-Key string Yes Your API subscription key

VEED Fabric 1.0 API generate request - VEED Fabric 1.0

Request Code

POST /veed-fabric-1-0-api-request HTTP/1.1
Host: gateway.pixazo.ai
Content-Type: application/json
Cache-Control: no-cache
Ocp-Apim-Subscription-Key: YOUR_SUBSCRIPTION_KEY

{
  "image_url": "https://pub-582b7213209642b9b995c96c95a30381.r2.dev/input_model.png",
  "audio_url": "https://pub-582b7213209642b9b995c96c95a30381.r2.dev/Oz_g4AwQvXtXpUHL3Pa7u_Hope.mp3",
  "resolution": "720p"
}
import requests

url = "https://gateway.pixazo.ai/veed-fabric-1-0-api-130/v1/veed-fabric-1-0-api-request"
headers = {
    "Content-Type": "application/json",
    "Cache-Control": "no-cache",
    "Ocp-Apim-Subscription-Key": "YOUR_SUBSCRIPTION_KEY"
}
data = {
    "image_url": "https://pub-582b7213209642b9b995c96c95a30381.r2.dev/input_model.png",
    "audio_url": "https://pub-582b7213209642b9b995c96c95a30381.r2.dev/Oz_g4AwQvXtXpUHL3Pa7u_Hope.mp3",
    "resolution": "720p"
}

response = requests.post(url, json=data, headers=headers)
print(response.json())
const url = "https://gateway.pixazo.ai/veed-fabric-1-0-api-130/v1/veed-fabric-1-0-api-request";

const data = {
  image_url: "https://pub-582b7213209642b9b995c96c95a30381.r2.dev/input_model.png",
  audio_url: "https://pub-582b7213209642b9b995c96c95a30381.r2.dev/Oz_g4AwQvXtXpUHL3Pa7u_Hope.mp3",
  resolution: "720p"
};

fetch(url, {
  method: "POST",
  headers: {
    "Content-Type": "application/json",
    "Cache-Control": "no-cache",
    "Ocp-Apim-Subscription-Key": "YOUR_SUBSCRIPTION_KEY"
  },
  body: JSON.stringify(data)
})
.then(response => response.json())
.then(data => console.log(data))
.catch(error => console.error("Error:", error));
curl -X POST "https://gateway.pixazo.ai/veed-fabric-1-0-api-130/v1/veed-fabric-1-0-api-request" \
  -H "Content-Type: application/json" \
  -H "Cache-Control: no-cache" \
  -H "Ocp-Apim-Subscription-Key: YOUR_SUBSCRIPTION_KEY" \
  --data-raw '{
    "image_url": "https://pub-582b7213209642b9b995c96c95a30381.r2.dev/input_model.png",
    "audio_url": "https://pub-582b7213209642b9b995c96c95a30381.r2.dev/Oz_g4AwQvXtXpUHL3Pa7u_Hope.mp3",
    "resolution": "720p"
  }'

Output

{
  "request_id": "veed-fabric-1-0-api-130_019dxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
  "status": "QUEUED",
  "polling_url": "/v2/requests/status/veed-fabric-1-0-api-130_019dxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
}

Webhook (Optional)

Add the X-Webhook-URL header to your submit request to receive a POST callback when the job completes — no polling required.

Using curl? These are HTTP request headers — pass each with -H, e.g. -H "X-Webhook-URL: https://your-server.com/webhook/callback". Do not paste them as bare lines, and end every line of a multi-line command with \.

Webhook Headers

HeaderRequiredDefaultDescription
X-Webhook-URLYes (to enable)—HTTPS endpoint on your server that will receive the POST callback. Must respond 2xx within a few seconds (process async if needed).
X-Webhook-ModeNoterminalterminal — fires once at the final status (COMPLETED/FAILED/ERROR). sync — fires on every poll cycle plus the terminal event, and caps the queue’s polling delay at 15s for tighter progress updates.

Example: enable webhook

X-Webhook-URL: https://your-server.com/webhook/callback
X-Webhook-Mode: terminal

Callback Payload

Your endpoint receives a POST application/json with the same shape as the GET /v2/requests/status/{request_id} response. Example terminal callback (mode terminal):

{
  "request_id": "veed-fabric-1-0-api-130_019dxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
  "status": "COMPLETED",
  "model_id": "veed-fabric-1-0-api-130",
  "error": null,
  "output": {
    "media_url": [
      "https://pub-582b7213209642b9b995c96c95a30381.r2.dev/v1/veed-fabric-1-0-api-130_019dxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx/output.png"
    ],
    "media_type": "image/png"
  },
  "created_at": "2026-05-22T13:17:32.110Z",
  "updated_at": "2026-05-22 13:19:23",
  "completed_at": "2026-05-22 13:19:23"
}

Failure callback shape

{
  "request_id": "veed-fabric-1-0-api-130_019dxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
  "status": "ERROR",
  "model_id": "veed-fabric-1-0-api-130",
  "error": "Description of the error",
  "output": null,
  "created_at": "...",
  "updated_at": "...",
  "completed_at": "..."
}

Delivery semantics

  • terminal mode (default) — exactly one POST when the request reaches a terminal status. No callback during PROCESSING.
  • sync mode — POST on every status poll (with delay capped at ~15s) plus a final POST at terminal status. Use when you want progress updates.
  • Idempotency — use request_id as your idempotency key. Network retries can deliver the same callback more than once; your handler must tolerate duplicates.
  • Response — respond 200 OK within a few seconds. The queue does not block on slow handlers, but persistent failures may stop further deliveries.
  • HTTPS required — plain http:// URLs are rejected.

Request Parameters - VEED Fabric 1.0 API generate request

ParameterRequiredTypeDefaultAllowed values / rangeDescription
image_urlYesstring—Publicly accessible HTTPS URL (max 2083 characters)Source image containing the face / avatar to animate. The face is animated and lip-synced to the supplied audio. Supported formats: JPG, PNG, WEBP.
audio_urlYesstring—Publicly accessible HTTPS URL (max 2083 characters)Audio track that drives the lip-sync and facial motion. The length of this audio determines the length of the generated video. Supported formats: MP3, WAV.
resolutionYesstring—"480p", "720p"Output resolution of the generated video. Required by the provider — there is no server-side default, so send it explicitly with every request.

Content Item Types & Limits

TypeMaxFormat / SizeDescription
image1JPG, PNG, WEBPPortrait / avatar image.
audio1MP3, WAVVoice / audio track.

Minimum Request

{
  "image_url": "https://pub-582b7213209642b9b995c96c95a30381.r2.dev/input_model.png",
  "audio_url": "https://pub-582b7213209642b9b995c96c95a30381.r2.dev/Oz_g4AwQvXtXpUHL3Pa7u_Hope.mp3",
  "resolution": "720p"
}

Full Request (all options)

{
  "image_url": "https://pub-582b7213209642b9b995c96c95a30381.r2.dev/input_model.png",
  "audio_url": "https://pub-582b7213209642b9b995c96c95a30381.r2.dev/Oz_g4AwQvXtXpUHL3Pa7u_Hope.mp3",
  "resolution": "720p"
}

Response

{
  "request_id": "veed-fabric-1-0-api-130_019dxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
  "status": "QUEUED",
  "polling_url": "/v2/requests/status/veed-fabric-1-0-api-130_019dxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
}

Request Headers

Header Value
Content-Type application/json
Cache-Control no-cache
Ocp-Apim-Subscription-Key Your subscription key

Response Handling

Common status codes for VEED Fabric 1.0 API generate request.

Code Meaning
202 Accepted — Request queued
Bad Request
401 Unauthorized
403 Forbidden
404 Not Found
Too Many Requests
500 Internal Server Error

Error Responses

Queue system errors and model validation errors.

Queue System Errors

// 402 — Insufficient balance
{
  "error": "Insufficient Balance",
  "message": "Your wallet does not have enough balance."
}
// 400 — Model not found
{
  "error": "Model not found",
  "message": "Model 'veed-fabric-1-0-api-130' not found or is disabled"
}

Error via Status/Webhook

{
  "request_id": "veed-fabric-1-0-api-130_019dxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
  "status": "ERROR",
  "model_id": "veed-fabric-1-0-api-130",
  "error": "Description of the error",
  "output": null
}

Retrieving Results

Poll the universal status endpoint to check progress and retrieve results.

Endpoint

GET /v2/requests/status/{request_id}
Ocp-Apim-Subscription-Key: YOUR_API_KEY

cURL Example

curl -H "Ocp-Apim-Subscription-Key: YOUR_API_KEY" \
  "/v2/requests/status/veed-fabric-1-0-api-130_019dxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"

Response (Completed)

{
  "request_id": "veed-fabric-1-0-api-130_019dxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
  "status": "COMPLETED",
  "model_id": "veed-fabric-1-0-api-130",
  "error": null,
  "output": {
    "media_url": [
      "https://pub-582b7213209642b9b995c96c95a30381.r2.dev/v1/veed-fabric-1-0-api-130_019dxxxx-xxxx/output.ext"
    ],
    "media_type": "application/octet-stream"
  },
  "created_at": "2026-03-31T10:00:00.000Z",
  "updated_at": "2026-03-31T10:00:15.000Z",
  "completed_at": "2026-03-31T10:00:15.000Z"
}

Response Fields

FieldTypeDescription
request_idstringUnique request identifier
statusstringQUEUED, PROCESSING, COMPLETED, FAILED, or ERROR
model_idstringModel that processed the request
errorstring|nullError message if failed
output.media_urlarrayURLs to generated media (R2 CDN)
output.media_typestringMIME type of the output
created_atstringWhen request was created
completed_atstring|nullWhen request completed
polling_urlstringStatus URL (initial response only)

Status Values

StatusDescription
QUEUEDRequest accepted, waiting to be processed
PROCESSINGBeing processed by the model
COMPLETEDDone — output contains the result
FAILEDFailed — check error field
ERRORSystem error — not charged

Status Flow

QUEUED → PROCESSING → COMPLETED
                    → FAILED
                    → ERROR

Typical Workflow

  1. Send a generate request to the API endpoint
  2. Save the request_id from the response
  3. Poll every 5-10 seconds: GET /v2/requests/status/{request_id}
  4. When status is "COMPLETED", download from output.media_url

Tip: Use X-Webhook-URL header to get a callback instead of polling.

Veed Fabric 1.0 API Pricing

ResolutionPrice (USD)
480p / per second$0.08
720p / per second$0.15
10-second 720p avatar ≈ $1.50
4. Veed 1.0

Veed 1.0 API Documentation

https://gateway.pixazo.ai/veed-video-background-remover-541/v1/veed-video-background-remover-request

Authentication

All requests require an API key passed via header.

Header Type Required Description
Ocp-Apim-Subscription-Key string Yes Your API subscription key

Veed Video Background Remover generate request - Veed Video Background Remover

Request Code

POST https://gateway.pixazo.ai/veed-video-background-remover-541/v1/veed-video-background-remover-request
Content-Type: application/json
Cache-Control: no-cache
Ocp-Apim-Subscription-Key: YOUR_SUBSCRIPTION_KEY

{
  "video_url": "https://pub-582b7213209642b9b995c96c95a30381.r2.dev/kandinsky-5-0-pro-953/ijNirwcnwvZ0VLVPIylDF_output.mp4",
  "output_codec": "vp9",
  "refine_foreground_edges": true,
  "subject_is_person": true
}
import requests

url = "https://gateway.pixazo.ai/veed-video-background-remover-541/v1/veed-video-background-remover-request"
headers = {
    "Content-Type": "application/json",
    "Cache-Control": "no-cache",
    "Ocp-Apim-Subscription-Key": "YOUR_SUBSCRIPTION_KEY"
}
data = {
    "video_url": "https://pub-582b7213209642b9b995c96c95a30381.r2.dev/kandinsky-5-0-pro-953/ijNirwcnwvZ0VLVPIylDF_output.mp4",
    "output_codec": "vp9",
    "refine_foreground_edges": true,
    "subject_is_person": true
}

response = requests.post(url, json=data, headers=headers)
print(response.json())
const url = "https://gateway.pixazo.ai/veed-video-background-remover-541/v1/veed-video-background-remover-request";
const headers = {
  "Content-Type": "application/json",
  "Cache-Control": "no-cache",
  "Ocp-Apim-Subscription-Key": "YOUR_SUBSCRIPTION_KEY"
};
const data = {
  video_url: "https://pub-582b7213209642b9b995c96c95a30381.r2.dev/kandinsky-5-0-pro-953/ijNirwcnwvZ0VLVPIylDF_output.mp4",
  output_codec: "vp9",
  refine_foreground_edges: true,
  subject_is_person: true
};

fetch(url, {
  method: "POST",
  headers: headers,
  body: JSON.stringify(data)
})
.then(response => response.json())
.then(data => console.log(data))
.catch(error => console.error("Error:", error));
curl -X POST "https://gateway.pixazo.ai/veed-video-background-remover-541/v1/veed-video-background-remover-request" \
  -H "Content-Type: application/json" \
  -H "Cache-Control: no-cache" \
  -H "Ocp-Apim-Subscription-Key: YOUR_SUBSCRIPTION_KEY" \
  --data-raw '{
    "video_url": "https://pub-582b7213209642b9b995c96c95a30381.r2.dev/kandinsky-5-0-pro-953/ijNirwcnwvZ0VLVPIylDF_output.mp4",
    "output_codec": "vp9",
    "refine_foreground_edges": true,
    "subject_is_person": true
  }'

Output

{
  "request_id": "veed-video-background-remover-541_019dxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
  "status": "QUEUED",
  "polling_url": "https://gateway.pixazo.ai/v2/requests/status/veed-video-background-remover-541_019dxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
}

Webhook (Optional)

Add the X-Webhook-URL header to your submit request to receive a POST callback when the job completes — no polling required.

Using curl? These are HTTP request headers — pass each with -H, e.g. -H "X-Webhook-URL: https://your-server.com/webhook/callback". Do not paste them as bare lines, and end every line of a multi-line command with \.

Webhook Headers

HeaderRequiredDefaultDescription
X-Webhook-URLYes (to enable)—HTTPS endpoint on your server that will receive the POST callback. Must respond 2xx within a few seconds (process async if needed).
X-Webhook-ModeNoterminalterminal — fires once at the final status (COMPLETED/FAILED/ERROR). sync — fires on every poll cycle plus the terminal event, and caps the queue’s polling delay at 15s for tighter progress updates.

Example: enable webhook

X-Webhook-URL: https://your-server.com/webhook/callback
X-Webhook-Mode: terminal

Callback Payload

Your endpoint receives a POST application/json with the same shape as the GET /v2/requests/status/{request_id} response. Example terminal callback (mode terminal):

{
  "request_id": "veed-video-background-remover-541_019dxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
  "status": "COMPLETED",
  "model_id": "veed-video-background-remover-541",
  "error": null,
  "output": {
    "media_url": [
      "https://pub-582b7213209642b9b995c96c95a30381.r2.dev/v1/veed-video-background-remover-541_019dxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx/output.mp4"
    ],
    "media_type": "video/mp4"
  },
  "created_at": "2026-05-22T13:17:32.110Z",
  "updated_at": "2026-05-22 13:19:23",
  "completed_at": "2026-05-22 13:19:23"
}

Failure callback shape

{
  "request_id": "veed-video-background-remover-541_019dxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
  "status": "ERROR",
  "model_id": "veed-video-background-remover-541",
  "error": "Description of the error",
  "output": null,
  "created_at": "...",
  "updated_at": "...",
  "completed_at": "..."
}

Delivery semantics

  • terminal mode (default) — exactly one POST when the request reaches a terminal status. No callback during PROCESSING.
  • sync mode — POST on every status poll (with delay capped at ~15s) plus a final POST at terminal status. Use when you want progress updates.
  • Idempotency — use request_id as your idempotency key. Network retries can deliver the same callback more than once; your handler must tolerate duplicates.
  • Response — respond 200 OK within a few seconds. The queue does not block on slow handlers, but persistent failures may stop further deliveries.
  • HTTPS required — plain http:// URLs are rejected.

Request Parameters - Veed Video Background Remover generate request

ParameterRequiredTypeDefaultAllowed values / rangeDescription
video_urlYesstring—Public HTTP(S) URL, max 2,083 charactersThe video to remove the background from. Must be a publicly accessible URL (no authentication required).
output_codecNostringvp9vp9, h264Codec of the returned video. vp9 returns a single VP9 video with an alpha channel; h264 returns two videos (RGB and alpha) and is recommended for better RGB quality.
refine_foreground_edgesNobooleantruetrue, falseImproves the quality of the extracted subject’s edges. Set to false to skip edge refinement.
subject_is_personNobooleantruetrue, falseOptimizes segmentation for human subjects. Set to false when the subject is not a person (for example a product or an object).

Content Item Types & Limits

TypeMaxFormat / SizeDescription
video1MP4, MOVVideo to remove the background from.

Minimum Request

{
  "video_url": "https://pub-582b7213209642b9b995c96c95a30381.r2.dev/kandinsky-5-0-pro-953/ijNirwcnwvZ0VLVPIylDF_output.mp4"
}

Full Request (all options)

{
  "video_url": "https://pub-582b7213209642b9b995c96c95a30381.r2.dev/kandinsky-5-0-pro-953/ijNirwcnwvZ0VLVPIylDF_output.mp4",
  "output_codec": "vp9",
  "refine_foreground_edges": true,
  "subject_is_person": true
}

Response

{
  "request_id": "veed-video-background-remover-541_019dxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
  "status": "QUEUED",
  "polling_url": "https://gateway.pixazo.ai/v2/requests/status/veed-video-background-remover-541_019dxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
}

Request Headers

Header Value
Content-Type application/json
Cache-Control no-cache
Ocp-Apim-Subscription-Key Your API subscription key

Response Handling

Common status codes for Veed Video Background Remover generate request.

Code Meaning
202 Accepted — Request queued
Bad Request
401 Unauthorized
403 Forbidden
404 Not Found
Too Many Requests
500 Internal Server Error

Error Responses

Queue system errors and model validation errors.

Queue System Errors

// 402 — Insufficient balance
{
  "error": "Insufficient Balance",
  "message": "Your wallet does not have enough balance."
}
// 400 — Model not found
{
  "error": "Model not found",
  "message": "Model 'veed-video-background-remover-541' not found or is disabled"
}

Error via Status/Webhook

{
  "request_id": "veed-video-background-remover-541_019dxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
  "status": "ERROR",
  "model_id": "veed-video-background-remover-541",
  "error": "Description of the error",
  "output": null
}

Retrieving Results

Poll the universal status endpoint to check progress and retrieve results.

Endpoint

GET https://gateway.pixazo.ai/v2/requests/status/{request_id}
Ocp-Apim-Subscription-Key: YOUR_API_KEY

cURL Example

curl -H "Ocp-Apim-Subscription-Key: YOUR_API_KEY" \
  "https://gateway.pixazo.ai/v2/requests/status/veed-video-background-remover-541_019dxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"

Response (Completed)

{
  "request_id": "veed-video-background-remover-541_019dxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
  "status": "COMPLETED",
  "model_id": "veed-video-background-remover-541",
  "error": null,
  "output": {
    "media_url": [
      "https://pub-582b7213209642b9b995c96c95a30381.r2.dev/v1/veed-video-background-remover-541_019dxxxx-xxxx/output.ext"
    ],
    "media_type": "application/octet-stream"
  },
  "created_at": "2026-03-31T10:00:00.000Z",
  "updated_at": "2026-03-31T10:00:15.000Z",
  "completed_at": "2026-03-31T10:00:15.000Z"
}

Response Fields

FieldTypeDescription
request_idstringUnique request identifier
statusstringQUEUED, PROCESSING, COMPLETED, FAILED, or ERROR
model_idstringModel that processed the request
errorstring|nullError message if failed
output.media_urlarrayURLs to generated media (R2 CDN)
output.media_typestringMIME type of the output
created_atstringWhen request was created
completed_atstring|nullWhen request completed
polling_urlstringStatus URL (initial response only)

Status Values

StatusDescription
QUEUEDRequest accepted, waiting to be processed
PROCESSINGBeing processed by the model
COMPLETEDDone — output contains the result
FAILEDFailed — check error field
ERRORSystem error — not charged

Status Flow

QUEUED → PROCESSING → COMPLETED
                    → FAILED
                    → ERROR

Typical Workflow

  1. Send a generate request to the API endpoint
  2. Save the request_id from the response
  3. Poll every 5-10 seconds: GET /v2/requests/status/{request_id}
  4. When status is "COMPLETED", download from output.media_url

Tip: Use X-Webhook-URL header to get a callback instead of polling.

Veed 1.0 API Pricing

ModePrice (USD)
Refine edges ON / per second$0.0225
Refine edges OFF / per second$0.015
5. Veed Lipsync

Veed Lipsync API Documentation

POST https://gateway.pixazo.ai/veed-lipsync/v1/video-to-video/lip-sync

Authentication

All requests require an API key passed via header.

HeaderTypeRequiredDescription
Ocp-Apim-Subscription-KeystringYesYour API subscription key

Video + Audio to Video - VEED Lipsync

Request Code

POST https://gateway.pixazo.ai/veed-lipsync/v1/video-to-video/lip-sync
Content-Type: application/json
Cache-Control: no-cache
Ocp-Apim-Subscription-Key: YOUR_SUBSCRIPTION_KEY

{
  "video_url": "https://pub-582b7213209642b9b995c96c95a30381.r2.dev/doc-assets/lipsync/talking-head-17s.mp4",
  "audio_url": "https://pub-582b7213209642b9b995c96c95a30381.r2.dev/test-audio/hg_audio17.mp3"
}
import requests

url = "https://gateway.pixazo.ai/veed-lipsync/v1/video-to-video/lip-sync"
headers = {
    "Content-Type": "application/json",
    "Ocp-Apim-Subscription-Key": "YOUR_SUBSCRIPTION_KEY"
}
payload = {
    "video_url": "https://pub-582b7213209642b9b995c96c95a30381.r2.dev/doc-assets/lipsync/talking-head-17s.mp4",
    "audio_url": "https://pub-582b7213209642b9b995c96c95a30381.r2.dev/test-audio/hg_audio17.mp3"
}

resp = requests.post(url, headers=headers, json=payload)
print(resp.json())  # { "request_id": "...", "status": "QUEUED", "polling_url": "..." }
const res = await fetch("https://gateway.pixazo.ai/veed-lipsync/v1/video-to-video/lip-sync", {
  method: "POST",
  headers: {
    "Content-Type": "application/json",
    "Ocp-Apim-Subscription-Key": "YOUR_SUBSCRIPTION_KEY"
  },
  body: JSON.stringify({
    video_url: "https://pub-582b7213209642b9b995c96c95a30381.r2.dev/doc-assets/lipsync/talking-head-17s.mp4",
    audio_url: "https://pub-582b7213209642b9b995c96c95a30381.r2.dev/test-audio/hg_audio17.mp3"
  })
});
const data = await res.json();
console.log(data); // { request_id, status: "QUEUED", polling_url }
curl -X POST "https://gateway.pixazo.ai/veed-lipsync/v1/video-to-video/lip-sync" \
  -H "Content-Type: application/json" \
  -H "Cache-Control: no-cache" \
  -H "Ocp-Apim-Subscription-Key: YOUR_SUBSCRIPTION_KEY" \
  --data-raw '{
    "video_url": "https://pub-582b7213209642b9b995c96c95a30381.r2.dev/doc-assets/lipsync/talking-head-17s.mp4",
    "audio_url": "https://pub-582b7213209642b9b995c96c95a30381.r2.dev/test-audio/hg_audio17.mp3"
  }'

Output

{
  "request_id": "veed-lipsync_019dxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
  "status": "QUEUED",
  "polling_url": "https://gateway.pixazo.ai/v2/requests/status/veed-lipsync_019dxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
}

Webhook (Optional)

Instead of polling, you can receive a callback when the request reaches a terminal state. Pass the webhook headers on the submit request; the gateway will POST the result to your URL.

HeaderTypeRequiredDescription
X-Webhook-URLstringNoHTTPS URL to receive the callback. Providing it enables webhook delivery.
X-Webhook-ModestringNoterminal (default) fires once on COMPLETED/ERROR; sync fires on each status transition.

Example: enable webhook

curl -X POST "https://gateway.pixazo.ai/veed-lipsync/v1/video-to-video/lip-sync" \
  -H "Content-Type: application/json" \
  -H "Ocp-Apim-Subscription-Key: YOUR_SUBSCRIPTION_KEY" \
  -H "X-Webhook-URL: https://your-server.com/webhooks/pixazo" \
  -H "X-Webhook-Mode: terminal" \
  --data-raw '{ "video_url": "https://pub-582b7213209642b9b995c96c95a30381.r2.dev/doc-assets/lipsync/talking-head-17s.mp4", "audio_url": "https://pub-582b7213209642b9b995c96c95a30381.r2.dev/test-audio/hg_audio17.mp3" }'

Callback Payload (success)

{
  "request_id": "veed-lipsync_019dxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
  "status": "COMPLETED",
  "model_id": "veed-lipsync",
  "output": {
    "media_url": ["https://pub-582b7213209642b9b995c96c95a30381.r2.dev/v1/veed-lipsync_019dxxxx.../output.mp4"],
    "media_type": "video/mp4"
  }
}

Failure callback shape

{
  "request_id": "veed-lipsync_019dxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
  "status": "ERROR",
  "error": "Failed to download the file. Please check if the URL is accessible."
}
  • terminal mode delivers one callback on COMPLETED or ERROR; sync mode delivers on each status transition.
  • Deliveries are keyed by request_id — make your handler idempotent.
  • Respond with HTTP 200 within a few seconds; non-2xx responses are retried.
  • The webhook URL must be HTTPS and publicly reachable.

Request Parameters

ParameterRequiredTypeDefaultAllowed values / rangeDescription
video_urlYesstring——Upload the talking-head video clip whose lips will be re-synced to your audio.
audio_urlYesstring——Upload the audio track to sync the video's lips to.

Content Item Types & Limits

TypeMaxFormat / SizeDescription
video1MP4, MOVSource video.
audio1MP3, WAVVoice / audio track.

Example Request

{
  "video_url": "https://pub-582b7213209642b9b995c96c95a30381.r2.dev/doc-assets/lipsync/talking-head-17s.mp4",
  "audio_url": "https://pub-582b7213209642b9b995c96c95a30381.r2.dev/test-audio/hg_audio17.mp3"
}

Example Response

{
  "request_id": "veed-lipsync_019dxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
  "status": "QUEUED",
  "polling_url": "https://gateway.pixazo.ai/v2/requests/status/veed-lipsync_019dxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
}

Request Headers

HeaderRequiredDescription
Ocp-Apim-Subscription-KeyYesYour API subscription key.
Content-TypeYesMust be application/json.
X-Webhook-URLNoHTTPS callback URL (see Webhook section).

Response Handling

Common status codes returned by the submit endpoint.

Status CodeMeaning
202 AcceptedRequest queued. Returns request_id, status: "QUEUED", and polling_url.
400 Bad RequestInvalid request body or unknown model.
401 UnauthorizedMissing or invalid subscription key.
402 Payment RequiredInsufficient wallet balance.
403 ForbiddenSubscription not permitted to access this API.
429 Too Many RequestsRate limit exceeded.
500 Internal Server ErrorUnexpected gateway error.

Error Responses

Queue-system errors are returned at submit time; generation errors are surfaced via the status endpoint / webhook with status: "ERROR".

// 402 — insufficient balance
{ "error": "Insufficient balance", "message": "Wallet balance is too low for this request." }

// 400 — model not found / invalid body
{ "error": "Model not found", "message": "Model 'veed-lipsync' not found or is disabled" }

// generation failure (via status / webhook)
{ "request_id": "veed-lipsync_019dxxxx...", "status": "ERROR", "error": "Failed to download the input file." }

Retrieving Results

Poll the status endpoint with the request_id until status is COMPLETED (or FAILED/ERROR).

curl -X GET "https://gateway.pixazo.ai/v2/requests/status/veed-lipsync_019dxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx" \
  -H "Ocp-Apim-Subscription-Key: YOUR_SUBSCRIPTION_KEY"

Completed response

{
  "request_id": "veed-lipsync_019dxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
  "status": "COMPLETED",
  "model_id": "veed-lipsync",
  "error": null,
  "output": {
    "media_url": ["https://pub-582b7213209642b9b995c96c95a30381.r2.dev/v1/veed-lipsync_019dxxxx.../output.mp4"],
    "media_type": "video/mp4"
  },
  "created_at": "2026-06-30T09:20:33.812Z",
  "completed_at": "2026-06-30T09:22:19.000Z"
}

Response Fields

FieldTypeDescription
request_idstringUnique identifier for the request.
statusstringQUEUED, PROCESSING, COMPLETED, FAILED, or ERROR.
model_idstringThe model that handled the request (veed-lipsync).
errorstring | nullError message when the request fails; null otherwise.
output.media_urlstring[]Array of URLs to the generated lip-synced MP4 video.
output.media_typestringMIME type of the output (video/mp4).
created_atstringISO-8601 timestamp when the request was created.
completed_atstringISO-8601 timestamp when the request reached a terminal state.
polling_urlstringURL to poll for status (returned on submit).

Status Values & Flow

StatusMeaning
QUEUEDRequest accepted and waiting to be processed.
PROCESSINGThe lip-sync job is running.
COMPLETEDDone — output.media_url contains the synced video.
FAILED / ERRORGeneration failed — see error.

Typical workflow

QUEUED → PROCESSING → COMPLETED (or FAILED / ERROR). Submit the request, then poll GET /v2/requests/status/{request_id} (or use a webhook) until the status is terminal, then download the video from output.media_url.

Veed Lipsync API Pricing

Your request will cost $0.0067 per second of output video.
1-minute clip = $0.40

⚡ Performance

Live usage measured on Pixazo's gateway, split by model version. Generation time is how long a generation takes end-to-end (lower is better). Success rate is the percent of generations that complete (higher is better).

Show data for the last
Generations
1,400last 30d
~47 per day
Success rate
100.0%
of completed generations
Generation time
112.9savg
p95 103.1s
Requests
Sep 17max 300Oct 16
Veed LipsyncAvg 23/day
Veed Lipsync 2.0Avg 13/day
Veed Clean AudioAvg 10/day
Generation Time
Sep 17max 2.8minOct 16
Veed LipsyncAvg 2.3min
Veed Lipsync 2.0Avg 2.1min
Veed Clean AudioAvg 54.1s
Error Rate
Sep 17max 5.0%Oct 16
Veed LipsyncAvg 0.0%
Veed Lipsync 2.0Avg 0.0%
Veed Clean AudioAvg 0.0%

〰 Uptime

Percent of generations that succeeded over the selected period, per model version.

Avg. Success Rate (30d)
100.00%
across all generations of this model family
Uptime
Sep 17max 100%Oct 16
Veed LipsyncAvg 100.00%
Veed Lipsync 2.0Avg 100.00%
Veed Clean AudioAvg 100.00%