Browse documentation

AI Studio REST API

Personalize videos with the API.

Send recipient values to an existing AI Studio campaign, track each generation and retrieve its finished video.

Beta integration guide · qualification incomplete

REST release verification is on hold. Wait for qualification before provisioning new production REST credentials. Personalized video remains in beta. Fresh-account access, credential-error handling, insufficient-credit failures, Claude generation, Cursor IDE, and LeadR video preview and outreach are not yet fully qualified. Confirm your use case with support before production use.

Before your first request

This REST integration personalizes an existing AI Studio template or campaign. It does not create a Speakeasy presenter video from a prompt. Create an account at app.bhuman.ai, prepare your own source video, configure its variables, and create a campaign before calling the generation endpoint.

Use Settings → API Keys → Generate new key to obtain a Client ID and Client Secret. Your integration acts with the account's access. Use a campaign you own and media you have permission to use. An MCP key is a separate credential and cannot replace this Basic Authentication pair.

Review Settings → Plan & usage before generating. Free, Growth, Scale and Ultimate use account entitlements and available credits; key creation is not a promise of unlimited generation. Legacy and promotional balances may have product restrictions. If the needed product or credential control is unavailable, confirm eligibility with support before sending a paid request.

AI Studio generation consumes video credits. Standard personalized output normally uses one shared credit per video; alternate generation/quality paths can change the charge. Use the app's estimate for the exact campaign. Requests run against production; there is no documented free API sandbox or separate API latency SLA.

Authenticate with REST credentials

Base URL: https://studio.bhuman.ai. Generation requests use HTTP Basic Authentication: the Client ID is the username and the Client Secret is the password. curl --user constructs the header for you. Use private environment variables or a secret manager, and never use verbose HTTP logging with real credentials.

Set BHUMAN_CLIENT_ID and BHUMAN_CLIENT_SECRET privately in your terminal or server environment. Do not put real values in committed files, screenshots, shared chat, or browser code. The downloadable Python example prompts without echoing either value.

Basic Authentication header shape

HTTP
Authorization: Basic BASE64_OF_CLIENT_ID_COLON_CLIENT_SECRET

Quickstart: generate one personalized video

1. Create a ready AI Studio campaign with exactly one variable named first_name. Copy its campaign UUID. This example supplies only the replacement word Alex; the fixed greeting remains in the template.

2. Save the JSON below as campaign.json and replace the all-zero placeholder UUID with your owned campaign ID. Change variables and names together if your template uses different fields. Each row must contain one value for each variable, in the same order.

3. Review the campaign's credit cost and available balance, then send the POST once. The response envelope is {code: 200, result: [generation UUID, …]}. Acceptance queues work; it does not mean playback is ready. Save every returned ID before doing anything else.

4. Poll the individual ID endpoint below, starting about every 10 seconds. Read result.status, wait for succeeded and a nonempty result.url, and open the returned MP4. A failed status is terminal; read the safe message and keep the generation ID for support. Stop polling after your own deadline and resume checking the same ID later.

For an account-to-result command-line flow with hidden credential prompts, a single paid submission, saved IDs and bounded polling, download rest-quickstart.py. Run python3 rest-quickstart.py. It asks for the campaign ID and explicit confirmation before submitting. To match a different template, pass --variable name --value Alex with your actual field and value; optionally pass --callback-url YOUR_HTTPS_RECEIVER. Use python3 rest-quickstart.py --resume after an interrupted accepted run.

campaign.json · one recipient

JSON
{
  "campaign_id": "00000000-0000-0000-0000-000000000000",
  "generation_mode": "keep_original",
  "variables": ["first_name"],
  "names": [["Alex"]]
}
Download campaign.json

Submit once

cURL
curl --fail-with-body --request POST \
  'https://studio.bhuman.ai/api/ai_studio/pipeline/campaign' \
  --user "$BHUMAN_CLIENT_ID:$BHUMAN_CLIENT_SECRET" \
  --header 'Content-Type: application/json' \
  --data @campaign.json

Read one generation

