Genace

Image generation API: what changes when you move from a UI to code

Most people arrive here from a web UI where you type a prompt and wait. Four things change when the same models are behind an API.

1. You get a job, not an image

{ "job_id": "abc123", "state": "queued", "credits_held": 4 }

Poll it, stream it, or receive a webhook. The upside is that nothing has to stay connected — the downside is that a failed job arrives as a successful HTTP response describing a failure, and your error handling will not catch it unless you check state.

2. Billing is per call, not per month

ModelCredits per imageBatchResolution
Flux5up to 4480p, 720p, 1080p
Nano Banana4up to 4480p, 720p, 1080p
Ideogram6up to 4480p, 720p, 1080p

No subscription tier gates which model you can use. You hold a credit balance and each call draws down from it; failed jobs refund in full.

3. There are ceilings, and they are per key

TierRequests per minuteConcurrent jobs
Free51
Pro605

One in-flight job on the free tier. Exceeding either returns a 429 — and the two 429s need opposite responses, so branch on error.code rather than the status. See api rate limit exceeded and CONCURRENCY_LIMIT_EXCEEDED.

4. Parameters are validated locally

A value outside a model’s schema fails before anything is submitted, with the offending field named in error.param. No credits are touched. Each model has a different schema — see AI image API for the per-model references.

The minimal working call

curl -X POST https://genace.ai/api/v1/images/generations \
  -H "Authorization: Bearer $GENACE_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"prompt":"a red ceramic mug on a white table"}'

No model needed — it defaults to Nano Banana at 4 credits ($0.04 at the Enterprise rate).

Models covered on this page

Where these facts come from

  • codebase: src/ai/providers/*.ts — every pricing() and paramsSchema
  • codebase: src/ai/api/quota.ts — per-tier ceilings