Disclosure: I'm Blare Lewis and I run VELIN, the API used in the examples. The pattern works with any submit-then-poll image API.
Most image APIs I tried behave like chat APIs: one request, one response. Modern image models don't. A 4K generation with reference images can take 45–100 seconds, so a synchronous request will time out behind most proxies and serverless platforms. Here is the pattern that works.
1. Submit, then poll
// Node 18+, no dependencies
const BASE = "https://72agi.com";
const KEY = process.env.VELIN_API_KEY;
async function submit(prompt, model = "nano-banana-pro", size = "1:1", resolution = "4K") {
const fd = new FormData();
fd.append("prompt", prompt);
fd.append("model", model);
fd.append("size", size);
fd.append("resolution", resolution);
const r = await fetch(`${BASE}/api/generate`, { method: "POST", headers: { Authorization: `Bearer ${KEY}` }, body: fd });
if (r.status === 429) throw new Error("rate limited");
if (r.status === 402) throw new Error("not enough credits");
return (await r.json()).id; // HTTP 202 {"id": "...", "status": "queued"}
}
async function wait(id, maxMs = 180000) {
const t0 = Date.now();
while (Date.now() - t0 < maxMs) {
const t = await (await fetch(`${BASE}/api/task/${id}`, { headers: { Authorization: `Bearer ${KEY}` } })).json();
if (t.status === "succeeded") return BASE + t.url;
if (t.status === "failed") throw new Error(t.error);
await new Promise(r => setTimeout(r, 4000)); // poll every 3–5 s
}
throw new Error("timeout");
}
2. Respect the rate limit with a small queue
The default limit is 8 single-image generations per minute per account. A tiny concurrency limiter beats retry storms:
async function pool(items, worker, size = 4) {
const out = []; let i = 0;
await Promise.all(Array.from({ length: size }, async () => {
while (i < items.length) { const n = i++; out[n] = await worker(items[n]).catch(e => ({ error: String(e) })); }
}));
return out;
}
3. Add reference images
Send repeated multipart fields named refs (up to 14 files, 8 MB each) for product-on-background or style-consistency jobs.
4. Download results immediately
Don't rely on the result URL staying available forever, so copy the file to your own storage in the same job.
What it costs (worked example)
For 1,000 product shots at 4K with Nano Banana Pro:
- Google's published list price is $0.24 per 4K image, which is about $240.
- At a flat $0.037 per image, VELIN is about $37. Failed generations are not charged, so you don't budget for retries. The flat price comes from stable bulk supply, and the same price applies at 1K, 2K and 4K. If your images are 1K, other providers may be cheaper, so compare on your actual resolution mix.
Limits (please read before you build on it)
- Async only (45–100 s per image), backend calls only (no CORS headers).
- USDT top-up only for now, cards are coming soon.
- Not OpenAI-compatible; it has its own small REST API.
- Moderation matches the upstream providers.
Examples in Python, Node, curl and an importable n8n workflow: https://github.com/velin-api/velin-image-api. Docs: https://72agi.com/docs.html. A free test is available on request (see the repo README).
— Blare Lewis, VELIN
Top comments (0)