Skip to Content
FeaturesImage Generation and Editing

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):

  1. POST /v1/generation/images → returns a backend media URL in data.image.url (e.g., /v1/media/images/orgs%2F64%2Fimages%2F...).

  2. Authorized GET to that backend URL → returns {"url": "<presigned-download-url>"}.

  3. GET the presigned URL (no auth) to download the image bytes.

Guidelines to Best Practices for Image Generation reference

Image API

Endpoint: POST /v1/generation/images

FieldTypeRequiredExampleNotes
modelstring"image-gen.pro-1.0"Model identifier
promptstring"A forest at sunrise..."Natural language description or edit instruction
imagestring | 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_generationstring"disabled"Keep as "disabled" unless otherwise enabled
response_formatstring"url"Use "url" to receive a backend media URL
sizestring"2K"Output resolution preset
streambooleanfalseStreaming not used in examples
watermarkbooleanfalseEnable/disable watermark

Successful Response (JSON)

{ "data": { "image": { "url": "/v1/media/images/orgs%2F64%2Fimages%2Fabc123.png" } } }

Resolve/Download

  1. Resolve (authorized):
GET /v1/media/images/orgs%2F64%2Fimages%2Fabc123.png Authorization: Bearer <AIML_API_KEY>

Response:

{ "url": "https://presigned.cdn.ai.ml/...." }
  1. 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 watermark according to your brand policy.

  • Resilience: Check for data.image.url before resolving. Always handle non-200 responses and timeouts.

  • Caching: Presigned URLs are typically time-limited; resolve on demand before downloading.

Last updated on