Developer API

Make AutoPersonify videos from your own software

One API key connects your CRM, reporting tool or AI coding assistant. Pick a presenter or your twin, send a script, get a finished video. Simple, secure and honest about errors.

In short: create a key in Integrations, call https://autopersonify.com/api/v1 from your server with Authorization: Bearer ap_live_…, and show error.user_message whenever something goes wrong.

How it works

  1. Sign in to AutoPersonify and, if you want, build your twin in the app (twins can only be made in the app, with a guided, consented recording).
  2. Go to Integrations → Developer API and create a key. It's shown once — store it as a server secret.
  3. List presenters or twins, then post a script to /videos. Poll or use a webhook until it's ready.

Videos use your normal plan minutes and also appear in your Projects, marked as made through the API.

Using Lovable or another AI coding agent

Paste this into Lovable, Cursor, Claude Code or any coding agent. It tells the agent where the docs are, to ask you for the key securely, and how to handle every error. Example: “Every morning, use my twin to summarise each client's PPC review and attach the video to the report.”

Integrate my AutoPersonify account so I can make AI presenter videos (with a stock presenter or my own digital twin) from this app.

1. Read the docs at https://autopersonify.com/developers.md (OpenAPI: https://autopersonify.com/openapi.json).
2. Ask me for my AutoPersonify API key and store it as a server-side secret named AUTOPERSONIFY_API_KEY. Never expose it to the browser.
3. Make all calls from server code to https://autopersonify.com/api/v1 with the header Authorization: Bearer <key>.
4. Build a page where I pick a presenter (GET /presenters, show thumbnail + preview video) or one of my twins (GET /twins, only those with usable_in_videos=true), type or generate a script, and create the video (POST /videos with an idempotency_key).
5. Track status by polling GET /videos/{id} every 10–15 seconds (or via webhook) and show the finished video_url in a player.
6. Handle every error exactly as the docs' error table says — always show error.user_message, and show an Upgrade button linking to error.upgrade_url when error.action is "upgrade".

Quick start

# 1. See who can present
curl https://autopersonify.com/api/v1/presenters -H "Authorization: Bearer $AUTOPERSONIFY_API_KEY"

# 2. Make a video (use twin_id instead of presenter_id for your twin)
curl -X POST https://autopersonify.com/api/v1/videos \
  -H "Authorization: Bearer $AUTOPERSONIFY_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"presenter_id":"<id>","script":"Hi Sarah, here is this week in your ads...","idempotency_key":"ppc-2026-09-26-client-42"}'

# 3. Check progress until status is "ready"
curl https://autopersonify.com/api/v1/videos/<video id> -H "Authorization: Bearer $AUTOPERSONIFY_API_KEY"
// JavaScript (server only)
const res = await fetch("https://autopersonify.com/api/v1/videos", {
  method: "POST",
  headers: { Authorization: `Bearer ${process.env.AUTOPERSONIFY_API_KEY}`, "Content-Type": "application/json" },
  body: JSON.stringify({ twin_id, script, idempotency_key: reportId }),
});
const body = await res.json();
if (!res.ok) throw Object.assign(new Error(body.error.user_message), body.error);
# Python
import os, requests
r = requests.post("https://autopersonify.com/api/v1/videos",
    headers={"Authorization": f"Bearer {os.environ['AUTOPERSONIFY_API_KEY']}"},
    json={"presenter_id": pid, "script": script, "idempotency_key": report_id})
data = r.json()
if not r.ok: print(data["error"]["user_message"])

Endpoints

GET/meAccount, plan and remaining video seconds
GET/presentersPresenters available to the API, with thumbnail and preview video
GET/twinsYour twins, and whether each can be used in videos
GET/voicesYour own starred voices
POST/videosMake a video from a script
GET/videos/{id}Status, progress, video link or friendly error
GET/videosRecent videos
DELETE/videos/{id}Delete a video

POST /videos fields: script (required, up to 3,000 characters), presenter_id or twin_id, optional voice_id, title, webhook_url and idempotency_key (the same key always returns the same video and is never charged twice). Videos usually take 2–10 minutes. The video_url is a private link valid for one hour — store the video id, not the link.

Errors and what to show people

Every error has code, user_message (written for your end user — show it as it is), action, retryable, and upgrade_url when a plan upgrade is needed. Only retry when retryable is true.

CodeHTTPMeaningWhat your app should do
invalid_api_key401The key is missing, mistyped or unknown.Ask the user for a new key (AutoPersonify → Integrations → Developer API). Don't retry.
key_revoked401The key was revoked.Ask the user to create a new key. Don't retry.
allowance_exceeded402The account has used its video minutes.Show user_message and a button to upgrade_url. Don't retry until they upgrade.
plan_required402A paid plan is needed (for example using a free-plan twin in a new video).Show user_message and link to upgrade_url.
twin_not_ready409The twin is still building.Tell the user and refresh the picker later.
not_found404Presenter, twin or video doesn't exist (or was deleted).Refresh the picker list and ask the user to choose again.
invalid_request400Missing or invalid fields; see error.fields.Fix the request. Show field messages if the user typed them.
script_too_long400Script exceeds the per-video character limit.Ask the user to shorten or split the script.
rate_limited429More than 60 requests or 10 video creates per minute.Wait for the Retry-After header, then retry.
concurrency_limit429Too many videos rendering at once.Wait for one to finish (Retry-After), then retry.
daily_limit429Daily video limit reached.Tell the user to try again tomorrow. Don't retry today.
render_failed500The video couldn't be made (also appears as video.error when status is failed).Show user_message. Offer one manual retry; if it fails again suggest contacting support.
service_unavailable503Temporary problem on our side.Retry with exponential backoff (e.g. 5s, 20s, 60s), at most 3 times, then show user_message.

If a video fails after it was accepted, GET /videos/{id} returns status: "failed" with error.user_message. Show it, keep the script so the person can retry with one tap, and never loop retries automatically.

Webhooks

Add a webhook address in Integrations to be told when API videos are ready or failed. We send video.ready or video.failed with the video object, signed with X-AutoPersonify-Signature: sha256=… = HMAC-SHA256(secret, timestamp + "." + raw body) and X-AutoPersonify-Timestamp.

Limits and security

  • 60 requests a minute per key; 10 new videos a minute; plan-based daily and at-once limits.
  • Keys are stored only as a secure fingerprint and shown once. Revoke any key instantly.
  • Call only from your server. Never put the key in a web page or mobile app.
  • Plans: Free (3 video minutes, no card required), Starter £49, Growth £149, Scale £499 a month.

Start free, no card required

Create your account, make your twin in the app, then connect everything else with one key.

Get your API key