BeatAPI Realtime Video API

Create and manage short-lived BeatAPI browser sessions for live AI video effects.

Operations 3

POST /v1/realtime/sessions Create a realtime browser session #
GET /v1/realtime/sessions/{session_id} Get a realtime session #
DELETE /v1/realtime/sessions/{session_id} Close a realtime session #

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-realtime-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-realtime-video-api-openapi.yml Raw ↑
openapi: 3.2.0
info:
  title: BeatAPI Developer Realtime 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: Realtime Video
  description: Create and manage short-lived BeatAPI browser sessions for live AI video effects.
paths:
  /v1/realtime/sessions:
    post:
      operationId: createRealtimeSession
      tags:
      - Realtime Video
      x-apidog-folder: Realtime Video API
      summary: Create a realtime browser session
      security:
      - BearerAuth: []
      description: 'Reserve the selected USD amount and allocate a short-lived BeatAPI realtime session. Send a unique

        `Idempotency-Key`; retries with the same user, key, and body return the same session

        and deterministic short-lived `client_secret` without reserving funds or capacity

        twice. The browser receives only that BeatAPI secret and connects with

        `@beatapi/realtime`.


        Billing is fixed by the selected maximum duration. The BeatAPI browser runtime sends its

        first billing heartbeat only after the first remote output frame is rendered. When that

        accepted BeatAPI billing heartbeat succeeds, the Session becomes `active` and the selected

        duration is fully settled. A Session that closes or expires without an accepted billing

        heartbeat is fully refunded. Billing activation comes from the trusted transport lifecycle,

        not a caller-supplied browser event.

        Production availability remains gated until the documented commercial and capacity launch

        checks pass.'
      parameters:
      - in: header
        name: Idempotency-Key
        required: true
        schema:
          type: string
          minLength: 1
          maxLength: 255
        example: rts-create-cus_123-01
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              required:
              - max_duration_seconds
              - allowed_origins
              properties:
                max_duration_seconds:
                  type: integer
                  enum:
                  - 15
                  - 60
                  - 300
                  description: Required maximum live session duration in seconds. The USD amount is reserved for the selected 15, 60, or 300 second tier.
                allowed_origins:
                  type: array
                  minItems: 1
                  maxItems: 10
                  description: Exact browser origins allowed to use the short-lived session secret.
                  items:
                    type: string
                    format: uri
                    pattern: ^(https://[A-Za-z0-9.-]+(?::[0-9]+)?|http://(?:localhost|127\\.0\\.0\\.1|\\[::1\\])(?::[0-9]+)?)$
                    description: Exact browser origin. Use HTTPS in production; HTTP is accepted only for localhost development.
                    example: https://app.example.com
                metadata:
                  type: object
                  maxProperties: 20
                  description: Optional server-defined string metadata for your own correlation. Up to 20 keys; keys are at most 64 characters and values at most 256 characters.
                  propertyNames:
                    maxLength: 64
                  additionalProperties:
                    type: string
                    maxLength: 256
            example:
              max_duration_seconds: 60
              allowed_origins:
              - https://app.example.com
              metadata:
                customer_id: cus_123
      responses:
        '201':
          description: Realtime session created
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/RealtimeSessionCreateResponse'
              example:
                data:
                  id: rts_8K2qA
                  object: realtime.session
                  status: ready
                  client_secret: brt_live_example_short_lived_secret
                  expires_at: '2026-08-12T10:01:00.000Z'
                  max_duration_seconds: 60
                  allowed_origins:
                  - https://app.example.com
                  credits:
                    reserved: 1.2
                    settled: 0
                    refunded: 0
                  request_id: req_abc123
                  created_at: '2026-08-12T10:00:00.000Z'
                  connected_at: null
                  closed_at: null
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '402':
          $ref: '#/components/responses/InsufficientCredits'
        '409':
          $ref: '#/components/responses/Conflict'
        '429':
          $ref: '#/components/responses/RateLimited'
        '503':
          description: Realtime Video is not enabled on this deployment (`realtime_disabled`, not retryable; no self-service action, contact support) or capacity is temporarily unavailable (`realtime_capacity_unavailable`, retryable; retry shortly with backoff, no delay is indicated).
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
  /v1/realtime/sessions/{session_id}:
    parameters:
    - in: path
      name: session_id
      required: true
      schema:
        type: string
        pattern: ^rts_
    get:
      operationId: getRealtimeSession
      tags:
      - Realtime Video
      x-apidog-folder: Realtime Video API
      summary: Get a realtime session
      security:
      - BearerAuth: []
      responses:
        '200':
          description: Realtime session
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/RealtimeSessionResponse'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '404':
          description: Realtime session not found
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
    delete:
      operationId: closeRealtimeSession
      tags:
      - Realtime Video
      x-apidog-folder: Realtime Video API
      summary: Close a realtime session
      security:
      - BearerAuth: []
      description: Idempotently closes the session, clears temporary credentials, and releases account capacity.
      responses:
        '200':
          description: Realtime session closed
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/RealtimeSessionResponse'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '404':
          description: Realtime session not found
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
components:
  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
    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
    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
    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
  schemas:
    RealtimeSessionResponse:
      type: object
      required:
      - data
      properties:
        data:
          $ref: '#/components/schemas/RealtimeSession'
    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.
    RealtimeSession:
      type: object
      required:
      - id
      - object
      - status
      - expires_at
      - max_duration_seconds
      - allowed_origins
      - credits
      - request_id
      - created_at
      - connected_at
      - closed_at
      properties:
        id:
          type: string
          pattern: ^rts_
          description: Stable Realtime Session ID used to inspect or close the session.
        object:
          type: string
          enum:
          - realtime.session
          description: Object discriminator; always `realtime.session`.
        status:
          type: string
          enum:
          - ready
          - connecting
          - active
          - closed
          - failed
          - expired
          description: Active means BeatAPI accepted the first billing heartbeat after remote output began.
        expires_at:
          type: string
          format: date-time
          description: Time when the unconnected short-lived session credential expires.
        max_duration_seconds:
          type: integer
          enum:
          - 15
          - 60
          - 300
          description: Maximum selected live duration and billing tier in seconds.
        allowed_origins:
          type: array
          description: Exact browser origins authorized to use this Session.
          items:
            type: string
            format: uri
            pattern: ^(https://[A-Za-z0-9.-]+(?::[0-9]+)?|http://(?:localhost|127\\.0\\.0\\.1|\\[::1\\])(?::[0-9]+)?)$
            description: Exact browser origin. Use HTTPS in production; HTTP is accepted only for localhost development.
            example: https://app.example.com
        credits:
          type: object
          required:
          - reserved
          - settled
          - refunded
          description: USD reservation, settlement, and refund lifecycle for this Realtime Session. Compatibility field names are retained.
          properties:
            reserved:
              type: number
              format: double
              multipleOf: 0.01
              description: USD amount reserved when the Session is created.
            settled:
              type: number
              format: double
              multipleOf: 0.01
              description: USD amount settled after the first accepted billing heartbeat.
            refunded:
              type: number
              format: double
              multipleOf: 0.01
              description: USD amount refunded if the Session ends without billing activation.
        request_id:
          type: string
          description: Correlation ID to retain for logs and BeatAPI support.
        created_at:
          type: string
          format: date-time
          description: Time when the Session was created.
        connected_at:
          type:
          - string
          - 'null'
          format: date-time
          description: Time of the first accepted BeatAPI billing heartbeat; null before billing activation.
        closed_at:
          type:
          - string
          - 'null'
          format: date-time
          description: Time when the Session closed, or null while it remains open.
    RealtimeSessionCreated:
      allOf:
      - $ref: '#/components/schemas/RealtimeSession'
      - type: object
        required:
        - client_secret
        properties:
          client_secret:
            type: string
            description: Short-lived BeatAPI browser credential returned only by POST. Never expose an sk_ API key to the browser.
            pattern: ^brt_live_
    RealtimeSessionCreateResponse:
      type: object
      required:
      - data
      properties:
        data:
          $ref: '#/components/schemas/RealtimeSessionCreated'
          description: Created Realtime Session including the one-time short-lived browser credential.
  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