cURL
curl --fail-with-body --get \
  'https://studio.bhuman.ai/api/ai_studio/generated_video_by_id' \
  --data-urlencode 'id=YOUR_RETURNED_GENERATION_UUID'

Request fields and defaults

POST /api/ai_studio/pipeline/campaign requires campaign_id, variables and names. campaign_id must be a UUID. variables is an ordered string array; names is a matrix of strings with matching row width. Supply replacement values without surrounding fixed template words.

Send generation_mode explicitly: keep_original retains the original recording outside personalized sections; full_script regenerates the full spoken script. Missing or blank mode defaults to keep_original in the documented API. These modes are independent of Speakeasy's Standard/HD quality choices.

callback_url is optional. If used, provide an HTTPS endpoint under your control. assets and backgrounds are optional advanced background inputs; asset rows must align with recipient rows and asset columns with timed background definitions. Leave them out of your first request.

  • Campaign generation accepts up to 2,000 recipient rows per request; begin with one.
  • Keep Original supports up to 100 personalized sections, each no longer than 10 seconds.
  • Do not send admin, provider, billing, or raw pipeline controls copied from internal examples.

Customer integration endpoints

POST /api/ai_studio/pipeline/campaign generates from an owned campaign; POST /api/ai_studio/try_sample generates from video_instance_id with the same ordered variables and names shape. These generation routes support integration Basic Authentication.

GET /api/ai_studio/generated_video_by_id?id=UUID retrieves an individual result by its returned ID. The current route uses possession of that ID rather than account authentication. Treat generation IDs and returned media links as sensitive; do not publish them or put them in shared logs.

Use the app to prepare your templates and campaigns, then use the individual result route or your callback to track integration requests. This reference covers supported customer integration endpoints.

Use the customer API reference alongside this guide. Product access and authentication requirements still apply to every request.

Asynchronous results and callbacks

The accepted generation response returns an array of UUIDs inside result. Individual polling returns {code, result: generatedVideo}. Read status and the optional message before using media fields. url is the MP4; share_url is the hosted viewing page; thumbnail and gif are optional previews. Do not assume every field is populated before success.

A campaign completion callback contains id, campaign_id, status, video_url (hosted page), url (MP4), thumbnail, gif and campaign_result_id. On failure, media strings may be empty. Save IDs at submission and match incoming events to your own records; handle repeated delivery without repeated downstream actions.

If WhatsApp video generation is enabled in the saved campaign, main completion and the later event=whatsapp.ready callback are separate. The later event supplies whatsapp_video_url. Missing WhatsApp output does not reverse main-video success. This optional path needs account-specific testing before use.

No signed-callback verification or delivery retry SLA is promised by this guide. Use an unguessable receiver URL, validate expected IDs, and reconcile results through polling before security-sensitive downstream actions.

Failures and safe retries

These REST generation examples do not provide a documented idempotency key. Repeating POST can create additional work and charges. Disable automatic POST retries. On a timeout or lost response, check the campaign in the app and contact support if the outcome is uncertain before resubmitting. Once IDs are known, repeat only the status GET.

Correct 400 validation failures before resubmitting. Missing or malformed fields can return 422 before authentication is evaluated. A structurally valid request with missing or invalid integration credentials returns 401. Read both the HTTP status and the response body's code/result/error fields.

Insufficient quota is a business error, not a transport failure; review Plan & usage. A queued render can later fail even after HTTP 200. Preserve its generation ID, use the customer-safe failure message, and confirm whether a retry will consume credits. Never assume that a failed HTTP request was uncharged.

Limits, access and credential rotation

There is no published fixed REST requests-per-minute guarantee. Use modest concurrency, bounded polling with backoff, and coordinate large batches with support. A transient 5xx or 429 is a reason to back off read requests; it is not permission to blindly repeat a paid POST.

REST credentials do not use the MCP key's 90-day expiry policy. Keep separate secrets for each integration and update deployments when rotating. Confirm the old pair is rejected after replacing it; do not assume rotation completed until you have tested it. Admin operations, credit adjustments and account-specific restricted features are outside this guide.