BeatAPI Ecommerce Video API

Create product ad video tasks from product images and duration.

Operations 1

POST /v1/ecommerce-video/tasks Create an Ecommerce Video workflow task #

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/beatapi:beatapi-ecommerce-video-api"
All apis
curl "https://apis.io/api/v1/apis?limit=25"

Discovery needs no key. Ratings and market analysis are Pro.

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

beatapi-ecommerce-video-api-openapi.yml Raw ↑
openapi: 3.2.0
info:
  title: BeatAPI Developer Ecommerce Video API
  version: 1.0.0-launch
  license:
    name: BeatAPI Terms of Service
    url: https://beatapi.io/terms-of-service
  description: 'BeatAPI provides one API key for public text models, image generation, video generation,

    video analysis, Effects, asynchronous video workflows, and short-lived Realtime Video Sessions.


    For asynchronous operations, create a task, poll the shared task endpoint or receive webhook events,

    and read hosted output URLs from `output.media`. For Realtime, create a Session on a trusted server

    with your Bearer API key and pass only the returned short-lived `client_secret` to the browser.


    Customer balances and usage are USD-denominated. Compatibility fields such

    as `credit_balance` and `credits_reserved` remain in the API; 1 Credit = $1 USD.


    ## 5 minute Quick Start


    1. Set your base URL to `https://api.beatapi.io`.

    2. Create an API key in Dashboard → API Keys

    and send it as

    `Authorization: Bearer `.

    USD balance top-ups are available from

    Dashboard → Billing.

    3. Use public HTTPS URLs for input media. If your files are local, upload

    them with `POST /v1/files` first.

    4. Create a workflow task.

    5. Poll every 5-10 seconds until `status` is `succeeded` or `failed`.

    6. Add webhooks later if you do not want to poll.


    ```bash

    read -rsp "BeatAPI API key: " BEATAPI_API_KEY && echo

    export BEATAPI_API_KEY


    curl https://api.beatapi.io/v1/workflows


    curl https://api.beatapi.io/v1/music-video/tasks \

    -H "Authorization: Bearer $BEATAPI_API_KEY" \

    -H "Content-Type: application/json" \

    -d ''{

    "images": ["https://cdn.beatapi.io/samples/neon-singer.png"],

    "audio_url": "https://cdn.beatapi.io/samples/neon-singer-preview.mp3",

    "prompt": "Neon rooftop performance with cinematic light trails.",

    "language": "en",

    "resolution": "720p"

    }''


    curl https://api.beatapi.io/v1/tasks/task_8K2qA \

    -H "Authorization: Bearer $BEATAPI_API_KEY"

    ```


    ## How tasks work


    A task starts as `queued` or `processing`. Keep polling

    `GET /v1/tasks/{task_id}` every 5-10 seconds with a little jitter. Stop when

    the task is `succeeded` or `failed`.


    - `queued`: accepted and waiting for platform capacity.

    - `processing`: generation is running.

    - `storyboard_ready`: Music Video storyboard shots are available.

    - `requires_action`: choose storyboard shots and call compose.

    - `editing`: a storyboard shot edit is running.

    - `composing`: selected storyboard shots are being composed.

    - `succeeded`: output is ready in `output.media[]`.

    - `failed`: no usable output was produced. Inspect `error_code`,

    `error_message`, and `usage` for the final task result.


    The current 10 minute processing window is an operational timeout for launch

    testing, not a completion SLA.


    ## Inputs and limits


    Public workflow inputs must use HTTPS URLs that are reachable from the

    public internet. Localhost, private network URLs, and data URLs are rejected.

    Use `POST /v1/files` for local images, audio, subtitles, or Motion Control reference videos.


    Each verified new user account starts with a $2 welcome balance that never expires and

    1 active processing concurrency. Lifetime paid purchases unlock higher limits:

    $10+ = 2, $100+ = 5, $1,000+ = 10, $5,000+ = 15, and $20,000+ = 30.

    `GET /v1/usage` returns current usage totals, concurrency limit, and active

    processing task count. Active concurrency measures tasks that are currently

    using BeatAPI processing resources. storyboard_ready and requires_action

    tasks can have settled USD usage but do not count toward active processing

    concurrency.


    ## Webhooks are optional


    Polling is the simplest integration path. If you add webhooks, BeatAPI sends

    `task.succeeded` and `task.failed` events. Webhook delivery failures do not

    change task status; polling remains the source of truth.'
servers:
- url: https://api.beatapi.io
tags:
- name: Ecommerce Video
  description: Create product ad video tasks from product images and duration.
