The OpenAI Python SDK is mostly a base_url and an api_key. If an API speaks the same shapes — /images/generations, /chat/completions, /videos — the SDK you already have installed works against it.
LivePair exposes exactly that surface: an OpenAI-compatible endpoint covering 60+ image and video generation models (Seedream, Seedance, Wan, Qwen Image, Ideogram, Minimax) plus a set of chat models. One base_url change, and client.images.generate() produces media from models that don't exist on OpenAI.
Disclosure: I work on LivePair. Everything below is runnable against the live API — the catalog, prices, and shapes are public at GET /v1/agent/models.
Setup
pip install openai requests
Grab a key: sign up at livepairai.com → Settings → API keys → lp_…. Billing is a prepaid credit balance — each call debits the per-model price, no subscription.
from openai import OpenAI
client = OpenAI(
base_url="https://livepairai.com/v1/agent",
api_key="lp_...", # sent as a Bearer token, so the stock SDK works
)
Images — client.images.generate just works
img = client.images.generate(
model="seedream-5.0",
prompt="a lighthouse on a cliff at dusk, cinematic lighting",
size="1024x1024",
)
print(img.data[0].url)
That's the unmodified OpenAI call. The catalog decides what model can be — seedream-5.0, qwen-image-3, ideogram-3-turbo, and so on. size accepts the standard 1024x1024 / 1792x1024 / 1024x1792 values and maps onto each model's aspect-ratio ladder.
Chat — client.chat.completions.create
r = client.chat.completions.create(
model="deepseek/deepseek-v4.1-flash",
messages=[{"role": "user", "content": "Explain the CAP theorem in two sentences."}],
max_tokens=256,
)
print(r.choices[0].message.content)
Video — Sora-shaped, poll-then-download
The video endpoint mirrors OpenAI's Videos API shape: POST /videos returns a job immediately, GET /videos/{id} polls status, GET /videos/{id}/content streams the mp4. Newer SDK releases have a client.videos namespace; here's the plain-HTTP version so the contract is visible:
import time, requests
H = {"Authorization": "Bearer lp_...", "Content-Type": "application/json"}
BASE = "https://livepairai.com/v1/agent"
job = requests.post(f"{BASE}/videos", headers=H, json={
"model": "wan-3.0-t2v",
"prompt": "drone shot over a foggy forest at dawn, slow push-in",
"size": "1280x720", # 16:9; 720x1280 → 9:16
"seconds": "5",
}).json()
vid = job["id"]
while True:
v = requests.get(f"{BASE}/videos/{vid}", headers=H).json()
if v["status"] in ("completed", "failed"):
break
time.sleep(5)
if v["status"] == "completed":
mp4 = requests.get(f"{BASE}/videos/{vid}/content", headers=H) # 302 → media URL
open("out.mp4", "wb").write(mp4.content)
Prices are data, not a pricing page
GET /v1/agent/models returns every model with a priceUsd field — the exact per-call debit before you make it:
models = requests.get(f"{BASE}/models").json()
for m in models["models"]:
print(m["id"], m["mode"], m["priceUsd"])
GET /v1/agent/balance shows your prepaid balance and recent ledger entries.
Why bother
The useful part isn't another API key — it's that image gen, video gen, and chat land on the same OpenAI surface you already integrate, priced per call against a balance you can watch. For pipelines that need several model families (compare outputs, fallback chains, cost routing), switching models is a string, not a new provider account.
There's also a no-account path if you're wiring autonomous agents: the same endpoints answer 402 Payment Required and settle per call in USDC via x402, so a client that can sign a payment header can call without any signup at all.
Gotchas
-
n> 1 isn't supported on image generation — loop instead. - Video is async by design; budget ~1–3 min per clip depending on model.
- A generation that fails provider-side refunds to the balance automatically.
- Results aren't published anywhere and are deleted after 48h — save the bytes.
Docs: livepairai.com/docs, machine-readable spec at /v1/agent/openapi.json, MCP server for agent clients under /mcp.
Top comments (0)