Image generation & editing
Norlen offers two image endpoints: generation (text → image) and editing (image + instruction → image). Both return the image in base64 and follow the spirit of OpenAI’s images API.
Generation (text → image)
Section titled “Generation (text → image)”Generates an image from a text prompt. Follows OpenAI’s images/generations format.
POST https://app.norlen.io/api/v1/images/generationsAuthorization: Bearer YOUR_API_KEYContent-Type: application/jsonParameters
Section titled “Parameters”| Field | Type | Required | Description |
|---|---|---|---|
model | string | yes | qwen-image |
prompt | string | yes | Description of the desired image |
size | string | no | Dimensions, e.g. 1024x1024 (default and recommended) |
n | integer | no | Number of images (default 1) |
Example
Section titled “Example”curl https://app.norlen.io/api/v1/images/generations \ -H "Authorization: Bearer $NORLEN_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "model": "qwen-image", "prompt": "A brass compass on a nautical chart, studio lighting", "size": "1024x1024" }'import base64, requests
r = requests.post( "https://app.norlen.io/api/v1/images/generations", headers={"Authorization": "Bearer YOUR_TOKEN"}, json={"model": "qwen-image", "prompt": "A brass compass on a nautical chart", "size": "1024x1024"}, timeout=120,)data = r.json()["data"][0]["b64_json"]with open("image.png", "wb") as f: f.write(base64.b64decode(data))const r = await fetch("https://app.norlen.io/api/v1/images/generations", { method: "POST", headers: { Authorization: `Bearer ${process.env.NORLEN_API_KEY}`, "Content-Type": "application/json", }, body: JSON.stringify({ model: "qwen-image", prompt: "A brass compass on a nautical chart", size: "1024x1024" }),});const { data } = await r.json();const buffer = Buffer.from(data[0].b64_json, "base64");await require("fs/promises").writeFile("image.png", buffer);Response
Section titled “Response”{ "created": 1750000000, "data": [ { "b64_json": "iVBORw0KGgoAAAANSUhEUgAA..." } ]}The image comes in data[0].b64_json (base64-encoded PNG). Decode and save it, or display it with data:image/png;base64,<...>.
Editing (image + instruction → image)
Section titled “Editing (image + instruction → image)”Edit an existing image by instruction — describe the change and Norlen applies it while preserving the rest of the scene (Qwen-Image-Edit model). Follows the spirit of OpenAI’s images/edits.
POST https://app.norlen.io/api/v1/images/editsAuthorization: Bearer YOUR_API_KEYIt accepts two input formats:
multipart/form-data(like the OpenAI SDK): animagefile field plus apromptwith the instruction.- JSON:
{ "image": "<base64 or data URL>", "prompt": "..." }.
Parameters
Section titled “Parameters”| Field | Type | Required | Description |
|---|---|---|---|
image | file | string | yes | The image to edit — a file (multipart) or base64/data URL (JSON). Max ~10MB |
prompt | string | yes | The edit instruction, e.g. “make the apple blue”. Up to 2000 characters |
n | integer | no | Number of variations (1–4, default 1) |
There is no model field: editing uses the Qwen-Image-Edit model automatically.
Example
Section titled “Example”curl https://app.norlen.io/api/v1/images/edits \ -H "Authorization: Bearer $NORLEN_API_KEY" \ -F image=@photo.png \ -F prompt="make the apple blue"import base64, requests
r = requests.post( "https://app.norlen.io/api/v1/images/edits", headers={"Authorization": "Bearer YOUR_TOKEN"}, files={"image": open("photo.png", "rb")}, data={"prompt": "make the apple blue"}, timeout=180,)open("edited.png", "wb").write(base64.b64decode(r.json()["data"][0]["b64_json"]))import { readFile } from "node:fs/promises";
const form = new FormData();form.append("image", new Blob([await readFile("photo.png")]), "photo.png");form.append("prompt", "make the apple blue");
const r = await fetch("https://app.norlen.io/api/v1/images/edits", { method: "POST", headers: { Authorization: `Bearer ${process.env.NORLEN_API_KEY}` }, body: form,});const { data } = await r.json();const fs = await import("node:fs/promises");await fs.writeFile("edited.png", Buffer.from(data[0].b64_json, "base64"));curl https://app.norlen.io/api/v1/images/edits \ -H "Authorization: Bearer $NORLEN_API_KEY" \ -H "Content-Type: application/json" \ -d '{"image":"<base64-or-data-url>","prompt":"make the apple blue"}'The response has the same shape as generation: { "created": ..., "data": [{ "b64_json": "..." }] }.
Billing
Section titled “Billing”Each plan includes a monthly image quota — it covers both generation and editing. Images beyond the quota cost $0.03 each, debited from your balance. See Pricing & quotas.