API reference

Generate images and video from your own application. The API is server-to-server: your backend holds the key and calls us, the same way you would use any paid generation API. Work is billed per asset against a prepaid credit balance.

Authentication

Send your key as a bearer token. Keys look like cvk_<prefix>_<secret> and are shown once, at creation.

curl https://corovusagent.com/api/v1/media/images \
  -H 'Authorization: Bearer cvk_a1b2c3d4_…' \
  -H 'Content-Type: application/json' \
  -H 'Idempotency-Key: 9f2c1e40-…' \
  -d '{ "prompt": "a ceramic mug on a linen cloth", "quality": "standard" }'

Never put a key in browser JavaScript or a mobile binary. It is a full credential — whoever holds the string can spend your balance. There is no CORS on this API by design; calls must come from your server.

Idempotency-Key is required on /images. Send a unique value per submit; retrying with the same value returns the original result instead of generating — and paying — twice.

A successful call answers:

{
  "ok": true,
  "id": "8f1c2d3e-...",
  "request_id": "3ab2...",
  "status": "succeeded",
  "image": {
    "url": "https://media.13idea.org/mediaapi/.../0.png",
    "content_type": "image/png",
    "aspect_ratio": "1:1"
  },
  "credits_charged": 103,
  "balance_credits": 897
}

Base URL

https://corovusagent.com/api/v1/media

The API is host-neutral, so the console host answers identically. Either works with the same key.

Synchronous images, asynchronous video

Image generation is synchronous. POST /images holds the connection and returns 200 with the finished image — typically 10–30 seconds, and up to about five minutes in the worst case. Set your HTTP client timeout to at least 300 seconds, and send an Idempotency-Key on every submit so a timeout is always safe to retry.

Video is different. Renders take minutes, far longer than any load balancer will hold a connection open, so POST /videos is asynchronous: it returns 202 with an id and a poll_url, and you poll GET /jobs/{id} until its status leaves processing. Credits are held at submit and only charged when a video is delivered; every failure is refunded. The expires_at on the 202 is the point after which the job is definitively dead and the hold released.

Endpoints

POST/imagesGenerate one image from a text prompt. You choose a quality tier and an aspect ratio; we choose the engine. Synchronous — returns the finished image.
POST/videosText-to-video, image-to-video and video-to-video. Asynchronous — returns 202 with an id to poll.
GET/jobs/{job_id}Look up one submit by its id — status, credits charged and the output URL. Use it to recover a result whose connection dropped. Video jobs will use the same endpoint.
POST/uploadsnot yet liveGet a presigned URL to upload your own source image or video before referencing it.
GET/pricesnot yet liveLive price list in credits, so you can budget before you call.
GET/menot yet liveBalance, quota, rate limit and enabled capabilities.

POST /images — parameters

Text-to-image only for now. Unknown fields are rejected with a 400 rather than ignored, so a parameter that is not listed here will never be silently dropped from a call you were billed for.

FieldTypeNotes
promptstringRequired. 1–2000 characters.
qualitystandard | premiumOptional, defaults to standard. The premium tier uses the higher-fidelity engine and costs more.
aspect_ratio1:1 · 4:5 · 5:4 · 3:4 · 4:3 · 2:3 · 3:2 · 9:16 · 16:9 · 21:9Optional, defaults to 1:1.

POST /videos — parameters

Pick a mode; the fields below depend on it. Source media is sent inline as base64 — there is no URL field on any mode, and never will be. The whole request body is capped at 16 MB, which is roughly 12 MB of source once encoded, and a source clip may not exceed 15 seconds. Downscale before sending.

ModeFieldsNotes
text_to_videoprompt, seconds, quality, aspect_ratioseconds 4–15 (default 5). quality standard (720p) or hd (1080p).
image_to_videoprompt, image_b64, seconds, quality, aspect_ratioAnimates a still. Same duration and quality options.
video_to_videoprompt, video_b64, aspect_ratioRestyles a clip. NO seconds field — the duration is measured from your file, and that measured length is what you are billed for.

Real people need consent. If your source shows an identifiable person, the call is refused with likeness_consent_required until you resend with likeness_consent: true. Sending it records an attestation against your account that you hold that person's documented consent. Do not send it otherwise.

Sources are stored on our CDN only while the render runs — they are publicly readable at an unguessable path for that period, because the render engine fetches them — and are deleted as soon as the job finishes. Do not send source material that cannot be public for a few minutes.

Video has no audio. Every clip is delivered as a silent H.264 mp4 with no audio track. There is no audio parameter, and the per-second price covers video only. Plan for your own soundtrack if you need one.

Output storage

Generated images are stored on our CDN and returned as a direct URL. That URL is unguessable, but it is public and permanent — anyone holding the link can fetch the image, and it does not expire.

Download and re-host anything that needs to stay private or that you need to guarantee remains available.

Errors

Every failure returns a machine-readable code — branch on that, never on the message text, which may be reworded.

HTTPcodeMeaning
400invalid_requestBody failed validation, carried an unrecognised field, or the Idempotency-Key header was missing.
401unauthorizedMissing, malformed, revoked or expired key.
403forbiddenAccount not active, or this key lacks that capability.
403scope_pausedThat capability is temporarily paused on your account.
402insufficient_balanceNot enough credits for this call.
402monthly_cap_reachedYour period cap is exhausted.
409idempotency_key_in_flightA request with this Idempotency-Key is still running. Retry once it completes.
413source_too_largeRequest body exceeds 64 KB.
429rate_limitedSlow down. Honour the Retry-After header.
422content_blockedThe prompt was refused by content screening — ours or the engine's. You are not charged either way.
503vendor_unavailableAn upstream engine is down. Retry with backoff. You are not charged.
504timeoutGeneration took too long. You are not charged.

Rate limits & retries

Responses carry RateLimit-Limit, RateLimit-Remaining and RateLimit-Reset, and a 429 carries Retry-After in seconds. Limits are weighted: a generate call costs more of your budget than a job poll, so polling will not push you into a limit.

Send an Idempotency-Key on every submit — it is required on /images. If a response is lost and you retry with the same key, you get the original result back instead of paying twice. A retry that arrives while the first call is still running answers 409 idempotency_key_in_flight.

Request ids

Every response includes X-Request-Id. Quote it when you report a problem — it is the same id shown in your Usage tab and in our logs, so it turns a support thread into one lookup.

We use essential cookies to run this site. With your permission, we also remember which ad or invite link brought you here, and our ad partners use cookies to measure our ads and show them to past visitors. Change this any time in “Cookie settings”. Cookie Policy