REST API

POST

/api/v1/images/generations

Generate images from a text prompt. The request follows OpenAI's images.generate, so the OpenAI SDKs work with the Railwail base URL. Each image is its own run, billed at the model's price.

URL
https://railwail.com/api/v1/images/generations
Key scope
images
Returns
200 with URLs · 202 if slow
Default model
flux-1-schnell

Request body

JSON. Unknown fields are rejected with 400 validation_failed; for example aspect_ratio and seed cannot be sent here. Only prompt (and model) work for every model; the rest is used where the model has that input.

model
string
Image model slug; the list below shows what runs right now.Default flux-1-schnell
promptrequired
string
What to draw, up to 4,000 characters.
n
integerclamped to 4
Number of images, 1–10 accepted, clamped to 4. Every image is billed.Default 1
size
stringmodel-dependent
256x256, 512x512, 1024x1024, 1024x1792 or 1792x1024, converted to width and height. Models that take an aspect ratio (FLUX schnell, for example) ignore it.
quality
stringmodel-dependent
standard or hd.
style
stringmodel-dependent
vivid or natural.
negative_prompt
stringmodel-dependent
What to leave out.
response_format
stringURLs only
b64_json is accepted but you always get URLs.Default url
user
string
Your own end-user id, stored with the job.

Examples

Key in RAILWAIL_API_KEY, with the images scope (not on by default).

import OpenAI from "openai";

const client = new OpenAI({
  apiKey: process.env.RAILWAIL_API_KEY,
  baseURL: "https://railwail.com/api/v1",
});

const image = await client.images.generate({
  model: "flux-1-schnell",
  prompt: "A beautiful sunset over Tokyo, cinematic",
});
console.log(image.data[0].url); // null if the run was still processing (HTTP 202)

Response

200: finished

Shape of the answer; values are placeholders.

JSON
{
  "created": <unix seconds>,
  "data": [
    {
      "url": "https://…/out-0.webp",
      "revised_prompt": "<your prompt, unchanged>",
      "job_id": "<uuid>",
      "status": "completed"
    }
  ]
}

Download what you want to keep

The URL can point to the provider's storage and expire after a while. Fetch the file right away if you need it later.

202: still processing

Runs that take longer than about 85 seconds return HTTP 202 with status: "processing", url: null, a poll URL and a Location header. Fetch the result with GET /api/v1/jobs/{job_id}. The OpenAI SDKs do not raise on 202; they return url: null, so check for it.

Several images in one request

With n above 1, all images of the request are reserved and charged together: if the balance, the spend limit or the key's credit limit does not cover all of them, none runs and nothing is charged. If some images then fail at the provider, the answer is still 200 (or 202) with the delivered images in data and the failed ones in errors, each with its job_id and code generation_failed; failed images are refunded.

Models you can call here

Live from the catalog: image models that run through this endpoint with a text prompt, with the price as charged. Models that need an input image (editing, upscaling, background removal) run from their model pages.

Errors

StatusCodeWhat to do
400validation_failedA field is unknown or out of range; details lists which.
402insufficient_creditsTop up on the billing page.
402monthly_limit_exceededYour monthly spending limit is reached.
403insufficient_scopeThe key lacks the images scope.
404model_not_foundCheck the slug in the list above.
429api_key_limit_exceededThe key's daily or monthly credit limit; nothing was charged. Retry after X-Key-Limit-Reset, not before (credit limits).
429trial_limitTrial rules (at most 2 credits per run until the first top-up).
500internal_errorUnexpected server error; retry once.
503model_unavailableNo verified price or the provider is not reachable; pick another model.

All codes: Error codes. Rate-limit headers come with the 200 and error answers, not with a 202.