API Documentation
Generate creatives programmatically. Every generated image spends one credit from your subscription — the same balance the web app uses.
Authentication
Create an API key in Settings → API Keys. Pass it as a Bearer token on every request:
Authorization: Bearer cs_live_xxxxxxxxxxxxxxxxxxxxKeys are shown once at creation. Store them securely. Revoke a key anytime from Settings.
Generate creatives
Generation is asynchronous. You POST a request, get a jobId back immediately, then poll the job until it completes.
1. Create a job
POST creative-saas.vercel.app/api/v1/generate
Body parameters:
claim(string, required) — the topic / keyword.language(string, required) — one ofEN, ES, DE, FR, PT, IT.count(number, optional) — images to generate, 1–5. Default 3.
Optional header Idempotency-Key: repeating a request with the same key returns the original job instead of creating a new one (and does not double-spend credits).
curl -X POST creative-saas.vercel.app/api/v1/generate \
-H "Authorization: Bearer cs_live_xxxxxxxx" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: my-unique-id-123" \
-d '{"claim":"Best protein supplements","language":"EN","count":3}'Response (202 Accepted):
{
"jobId": "f1e2d3c4-...",
"status": "queued",
"pollUrl": "/api/v1/jobs/f1e2d3c4-...",
"result": { "requested": 3, "produced": 0, "progress": { "done": 0, "total": 3 } }
}2. Poll the job
GET creative-saas.vercel.app/api/v1/jobs/{jobId}
curl creative-saas.vercel.app/api/v1/jobs/f1e2d3c4-... \
-H "Authorization: Bearer cs_live_xxxxxxxx"Poll every ~2 seconds. status moves through queued → processing → completed (or partial / failed).
{
"jobId": "f1e2d3c4-...",
"status": "completed",
"creditsConsumed": 3,
"result": {
"requested": 3,
"produced": 3,
"failed": 0,
"images": ["https://.../image_1.png", "https://.../image_2.png", "..."],
"formats": ["F1", "F4", "F10"],
"failures": []
}
}Status values
queued/processing— keep polling.completed— all images generated.partial— some images failed; checkresult.failures. Only produced images were charged.failed— nothing produced; all credits refunded.
Example — Python
import time, requests
BASE = "creative-saas.vercel.app"
KEY = "cs_live_xxxxxxxx"
headers = {"Authorization": f"Bearer {KEY}"}
job = requests.post(
f"{BASE}/api/v1/generate",
headers=headers,
json={"claim": "Best protein supplements", "language": "EN", "count": 3},
).json()
job_id = job["jobId"]
while True:
time.sleep(2)
j = requests.get(f"{BASE}/api/v1/jobs/{job_id}", headers=headers).json()
if j["status"] in ("completed", "partial", "failed"):
print(j["result"])
breakExample — Node.js
const BASE = "creative-saas.vercel.app";
const KEY = "cs_live_xxxxxxxx";
const headers = { Authorization: `Bearer ${KEY}` };
const sleep = (ms) => new Promise((r) => setTimeout(r, ms));
const start = await fetch(`${BASE}/api/v1/generate`, {
method: "POST",
headers: { ...headers, "Content-Type": "application/json" },
body: JSON.stringify({ claim: "Best protein supplements", language: "EN", count: 3 }),
}).then((r) => r.json());
let job;
do {
await sleep(2000);
job = await fetch(`${BASE}/api/v1/jobs/${start.jobId}`, { headers })
.then((r) => r.json());
} while (["queued", "processing"].includes(job.status));
console.log(job.result);Errors
401— missing or invalid API key.402— insufficient credits. Upgrade your plan.400— invalid parameters (bad claim / language).404— job id not found (or not yours).500— server error. Safe to retry.
Rate limits are governed by your credit balance — you can't spend faster than you have credits. Need higher throughput? Upgrade to Business or contact us.