paths:
  /v1/ecommerce-video/tasks:
    post:
      operationId: createEcommerceVideoTask
      tags:
      - Ecommerce Video
      x-apidog-folder: Ecommerce Video API
      summary: Create an Ecommerce Video workflow task
      security:
      - BearerAuth: []
      parameters:
      - in: header
        name: Idempotency-Key
        required: false
        schema:
          type: string
        description: Optional retry key. Reusing the same key with the same request body returns the accepted task; reusing it with a different body returns `409 idempotency_conflict`.
        example: ecommerce-create-cus_123-01
      description: 'Ecommerce Video creates a complete product video from public HTTPS product or

        lifestyle images, an explicit duration, and optional creative direction. Upload

        local images with `POST /v1/files`, save the returned Task ID, and poll

        `GET /v1/tasks/{task_id}` until the task succeeds or fails.'
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              required:
              - images
              - duration
              properties:
                images:
                  type: array
                  minItems: 1
                  maxItems: 7
                  description: Primary product or scene image first, followed by up to six additional public HTTPS PNG, JPEG, or WebP product or lifestyle images. Upload local files with `POST /v1/files` and use the returned `data.url`.
                  items:
                    type: string
                    format: uri
                duration:
                  type: integer
                  minimum: 10
                  maximum: 60
                  description: Required target output duration in seconds and the basis for USD calculation. Allowed range is 10-60 seconds.
                prompt:
                  type: string
                  maxLength: 2000
                  description: Optional creative direction, audience, product benefit, offer, tone, scenes, or call to action. Maximum 2000 characters.
                aspect_ratio:
                  type: string
                  enum:
                  - '16:9'
                  - '9:16'
                  - '1:1'
                  description: Target output placement. Use 16:9 for landscape, 9:16 for vertical social, or 1:1 for square placements; set explicitly for stable layout.
                language:
                  type: string
                  enum:
                  - en
                  - zh
                  description: Dialogue and narration language. Use `en` for English or `zh` for Chinese; set explicitly when the prompt contains mixed languages.
            example:
              images:
              - https://cdn.beatapi.io/samples/smart-bottle.png
              duration: 15
              prompt: Fast product launch ad for paid social.
              aspect_ratio: '9:16'
      responses:
        '201':
          description: Task accepted
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/TaskResponse'
              example:
                data:
                  id: task_p9Lm2
                  object: task
                  task_kind: workflow
                  capability_id: ecommerce-video
                  capability_version: 1
                  workflow: ecommerce-video
                  status: queued
                  stage: queued
                  created_at: 1782210000
                  updated_at: 1782210000
                  completed_at: null
                  output: null
                  usage:
                    credits_reserved: 4.5
                    credits_charged: 4.5
                    billable_duration_seconds: 15
                    credits_settled: 0
                    credits_refunded: 0
                  request_id: req_def456
                  error_code: null
                  error_message: null
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '402':
          $ref: '#/components/responses/InsufficientCredits'
        '403':
          $ref: '#/components/responses/Forbidden'
        '409':
          $ref: '#/components/responses/Conflict'
        '429':
          $ref: '#/components/responses/RateLimited'
        '500':
          $ref: '#/components/responses/InternalError'
        '503':
          $ref: '#/components/responses/ProcessingUnavailable'
