Every API here is available over the APIs.io API and to AI agents over MCP.
MCP server
One button, every client — Claude, Cursor, VS Code and the rest.
https://apis.io/mcp
Tools for apis
7 MCP tools reach this
find_apisBrowse and filter every API in the catalog.
get_api_artifactsOne API's artifacts, grouped by type.
get_openapiThe primary OpenAPI for this API.
find_similar_apisAPIs that look like this one.
apis_io_searchSTART HERE — APIs, providers and tags for one query, each with its total.
resolveTurn a domain, URL or GitHub org into the provider it belongs to.
find_cohortsEvery scored population of providers in the catalog.
All 92 tools →
Call it yourself
curl for this page
This API
curl "https://apis.io/api/v1/apis/budgetpixel:budgetpixel-lip-sync-api"
All apis
curl "https://apis.io/api/v1/apis?limit=25"
Calls without X-API-Key need no key. Calls with it need a paid plan — get a key.
Get an API key
Free tier, no form to fill in. Signing in shares your email address with us — we
store it to create your key and to recognise you if you sign in with another
provider. See our Privacy Policy and
Terms.
A second provider on the same verified email joins the account you already have.
openapi: 3.2.0
info:
title: Budgetpixel Lip Sync API
version: '2026-06-20'
contact:
email: support@budgetpixel.com
name: BudgetPixel Support
description: 'Operations tagged Lip Sync across 2 of this provider''s published API definitions: budgetpixel-openapi.yaml, budgetpixel-openapi.yml. Each path carries the servers of the definition it was published in.'
servers:
- description: Production
url: https://api.budgetpixel.com/v1
security:
- ApiKeyAuth: []
tags:
- name: Lip Sync
paths:
/lip-sync/{id}:
get:
description: 'Poll until `status` is `succeeded`. The generated video is returned as a
short-lived signed `video_url` (valid for several hours; re-call for a fresh
URL anytime — the underlying object is deleted 24h after generation).'
operationId: getLipSyncJob
parameters:
- description: The opaque job id returned by the create endpoint (e.g. `lip_...`).
in: path
name: id
required: true
schema:
type: string
responses:
'200':
content:
application/json:
schema:
$ref: '#/components/schemas/LipSyncJob'
description: Current job status. `video_url` is populated once succeeded.
'401':
$ref: '#/components/responses/Unauthorized'
'403':
$ref: '#/components/responses/Forbidden'
'404':
$ref: '#/components/responses/NotFound'
summary: Get lip sync job status
tags:
- Lip Sync
servers:
- description: Production
url: https://api.budgetpixel.com/v1
/lip-sync/omni-human-1.5:
post:
description: 'BytePlus OmniHuman 1.5 — animates the person (or character/pet) in an image to speak the input audio with synchronized lips, facial expression, and body motion. Priced per second of the input audio, rounded UP to whole seconds (135 credits/second — e.g. a 12.4s clip bills as 13s).
**Asynchronous.** Returns a job `id` (the video is not in this response). Poll `GET /v1/lip-sync/{id}` until `status` is `succeeded` — the video URL is in that response''s `video_url`.'
operationId: createLipSync_omni_human_1_5
requestBody:
content:
application/json:
schema:
properties:
audio:
description: The speech/audio to lip-sync (mp3/wav, up to 60 seconds, max 5 MB). A public audio URL, a data URI, raw base64, or an uploaded-file URL from POST /v1/uploads.
type: string
image:
description: The subject to animate — a human face/portrait, character, or pet. A public image URL, a data URI, raw base64, or an uploaded-file URL from POST /v1/uploads. jpg/png/webp.
type: string
output_resolution:
default: 1080
description: Output resolution (same price for both).
enum:
- 720
- 1080
type: integer
prompt:
description: Optional text prompt to guide the animation style or actions.
type: string
required:
- image
- audio
type: object
required: true
responses:
'200':
content:
application/json:
schema:
$ref: '#/components/schemas/CreateMotionResponse'
description: Job accepted.
'400':
$ref: '#/components/responses/BadRequest'
'401':
$ref: '#/components/responses/Unauthorized'
'403':
$ref: '#/components/responses/Forbidden'
'429':
$ref: '#/components/responses/TooManyRequests'
summary: Lip sync with OmniHuman 1.5
tags:
- Lip Sync
servers:
- description: Production
url: https://api.budgetpixel.com/v1
/lip-sync/p-video-avatar:
post:
description: 'P-Video Avatar — a talking avatar from one image and a speech clip. Priced per second of the input audio, rounded UP to whole seconds, by output resolution: 40 credits/second at 720p, 60 credits/second at 1080p (e.g. a 12.4s clip at 1080p bills as 13s x 60).
**Asynchronous.** Returns a job `id` (the video is not in this response). Poll `GET /v1/lip-sync/{id}` until `status` is `succeeded` — the video URL is in that response''s `video_url`.'
operationId: createLipSync_p_video_avatar
requestBody:
content:
application/json:
schema:
properties:
audio:
description: The speech/audio to lip-sync (mp3/wav, up to 30 seconds, max 5 MB). A public audio URL, a data URI, raw base64, or an uploaded-file URL from POST /v1/uploads.
type: string
image:
description: The avatar image (a person facing the camera works best). A public image URL, a data URI, raw base64, or an uploaded-file URL from POST /v1/uploads. jpg/png/webp.
type: string
resolution:
default: 720p
description: Output resolution — sets the per-second price (720p = 40, 1080p = 60 credits/second).
enum:
- 720p
- 1080p
type: string
video_prompt:
description: Optional visual prompt describing how the person should appear or behave while speaking.
type: string
required:
- image
- audio
type: object
required: true
responses:
'200':
content:
application/json:
schema:
$ref: '#/components/schemas/CreateMotionResponse'
description: Job accepted.
'400':
$ref: '#/components/responses/BadRequest'
'401':
$ref: '#/components/responses/Unauthorized'
'403':
$ref: '#/components/responses/Forbidden'
'429':
$ref: '#/components/responses/TooManyRequests'
summary: Lip sync with P-Video Avatar
tags:
- Lip Sync
servers:
- description: Production
url: https://api.budgetpixel.com/v1
/lip-sync/omni-human-2.0:
post:
description: 'BytePlus OmniHuman 2.0 — the newest OmniHuman: animates the person (or character/pet) in an image to speak the input audio, with synchronized lips, expression, body motion and camera movement you can direct with a prompt. 720p; audio up to 120 seconds. Priced per second of the input audio, rounded UP to whole seconds, with a 4-second minimum (84 credits/second — e.g. a 12.4s clip bills as 13s, a 2.5s clip as 4s).
**Asynchronous.** Returns a job `id` (the video is not in this response). Poll `GET /v1/lip-sync/{id}` until `status` is `succeeded` — the video URL is in that response''s `video_url`.
Examples, sample output and pricing: OmniHuman 2.0'
operationId: createLipSync_omni_human_2_0
requestBody:
content:
application/json:
schema:
properties:
audio:
description: The speech/audio to lip-sync (mp3, wav or ogg, up to 120 seconds, max 15 MB; under 4 seconds is billed as 4). A public audio URL, a data URI, raw base64, or an uploaded-file URL from POST /v1/uploads.
type: string
x-bpx-media: audio
image:
description: The subject to animate — a human face/portrait, character, or pet. 300-6000 px a side, aspect ratio between 2:5 and 5:2. A public image URL, a data URI, raw base64, or an uploaded-file URL from POST /v1/uploads. jpg/png/webp.
type: string
x-bpx-media: image
prompt:
description: Optional text prompt to direct the scene, gestures and camera movement (Chinese, English, Japanese, Korean, Spanish or Indonesian).
type: string
required:
- image
- audio
type: object
required: true
responses:
'200':
content:
application/json:
schema:
$ref: '#/components/schemas/CreateMotionResponse_2'
description: Job accepted.
'400':
$ref: '#/components/responses/BadRequest'
'401':
$ref: '#/components/responses/Unauthorized'
'403':
$ref: '#/components/responses/Forbidden'
'429':
$ref: '#/components/responses/TooManyRequests_2'
summary: Lip sync with OmniHuman 2.0
tags:
- Lip Sync
servers:
- description: Production
url: https://api.budgetpixel.com/v1
components:
schemas:
Error:
properties:
error:
properties:
code:
description: Stable machine-readable code.
example: model_not_available
type: string
message:
type: string
type:
description: Error category.
example: invalid_request_error
type: string
required:
- type
- code
- message
type: object
required:
- error
type: object
LipSyncJob:
properties:
completed_at:
format: date-time
type: string
created_at:
format: date-time
type: string
error_message:
type: string
id:
type: string
model:
type: string
status:
description: Lifecycle state. `succeeded`/`failed`/`canceled` are terminal.
enum:
- pending
- processing
- succeeded
- failed
- canceled
type: string
video_url:
description: Short-lived presigned URL; present once `status=succeeded`.
format: uri
type: string
type: object
ModerationBlocked:
description: Returned (with HTTP 400) when the input content moderation gate blocks a generation request. The block is a property of the request's prompt or input media — reword the prompt or change the input and retry. Branch on `restriction_reason`, which is stable and machine-readable.
properties:
error:
description: Human-readable explanation of the block.
type: string
restriction_reason:
description: Stable machine-readable block reason.
enum:
- input_csam
- input_explicit_adult
- input_upload_nudity
- input_celebrity_likeness
- strict_model_nsfw
type: string
required:
- error
- restriction_reason
type: object
CreateMotionResponse:
properties:
credits:
description: Total price of this job (seconds x the model's per-second rate).
type: integer
id:
description: Opaque job id (`mtn_...`) — use it to poll status.
type: string
message:
type: string
model:
type: string
seconds:
description: Billed duration — the reference video's length
rounded up.: null
type: integer
status:
$ref: '#/components/schemas/JobStatus'
type: object
JobStatus:
description: Lifecycle state. `succeeded`/`failed`/`timeout` are terminal.
enum:
- pending
- starting
- processing
- completing
- succeeded
- failed
- timeout
type: string
QueueFull:
description: '`429` body when your account already has as many jobs of this kind
(image, video or audio) in flight as its concurrency cap allows. Submit
the next job when one of your running jobs finishes.
'
properties:
active_jobs:
description: Jobs of this kind in flight right now.
type: integer
code:
enum:
- queue_full
type: string
error:
description: Human-readable message.
type: string
queue_full:
enum:
- true
type: boolean
queue_limit:
description: Your concurrency cap for this kind of job.
type: integer
retry_after_seconds:
description: Same value as the `Retry-After` header.
type: integer
required:
- error
- code
- queue_full
- queue_limit
- active_jobs
- retry_after_seconds
type: object
LipSyncJob_2:
properties:
completed_at:
format: date-time
type: string
created_at:
format: date-time
type: string
error_message:
type: string
id:
type: string
model:
type: string
status:
description: Lifecycle state. `succeeded`/`failed`/`canceled` are terminal.
enum:
- pending
- processing
- succeeded
- failed
- canceled
type: string
video_codec:
description: Codec of the MP4 at `video_url`; present once `status=succeeded`. Lip-sync outputs are `h264`.
enum:
- h264
- h265
type: string
video_url:
description: Short-lived presigned URL; present once `status=succeeded`.
format: uri
type: string
type: object
CreateMotionResponse_2:
properties:
credits:
description: Total price of this job (seconds x the model's per-second rate).
type: integer
id:
description: Opaque job id (`mtn_...`) — use it to poll status.
type: string
message:
type: string
model:
type: string
seconds:
description: Billed duration — the reference video's length, rounded up.
type: integer
status:
$ref: '#/components/schemas/JobStatus'
type: object
responses:
TooManyRequests:
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
description: Rate or queue limit reached. Retry after a short delay.
NotFound:
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
description: The requested job was not found.
Unauthorized:
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
description: Missing or invalid API key.
BadRequest:
content:
application/json:
schema:
oneOf:
- $ref: '#/components/schemas/Error'
- $ref: '#/components/schemas/ModerationBlocked'
description: The request was malformed, referenced an unavailable model, or was blocked by input content moderation (moderation blocks carry a `restriction_reason` — see ModerationBlocked).
Forbidden:
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
description: Authenticated but not permitted (plan gate, ownership, account restriction). Content-moderation blocks are 400, not 403.
TooManyRequests_2:
content:
application/json:
schema:
oneOf:
- $ref: '#/components/schemas/Error'
- $ref: '#/components/schemas/QueueFull'
description: 'A limit was reached. Every `429` carries `Retry-After` (seconds). The
per-minute rate limit, the upload limit and the hourly API post cap answer
with the `Error` envelope, code `rate_limited`. The monthly spend limit answers with
code `monthly_spend_limit_reached`, and its `Retry-After` counts down to the
start of next month (raising the limit in the console clears it sooner).
A full concurrency queue answers with the flat `QueueFull` body (3D jobs:
the `Error` envelope with code `queue_full`); its `Retry-After` is a
suggested wait, because a slot frees as soon as one of your running jobs
finishes.
'
headers:
Retry-After:
description: Seconds to wait before retrying.
schema:
minimum: 1
type: integer
securitySchemes:
ApiKeyAuth:
bearerFormat: bpx_live_*
description: 'API key as a bearer token: Authorization: Bearer bpx_live_xxx'
scheme: bearer
type: http
x-refined-from:
- budgetpixel-openapi.yaml
- budgetpixel-openapi.yml