Guides

Generations

Images, image edits, videos and video extensions are all generations: asynchronous jobs you create with one request and follow until they finish.

Endpoints

  • POST/v1/images/generationsCreate images from a prompt.
  • POST/v1/images/editsTransform or inpaint an image.
  • POST/v1/videos/generationsCreate a video, optionally from start and end frames.
  • POST/v1/videos/extendContinue an existing video.
  • POST/v1/estimatePrice any of the above without running it.
  • GET/v1/generations/{id}Read one generation, optionally waiting up to 60 seconds.
  • GET/v1/generationsList generations, newest first.
  • POST/v1/generations/{id}/cancelCancel a generation that is still queued.
  • POST/v1/videos/{id}/framesGrab a still from a video in the library.

Creating needs the generate scope; reading needs read. Create calls answer 202 Accepted with the generation and a Location header pointing at it.

Lifecycle

queuedrunningsucceededorfailedqueuedcanceled
StatusMeaning
queuedAccepted and waiting in our queue for a free slot on Rogue. Only queued jobs can be canceled.
runningSent to Rogue and rendering.
succeededFinished. outputs[] holds the files. If some outputs failed, error.code is partial_failure.
failedDid not produce anything. error.code and error.message say why.
canceledCanceled while still queued. Never sent to Rogue, never charged.

succeeded, failed and canceled are final. Treat any status you do not recognise as still in progress. Jobs that Rogue does not finish in time fail with generation_failed: after 20 minutes for images and 45 minutes for videos.

You never manage Rogue's concurrency limit

Rogue runs a limited number of generations per account at once. Submit as many as you like: they wait as queued and start as slots free up. GET /v1/account/limits shows the limits and what is running and queued.

The generation object

A finished image generation
{
  "id": "gen_01k6g2m9x4c8vq3n7r5t2y8w0z",
  "object": "generation",
  "kind": "image",
  "status": "succeeded",
  "model": "xxxv2alt-sd-50prostandard",
  "project_id": "9d2f6a1c-3b7e-4c55-8f0a-6e1d2c3b4a5f",
  "cost": {
    "credits": 40
  },
  "expected_outputs": 2,
  "outputs": [
    {
      "id": "48213376",
      "type": "image",
      "url": "https://cdn.example.com/rogue/48213376.png",
      "thumb_url": "https://cdn.example.com/rogue/48213376-thumb.webp",
      "width": 832,
      "height": 1216,
      "duration": null,
      "nsfw": true
    }
  ],
  "error": null,
  "metadata": {
    "order_id": "1042"
  },
  "created_at": "2026-09-28T12:00:00.000Z",
  "submitted_at": "2026-09-28T12:00:02.113Z",
  "completed_at": "2026-09-28T12:00:31.870Z"
}
idstring
Starts with gen_.
kindstring
image, image_edit, video or video_extend.
statusstring
See the lifecycle above.
modelstring
The model that ran, after defaults were applied.
cost.creditsinteger
Credits this generation costs, fixed when it is created.
expected_outputsinteger
How many files the model makes per run.
outputs[]array
One entry per file: id, type (image or video), url, thumb_url, width, height, duration (seconds, videos) and nsfw.
errorobject | null
code and message when something went wrong.
metadataobject
Your own string map, echoed back unchanged.
created_at, submitted_at, completed_atstring
ISO 8601 timestamps in UTC. submitted_at is when it was sent to Rogue.

Common fields

These work on every create endpoint (extensions choose their model automatically, so they take no model).

promptstring
What to create, up to 4096 characters. Required unless the model marks it optional or you send a suggestion.
modelstring
A model id from GET /v1/models. Defaults to the platform's default for the suite.
base_modelstring
For character models: the base model to render with.
project_idstring
Where the results are filed. Defaults to a project named API, created on first use.
stylesstring[]
Up to 3 style ids from GET /v1/styles.
suggestionsstring[]
Up to 10 suggestion ids from GET /v1/suggestions, at most one per category.
optionsobject
Model-specific settings keyed by the option key listed on the model, for example {"resolution_sd50": "2k"}. Unknown keys are rejected; missing ones take the model default.
metadataobject
Up to 20 string values of up to 500 characters each. Echoed back on the generation and in webhooks.

Unknown fields are ignored. Anything that takes media (image, reference_images, start_image and so on) accepts an upload id, an https URL or a library id: see media references.

Images

curl -X POST "https://rogue-api.sentryq-va.com/v1/images/generations" \
  -H "Authorization: Bearer $ROGUE_API_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: $(uuidgen)" \
  -d '{
  "prompt": "portrait of a woman in a red dress, golden hour, 35mm film",
  "aspect_ratio": "2:3",
  "styles": [
    "cinematic"
  ],
  "metadata": {
    "order_id": "1042"
  }
}'
aspect_ratiostring
One of the model’s aspect_ratios, such as 1:1 or 16:9. Defaults to the first one.
cfgnumber
Prompt strength, within the model’s cfg range.
weightnumber
Model weight, within the model’s weight range.
clip_skipinteger
Within the model’s clip_skip range.
samplerstring
Sampler name, for models that expose one.
reference_imagesstring[]
Up to the model’s max_reference_images (and at most 10) media references.

Image edits

transform reworks a whole image guided by the prompt; inpaint changes only the masked area.