components:
  schemas:
    TaskUsage:
      type: object
      required:
      - credits_reserved
      - credits_settled
      - credits_refunded
      - credits_charged
      properties:
        credits_reserved:
          type: number
          format: double
          multipleOf: 0.01
          description: USD amount reserved for this task. The compatibility field name is retained; 1 Credit equals $1 USD.
        credits_charged:
          type: number
          format: double
          multipleOf: 0.01
          description: USD amount charged. `0` on a failed task, because the reserved amount was returned.
        billable_duration_seconds:
          type: integer
          description: Server-detected or request-declared billable duration used for USD calculation.
        credits_settled:
          type: number
          format: double
          multipleOf: 0.01
          description: USD amount settled after successful work.
        credits_refunded:
          type: number
          format: double
          multipleOf: 0.01
          description: USD amount returned after a failed task. On a failed task `credits_reserved` is the amount held at create, `credits_charged` and `credits_settled` are `0`, and `credits_refunded` is the amount returned.
    TaskStatus:
      type: string
      enum:
      - queued
      - processing
      - storyboard_ready
      - requires_action
      - editing
      - composing
      - succeeded
      - failed
    Error:
      type: object
      required:
      - error
      properties:
        error:
          type: object
          description: Structured BeatAPI error. Use `code` (or `retryable`) for program logic and retain `request_id` for support.
          required:
          - code
          - message
          - request_id
          properties:
            code:
              type: string
              description: 'Stable machine-readable error code. `unauthorized` is the legacy name for a 401; since 2026-09-29 a 401 is `missing_api_key` or `invalid_api_key`, but `unauthorized` may still appear. Treat it like `invalid_api_key`. `result_expired` is returned only by `POST /v1/capabilities/run` with `operation: "result"`.'
              enum:
              - bad_request
              - missing_api_key
              - invalid_api_key
              - unauthorized
              - forbidden
              - not_found
              - insufficient_credits
              - idempotency_conflict
              - rate_limit_exceeded
              - content_policy_violation
              - processing_unavailable
              - processing_failed
              - processing_timeout
              - result_transfer_failed
              - result_expired
              - not_implemented
              - realtime_disabled
              - realtime_capacity_unavailable
              - realtime_session_expired
              - origin_not_allowed
              - invalid_client_secret
              - transport_not_allowed
              - internal_error
            message:
              type: string
              description: English sentence that states the cause; for `bad_request` it names the field. Written for people and logs, not for parsing.
            retryable:
              type: boolean
              description: Whether making the same call again could succeed. Present for every code in the public table; it may be absent only for a code outside the table. True for rate_limit_exceeded, internal_error, processing_unavailable, processing_timeout, processing_failed, result_transfer_failed and realtime_capacity_unavailable. False for a request, key or balance that must change first (bad_request, content_policy_violation, missing_api_key, invalid_api_key, unauthorized, insufficient_credits, forbidden, not_found, idempotency_conflict, result_expired, not_implemented, realtime_disabled and the other realtime credential codes).
            request_id:
              type: string
              description: Correlation ID to retain for BeatAPI support.
            retry_after_seconds:
              type: integer
              description: Seconds to wait before retrying. Sent only with a 429 `rate_limit_exceeded`, and the same value is sent in the `Retry-After` header. No other code carries it.
            docs:
              type: string
              format: uri
              description: The public Skill page that says what to do about an error. Present on errors answered by the capability endpoints (`/v1/capabilities/search`, `/v1/capabilities/inspect`, `/v1/capabilities/run`); absent on every other endpoint.
    Task:
      type: object
      required:
      - id
      - object
      - task_kind
      - capability_id
      - capability_version
      - status
      - stage
      - created_at
      - updated_at
      - completed_at
      - output
      - usage
      - request_id
      - error_code
      - error_message
      properties:
        id:
          type: string
          description: Stable BeatAPI task ID used for polling and support.
          example: task_8K2qA
        object:
          type: string
          enum:
          - task
          description: Object discriminator; always `task`.
        task_kind:
          type: string
          enum:
          - workflow
          - effect
          - image
          - video
          - data
          description: Public task family that determines which capability fields are present. `data` is a data capability run as a task (`data:web.research`), polled through `POST /v1/capabilities/run`.
        capability_id:
          type: string
          description: Stable BeatAPI workflow, Effect, generation model, or data capability ID (such as `web.research`) selected when the task was accepted.
        capability_version:
          type: integer
          description: Always `1`.
        workflow:
          type: string
          enum:
          - music-video
          - ecommerce-video
          - video-analysis
          description: Present for workflow tasks; identifies the selected BeatAPI workflow.
          example: music-video
        effect_id:
          type: string
          description: Present for Effect tasks; stable selected Effect ID.
          example: video-muscle-max
        effect_version:
          type: integer
          description: Present for Effect tasks; immutable Effect version used for processing.
          example: 1
        media_type:
          type: string
          enum:
          - image
          - video
          description: Present when task_kind is image or video.
        model:
          type: string
          description: Stable BeatAPI model alias. It is independent from internal execution routing.
        status:
          $ref: '#/components/schemas/TaskStatus'
          description: Current task lifecycle status. Stop polling at `succeeded` or `failed`; Music Video can also require manual action.
        stage:
          $ref: '#/components/schemas/TaskStatus'
          description: Always repeats `status`. Kept for compatibility; read `status`.
        storyboard:
          $ref: '#/components/schemas/Storyboard'
          description: Music Video storyboard metadata when available.
        created_at:
          type: integer
          description: Unix timestamp when BeatAPI accepted the task.
        updated_at:
          type: integer
          description: Unix timestamp of the latest task update.
        completed_at:
          type:
          - integer
          - 'null'
          description: Terminal Unix timestamp, or null while work is in progress.
        poll_after_seconds:
          type: integer
          description: 'Present while the task is running: how long to wait before the next status call (5 for images, 8 for video and Effects, 10 for workflows and data tasks). Follow it instead of a fixed interval. Absent on a terminal task.'
          example: 8
        typical_seconds:
          type: object
          description: 'Present while the task is running, when enough recent finishes exist: how long this task''s model recently took from accepted to succeeded, measured on this gateway. Past `p90` with no change the task is running long; there is no ETA beyond that.'
          required:
          - p50
          - p90
          - samples
          - window
          properties:
            p50:
              type: integer
              description: Median seconds.
            p90:
              type: integer
              description: Ninetieth-percentile seconds.
            samples:
              type: integer
              description: Finished tasks the figures rest on.
            window:
              type: string
              description: The window measured, such as `7d`.
        output:
          description: Output is null until the task succeeds.
          oneOf:
          - type: 'null'
          - type: object
            required:
            - media
            - r2_url
            properties:
              media:
                type: array
                description: BeatAPI-hosted result assets.
                items:
                  type: object
                  required:
                  - type
                  - url
                  - mime_type
                  properties:
                    type:
                      type: string
                      enum:
                      - image
                      - video
                      description: Result asset type.
                    url:
                      type: string
                      format: uri
                      description: BeatAPI-hosted HTTPS result URL.
                    mime_type:
                      type: string
                      description: Result asset MIME type.
                      examples:
                      - video/mp4
                      - image/png
                      - image/jpeg
                      - image/webp
              r2_url:
                type: string
                format: uri
                deprecated: true
                description: Deprecated — read media[0].url. The primary asset's URL again (the video, else the first image), the same value as that media[].url, kept only for clients that read one URL.
          - type: object
            required:
            - text
            - usage
            - finish_reason
            properties:
              text:
                type: string
                description: Completed video analysis text.
              usage:
                type: object
                description: Measured token usage used for final USD settlement.
                required:
                - input_tokens
                - output_tokens
                - total_tokens
                properties:
                  input_tokens:
                    type: integer
                    minimum: 0
                    description: Tokens consumed by the prompt and video input.
                  output_tokens:
                    type: integer
                    minimum: 0
                    description: Tokens consumed by visible output and model reasoning.
                  total_tokens:
                    type: integer
                    minimum: 0
                    description: Total measured input and output tokens.
              finish_reason:
                type:
                - string
                - 'null'
                description: Why the model stopped generating.
          - type: object
            description: 'A data task''s result: the capability''s own result object, such as `web.research` with `research_notes` and `sources` (in a view: `items`).'
            required:
            - object
            additionalProperties: true
            properties:
              object:
                type: string
                description: The result type, such as `web.research`.
        usage:
          $ref: '#/components/schemas/TaskUsage'
          description: USD reservation, settlement, refund, and optional billable duration for this task.
        request_id:
          type: string
          description: Correlation ID to retain for logs and BeatAPI support.
          example: req_abc123
        error_code:
          type:
          - string
          - 'null'
          description: Machine-readable terminal failure code, or null when no task failure is recorded.
          example: processing_timeout
        error_message:
          type:
          - string
          - 'null'
          description: Human-readable terminal failure detail, or null when no task failure is recorded.
        retryable:
          type: boolean
          description: 'Present on a failed task: whether resubmitting could succeed. True when the task failed on our side or timed out (a failed task is not charged); false when it was refused for content or bad input. Same code-to-retryable rule as the error envelope.'
          example: true
    TaskResponse:
      type: object
      required:
      - data
      properties:
        data:
          $ref: '#/components/schemas/Task'
          description: Accepted or current BeatAPI task state.
    Storyboard:
      type: object
      required:
      - shots
      properties:
        shots:
          type: array
          description: Ordered Music Video storyboard shots. The array may be empty before storyboard generation completes.
          items:
            $ref: '#/components/schemas/StoryboardShot'
    StoryboardShot:
      type: object
      required:
      - id
      - index
      - status
      - created_at
      - updated_at
      properties:
        id:
          type: string
          description: BeatAPI shot id. Use this id for media retrieval, edit, and compose operations.
          example: shot_xxx
        index:
          type: integer
          description: Zero-based shot order in the storyboard.
          example: 0
        status:
          $ref: '#/components/schemas/TaskStatus'
          description: Current lifecycle state for this storyboard shot.
        duration_seconds:
          type: integer
          description: Planned or generated shot duration in seconds.
          example: 5
        prompt:
          type: string
          description: Creative instruction used to generate this shot.
          example: Opening lyric shot.
        lyric_text:
          type: string
          description: Lyric segment aligned with this shot when available.
          example: Intro
        media:
          type: object
          description: Present only after the shot media has been materialized or after a shot edit finishes.
          properties:
            type:
              type: string
              description: Hosted media type for the materialized shot.
              example: video
            url:
              type: string
              format: uri
              description: BeatAPI-hosted HTTPS URL for the materialized shot.
              example: https://media.beatapi.io/outputs/task_8K2qA/shots/0.mp4
            mime_type:
              type: string
              description: MIME type of the hosted shot media.
              example: video/mp4
        created_at:
          type: integer
          description: Unix timestamp when the shot record was created.
          example: 1782210000
        updated_at:
          type: integer
          description: Unix timestamp when the shot record last changed.
          example: 1782210300
  responses:
    Unauthorized:
      description: 'No API key (`missing_api_key`), or a key that is wrong, expired, disabled or exhausted (`invalid_api_key`; the message says which). Send it as `Authorization: Bearer <key>`; the key works with or without the `sk-` prefix. Not retryable.'
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error'
          example:
            error:
              code: invalid_api_key
              message: 'Invalid or inactive API key. Send it as Authorization: Bearer <key>; the key works with or without the sk- prefix.'
              retryable: false
              request_id: req_xxx
    Forbidden:
      description: The key or account is not permitted to make this call (`forbidden`), for example a model that is not available on free credit (a top-up unlocks it), a request from outside the key's IP allowlist, or a model outside the key's group. Not retryable.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error'
          example:
            error:
              code: forbidden
              message: This model is not available on free credit. Top up to use it.
              retryable: false
              request_id: req_xxx
    BadRequest:
      description: Malformed JSON or a field, value or combination this endpoint does not accept (`bad_request`; the message names the field), or input refused by moderation (`content_policy_violation`). Not retryable unchanged.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error'
          example:
            error:
              code: bad_request
              message: images must contain 1-7 public HTTPS URLs.
              retryable: false
              request_id: req_xxx
    InsufficientCredits:
      description: Insufficient balance (`insufficient_credits`). The account balance is zero or below the price of this request. Top up, then send it again; not retryable before that.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error'
          example:
            error:
              code: insufficient_credits
              message: Account balance is not sufficient for this task.
              retryable: false
              request_id: req_xxx
    InternalError:
      description: Unexpected internal error (`internal_error`). Retryable; keep `request_id` for support if it persists.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error'
          example:
            error:
              code: internal_error
              message: Internal error. Contact support with the request_id if the problem continues.
              retryable: true
              request_id: req_xxx
    Conflict:
      description: The `Idempotency-Key` was already used with a different request body or path within 24 hours, or the first request with it is still running (`idempotency_conflict`). Not retryable unchanged.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error'
          example:
            error:
              code: idempotency_conflict
              message: This Idempotency-Key was already used with a different request body.
              retryable: false
              request_id: req_xxx
    ProcessingUnavailable:
      description: The request could not be completed (`processing_unavailable`, `processing_timeout`, `processing_failed` or `result_transfer_failed`). Nothing was charged. Retryable with backoff; a 503 carries no `Retry-After` header and no `retry_after_seconds`. BeatAPI does not answer 502 or 504.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error'
          example:
            error:
              code: processing_unavailable
              message: This model is temporarily unavailable on our side. Retry in a few minutes or use another model; this request was not charged.
              retryable: true
              request_id: req_xxx
    RateLimited:
      description: Too many requests (`rate_limit_exceeded`, including the free-model limits). Retryable after `Retry-After` seconds (also `error.retry_after_seconds`).
      headers:
        Retry-After:
          description: Seconds to wait before retrying the request.
          schema:
            type: integer
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error'
          example:
            error:
              code: rate_limit_exceeded
              message: Too many polling requests. Poll every 5-10 seconds.
              retryable: true
              request_id: req_xxx
              retry_after_seconds: 12
  securitySchemes:
    BearerAuth:
      type: http
      scheme: bearer
      bearerFormat: sk_xxx
      description: 'Send your API key as `Authorization: Bearer <BEATAPI_API_KEY>`.'
    PersonalAccessToken:
      type: http
      scheme: bearer
      bearerFormat: nap_xxx
      description: 'Send the account''s personal access token as `Authorization: Bearer <token>`. Create it on the Dashboard''s Account security page. API keys are not accepted.'
    ApiKeyHeader:
      type: apiKey
      in: header
      name: x-api-key
      description: Anthropic-compatible API key header. Use a BeatAPI API key.
    GoogleApiKeyHeader:
      type: apiKey
      in: header
      name: x-goog-api-key
      description: Gemini-compatible API key header. Use a BeatAPI API key.
    GoogleApiKeyQuery:
      type: apiKey
      in: query
      name: key
      description: Gemini SDK compatibility only. Prefer the x-goog-api-key header when possible.
externalDocs:
  description: BeatAPI documentation
  url: https://docs.beatapi.io