Docs

Quickstart

One key, one request shape, every image and video model. Submit a job, poll it, get the file.

LiveEvery model on the models page runs on this endpoint. Pictures and video, one request shape; each model’s options and prices are in /data/models.json.
Base URLhttps://api.revana.si/v1
AuthAuthorization: Bearer <key>
SubmitPOST /v1/generations
PollGET /v1/generations/{id}
ModelsGET /v1/models (no key): every model you can generate with right now
FormatJSON in, JSON out. Prices in USD; 100 credits = $1.
Machine-readable/openapi.json · /llms.txt

Authentication

Create a key from your account, then send it as a bearer token on every request. Keep it on your server; never ship it in a browser or mobile app.

Submit a generation

POSThttps://api.revana.si/v1/generations

Send the model id and its input. The response comes back straight away with a generation id and status queued; the work happens in the background.

FieldTypeDescription
modelstring, requiredA model id from the models page, e.g. seedance-2.5.
inputobject, requiredThe prompt and settings; see input fields. Unknown fields are refused.
max_cost_usdnumber, optionalThe most you will pay for this generation, up to 100 (the default). Routes priced above it are skipped; if none is left the request answers 422 max_cost_exceeded.
max_wait_sinteger, optionalRoutes expected to take longer than this many seconds are skipped. Once it has passed no new route is tried, but one already running is allowed to finish (up to 40 minutes) and is charged if it delivers.
Idempotency-Keyheader, optionalUp to 200 characters. Send the same key and body again (after a timeout or a 503) and you get the same generation back, not a second one. The same key with a different body is 409 idempotency_conflict.

Get the result

GEThttps://api.revana.si/v1/generations/{id}

Poll every few seconds until status is succeeded or failed, then download the files in output.urls with your key: GET /v1/generations/{id}/content for the first, and /content/2, /content/3… when a picture model returns several. Images usually take seconds; video takes from under a minute to several minutes depending on the model and length.

A finished generation:

Input fields

The same names are used across models. Which fields and values each model takes, and its defaults, are listed per model in /data/models.json (options, tasks). If a model doesn’t support a field or value, the request is rejected with 422 invalid_input before anything is charged.

FieldTypeUsed for
promptstringWhat to generate. Required for text-to-image and text-to-video.
image_urlstring (URL)Start frame for image-to-video, or the image to edit for image-to-image.
end_image_urlstring (URL)Last frame, for models with first + last frame.
image_urlsstring[]Reference images, up to the model’s limit.
resolutionstring720p, 1080p, 2K... one of the model’s resolutions.
durationnumberVideo length in seconds, one of the model’s durations.
aspect_ratiostring16:9, 9:16, 1:1...
audiobooleanGenerate sound with the video, where the model supports it. May change the price.
negative_promptstringWhat to avoid, on models that take it.
video_urlstring (URL)A clip to transform, extend or upscale. Its length is measured and, on per-second models, billed.
audio_urlstring (URL)The voice or sound a talking-avatar or lip-sync model animates to.
qualitystringA quality tier on models priced by one (e.g. low, medium, high).
seedintegerA seed, on models that take one.

Seedance 2.5 defaults to 720p, 5 seconds (4–30), 16:9 and no sound, and also takes:

FieldTypeUsed for
video_urlstring (URL)A 4–30 s clip to edit. The result keeps its length, so leave out duration.
video_urlsstring[]Reference clips, up to 10 and 30 seconds in all. Their seconds are billed at the video-input rate.
audio_urlsstring[]Reference sound, up to 10 and 30 seconds in all.

image_url is an exact first frame, so it can’t be combined with reference media; use image_urls for a looser visual reference. end_image_url needs image_url. Media must be public https URLs that download directly.

Generation object

FieldTypeDescription
idstringGeneration id (gen_…), used to poll.
objectstringAlways generation.
modelstringThe model you asked for.
statusstringSee statuses.
messagestringOnly while a result is being confirmed with a provider: what is happening.
quoted_usdnumberThe price on the cheapest route, which is the one tried first.
reserved_usdnumberWhat is held from your balance: the dearest route that may run. The difference is released when it settles.
outputobject | nullWhen succeeded: urls, the result files (a picture model can return several), with width and height; video also has duration_s and has_audio. Download them promptly; files expire.
cost_usdnumber | nullWhat was charged. Set once the generation succeeds; 0 when it fails.
attemptsnumberRoutes tried, including fallbacks. Only the successful one is billed.
errorobject | nullWhen failed: code and message.
created_at, completed_atstringISO 8601 timestamps.

Statuses

StatusMeaning
queuedAccepted, waiting for a route.
runningGenerating. If a route fails, the job stays running while it moves to the next one, and while a result is being confirmed (see message).
succeededDone. output.urls holds the files and cost_usd what you paid.
failedEvery route failed or the input was refused. Nothing is charged.

Billing

  • You pay from prepaid credits, 100 to the dollar, bought in packs from $10 to $5,000. Every price is a whole number of credits.
  • When you submit, reserved_usd is held from your balance. If the generation fails, all of it is released.
  • Only the route that succeeds is charged, at the price quoted for it when you submitted. Failed attempts on other routes cost nothing.
  • There is no monthly quota or per-minute cap: your balance and max_cost_usd are the limit.
  • Each model’s price is on its page and in the price table.

Errors

Errors use HTTP status codes and a JSON body: {"error": {"code": "...", "message": "..."}}.

HTTPCodeWhen
400invalid_requestThe body isn’t JSON, is missing model or input, or has a field the API doesn’t know.
401unauthorizedMissing or invalid API key.
402insufficient_creditsYour available balance doesn’t cover reserved_usd. Top up and retry.
403account_disabledThe account is paused. Contact support.
403generation_not_enabledYour key can read prices but can’t generate yet.
404not_foundNo generation with this id on your account.
409idempotency_conflictThis Idempotency-Key was already used with a different body.
409not_readyAsked for the file before the generation succeeded.
413body_too_largeThe body is over 1 MB. Send media as URLs.
422invalid_inputA field, value or combination the model doesn’t support, or media that can’t be read. Nothing is charged.
422max_cost_exceededEvery route costs more than max_cost_usd.
422model_not_availableNo model with this id on the API. Ids are on the models page.
429rate_limitedToo many requests in the same second from one account (a guard against runaway loops, not a quota). Wait the Retry-After seconds.
429concurrency_limitThe account already has its maximum of generations in progress. Retry when one finishes.
503restarting, busyA restart or a moment of load. Retry after Retry-After with the same Idempotency-Key.
503model_unavailableNo route for this model is up right now. Retry shortly.
500server_errorSomething broke on our side. Safe to retry with the same Idempotency-Key.

Model list

Every model, its options and prices are published as JSON at /data/models.json, the same file this site renders from.