Develop / Reference
Images
Generates images from a text prompt in the OpenAI format; the gateway checks number and size and does not inspect prompts with Noirdoc Shield.
/v1/images/generations - Family
- image_gen
- Shield
- no
- Streaming
- no
- Format
- JSON
- Billing
- images or megapixels
Request
The gateway accepts the body in the format of the OpenAI Images API. model is required and must be a model of the image_gen family from GET /v1/models. The endpoint accepts only POST.
The gateway returns the provider’s JSON response. With the connected providers, the image data is Base64-encoded in data[].b64_json.
curl https://api.noirdoc.de/v1/images/generations \
-H "Authorization: Bearer $NOIRDOC_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "black-forest-labs/FLUX.1-schnell",
"prompt": "A lighthouse on the North Sea at sunrise",
"size": "1024x1024",
"n": 1
}'import base64
import os
from openai import OpenAI
client = OpenAI(
base_url="https://api.noirdoc.de/v1",
api_key=os.environ["NOIRDOC_API_KEY"],
)
response = client.images.generate(
model="black-forest-labs/FLUX.1-schnell",
prompt="A lighthouse on the North Sea at sunrise",
size="1024x1024",
n=1,
)
with open("lighthouse.png", "wb") as f:
f.write(base64.b64decode(response.data[0].b64_json))import fs from "node:fs";
import OpenAI from "openai";
const client = new OpenAI({
baseURL: "https://api.noirdoc.de/v1",
apiKey: process.env.NOIRDOC_API_KEY,
});
const response = await client.images.generate({
model: "black-forest-labs/FLUX.1-schnell",
prompt: "A lighthouse on the North Sea at sunrise",
size: "1024x1024",
n: 1,
});
const png = Buffer.from(response.data![0].b64_json!, "base64");
fs.writeFileSync("lighthouse.png", png);Limits
The gateway checks these values before forwarding the request. It answers violations with 400 invalid_image_request.
| Field | Rule |
|---|---|
prompt | non-empty string |
n | integer from 1 to 10, default 1 |
size | WIDTHxHEIGHT, each side 1 to 2048 pixels. Without size, the gateway calculates with 1024x1024. It rejects values such as auto. |
| Total size | n × megapixels per image at most 16. The gateway rounds each image up to full units of 1024 × 1024 pixels. |
Examples for the total size: 1024x1024 counts as one unit, so up to ten images are possible. 2048x2048 counts as four units, so at most four images. 1536x1024 counts as two units.
Many models allow narrower values, such as only one image per request or only certain resolutions. If the provider rejects the request, you receive its status code and its message under the code provider_rejected_request.
What Noirdoc changes
| Area | Behaviour |
|---|---|
| Model | The gateway resolves the model ID through the catalogue and sends the provider its own model name. |
| Provider | The X-Noirdoc-Provider header in the response names the provider. See Providers & routing. |
| Streaming | None. The gateway answers "stream": true with 400 streaming_not_supported_for_endpoint. |
| Billing | Depending on the model, the gateway bills per image or per megapixel. It counts the images in data of the response. It takes the size from the size field of the response, otherwise from the request, otherwise 1024x1024. Models & pricing lists the prices. |
| Headers | The gateway removes your key, X-Noirdoc-Shield and X-Noirdoc-Mask before forwarding the request. |
Sub-routes
None. The gateway answers image editing (/v1/images/edits) and other paths under /v1/images/ with 404 unsupported_endpoint.
Errors on this endpoint
| Status | Code | Meaning |
|---|---|---|
| 400 | model_required | The request names no model (model in the body, or in the form field for /v1/audio/transcriptions). |
| 400 | wrong_endpoint_for_model | The model belongs to a different endpoint family or API format than the endpoint called. |
| 400 | streaming_not_supported_for_endpoint | The request asks for streaming, but the endpoint does not support it. |
| 400 | invalid_request_body | The body is not a JSON object or not encoded in UTF-8. |
| 400 | invalid_image_request | prompt, n or size is outside the gateway's limits; message names the parameter. |
| 402 | insufficient_credit | The organisation's credit is used up or lower than the estimated maximum cost of the request (including Noirdoc Shield, also on BYOK routes when Shield is active). |
| 402 | key_budget_exhausted | This key's budget is used up for the current period or does not cover the estimated cost of the request. |
| 403 | model_not_allowed_for_key | The model is not one of this key's allowed models. |
| 403 | provider_not_allowed_for_tenant | The organisation counts as bound by professional secrecy (§ 203 StGB); this excludes every provider that offers this model. |
| 403 | provider_not_allowed_for_key | The key's restrictions (providers, data residency, CLOUD Act, § 203) exclude every provider of this model. |
| 403 | starter_model_not_allowed | The organisation is still using only its starter credit, and the model or its managed provider is not included in starter credit. |
| 403 | masking_not_supported_for_endpoint | The endpoint supports neither Noirdoc Shield nor legacy masking, yet the policy is enforced or the request sends X-Noirdoc-Mask: on (and on /v1/images/generations also X-Noirdoc-Shield: on). During the legacy masking transition until 30.11.2026, this also affects /v1/embeddings and /v1/rerank on pre-existing organisations that have not switched to Shield yet. |
| 404 | model_not_available | The model ID is not available to the organisation. |
| 405 | method_not_allowed | The endpoint accepts only POST. |
| 502 | provider_unreachable | The gateway could not connect to the provider, or the connection dropped. |
| 504 | provider_timeout | The provider did not answer within the gateway's timeout. The response contains Retry-After with 10 seconds. |
OpenAI reference
OpenAI’s API reference describes all other request and response fields: Images (checked on 30 September 2026).