BudgetPixel Lip Sync API

The Lip Sync API from BudgetPixel — 3 operation(s) for lip sync.

Business capability
Generative Media AE-110.20

Operations 4

GET /lip-sync/{id} Get lip sync job status #
POST /lip-sync/omni-human-1.5 Lip sync with OmniHuman 1.5 #
POST /lip-sync/p-video-avatar Lip sync with P-Video Avatar #
POST /lip-sync/omni-human-2.0 Lip sync with OmniHuman 2.0 #

Work with this as data

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 Specification

budgetpixel-lip-sync-api-openapi.yml Raw ↑
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