Image Generation
Learn how to make API calls to generate image, edit image or create new image from multiple images
Overview
AI.ML’s image generation API enables users to generate, edit, and compose images using the advanced image-gen.pro-1.0 model. Key capabilities include text-to-image generation, image editing, and multi-image composition for creative and business use cases. The API follows RESTful conventions and ensures secure access using Bearer token authentication.
Base URL: https://api.ai.ml/
Auth: Bearer token via Authorization: Bearer <AIML_API_KEY>
Primary endpoint: POST /v1/generation/images
Media resolver: GET /v1/media/images/{path-encoded} → returns a presigned download URL
Core workflow (all flows):
-
POST /v1/generation/images→ returns a backend media URL indata.image.url(e.g.,/v1/media/images/orgs%2F64%2Fimages%2F...). -
Authorized
GETto that backend URL → returns{"url": "<presigned-download-url>"}. -
GETthe presigned URL (no auth) to download the image bytes.
Guidelines to Best Practices for Image Generation reference
Image API
Endpoint: POST /v1/generation/images
| Field | Type | Required | Example | Notes |
|---|---|---|---|---|
| model | string | ✓ | "image-gen.pro-1.0" | Model identifier |
| prompt | string | ✓ | "A forest at sunrise..." | Natural language description or edit instruction |
| image | string | string[] | ✕ | "https://.../img.png" or ["https://.../a.png","https://.../b.png"] | Omit for pure text→image. Provide 1 for Edit Image. Provide 2+ for Multi-image to new image |
| sequential_image_generation | string | ✕ | "disabled" | Keep as "disabled" unless otherwise enabled |
| response_format | string | ✕ | "url" | Use "url" to receive a backend media URL |
| size | string | ✕ | "2K" | Output resolution preset |
| stream | boolean | ✕ | false | Streaming not used in examples |
| watermark | boolean | ✕ | false | Enable/disable watermark |
Successful Response (JSON)
{
"data": {
"image": {
"url": "/v1/media/images/orgs%2F64%2Fimages%2Fabc123.png"
}
}
}Resolve/Download
- Resolve (authorized):
GET /v1/media/images/orgs%2F64%2Fimages%2Fabc123.png
Authorization: Bearer <AIML_API_KEY>Response:
{ "url": "https://presigned.cdn.ai.ml/...." }- Download(no auth):
GET https://presigned.cdn.ai.ml/.... → bytes
Errors
-
400 Bad Request — malformed JSON or invalid fields
-
401 Unauthorized — missing/invalid token
-
403 Forbidden — not allowed for this resource
-
429 Too Many Requests — throttled
-
5xx — transient server error
Error body (example):
{
"error": {
"code": "invalid_request",
"message": "Field 'prompt' is required"
}
}Generate Image from Text
Use this method when you have no source image(s)—the model creates a new image from your prompt. This is generally used to explore new ideas.
import fs from 'node:fs';
import fetch from 'node-fetch';
const API = 'https://api.ai.ml';
const BASE_URL = `${API}/v1/generation/images`;
const API_KEY = process.env.AIML_API_KEY || 'AIML_API_KEY';
async function generateImage() {
const body = {
model: 'image-gen.pro-1.0',
prompt: 'A girl and a cow plushie on a roller coaster at sunrise.',
sequential_image_generation: 'disabled',
response_format: 'url',
size: '2K',
stream: false,
watermark: false
};
// 1) Create image
const res = await fetch(BASE_URL, {
method: 'POST',
headers: {
Authorization: `Bearer ${API_KEY}`,
'Content-Type': 'application/json'
},
body: JSON.stringify(body)
});
if (!res.ok) throw new Error(`HTTP ${res.status}: ${await res.text()}`);
const json = await res.json();
const backendImageUrl = json?.data?.image?.url;
if (!backendImageUrl) throw new Error('No image URL returned');
// 2) Resolve to presigned URL
const resolveUrl = backendImageUrl.startsWith('http') ? backendImageUrl : `${API}${backendImageUrl}`;
const presignRes = await fetch(resolveUrl, {
headers: { Authorization: `Bearer ${API_KEY}` }
});
if (!presignRes.ok) throw new Error(`Resolve HTTP ${presignRes.status}: ${await presignRes.text()}`);
const { url: presignedUrl } = await presignRes.json();
if (!presignedUrl) throw new Error('Missing presigned URL');
// 3) Download from presigned URL
const fileRes = await fetch(presignedUrl);
if (!fileRes.ok) throw new Error(`Download HTTP ${fileRes.status}`);
const buf = Buffer.from(await fileRes.arrayBuffer());
fs.writeFileSync('image.png', buf);
console.log('Saved image.png');
}
generateImage().catch(err => {
console.error(err);
process.exit(1);
});Edit Image (single source)
Provide one image URL and a prompt describing the desired edit.
import fs from 'node:fs';
import fetch from 'node-fetch';
const API = 'https://api.ai.ml';
const BASE_URL = `${API}/v1/generation/images`;
const API_KEY = process.env.AIML_API_KEY || 'AIML_API_KEY';
const RESPONSE_FORMAT = process.env.RESPONSE_FORMAT || 'url'; // 'url' | 'presigned_url' | 'b64_json'
async function editImage() {
const body = {
model: 'image-gen.pro-1.0',
prompt: 'Remove the background and replace it with a soft gradient; keep subject lighting natural.',
image: 'https://example.com/source_image.png',
sequential_image_generation: 'disabled',
response_format: RESPONSE_FORMAT,
size: '2K',
stream: false,
watermark: false
};
// 1) Edit image
const res = await fetch(BASE_URL, {
method: 'POST',
headers: {
Authorization: `Bearer ${API_KEY}`,
'Content-Type': 'application/json'
},
body: JSON.stringify(body)
});
if (!res.ok) throw new Error(`HTTP ${res.status}: ${await res.text()}`);
const json = await res.json();
const data = json?.data?.image || {};
if (RESPONSE_FORMAT === 'b64_json') {
const b64 = data.b64_json;
if (!b64) throw new Error('No b64_json found');
fs.writeFileSync('image.png', Buffer.from(b64, 'base64'));
console.log('Saved image.png (from Base64)');
return;
}
const urlFromApi = data.url;
if (!urlFromApi) throw new Error('No image URL returned');
if (RESPONSE_FORMAT === 'presigned_url') {
// Direct download
const fileRes = await fetch(urlFromApi);
if (!fileRes.ok) throw new Error(`Download HTTP ${fileRes.status}`);
fs.writeFileSync('image.png', Buffer.from(await fileRes.arrayBuffer()));
console.log('Saved image.png (from presigned_url)');
return;
}
// RESPONSE_FORMAT === 'url' → resolve to presigned URL
const resolveUrl = urlFromApi.startsWith('http') ? urlFromApi : `${API}${urlFromApi}`;
const presignRes = await fetch(resolveUrl, {
headers: { Authorization: `Bearer ${API_KEY}` }
});
if (!presignRes.ok) throw new Error(`Resolve HTTP ${presignRes.status}: ${await presignRes.text()}`);
const { url: presignedUrl } = await presignRes.json();
if (!presignedUrl) throw new Error('Missing presigned URL');
const fileRes = await fetch(presignedUrl);
if (!fileRes.ok) throw new Error(`Download HTTP ${fileRes.status}`);
fs.writeFileSync('image.png', Buffer.from(await fileRes.arrayBuffer()));
console.log('Saved image.png');
}
editImage().catch(err => {
console.error(err);
process.exit(1);
});Tip : You can also set "response_format": "presigned_url" to get a direct downloadable URL,
or "response_format": "b64_json" to receive the image inline as Base64 data.
Use Multiple Images to Create a New Image
Provide two or more image URLs in image and describe the transformation or composition logic in prompt.
import fs from 'node:fs';
import fetch from 'node-fetch';
const API = 'https://api.ai.ml';
const BASE_URL = `${API}/v1/generation/images`;
const API_KEY = process.env.AIML_API_KEY || 'AIML_API_KEY';
async function generateImage() {
const body = {
model: 'image-gen.pro-1.0',
prompt: 'Replace the first person in image 1 with the person in image 2.',
image: ['https://google.com/sample_1.png', 'https://google.com/sample_2.png'],
sequential_image_generation: 'disabled',
response_format: 'url',
size: '2K',
stream: false,
watermark: false
};
// 1) Create image
const res = await fetch(BASE_URL, {
method: 'POST',
headers: {
Authorization: `Bearer ${API_KEY}`,
'Content-Type': 'application/json'
},
body: JSON.stringify(body)
});
if (!res.ok) throw new Error(`HTTP ${res.status}: ${await res.text()}`);
const json = await res.json();
const backendImageUrl = json?.data?.image?.url;
if (!backendImageUrl) throw new Error('No image URL returned');
// 2) Resolve to presigned URL
const resolveUrl = backendImageUrl.startsWith('http') ? backendImageUrl : `${API}${backendImageUrl}`;
const presignRes = await fetch(resolveUrl, { headers: { Authorization: `Bearer ${API_KEY}` } });
if (!presignRes.ok) throw new Error(`Resolve HTTP ${presignRes.status}: ${await presignRes.text()}`);
const { url: presignedUrl } = await presignRes.json();
if (!presignedUrl) throw new Error('Missing presigned URL');
// 3) Download
const fileRes = await fetch(presignedUrl);
if (!fileRes.ok) throw new Error(`Download HTTP ${fileRes.status}`);
const buf = Buffer.from(await fileRes.arrayBuffer());
fs.writeFileSync('image.png', buf);
console.log('Saved image.png');
}
generateImage().catch(err => {
console.error(err);
process.exit(1);
});Implementation Notes & Best Practices
-
Prompts: Be specific and directive. For edits/compositions, refer to “image 1 / image 2” explicitly in the prompt. Refer to our Guideline and Best Practices for Image Generation Reference.
-
Security: Never expose your API key client-side; proxy requests server-side or use environment variables.
-
Watermarks: Set
watermarkaccording to your brand policy. -
Resilience: Check for
data.image.urlbefore resolving. Always handle non-200 responses and timeouts. -
Caching: Presigned URLs are typically time-limited; resolve on demand before downloading.