Mobile apps

LivePair is a plain REST API — no SDK needed. If your app can fetch, it can generate. One rule matters more than any library:

Never ship your lp_ key inside an app binary. API keys are prepaid money — anything embedded in a shipped IPA/APK is extractable in minutes, and someone else's traffic bills your credits. Put the key on your own backend; the app talks to you, your backend talks to LivePair.

The pattern

app (auth as YOUR user)  →  your backend (holds lp_ key)  →  livepairai.com/v1/agent/*

Minimal backend (any language — this is Node):

// POST /generate on YOUR server
const res = await fetch("https://livepairai.com/v1/agent/generate", {
  method: "POST",
  headers: { "Content-Type": "application/json", "x-api-key": process.env.LP_KEY },
  body: JSON.stringify({ model: "qwen-image-3", prompt: userPrompt }),
});
const { jobId } = await res.json();
// poll /v1/agent/jobs/{jobId} server-side or hand the id back for the app to poll
// via a second endpoint — either way the key never leaves your server.

Generation is async: generate returns a jobId, GET /v1/agent/jobs/{jobId} polls until status: "done" with a media URL. Renders auto-delete after 48h — if your app needs persistence, copy the file to your own storage when the job completes.

Client snippets (talking to YOUR backend)

React Native / Expo:

const r = await fetch("https://your-backend.example.com/generate", {
  method: "POST",
  headers: { "Content-Type": "application/json", Authorization: `Bearer ${userToken}` },
  body: JSON.stringify({ prompt }),
});
const { jobId } = await r.json(); // then poll your backend's /jobs/{jobId}

Flutter:

final r = await http.post(
  Uri.parse("https://your-backend.example.com/generate"),
  headers: {"Authorization": "Bearer $userToken", "Content-Type": "application/json"},
  body: jsonEncode({"prompt": prompt}),
);
final jobId = jsonDecode(r.body)["jobId"];

Swift (iOS):

var req = URLRequest(url: URL(string: "https://your-backend.example.com/generate")!)
req.httpMethod = "POST"
req.setValue("Bearer \(userToken)", forHTTPHeaderField: "Authorization")
req.setValue("application/json", forHTTPHeaderField: "Content-Type")
req.httpBody = try JSONEncoder().encode(["prompt": prompt])
let (data, _) = try await URLSession.shared.data(for: req)

Kotlin (Android):

val req = Request.Builder()
    .url("https://your-backend.example.com/generate")
    .addHeader("Authorization", "Bearer $userToken")
    .post("""{"prompt":"$prompt"}""".toRequestBody("application/json".toMediaType()))
    .build()
val res = client.newCall(req).execute()

Prototyping directly (dev only)

For a local dev build where key exposure doesn't matter, hitting the API straight is fine — same endpoints, x-api-key header, job polling as above. Just never ship it.

Billing model

Per result, from prepaid credits — no subscription. Failed or rejected generations don't charge. Full endpoint contract: API reference · Getting started · OpenAPI at https://livepairai.com/v1/agent/openapi.json.