Visnea API

Generate

One endpoint starts a generation of any modality — images, video and voice. The model is selected with model_id; the rest of the parameters depend on its capabilities.

Endpoint

POST/v1/generate

Request body

Only model_id and prompt are required (editing tools — upscale, background removal etc. — run without a prompt). Everything else is optional and applies when the model supports it.

ParameterTypeDescription
model_idrequiredstringModel ID from GET /v1/models.
promptrequiredstringThe prompt text. Each model has its own length limit (max_prompt_chars); exceeding it returns a prompt_too_long error.
translate_promptbooleanAuto-translate the prompt RU→EN before sending it to the model (on by default for image and video; never applies to voice). false sends it as is.
num_imagesimagenumberNumber of images per request (1–4). Each one is billed separately.
image_sizeimageenumSize preset: square_hd, square, portrait_4_3, portrait_16_9, landscape_4_3, landscape_16_9, auto.
aspect_ratioenumAspect ratio from the model's aspect_ratios list, e.g. "16:9".
qualityimageenumResolution (1K | 2K | 4K) when the model declares this field in its form.
seednumberFixes the generation seed for reproducibility.
negative_promptstringWhat to avoid in the result (supported by some models).
output_formatstringOutput file format when the model supports it.
voiceaudioenumVoice for TTS models; allowed values are in the model's voice form field.
reference_imagesimagestring[]Input image URLs (img2img/editing) — for models with supports_refs, up to max_refs.
mask_imageimagestringMask URL for inpaint/object removal (models with requires_mask).
image_urlvideostringStart frame for image-to-video (models with supports_start_frame).
end_image_urlvideostringEnd frame (models with supports_end_frame).
…formmixedModel-specific params from form — sent as top-level keys of the body, e.g. duration or resolution.
The exact parameter set of every model lives in the live models reference. A value outside the allowed list returns a param_unsupported error before anything is charged.

Request examples

curl · Image
curl https://visnea-labs.com/v1/generate \  -H "Authorization: Bearer sk-visnea-..." \  -H "Content-Type: application/json" \  -d '{    "model_id": "z-image",    "prompt": "portrait in warm editorial light",    "image_size": "portrait_4_3",    "num_images": 2  }'
curl · Video
curl https://visnea-labs.com/v1/generate \  -H "Authorization: Bearer sk-visnea-..." \  -H "Content-Type: application/json" \  -d '{    "model_id": "kling-1-5-pro",    "prompt": "a drone shot over mountain peaks at dawn",    "aspect_ratio": "16:9",    "duration": 5  }'
curl · Voice
curl https://visnea-labs.com/v1/generate \  -H "Authorization: Bearer sk-visnea-..." \  -H "Content-Type: application/json" \  -d '{    "model_id": "elevenlabs-tts",    "prompt": "Text to voice over",    "voice": "rachel"  }'

Response

The response carries a generation object and your current balance. Synchronous models return status: "succeeded" right away with links in results; asynchronous ones return status: "processing".

200 · response
{  "generation": {    "id": "gen_01hx…",    "model_id": "z-image",    "kind": "image",    "status": "succeeded",    "prompt": "…",    "price_cherries": 4,    "results": [      { "url": "https://visnea-labs.com/files/….png", "width": 1024, "height": 1365 }    ],    "created_at": "2026-07-24T10:00:00Z"  },  "balance": 496}

Statuses:

  • processingthe generation is running; poll it by id;
  • succeededdone, links in results[].url (and result_url);
  • failedit didn't work out; spent cherries are refunded automatically.

Polling the result

While the status is processing, fetch the generation every 2–5 seconds. Video can take several minutes to render.

GET/v1/generations/{id}
curl
curl https://visnea-labs.com/v1/generations/GEN_ID \  -H "Authorization: Bearer sk-visnea-..."# → { "generation": { "id": "GEN_ID", "status": "processing", … } }# → { "generation": { "id": "GEN_ID", "status": "succeeded", "results": [ … ] } }

References & file uploads

Models with supports_refs accept input images via reference_images (up to max_refs URLs). If your file is local, upload it first:

POST/v1/uploads
curl · multipart
curl https://visnea-labs.com/v1/uploads \  -H "Authorization: Bearer sk-visnea-..." \  -F "file=@reference.png"# → { "id": "…", "url": "https://visnea-labs.com/files/….png", … }

The response contains a url — use it in reference_images, mask_image or image_url.

Prompt improvement

A dedicated endpoint rewrites a prompt into a richer, cleaner one in the same language. Pass model_id so the response respects that model's length limit.

POST/v1/generation/improve-prompt
curl
curl https://visnea-labs.com/v1/generation/improve-prompt \  -H "Authorization: Bearer sk-visnea-..." \  -H "Content-Type: application/json" \  -d '{    "prompt": "cat on a roof",    "kind": "image",    "model_id": "z-image"  }'# → { "prompt": "…", "changed": true, "chars": 214, "max_chars": 2000, "over_limit": false }

Chat

Chat models use their own endpoint. The first request without session_id creates a session; continue the dialog by passing the session_id from the response.

POST/v1/chat/send
curl
curl https://visnea-labs.com/v1/chat/send \  -H "Authorization: Bearer sk-visnea-..." \  -H "Content-Type: application/json" \  -d '{ "model_id": "gpt-5-5", "message": "Hello!" }'# → { "session_id": "…", "message": { "role": "assistant", "content": "…" }, "balance": 495, "new": true }