Skip to main content

Documentation Index

Fetch the complete documentation index at: https://mintlify.com/anil-matcha/open-generative-ai/llms.txt

Use this file to discover all available pages before exploring further.

Before you can use a local file as a reference image or audio input in any generation call, you need to upload it to Muapi.ai to receive a hosted URL. The uploadFile function handles this using a multipart/form-data POST to /api/v1/upload_file and uses an XMLHttpRequest internally so you can track upload progress in real time. The returned URL is what you pass as image_url, audio_url, or inside the images_list array in downstream generation calls.

uploadFile(apiKey, file, onProgress)

Upload a single file to Muapi.ai and receive a hosted URL. Uses XMLHttpRequest for browser-native progress events and resolves the URL from the url, file_url, or data.url field in the JSON response.
apiKey
string
required
Your Muapi.ai API key. Obtain one at muapi.ai/access-keys.
file
File
required
A browser File object. Typically obtained from an <input type="file"> element or a drag-and-drop handler. The file is sent as the file field in a FormData body.
onProgress
function
Optional progress callback invoked as the upload proceeds. Receives a single percent argument — an integer from 0 to 100 computed from event.loaded / event.total.
(percent: number) => void
Returns: Promise<string> — resolves to the hosted URL string of the uploaded file. Rejects with an Error if the upload fails, the server returns a non-2xx status, or the response body contains no URL.
uploadFile is browser-only. It relies on XMLHttpRequest and FormData, which are not available in Node.js. For server-side uploads, post the file as multipart/form-data directly to https://api.muapi.ai/api/v1/upload_file with the x-api-key header using any HTTP library that supports multipart bodies.

Example — upload a reference image with progress tracking

import { uploadFile } from 'studio';

// In a browser with a file input
const fileInput = document.querySelector('input[type="file"]');
const file = fileInput.files[0];

const url = await uploadFile('your-api-key', file, (percent) => {
  console.log(`Upload progress: ${percent}%`);
});

console.log(url); // https://cdn.muapi.ai/uploads/...

// Now use the URL in a generation call
const result = await generateI2I('your-api-key', {
  model: 'flux-kontext-dev',
  image_url: url,
  prompt: 'transform into watercolor painting'
});

Supported File Types

Pass files matching the formats expected by the downstream model. Sending an incompatible type will cause the generation call (not the upload itself) to fail.
Use caseAccepted formats
Image models (reference images, style inputs)JPEG, PNG, WebP, GIF
Lip sync models (audio-driven talking video)MP3, WAV, M4A
The upload endpoint accepts the file regardless of type — format validation happens at generation time when the hosted URL is passed to the model. Always confirm the model’s accepted input formats before uploading.

Upload History and localStorage Caching

The Open Generative AI app caches every uploaded URL (along with a thumbnail) in localStorage so the same file is not re-uploaded across browser sessions. When you open the reference image picker, all previously uploaded images appear as reusable thumbnails. The cache key is upload_history and each entry stores the hosted URL and a display name. If you are embedding uploadFile in your own application and want to replicate this behaviour, store the returned URL in localStorage after a successful upload:
import { uploadFile } from 'studio';

async function uploadAndCache(apiKey, file) {
  const url = await uploadFile(apiKey, file);

  const history = JSON.parse(localStorage.getItem('upload_history') || '[]');
  history.unshift({ url, name: file.name, uploadedAt: Date.now() });
  localStorage.setItem('upload_history', JSON.stringify(history));

  return url;
}

Multi-Image Upload

Models that accept multiple reference images (such as nano-banana-2-edit, which supports up to 14 images) require an images_list array rather than a single image_url. Upload each file individually with uploadFile, collect the returned URLs, then pass the array to the generation call.
import { uploadFile, generateI2I } from 'studio';

const files = Array.from(fileInput.files); // up to 14 files

const urls = await Promise.all(
  files.map(f => uploadFile('your-api-key', f).then(r => r))
);

const result = await generateI2I('your-api-key', {
  model: 'nano-banana-2-edit',
  images_list: urls,
  resolution: '2K'
});
Use Promise.all to upload all files in parallel rather than sequentially — this significantly reduces total upload time when working with multiple large images.
The following models support images_list input with varying maximum counts:
ModelMax images
Nano Banana 2 Edit14
Nano Banana Edit10
Flux Kontext Dev I2I10
Kling O1 Edit Image10
GPT-4o Edit / GPT Image 1.5 Edit10
Bytedance Seedream Edit v4 / v4.510
Flux 2 Flex/Pro Edit8
Nano Banana Pro Edit8
Vidu Q2 Reference to Image7
GPT-4o Image to Image5
Flux 2 Klein 4b/9b Edit4
Qwen Image Edit Plus / 25113
Wan 2.5/2.6 Image Edit2–3
Flux Kontext Pro/Max I2I2

Server-Side Upload

uploadFile uses XMLHttpRequest and cannot run in Node.js or edge runtimes. For server-side environments — such as a Next.js API route, a background job, or a CLI tool — post the file as multipart/form-data directly to https://api.muapi.ai/api/v1/upload_file with the x-api-key header, using any HTTP library that supports multipart bodies (e.g., form-data + node-fetch, axios, or undici).
For standard browser usage, uploadFile is the recommended path — it handles the multipart encoding, progress events, and URL extraction automatically.

Build docs developers (and LLMs) love