curl -X POST "https://rogue-api.sentryq-va.com/v1/images/edits" \
  -H "Authorization: Bearer $ROGUE_API_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: $(uuidgen)" \
  -d '{
  "image": "upl_01k6g1z8q2w3e4r5t6y7u8i9o0",
  "mode": "inpaint",
  "prompt": "a black leather jacket",
  "mask": "data:image/png;base64,iVBORw0KGgo...",
  "strength": 0.6
}'
imagestringrequired
The image to edit: an upload id, an https URL or a library id.
modestring
transform (default) or inpaint.
strengthnumber
How far to move from the original, 0.1 to 1. Defaults to 0.5, or 0.8 for a fill inpaint.
maskstring
Required for inpaint. A PNG data URL, or the upload id of a PNG, the size of the image: white areas change, black areas stay.
inpaint_typestring
refine (default) keeps the masked content as a starting point; fill replaces it.
mask_blurnumber
Softens the mask edge, within the model’s mask_blur range.
aspect_ratiostring
Defaults to the size of the source image.

Edits also take cfg, weight, clip_skip, sampler and reference_images, like images.

Videos

curl -X POST "https://rogue-api.sentryq-va.com/v1/videos/generations" \
  -H "Authorization: Bearer $ROGUE_API_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: $(uuidgen)" \
  -d '{
  "prompt": "she turns towards the camera and smiles, slow push in",
  "start_image": "upl_01k6g1z8q2w3e4r5t6y7u8i9o0",
  "aspect_ratio": "9:16",
  "duration": "5"
}'
aspect_ratiostring
One of the model’s video_aspect_ratios. Defaults to the first one.
durationstring
Seconds, as a string such as "5", from the model’s durations. Defaults to the first one.
start_imagestring
First frame, for models whose frames.start is true (required when frames.start_required is).
end_imagestring
Last frame, for models whose frames.end is true.
reference_imagesstring[]
Up to 10 image references, for models that take them.
reference_audiosstring[]
Up to 5 audio uploads or URLs, for models with audio support.
source_videostring
A video to transform, for models that take one (required by some, refused by others).
cfgnumber
Prompt strength, within the model’s cfg range.

Extending a video

Continue a finished video from your library. The platform picks the extension model, so there is no model field.

curl -X POST "https://rogue-api.sentryq-va.com/v1/videos/extend" \
  -H "Authorization: Bearer $ROGUE_API_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: $(uuidgen)" \
  -d '{
  "video_id": "48213377",
  "prompt": "she walks out of frame to the left",
  "duration": "5"
}'
video_idstringrequired
The library id of the video to continue (from outputs[].id or GET /v1/assets).
promptstringrequired
What happens next, up to 2048 characters.
durationstring
Seconds to add. Defaults to the extension model’s first option.
resolutionstring
Output resolution, when the extension model offers a choice.

Waiting for results

Add wait (0 to 60 seconds) to GET /v1/generations/{id}. The request returns as soon as the generation is final, or with its current state when the time is up. Loop until it is final; keep your HTTP timeout above 60 seconds.

const API = "https://rogue-api.sentryq-va.com";
const headers = { Authorization: `Bearer ${process.env.ROGUE_API_KEY}` };
const FINAL = ["succeeded", "failed", "canceled"];

async function waitForGeneration(id) {
  for (;;) {
    const res = await fetch(`${API}/v1/generations/${id}?wait=60`, { headers });
    const generation = await res.json();
    if (FINAL.includes(generation.status)) return generation;
  }
}

const done = await waitForGeneration("gen_01k6g2m9x4c8vq3n7r5t2y8w0z");
console.log(done.status, done.outputs.map((o) => o.url));

Images usually finish in under a minute, videos in a few minutes. For long jobs or large batches, subscribe to webhooks instead and skip polling entirely.

Retries and idempotency

Send an Idempotency-Key header (any unique string up to 200 characters, a UUID is ideal) with every POST. If the network drops and you retry with the same key and body within 24 hours, you get the original response back with an Idempotent-Replayed: true header, and nothing runs or is charged twice. The same key with a different body answers 409 conflict.

For generations the protection is permanent: a key once used on your account always returns that same generation.

Estimating the cost

POST /v1/estimate takes a kind plus the same body you would send to create, and prices it without running anything.

curl -X POST "https://rogue-api.sentryq-va.com/v1/estimate" \
  -H "Authorization: Bearer $ROGUE_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
  "kind": "video",
  "prompt": "slow push in",
  "start_image": "upl_01k6g1z8q2w3e4r5t6y7u8i9o0",
  "duration": "10"
}'
Response
{
  "object": "estimate",
  "kind": "video",
  "model": "rogue-character-W30pre",
  "credits": 220,
  "balance": 1000,
  "sufficient": true,
  "outputs": 1
}

The cost is checked again when you create: a request the account cannot afford answers 402 insufficient_credits and a request over the key's daily budget 403 budget_exceeded, before anything is queued.

Listing and canceling

GET /v1/generations lists the generations made through the API on your account, newest first. Filter with status and kind, page with page and limit (1 to 100, default 20).

Response
{
  "object": "list",
  "data": [
    {
      "id": "gen_01k6g2m9x4c8vq3n7r5t2y8w0z",
      "object": "generation",
      "status": "running"
    }
  ],
  "page": 1,
  "limit": 20,
  "has_more": false
}

Canceling

POST /v1/generations/{id}/cancel cancels a generation that is still queued; it is never sent to Rogue or charged. Once a job is running it can no longer be stopped, and the call answers 409 conflict.

Grabbing a frame

POST /v1/videos/{id}/frames extracts a still from a video in your library, for example to start the next clip from the last frame. It is immediate and costs no credits.

curl -X POST "https://rogue-api.sentryq-va.com/v1/videos/48213377/frames" \
  -H "Authorization: Bearer $ROGUE_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
  "time": "last"
}'
Response
{
  "object": "frame",
  "url": "https://cdn.example.com/rogue/frame-48213377.png"
}

Send time as seconds from the start (for example 2.5) or "last". Pass the returned URL as start_image of a new video.