API reference

Put the studio
inside your pipeline.

A single HTTP interface across every image, video and music model. Submit a job, poll or receive a webhook, and read the result — with the credit cost returned on every response.

Private beta. The public API and self-serve API keys are rolling out to Studio accounts. The shapes below are stable and safe to build against — request access and we will enable keys on your account.

Overview

The API is REST over HTTPS with JSON bodies. Every path is prefixed with /api. Generation is asynchronous: you submit a job, get an id back immediately, then either poll the status endpoint or let a webhook tell you when it is done.

Base URL
https://api.ideovex.com,/api

Provider identity is deliberately never exposed. Media is served through Ideovex proxy URLs, so results keep working even if we move a model between providers.

Authentication

Send your API key as a bearer token on every request. Keys are scoped per environment, can be rotated without downtime, and carry their own rate limit.

Request
curl https://api.ideovex.com/api/models/catalog \
  -H "Authorization: Bearer $IDEOVEX_API_KEY"

Never ship a key in a browser bundle or mobile binary. Call the API from your own server and proxy the result to your client.

Generations

POST/api/generate/imageSubmit an image job
POST/api/generate/videoSubmit a video job
POST/api/generate/musicSubmit a music job
GET/api/generate/status/{id}Poll an image / video job
GET/api/generate/music/status/{id}Poll a music job
GET/api/generationsList your generations
DELETE/api/generations/{id}Delete a generation

Submitting a job

POST /api/generate/image
{
  "prompt": "a weathered brass diving helmet half-buried in wet sand,
             grey Atlantic beach at first light, 85mm, soft overcast light",
  "model": "mdl_nano_banana_pro",
  "aspect_ratio": "3:2",
  "num_images": 2
}
202 Accepted
{
  "generation_id": "gen_4ab482abb371",
  "status": "processing",
  "credits_used": 10,
  "queue_position": 1
}

Polling for the result

GET /api/generate/status/gen_4ab482abb371
{
  "generation_id": "gen_4ab482abb371",
  "status": "completed",
  "type": "image",
  "credits_used": 10,
  "result_url": "/api/media/image/gen_4ab482abb371",
  "all_results": [
    "/api/media/image/gen_4ab482abb371?i=0",
    "/api/media/image/gen_4ab482abb371?i=1"
  ]
}

Poll no faster than once every two seconds. status moves through queued → processing → completed, or lands on failed / timed_out — both of which refund the reserved credits automatically.

Video and music

Video accepts duration, resolution and an optional image_url for image-to-video models. Music accepts lyrics, style, title and instrumental, and is submitted to /api/generate/music then polled at /api/generate/music/status/{id}. Which fields a model honours is described on its catalogue entry.

Model catalogue

Always read the catalogue rather than hardcoding model ids — models are added, retired and health-gated continuously, and hidden models are filtered out of this response for you.

GET /api/models/catalog
{
  "image": [
    {
      "id": "mdl_nano_banana_pro",
      "name": "Nano Banana Pro",
      "cost": 5,
      "free": false,
      "mode": "t2i",
      "needs_image": false,
      "resolutions": ["1024x1024", "1024x1536", "1536x1024"]
    }
  ],
  "video": [ /* … */ ],
  "music": [ /* … */ ]
}

Credits

GET/api/user/creditsCurrent balance
GET/api/user/quotaDaily quota state
GET/api/user/concurrencySlots in use
GET/api/pricingPublic cost table

Check /api/user/concurrency before firing a batch. If no slot is free the job queues rather than erroring, but knowing the slot count lets you pace your own fan-out sensibly.

Webhooks

Rather than polling, register a callback URL in the studio under Developer → Webhooks and receive a POST the moment a job reaches a terminal state. Registration returns a whsec_ signing secret once — store it. Respond 2xx within ten seconds; we attempt delivery up to three times.

POST to your endpoint
{
  "event": "generation.completed",
  "timestamp": "2026-06-15T09:12:44Z",
  "data": {
    "generation_id": "gen_4ab482abb371",
    "type": "image",
    "status": "completed",
    "result_url": "/api/media/image/gen_4ab482abb371"
  }
}

Events: generation.started, generation.completed, generation.failed, generation.cancelled (or * for all). Each terminal event fires exactly once per generation.

Verifying the signature

Every request carries X-Webhook-Signature: sha256=<hex>, plus X-Webhook-Event and X-Webhook-Id. The signature is an HMAC-SHA256 of the raw request body keyed by your whsec_ secret. Compare it against the raw bytes you received — never against a re-serialised object — and reject anything that does not match.

Verify (Node.js / Express)
import crypto from "crypto";

app.post("/hooks/ideovex", express.raw({ type: "application/json" }), (req, res) => {
  const sig = (req.header("X-Webhook-Signature") || "").replace("sha256=", "");
  const expected = crypto.createHmac("sha256", process.env.IDEOVEX_WEBHOOK_SECRET)
    .update(req.body)               // req.body is the raw Buffer
    .digest("hex");
  const ok = crypto.timingSafeEqual(Buffer.from(sig), Buffer.from(expected));
  if (!ok) return res.status(400).send("bad signature");

  const { event, data } = JSON.parse(req.body);
  // data.result_url is ready — no need to poll
  res.sendStatus(200);
});

Errors & rate limits

Errors are JSON with a stable HTTP status. The message is safe to log but not to show to end users verbatim.

429 Too Many Requests
{
  "detail": "Rate limit exceeded. Retry after 12s."
}
StatusMeaningWhat to do
400Invalid or unavailable model / bad parametersRe-read the catalogue
401Missing or revoked keyRotate the key
402Not enough creditsTop up, then retry
403Account not verified, or scope missingCheck key scopes
429Rate or quota limit hitBack off using the headers
503Upstream capacity unavailableRetry with jitter

Every response carries X-RateLimit-Limit, X-RateLimit-Remaining and X-RateLimit-Reset. Drive your backoff from those rather than from a fixed sleep, and always add jitter when you retry.

Idempotency

Send an X-Idempotency-Key header on submissions. A repeat of the same key inside twenty-four hours returns the original generation instead of charging twice — the safe way to retry after a network error.

Getting access

Two steps to a key.

API keys are enabled per account while the API is in private beta.

Tell us the use case

Volume, output type and where the generation sits in your product. One paragraph is enough.

We enable keys

Keys appear in the studio under API Keys, scoped and rate-limited to your plan.

Build against the shapes above

They are stable. Anything that changes before general availability is announced in the changelog.

Request API access

Tell us what you are building and we will turn keys on for your account.

110+

AI models

Image, video & music — one prompt bar

22 / day

Free credits

Plus 0-credit models. No card to start.

Auto-refund

On failed renders

Credits reserved on start, refunded if it fails

One balance

For everything

Image, video and music on the same credits