Upload, list, inspect, and delete model images.
Images
Images can be uploaded for model training or reference-image workflows. The same upload
endpoint handles both, but the type value changes how the image is used.
| Type | Use for |
|---|---|
modelInput | Training images attached to a trained model. |
auxiliaryType | Reference images used by generation prompts and workflows. |
Limits
| Property | Value |
|---|---|
| Supported image types | modelInput, auxiliaryType |
| Supported formats | jpg, jpeg, webp, png, heic |
| Maximum request size | 20MB |
| Maximum images | 20 images of each type per model |
Upload an image
Upload requests use multipart/form-data with:
| Part | Value |
|---|---|
file | Binary image file. |
data | JSON string with modelID and type. |
const modelId = '<MODEL_ID>'
const file = document.querySelector('input[type="file"]').files?.[0]
if (!file) {
throw new Error('Select an image file before uploading.')
}
const payload = {
modelID: modelId,
type: 'modelInput',
}
const formData = new FormData()
formData.append('file', file)
formData.append('data', JSON.stringify(payload))
const response = await fetch(`${BASE_URL}/images/upload`, {
method: 'POST',
headers,
body: formData,
})
if (!response.ok) {
throw new Error(await response.text())
}
const body = await response.json()
const image = body.resultimport json
model_id = "<MODEL_ID>"
payload = {
"modelID": model_id,
"type": "modelInput",
}
with open("example/image.jpg", "rb") as image_file:
files = {
"file": image_file,
"data": (None, json.dumps(payload), "application/json"),
}
response = requests.post(f"{BASE_URL}/images/upload", headers=headers, files=files)
response.raise_for_status()
image = response.json()["result"]The response includes the uploaded image id, url, modelID, and type.
List model images
Use GET /models/{modelID}/images to list images for a model. The imageType filter
supports all, input, output, and auxiliaryType.
Omit cursor or send an empty string for the first page. When hasMore is true,
send the returned nextCursor as cursor to fetch the next page. Keep
filters unchanged between pages; restart with an empty cursor when they change.
pageSize defaults to 20 and accepts values from 1 to 100.
const modelId = '<MODEL_ID>'
const params = new URLSearchParams({
imageType: 'all',
cursor: '',
pageSize: '20',
})
const response = await fetch(`${BASE_URL}/models/${modelId}/images?${params}`, {
headers,
})
if (!response.ok) {
throw new Error(await response.text())
}
const body = await response.json()
const images = body.result
const nextCursor = body.hasMore ? body.nextCursor : nullmodel_id = "<MODEL_ID>"
response = requests.get(
f"{BASE_URL}/models/{model_id}/images",
headers=headers,
params={"imageType": "all", "cursor": "", "pageSize": 20},
)
response.raise_for_status()
body = response.json()
images = body["result"]
next_cursor = body["nextCursor"] if body["hasMore"] else NoneGet image metadata
const imageId = '<IMAGE_ID>'
const response = await fetch(`${BASE_URL}/images/${imageId}`, {
headers,
})
if (!response.ok) {
throw new Error(await response.text())
}
const body = await response.json()
const image = body.resultimage_id = "<IMAGE_ID>"
response = requests.get(f"{BASE_URL}/images/{image_id}", headers=headers)
response.raise_for_status()
image = response.json()["result"]Delete an image
const imageId = '<IMAGE_ID>'
const response = await fetch(`${BASE_URL}/images/${imageId}`, {
method: 'DELETE',
headers,
})
if (!response.ok) {
throw new Error(await response.text())
}image_id = "<IMAGE_ID>"
response = requests.delete(f"{BASE_URL}/images/{image_id}", headers=headers)
response.raise_for_status()