Reference

Images API

Compress an image from a file or a URL, poll it, download it, rename it, share it, run it again or delete it. Every images endpoint with samples.

An image is one compression: the file you sent, the settings you chose, and once it has finished, the optimized copy. Every image on your account is here, the ones you uploaded through the website included.

The life of an image

TEXT
queued ──► optimizing ──► completed
   │                  ├──► already-optimized
   │                  └──► failed
   └──► cancelled

An image is queued the moment you send it, and a worker usually picks it up within seconds. It ends in one of three ways: completed with a smaller copy, already-optimized when nothing came out smaller and the upload itself is handed back, or failed. While it's still queued you can cancel it. A failed or cancelled image can be retried, and any image that isn't running can be compressed again with other settings, which makes a new image and leaves the old one as it is.

Poll GET /images/{id} until the status is no longer queued or optimizing. Once it has finished, optimized holds the copy and download_url fetches it with your key. The alt text comes a few seconds after a completed or already-optimized image, so if you want it, keep polling that image until alt_text.status is no longer pending too. A failed or cancelled image's alt text stays pending until the image is retried, so stop there.

Files and names

An image has two files. The original is exactly what you uploaded and keeps the name it came with. The optimized copy is named after it, with the extension of the format it was delivered in, until you rename it. Both stay in storage until you delete the image, or until about 24 hours after it finished for an image you sent as ephemeral.

Folders

On a paid plan, an image can carry the folder it belongs in. Send folder with the upload, like holiday/beach, and POST /images/download puts the image there in the zip, so a folder you send image by image comes back the way it was. Images sent without one sit at the top of the zip, and two files with the same name in one folder are kept apart as name.webp and name (2).webp.

The website sends the same folder for a folder picked with Upload a folder, and for a zip dropped on the upload box, which the browser opens and uploads image by image. The API takes no zip: unzip it on your side and send each file with the folder it sat in.

Either slash separates folders. Characters a file name can't hold become a hyphen, and a . or .. folder is dropped, so the image's folder is exactly what the zip uses. On the free plan an upload with a folder is refused with pro_required. An image keeps its folder if the plan lapses, and so does a copy made by compressing it again.

Responsive sizes

On a paid plan, an image can also come back at several widths, for an <img srcset> that lets each screen download the size it needs. Send responsive_widths with the upload, or with a recompress, like [480, 768, 1200, 1600], the website's default: up to 8 widths, each from 16 to 65535 pixels. In a multipart form, repeat responsive_widths[] or send them in one field as 480, 768, 1200, 1600.

Each width is made from your upload, at the same level and in the format the image is delivered in, so every file is one step of compression from the original. Your width, height, scale and size_limit shape the optimized copy alone. Nothing is enlarged: a width wider than the upload is made at the upload's own width, and only once, however many of your widths are wider.

The sizes are made a few seconds after the image finishes, under responsive in the image:

JSON
"responsive": {
    "status": "ready",
    "files": [
        {
            "width": 480,
            "height": 360,
            "size": 24118,
            "name": "team-offsite-480w.webp",
            "download_url": "https://www.iminify.com/api/v1/images/9d3c5b8e-6f0a-4c1e-9b7d-2a4e8f1c6b35/responsive/480"
        }
    ],
    "download_url": "https://www.iminify.com/api/v1/images/9d3c5b8e-6f0a-4c1e-9b7d-2a4e8f1c6b35/responsive.zip",
    "html": "<img\n  src=\"team-offsite-1600w.webp\"\n  srcset=\"team-offsite-480w.webp 480w, ...\"\n  ..."
}

status is pending while they're being made, ready once every width is, failed when one couldn't be made (none is kept; compress the image again with the widths to try again), and skipped for an animation, which gets none. responsive itself is null for an image sent without widths.

  • Files: each one is named after the image with its width, like team-offsite-768w.webp, and downloads with your key from its download_url (one size), or all of them in one zip from responsive.download_url (every size). They follow a rename of the image. POST /images/download zips the optimized copies alone.
  • The snippet: html is an <img> with a srcset over the files, its width and height from the widest, and the image's alt text. It names each file by its name, so paste it beside the files, or put their folder's path in front, and change sizes to the width the image takes in your layout.
  • Waiting: poll the image until responsive.status is no longer pending, or on a paid plan let a webhook tell you: image.responsive_finished arrives once they're done. An image can't be deleted while its sizes are being made.
  • Plans: sent on the free plan, an upload with responsive_widths is refused with pro_required. Sizes already made stay downloadable if the plan lapses.

Alt text and file names

Every image you compress also gets an alt text written by AI: one sentence describing what it shows, for its alt attribute, so screen readers and search engines know what's there. It comes with a suggested file name, a few descriptive words joined by hyphens. Send alt_text as false to leave both out.

They're written from a small copy of the image, at most 768 pixels on its longest side, which goes to Anthropic, whose Claude model writes them. They arrive a few seconds after the image finishes, under alt_text in the image:

JSON
"alt_text": {
    "status": "written",
    "text": "Six colleagues laughing around a picnic table on a lakeside lawn",
    "language": "en",
    "suggested_name": "colleagues-picnic-table-lakeside"
}

status is pending while it's being written, written once it's ready, failed when the model gave no usable answer, and skipped when your daily AI alt texts were used up as the image was queued. alt_text itself is null for an image sent with it switched off.

  • Language: alt_text_language takes one of these tags: en (English), es (Spanish), fr (French), de (German), it (Italian), pt (Portuguese), nl (Dutch), pl (Polish), sv (Swedish), tr (Turkish), ru (Russian), uk (Ukrainian), ar (Arabic), fa (Persian), he (Hebrew), hi (Hindi), id (Indonesian), vi (Vietnamese), th (Thai), ja (Japanese), ko (Korean), zh-Hans (Simplified Chinese), zh-Hant (Traditional Chinese). English is the default. The suggested name follows the language when it's written in the Latin alphabet, and is in English otherwise, so it stays a safe file name.
  • The name: the suggestion doesn't rename anything on its own. Pass it to rename the image, or send use_suggested_name as true with the upload and the optimized copy takes it as soon as it arrives, so name changes after you may already have read it. An image that already has a new name by then, yours or an earlier suggestion, keeps it.
  • Counting: each alt text counts against your plan's daily AI alt texts, the same count the website spends. An image whose bytes Iminify has already described in that language gets the same text back at no cost. Once the day's alt texts are used up, images still compress, without one.
  • Later: an image sent without one, whose alt text failed, or that was skipped can get one with POST /images/{id}/alt-text. A written one can be asked for again in another language.

The text is written by AI, so read it before you publish it. Like any description, it can be wrong about what it can't see clearly, a count of small objects for example.

Deleting images once saved

An image stays on your account until you delete it. A program that keeps its own copy of every result, like a plugin that writes the smaller file back into a site, can send ephemeral as true with the upload instead, then send DELETE /images/{id} once it has written the result.

Anything you leave is deleted for you about 24 hours after the image finished, whether it completed, failed or was cancelled, with its original and its optimized copy. A download deletes nothing, so a result you failed to save can still be fetched again until then. Until it goes, an ephemeral image is listed, downloaded and counted like any other, on the website too. As with every delete, only a note of what the compression measured stays, with no file or name.

An upload group takes ephemeral the same way, and goes with every file it made and its source about 24 hours after its last file finished.

Bulk work

Send priority as background with work nobody is waiting on, such as a whole library. A background image waits until no image sent without it is waiting, from any account on any plan, so someone watching an upload is never held up by a bulk run. On a busy day that can be a long wait. It counts against your daily and per-minute limits the same as any other image, and comes out the same.

Leave priority out, or send interactive, for everything a person waits on. An upload group takes priority too, for every file it makes.

The Image object

id string
The image's id.
status string
Where the image is. queued: waiting for a worker. optimizing: being compressed. completed: finished, the optimized copy is ready. already-optimized: finished, but nothing came out smaller than the upload, so the upload itself is handed back as the optimized copy. failed: it could not be compressed. cancelled: called off before it started.
name string
The name the optimized copy downloads under: the uploaded name, or the one you gave it, with the delivered format's extension. An auto conversion has no format until it finishes, so until then the extension is the uploaded file's own.
original object
The file as it was uploaded.
original.name string
The file name it downloads under.
original.format string
The file's format, as its extension: jpg, png, webp, avif, gif, heic, tiff and so on.
original.size integer
Its size in bytes.
original.width integer
Its width in pixels, the way it displays: a phone photo stored on its side is measured upright.
original.height integer
Its height in pixels, the way it displays.
original.download_url string
Where to download it with your key.
optimized object or null
The optimized copy, or null until the image has finished.
optimized.name string
The file name it downloads under.
optimized.format string
The file's format, as its extension: jpg, png, webp, avif, gif, heic, tiff and so on.
optimized.size integer
Its size in bytes.
optimized.width integer
Its width in pixels, the way it displays: a phone photo stored on its side is measured upright.
optimized.height integer
Its height in pixels, the way it displays.
optimized.download_url string
Where to download it with your key.
saved_bytes integer or null
Bytes the optimized copy saves against the original. Negative when a conversion or an enlargement made the file bigger. null until the image has finished.
saved_percent number or null
The same saving as a percentage of the original, to two decimal places. null until the image has finished.
settings object
The settings the image was compressed with, as they were sent.
settings.level string
The compression level.
settings.format string or null
The format that was asked for, or null when none was sent. auto stays auto after the image finishes; the format the optimized copy came out in is optimized.format.
settings.keep_metadata boolean
Whether the EXIF metadata was kept.
settings.width integer or null
The width it was resized to, or null.
settings.height integer or null
The height it was resized to, or null.
settings.scale integer or null
The percentage it was scaled to, or null.
settings.size_limit integer or null
The most the optimized copy may weigh, in kilobytes of 1,000 bytes, or null when no limit was sent.
settings.responsive_widths array or null
The widths of the responsive sizes asked for, narrowest first, or null when none were.
size_limit_status string or null
How the optimized copy came out against settings.size_limit. under: at or under it. resized: under it, made smaller in pixels to get there, so optimized.width and optimized.height are smaller than the size you asked for, or than the upload's own. over: still over it after everything Iminify could try; an animation is never fitted. null when no limit was sent, and until the image has finished.
content_credentials object or null
The Content Credentials the upload carried, a signed C2PA record of where the image came from, and what became of them. null when it carried none, and until the image has finished. See Content Credentials.
content_credentials.status string
Whether the optimized copy still carries them.
content_credentials.generative_ai boolean
Whether they say generative AI made the image, wholly or in part. Iminify reads what they state and doesn't check their signature.
alt_text object or null
The AI alt text and suggested file name, or null when none was asked for. See Alt text and file names.
alt_text.status string
pending: being written; it arrives a few seconds after the image finishes, and waits for a retry while the image is failed or cancelled. written: ready. failed: the model gave no usable answer, or something broke; ask again with the alt text call. skipped: your daily AI alt texts were used up when the image was queued.
alt_text.text string or null
One sentence for the image's alt attribute, or null until it is written.
alt_text.language string or null
The language tag it was written in.
alt_text.suggested_name string or null
A short descriptive file name without an extension, ready for the rename call, or null until it is written or when the model offered none.
responsive object or null
The image's responsive sizes (paid plans), or null when none were asked for. See Responsive sizes.
responsive.status string
pending: being made, a few seconds after the image finishes; it waits for a retry while the image is failed or cancelled. ready: every width is made. failed: a width could not be made, so none was kept; compress the image again with responsive_widths to try again. skipped: an animation, which gets none.
responsive.files array
Each width once it is ready, narrowest first, empty until then: its width and height in pixels, its size in bytes, the name it downloads under (the image's name, then the width, like team-offsite-768w.webp) and where to download it with your key. A width wider than the upload was made at the upload's own width.
responsive.download_url string or null
Where to download every width in one zip with your key, or null until they are ready.
responsive.html string or null
An <img> with a srcset over the files, ready to paste beside them, or null until they are ready. It names each file by its name, so put the folder's path in front when the files sit in another folder, and change sizes to the width the image takes in your layout.
scan_id string or null
The page scan that found the image, or null for an upload.
source_url string or null
The address the image was fetched from: the image's address on the scanned page, or the url you sent instead of a file. null for a file you sent.
folder string or null
The folder the image was uploaded from, inside the folder you picked, like holiday/beach: the zip of several images puts it there. null for an image sent on its own. Keeping folders comes with a paid plan. See Folders.
share_url string or null
The public page while the image is shared, or null.
created_at timestamp
When the image was queued.
updated_at timestamp
When anything about it last changed, its status included.

List images

GET /api/v1/images

Every image on your account, newest first: your uploads, the images your page scans found, and every re-run. The website's results table lists the same images. Follow links.next for the next page.

Query parameters

status
string
Only images with this status.

queued optimizing completed failed already-optimized cancelled

source
string
upload for images you sent (and their re-runs), scan for the ones page scans found.

upload scan

scan
string (id)
Only the images of this page scan.
per_page
integer
Images a page, 1 to 100. 1 to 100 Default: 15
page
integer
The page to read. 1 to 10000000 Default: 1

Request

curl "https://www.iminify.com/api/v1/images?status=completed&per_page=20" \
  --connect-timeout 10 --max-time 30 \
  -H "Authorization: Bearer $IMINIFY_API_KEY" \
  -H "Accept: application/json"

Response 200

JSON
{
    "data": [
        {
            "id": "9d3c5b8e-6f0a-4c1e-9b7d-2a4e8f1c6b35",
            "status": "completed",
            "name": "team-offsite.webp",
            "original": {
                "name": "team-offsite.jpg",
                "format": "jpg",
                "size": 2841205,
                "width": 4032,
                "height": 3024,
                "download_url": "https://www.iminify.com/api/v1/images/9d3c5b8e-6f0a-4c1e-9b7d-2a4e8f1c6b35/download?type=original"
            },
            "optimized": {
                "name": "team-offsite.webp",
                "format": "webp",
                "size": 212877,
                "width": 1600,
                "height": 1200,
                "download_url": "https://www.iminify.com/api/v1/images/9d3c5b8e-6f0a-4c1e-9b7d-2a4e8f1c6b35/download"
            },
            "saved_bytes": 2628328,
            "saved_percent": 92.51,
            "settings": {
                "level": "smart",
                "format": "webp",
                "keep_metadata": false,
                "width": 1600,
                "height": null,
                "scale": null,
                "size_limit": 250,
                "responsive_widths": [
                    480,
                    768,
                    1200,
                    1600
                ]
            },
            "size_limit_status": "under",
            "content_credentials": {
                "status": "removed",
                "generative_ai": false
            },
            "alt_text": {
                "status": "written",
                "text": "Six colleagues laughing around a picnic table on a lakeside lawn",
                "language": "en",
                "suggested_name": "colleagues-picnic-table-lakeside"
            },
            "responsive": {
                "status": "ready",
                "files": [
                    {
                        "width": 480,
                        "height": 360,
                        "size": 24118,
                        "name": "team-offsite-480w.webp",
                        "download_url": "https://www.iminify.com/api/v1/images/9d3c5b8e-6f0a-4c1e-9b7d-2a4e8f1c6b35/responsive/480"
                    },
                    {
                        "width": 768,
                        "height": 576,
                        "size": 55904,
                        "name": "team-offsite-768w.webp",
                        "download_url": "https://www.iminify.com/api/v1/images/9d3c5b8e-6f0a-4c1e-9b7d-2a4e8f1c6b35/responsive/768"
                    },
                    {
                        "width": 1200,
                        "height": 900,
                        "size": 128330,
                        "name": "team-offsite-1200w.webp",
                        "download_url": "https://www.iminify.com/api/v1/images/9d3c5b8e-6f0a-4c1e-9b7d-2a4e8f1c6b35/responsive/1200"
                    },
                    {
                        "width": 1600,
                        "height": 1200,
                        "size": 212877,
                        "name": "team-offsite-1600w.webp",
                        "download_url": "https://www.iminify.com/api/v1/images/9d3c5b8e-6f0a-4c1e-9b7d-2a4e8f1c6b35/responsive/1600"
                    }
                ],
                "download_url": "https://www.iminify.com/api/v1/images/9d3c5b8e-6f0a-4c1e-9b7d-2a4e8f1c6b35/responsive.zip",
                "html": "<img\n  src=\"team-offsite-1600w.webp\"\n  srcset=\"team-offsite-480w.webp 480w, team-offsite-768w.webp 768w, team-offsite-1200w.webp 1200w, team-offsite-1600w.webp 1600w\"\n  sizes=\"(max-width: 1600px) 100vw, 1600px\"\n  width=\"1600\"\n  height=\"1200\"\n  alt=\"Six colleagues laughing around a picnic table on a lakeside lawn\"\n  style=\"max-width: 100%; height: auto\"\n  decoding=\"async\"\n>"
            },
            "scan_id": null,
            "source_url": null,
            "folder": null,
            "share_url": null,
            "created_at": "2026-10-01T09:30:00+00:00",
            "updated_at": "2026-10-01T09:30:09+00:00"
        },
        {
            "id": "9d3c5b91-0b2e-4a7f-8c1d-5e6f7a8b9c0d",
            "status": "queued",
            "name": "IMG_4471.heic",
            "original": {
                "name": "IMG_4471.heic",
                "format": "heic",
                "size": 3402118,
                "width": 4032,
                "height": 3024,
                "download_url": "https://www.iminify.com/api/v1/images/9d3c5b91-0b2e-4a7f-8c1d-5e6f7a8b9c0d/download?type=original"
            },
            "optimized": null,
            "saved_bytes": null,
            "saved_percent": null,
            "settings": {
                "level": "ultra",
                "format": "auto",
                "keep_metadata": true,
                "width": null,
                "height": null,
                "scale": null,
                "size_limit": null,
                "responsive_widths": [
                    480,
                    768,
                    1200,
                    1600
                ]
            },
            "size_limit_status": null,
            "content_credentials": null,
            "alt_text": {
                "status": "pending",
                "text": null,
                "language": "de",
                "suggested_name": null
            },
            "responsive": {
                "status": "pending",
                "files": [],
                "download_url": null,
                "html": null
            },
            "scan_id": null,
            "source_url": null,
            "folder": null,
            "share_url": null,
            "created_at": "2026-10-01T09:31:12+00:00",
            "updated_at": "2026-10-01T09:31:12+00:00"
        }
    ],
    "links": {
        "first": "https://www.iminify.com/api/v1/images?page=1",
        "last": "https://www.iminify.com/api/v1/images?page=1",
        "prev": null,
        "next": null
    },
    "meta": {
        "current_page": 1,
        "from": 1,
        "last_page": 1,
        "links": [
            {
                "url": null,
                "label": "&laquo; Previous",
                "page": null,
                "active": false
            },
            {
                "url": "https://www.iminify.com/api/v1/images?page=1",
                "label": "1",
                "page": 1,
                "active": true
            },
            {
                "url": null,
                "label": "Next &raquo;",
                "page": null,
                "active": false
            }
        ],
        "path": "https://www.iminify.com/api/v1/images",
        "per_page": 15,
        "to": 2,
        "total": 2
    }
}

Compress an image

POST /api/v1/images

Send the image itself as a multipart file, or its address as url and Iminify fetches it. The answer comes straight back with the status queued and a Location header; the compression runs in the background, usually for a few seconds, so poll the image until its status is completed, already-optimized, failed or cancelled. Each image counts one against your daily images and your compressions a minute, whether it came through here or through the website.

The file goes through the same checks as an upload on the website: a format Iminify reads (PNG, JPG, JPEG, WEBP, GIF, HEIC, HEIF, TIFF, TIF), your plan's file size, a name of at most 128 bytes, and at most 64 megapixels, before and after any resize. An animated WebP or PNG can't be resized: with width, height or scale it is refused with animation_not_resizable, and one sent without them, in its own format, comes back with every frame. An address has to be public http or https: Iminify fetches it from its own servers, refuses private networks on the address and on every redirect, follows up to five redirects and gives up after 30 seconds. A file larger than your plan's size is refused, and Iminify keeps no more of it than that size. The file is named after the address. Iminify fetches up to 2 addresses for you at a time; one more sent before those finish is refused with rate_limited.

Body (multipart/form-data, or JSON for a url)

file
file
The image. Send either this or url.
url
string (URL)
The public address of the image to fetch. Send either this or file.
folder
string
The folder the image belongs in, like holiday/beach, so a zip of several images (POST /images/download) puts it there. Either slash separates folders, and characters a file name can't hold become a hyphen. Keeping folders comes with a paid plan; sent on another plan, the image is refused with pro_required.
ephemeral
boolean
Delete the image once you've saved it, for a caller that keeps its own copy. Send DELETE /images/{id} once you've written the result; anything you leave is deleted for you about 24 hours after the image finished, its files with it. Off by default, which keeps the image until you delete it. See Deleting images once saved. Default: false
priority
string
background for bulk work nobody waits on, such as a whole library: it runs after every image sent without it, on every plan, and counts against your limits the same. See Bulk work.

interactive background

Default: interactive
level
string
How hard to compress. smart finds the lowest quality that still looks like your upload, ultra goes further and softens fine texture a little, lossless changes no pixel unless a size_limit needs it to, none only applies the format, the resize, the size limit and the metadata choice. See Compression settings.

none lossless ultra smart

Default: smart
format
string
Convert to this format. auto encodes the image in every format that can hold it and keeps the smallest. Leave it out to keep the upload's own format; a HEIC or TIFF always comes back in another one, because Iminify doesn't write either. jpeg is read as jpg.

auto webp avif png jpg

keep_metadata
boolean
Keep the EXIF metadata (camera, date, location) in the optimized copy. Off by default, which strips it; the orientation is applied to the pixels first, so a photo never comes back on its side. Default: false
width
integer
Resize to this width in pixels. Alone, the height follows the aspect ratio. With height too, the image is resized to exactly that size, and its proportions change if they differ. Up to 65535. 1 to 65535
height
integer
Resize to this height in pixels, the same way as width. Up to 65535. 1 to 65535
scale
integer
Resize to this percentage of the original, 1 to 100. Cannot be combined with width or height. 1 to 100
size_limit
integer
The most the optimized copy may weigh, in kilobytes of 1,000 bytes, from 5 KB up. Iminify lowers the quality until the file fits, and makes the image smaller in pixels when the lowest quality is still over it. The limit comes before the level: under lossless or none, a file over it is encoded again with loss. A PNG or GIF kept in its own format that is over the limit comes back in a format with a quality to lower (JPG, WebP or AVIF), so png as the format is refused; an animation is never fitted. size_limit_status on the finished image says how it came out. See Size limit.
responsive_widths
array of strings
Paid plans: also make the image at each of these widths in pixels, for an <img srcset>, like [480, 768, 1200, 1600], the website's default. Up to 8 widths, each from 16 to 65535. Each width is made from the upload, at the same level and in the format the image is delivered in, and never enlarged: a width wider than the upload is made at the upload's own width, once. In a multipart form, repeat responsive_widths[] or send them in one field, separated by commas. They are made a few seconds after the image finishes; responsive on the image lists them. Sent on another plan, the image is refused with pro_required. See Responsive sizes.
alt_text
boolean
Write an alt text and a suggested file name for the image with AI. On by default; send false to leave it out. A small copy of the image goes to Anthropic, whose Claude model writes both, and they arrive a few seconds after the image finishes. Each one counts against your daily AI alt texts; once those are used up the image still compresses, without one. See Alt text and file names. Default: true
alt_text_language
string
The language to write the alt text in, as one of these tags: en (English), es (Spanish), fr (French), de (German), it (Italian), pt (Portuguese), nl (Dutch), pl (Polish), sv (Swedish), tr (Turkish), ru (Russian), uk (Ukrainian), ar (Arabic), fa (Persian), he (Hebrew), hi (Hindi), id (Indonesian), vi (Vietnamese), th (Thai), ja (Japanese), ko (Korean), zh-Hans (Simplified Chinese), zh-Hant (Traditional Chinese). The suggested file name follows it when the language is written in the Latin alphabet, and is in English otherwise.

en es fr de it pt nl pl sv tr ru uk ar fa he hi id vi th ja ko zh-Hans zh-Hant

Default: en
use_suggested_name
boolean
Rename the optimized copy to the suggested file name as soon as the alt text arrives, unless it already has a new name by then: yours, or an earlier suggestion. Default: false

Request

curl -X POST "https://www.iminify.com/api/v1/images" \
  --connect-timeout 10 --max-time 1800 \
  -H "Authorization: Bearer $IMINIFY_API_KEY" \
  -H "Accept: application/json" \
  -F "[email protected]" \
  -F "level=smart" \
  -F "format=webp" \
  -F "width=1600"

Response 202

JSON
{
    "data": {
        "id": "9d3c5b91-0b2e-4a7f-8c1d-5e6f7a8b9c0d",
        "status": "queued",
        "name": "IMG_4471.heic",
        "original": {
            "name": "IMG_4471.heic",
            "format": "heic",
            "size": 3402118,
            "width": 4032,
            "height": 3024,
            "download_url": "https://www.iminify.com/api/v1/images/9d3c5b91-0b2e-4a7f-8c1d-5e6f7a8b9c0d/download?type=original"
        },
        "optimized": null,
        "saved_bytes": null,
        "saved_percent": null,
        "settings": {
            "level": "ultra",
            "format": "auto",
            "keep_metadata": true,
            "width": null,
            "height": null,
            "scale": null,
            "size_limit": null,
            "responsive_widths": [
                480,
                768,
                1200,
                1600
            ]
        },
        "size_limit_status": null,
        "content_credentials": null,
        "alt_text": {
            "status": "pending",
            "text": null,
            "language": "de",
            "suggested_name": null
        },
        "responsive": {
            "status": "pending",
            "files": [],
            "download_url": null,
            "html": null
        },
        "scan_id": null,
        "source_url": null,
        "folder": null,
        "share_url": null,
        "created_at": "2026-10-01T09:31:12+00:00",
        "updated_at": "2026-10-01T09:31:12+00:00"
    }
}

Get an image

GET /api/v1/images/{id}

One image, with its status. This is the call to poll while an image is compressing; once a second or two apart is plenty.

Path parameters

id
string (id) required
The image's id.

Request

curl "https://www.iminify.com/api/v1/images/9d3c5b8e-6f0a-4c1e-9b7d-2a4e8f1c6b35" \
  --connect-timeout 10 --max-time 30 \
  -H "Authorization: Bearer $IMINIFY_API_KEY" \
  -H "Accept: application/json"

Response 200

JSON
{
    "data": {
        "id": "9d3c5b8e-6f0a-4c1e-9b7d-2a4e8f1c6b35",
        "status": "completed",
        "name": "team-offsite.webp",
        "original": {
            "name": "team-offsite.jpg",
            "format": "jpg",
            "size": 2841205,
            "width": 4032,
            "height": 3024,
            "download_url": "https://www.iminify.com/api/v1/images/9d3c5b8e-6f0a-4c1e-9b7d-2a4e8f1c6b35/download?type=original"
        },
        "optimized": {
            "name": "team-offsite.webp",
            "format": "webp",
            "size": 212877,
            "width": 1600,
            "height": 1200,
            "download_url": "https://www.iminify.com/api/v1/images/9d3c5b8e-6f0a-4c1e-9b7d-2a4e8f1c6b35/download"
        },
        "saved_bytes": 2628328,
        "saved_percent": 92.51,
        "settings": {
            "level": "smart",
            "format": "webp",
            "keep_metadata": false,
            "width": 1600,
            "height": null,
            "scale": null,
            "size_limit": 250,
            "responsive_widths": [
                480,
                768,
                1200,
                1600
            ]
        },
        "size_limit_status": "under",
        "content_credentials": {
            "status": "removed",
            "generative_ai": false
        },
        "alt_text": {
            "status": "written",
            "text": "Six colleagues laughing around a picnic table on a lakeside lawn",
            "language": "en",
            "suggested_name": "colleagues-picnic-table-lakeside"
        },
        "responsive": {
            "status": "ready",
            "files": [
                {
                    "width": 480,
                    "height": 360,
                    "size": 24118,
                    "name": "team-offsite-480w.webp",
                    "download_url": "https://www.iminify.com/api/v1/images/9d3c5b8e-6f0a-4c1e-9b7d-2a4e8f1c6b35/responsive/480"
                },
                {
                    "width": 768,
                    "height": 576,
                    "size": 55904,
                    "name": "team-offsite-768w.webp",
                    "download_url": "https://www.iminify.com/api/v1/images/9d3c5b8e-6f0a-4c1e-9b7d-2a4e8f1c6b35/responsive/768"
                },
                {
                    "width": 1200,
                    "height": 900,
                    "size": 128330,
                    "name": "team-offsite-1200w.webp",
                    "download_url": "https://www.iminify.com/api/v1/images/9d3c5b8e-6f0a-4c1e-9b7d-2a4e8f1c6b35/responsive/1200"
                },
                {
                    "width": 1600,
                    "height": 1200,
                    "size": 212877,
                    "name": "team-offsite-1600w.webp",
                    "download_url": "https://www.iminify.com/api/v1/images/9d3c5b8e-6f0a-4c1e-9b7d-2a4e8f1c6b35/responsive/1600"
                }
            ],
            "download_url": "https://www.iminify.com/api/v1/images/9d3c5b8e-6f0a-4c1e-9b7d-2a4e8f1c6b35/responsive.zip",
            "html": "<img\n  src=\"team-offsite-1600w.webp\"\n  srcset=\"team-offsite-480w.webp 480w, team-offsite-768w.webp 768w, team-offsite-1200w.webp 1200w, team-offsite-1600w.webp 1600w\"\n  sizes=\"(max-width: 1600px) 100vw, 1600px\"\n  width=\"1600\"\n  height=\"1200\"\n  alt=\"Six colleagues laughing around a picnic table on a lakeside lawn\"\n  style=\"max-width: 100%; height: auto\"\n  decoding=\"async\"\n>"
        },
        "scan_id": null,
        "source_url": null,
        "folder": null,
        "share_url": null,
        "created_at": "2026-10-01T09:30:00+00:00",
        "updated_at": "2026-10-01T09:30:09+00:00"
    }
}

Rename an image

PATCH /api/v1/images/{id}

Changes the name the optimized copy downloads under. The original keeps the name it was uploaded with. The extension is always the delivered format's, so a typed one (hero.webp) is dropped, and characters that don't belong in a file name become a hyphen. Only a finished image can be renamed.

Path parameters

id
string (id) required
The image's id.

Body (JSON)

name
string required
The new name, without an extension. With the extension it has to fit in 128 bytes.

Request

curl -X PATCH "https://www.iminify.com/api/v1/images/9d3c5b8e-6f0a-4c1e-9b7d-2a4e8f1c6b35" \
  --connect-timeout 10 --max-time 30 \
  -H "Authorization: Bearer $IMINIFY_API_KEY" \
  -H "Accept: application/json" \
  -H "Content-Type: application/json" \
  -d '{"name":"team-offsite"}'

Response 200

JSON
{
    "data": {
        "id": "9d3c5b8e-6f0a-4c1e-9b7d-2a4e8f1c6b35",
        "status": "completed",
        "name": "team-offsite.webp",
        "original": {
            "name": "team-offsite.jpg",
            "format": "jpg",
            "size": 2841205,
            "width": 4032,
            "height": 3024,
            "download_url": "https://www.iminify.com/api/v1/images/9d3c5b8e-6f0a-4c1e-9b7d-2a4e8f1c6b35/download?type=original"
        },
        "optimized": {
            "name": "team-offsite.webp",
            "format": "webp",
            "size": 212877,
            "width": 1600,
            "height": 1200,
            "download_url": "https://www.iminify.com/api/v1/images/9d3c5b8e-6f0a-4c1e-9b7d-2a4e8f1c6b35/download"
        },
        "saved_bytes": 2628328,
        "saved_percent": 92.51,
        "settings": {
            "level": "smart",
            "format": "webp",
            "keep_metadata": false,
            "width": 1600,
            "height": null,
            "scale": null,
            "size_limit": 250,
            "responsive_widths": [
                480,
                768,
                1200,
                1600
            ]
        },
        "size_limit_status": "under",
        "content_credentials": {
            "status": "removed",
            "generative_ai": false
        },
        "alt_text": {
            "status": "written",
            "text": "Six colleagues laughing around a picnic table on a lakeside lawn",
            "language": "en",
            "suggested_name": "colleagues-picnic-table-lakeside"
        },
        "responsive": {
            "status": "ready",
            "files": [
                {
                    "width": 480,
                    "height": 360,
                    "size": 24118,
                    "name": "team-offsite-480w.webp",
                    "download_url": "https://www.iminify.com/api/v1/images/9d3c5b8e-6f0a-4c1e-9b7d-2a4e8f1c6b35/responsive/480"
                },
                {
                    "width": 768,
                    "height": 576,
                    "size": 55904,
                    "name": "team-offsite-768w.webp",
                    "download_url": "https://www.iminify.com/api/v1/images/9d3c5b8e-6f0a-4c1e-9b7d-2a4e8f1c6b35/responsive/768"
                },
                {
                    "width": 1200,
                    "height": 900,
                    "size": 128330,
                    "name": "team-offsite-1200w.webp",
                    "download_url": "https://www.iminify.com/api/v1/images/9d3c5b8e-6f0a-4c1e-9b7d-2a4e8f1c6b35/responsive/1200"
                },
                {
                    "width": 1600,
                    "height": 1200,
                    "size": 212877,
                    "name": "team-offsite-1600w.webp",
                    "download_url": "https://www.iminify.com/api/v1/images/9d3c5b8e-6f0a-4c1e-9b7d-2a4e8f1c6b35/responsive/1600"
                }
            ],
            "download_url": "https://www.iminify.com/api/v1/images/9d3c5b8e-6f0a-4c1e-9b7d-2a4e8f1c6b35/responsive.zip",
            "html": "<img\n  src=\"team-offsite-1600w.webp\"\n  srcset=\"team-offsite-480w.webp 480w, team-offsite-768w.webp 768w, team-offsite-1200w.webp 1200w, team-offsite-1600w.webp 1600w\"\n  sizes=\"(max-width: 1600px) 100vw, 1600px\"\n  width=\"1600\"\n  height=\"1200\"\n  alt=\"Six colleagues laughing around a picnic table on a lakeside lawn\"\n  style=\"max-width: 100%; height: auto\"\n  decoding=\"async\"\n>"
        },
        "scan_id": null,
        "source_url": null,
        "folder": null,
        "share_url": null,
        "created_at": "2026-10-01T09:30:00+00:00",
        "updated_at": "2026-10-01T09:30:09+00:00"
    }
}

Delete an image

DELETE /api/v1/images/{id}

Deletes the image and both of its files from storage for good, its responsive sizes too. There is no trash and no undo. An image that is still queued or compressing, or whose responsive sizes are still being made, is refused; cancel it while it is queued, or wait for it to finish.

Path parameters

id
string (id) required
The image's id.

Request

curl -X DELETE "https://www.iminify.com/api/v1/images/9d3c5b8e-6f0a-4c1e-9b7d-2a4e8f1c6b35" \
  --connect-timeout 10 --max-time 30 \
  -H "Authorization: Bearer $IMINIFY_API_KEY" \
  -H "Accept: application/json"

Response 204

No content.

Download an image

GET /api/v1/images/{id}/download

The optimized copy, or with type=original the file exactly as it was uploaded. The answer is the file itself, with its type in Content-Type and its name in Content-Disposition. The original is there from the moment the image is queued; the optimized copy once it has finished.

Path parameters

id
string (id) required
The image's id.

Query parameters

type
string
Which file: the optimized copy, or the original as it was uploaded.

optimized original

Default: optimized

Request

curl --fail-with-body -o team-offsite.webp "https://www.iminify.com/api/v1/images/9d3c5b8e-6f0a-4c1e-9b7d-2a4e8f1c6b35/download" \
  --connect-timeout 10 --max-time 1800 \
  -H "Authorization: Bearer $IMINIFY_API_KEY"

Response 200

The file itself, not JSON.

Download one responsive size

GET /api/v1/images/{id}/responsive/{width}

One width of the image's responsive sizes, under the name it has in responsive.files, like team-offsite-768w.webp. The answer is the file itself, with its type in Content-Type and its name in Content-Disposition. The sizes can be downloaded once responsive.status is ready, and stay downloadable if the plan lapses. See Responsive sizes.

Path parameters

id
string (id) required
The image's id.
width
integer required
One of the widths in responsive.files.

Request

curl --fail-with-body -o team-offsite-768w.webp "https://www.iminify.com/api/v1/images/9d3c5b8e-6f0a-4c1e-9b7d-2a4e8f1c6b35/responsive/768" \
  --connect-timeout 10 --max-time 1800 \
  -H "Authorization: Bearer $IMINIFY_API_KEY"

Response 200

The file itself, not JSON.

Download every responsive size

GET /api/v1/images/{id}/responsive.zip

Every width of the image's responsive sizes in one zip, each file under the name it has in responsive.files. The sizes can be downloaded once responsive.status is ready. See Responsive sizes.

Path parameters

id
string (id) required
The image's id.

Request

curl --fail-with-body -o team-offsite-sizes.zip "https://www.iminify.com/api/v1/images/9d3c5b8e-6f0a-4c1e-9b7d-2a4e8f1c6b35/responsive.zip" \
  --connect-timeout 10 --max-time 1800 \
  -H "Authorization: Bearer $IMINIFY_API_KEY"

Response 200

The file itself, not JSON.

Compress an image again

POST /api/v1/images/{id}/recompress

Runs the stored original through again with new settings and answers with a new image; the one you started from stays as it is. Nothing is uploaded again, but it counts as a compression like an upload does. It is how you try ultra after smart, or AVIF after WebP. Any image that isn't still running can go again, a failed or cancelled one included. A resize that would take the image past 64 megapixels is refused with the message under errors.image.

Path parameters

id
string (id) required
The image's id.

Body (JSON)

level
string
How hard to compress. smart finds the lowest quality that still looks like your upload, ultra goes further and softens fine texture a little, lossless changes no pixel unless a size_limit needs it to, none only applies the format, the resize, the size limit and the metadata choice. See Compression settings.

none lossless ultra smart

Default: smart
format
string
Convert to this format. auto encodes the image in every format that can hold it and keeps the smallest. Leave it out to keep the upload's own format; a HEIC or TIFF always comes back in another one, because Iminify doesn't write either. jpeg is read as jpg.

auto webp avif png jpg

keep_metadata
boolean
Keep the EXIF metadata (camera, date, location) in the optimized copy. Off by default, which strips it; the orientation is applied to the pixels first, so a photo never comes back on its side. Default: false
width
integer
Resize to this width in pixels. Alone, the height follows the aspect ratio. With height too, the image is resized to exactly that size, and its proportions change if they differ. Up to 65535. 1 to 65535
height
integer
Resize to this height in pixels, the same way as width. Up to 65535. 1 to 65535
scale
integer
Resize to this percentage of the original, 1 to 100. Cannot be combined with width or height. 1 to 100
size_limit
integer
The most the optimized copy may weigh, in kilobytes of 1,000 bytes, from 5 KB up. Iminify lowers the quality until the file fits, and makes the image smaller in pixels when the lowest quality is still over it. The limit comes before the level: under lossless or none, a file over it is encoded again with loss. A PNG or GIF kept in its own format that is over the limit comes back in a format with a quality to lower (JPG, WebP or AVIF), so png as the format is refused; an animation is never fitted. size_limit_status on the finished image says how it came out. See Size limit.
responsive_widths
array of strings
Paid plans: also make the image at each of these widths in pixels, for an <img srcset>, like [480, 768, 1200, 1600], the website's default. Up to 8 widths, each from 16 to 65535. Each width is made from the upload, at the same level and in the format the image is delivered in, and never enlarged: a width wider than the upload is made at the upload's own width, once. In a multipart form, repeat responsive_widths[] or send them in one field, separated by commas. They are made a few seconds after the image finishes; responsive on the image lists them. Sent on another plan, the image is refused with pro_required. See Responsive sizes.
alt_text
boolean
Write an alt text and a suggested file name for the image with AI. On by default; send false to leave it out. A small copy of the image goes to Anthropic, whose Claude model writes both, and they arrive a few seconds after the image finishes. Each one counts against your daily AI alt texts; once those are used up the image still compresses, without one. See Alt text and file names. Default: true
alt_text_language
string
The language to write the alt text in, as one of these tags: en (English), es (Spanish), fr (French), de (German), it (Italian), pt (Portuguese), nl (Dutch), pl (Polish), sv (Swedish), tr (Turkish), ru (Russian), uk (Ukrainian), ar (Arabic), fa (Persian), he (Hebrew), hi (Hindi), id (Indonesian), vi (Vietnamese), th (Thai), ja (Japanese), ko (Korean), zh-Hans (Simplified Chinese), zh-Hant (Traditional Chinese). The suggested file name follows it when the language is written in the Latin alphabet, and is in English otherwise.

en es fr de it pt nl pl sv tr ru uk ar fa he hi id vi th ja ko zh-Hans zh-Hant

Default: en
use_suggested_name
boolean
Rename the optimized copy to the suggested file name as soon as the alt text arrives, unless it already has a new name by then: yours, or an earlier suggestion. Default: false

Request

curl -X POST "https://www.iminify.com/api/v1/images/9d3c5b8e-6f0a-4c1e-9b7d-2a4e8f1c6b35/recompress" \
  --connect-timeout 10 --max-time 30 \
  -H "Authorization: Bearer $IMINIFY_API_KEY" \
  -H "Accept: application/json" \
  -H "Content-Type: application/json" \
  -d '{"level":"ultra","format":"avif"}'

Response 202

JSON
{
    "data": {
        "id": "9d3c5b91-0b2e-4a7f-8c1d-5e6f7a8b9c0d",
        "status": "queued",
        "name": "IMG_4471.heic",
        "original": {
            "name": "IMG_4471.heic",
            "format": "heic",
            "size": 3402118,
            "width": 4032,
            "height": 3024,
            "download_url": "https://www.iminify.com/api/v1/images/9d3c5b91-0b2e-4a7f-8c1d-5e6f7a8b9c0d/download?type=original"
        },
        "optimized": null,
        "saved_bytes": null,
        "saved_percent": null,
        "settings": {
            "level": "ultra",
            "format": "auto",
            "keep_metadata": true,
            "width": null,
            "height": null,
            "scale": null,
            "size_limit": null,
            "responsive_widths": [
                480,
                768,
                1200,
                1600
            ]
        },
        "size_limit_status": null,
        "content_credentials": null,
        "alt_text": {
            "status": "pending",
            "text": null,
            "language": "de",
            "suggested_name": null
        },
        "responsive": {
            "status": "pending",
            "files": [],
            "download_url": null,
            "html": null
        },
        "scan_id": null,
        "source_url": null,
        "folder": null,
        "share_url": null,
        "created_at": "2026-10-01T09:31:12+00:00",
        "updated_at": "2026-10-01T09:31:12+00:00"
    }
}

Retry an image

POST /api/v1/images/{id}/retry

Queues a failed or cancelled image again with the settings it had. It counts as a compression.

Path parameters

id
string (id) required
The image's id.

Request

curl -X POST "https://www.iminify.com/api/v1/images/9d3c5b8e-6f0a-4c1e-9b7d-2a4e8f1c6b35/retry" \
  --connect-timeout 10 --max-time 30 \
  -H "Authorization: Bearer $IMINIFY_API_KEY" \
  -H "Accept: application/json"

Response 202

JSON
{
    "data": {
        "id": "9d3c5b91-0b2e-4a7f-8c1d-5e6f7a8b9c0d",
        "status": "queued",
        "name": "IMG_4471.heic",
        "original": {
            "name": "IMG_4471.heic",
            "format": "heic",
            "size": 3402118,
            "width": 4032,
            "height": 3024,
            "download_url": "https://www.iminify.com/api/v1/images/9d3c5b91-0b2e-4a7f-8c1d-5e6f7a8b9c0d/download?type=original"
        },
        "optimized": null,
        "saved_bytes": null,
        "saved_percent": null,
        "settings": {
            "level": "ultra",
            "format": "auto",
            "keep_metadata": true,
            "width": null,
            "height": null,
            "scale": null,
            "size_limit": null,
            "responsive_widths": [
                480,
                768,
                1200,
                1600
            ]
        },
        "size_limit_status": null,
        "content_credentials": null,
        "alt_text": {
            "status": "pending",
            "text": null,
            "language": "de",
            "suggested_name": null
        },
        "responsive": {
            "status": "pending",
            "files": [],
            "download_url": null,
            "html": null
        },
        "scan_id": null,
        "source_url": null,
        "folder": null,
        "share_url": null,
        "created_at": "2026-10-01T09:31:12+00:00",
        "updated_at": "2026-10-01T09:31:12+00:00"
    }
}

Cancel an image

POST /api/v1/images/{id}/cancel

Calls off an image still waiting in the queue. Once a worker has picked it up it runs to the end.

Path parameters

id
string (id) required
The image's id.

Request

curl -X POST "https://www.iminify.com/api/v1/images/9d3c5b8e-6f0a-4c1e-9b7d-2a4e8f1c6b35/cancel" \
  --connect-timeout 10 --max-time 30 \
  -H "Authorization: Bearer $IMINIFY_API_KEY" \
  -H "Accept: application/json"

Response 200

JSON
{
    "data": {
        "id": "9d3c5b91-0b2e-4a7f-8c1d-5e6f7a8b9c0d",
        "status": "cancelled",
        "name": "IMG_4471.heic",
        "original": {
            "name": "IMG_4471.heic",
            "format": "heic",
            "size": 3402118,
            "width": 4032,
            "height": 3024,
            "download_url": "https://www.iminify.com/api/v1/images/9d3c5b91-0b2e-4a7f-8c1d-5e6f7a8b9c0d/download?type=original"
        },
        "optimized": null,
        "saved_bytes": null,
        "saved_percent": null,
        "settings": {
            "level": "ultra",
            "format": "auto",
            "keep_metadata": true,
            "width": null,
            "height": null,
            "scale": null,
            "size_limit": null,
            "responsive_widths": [
                480,
                768,
                1200,
                1600
            ]
        },
        "size_limit_status": null,
        "content_credentials": null,
        "alt_text": {
            "status": "pending",
            "text": null,
            "language": "de",
            "suggested_name": null
        },
        "responsive": {
            "status": "pending",
            "files": [],
            "download_url": null,
            "html": null
        },
        "scan_id": null,
        "source_url": null,
        "folder": null,
        "share_url": null,
        "created_at": "2026-10-01T09:31:12+00:00",
        "updated_at": "2026-10-01T09:31:40+00:00"
    }
}

Write an image's alt text

POST /api/v1/images/{id}/alt-text

Asks AI for the alt text and suggested file name of a finished image: one sent with alt_text off, compressed before alt text existed, whose alt text failed, or skipped on a day that was used up. A written one can be asked again in another language. It counts one against your daily AI alt texts, unless an image with the same bytes already has one in that language, which is copied at once and costs nothing. The answer is the image; poll it until alt_text.status is no longer pending. While one is being written, asking again changes nothing.

Path parameters

id
string (id) required
The image's id.

Body (JSON)

alt_text_language
string
The language to write the alt text in, as one of these tags: en (English), es (Spanish), fr (French), de (German), it (Italian), pt (Portuguese), nl (Dutch), pl (Polish), sv (Swedish), tr (Turkish), ru (Russian), uk (Ukrainian), ar (Arabic), fa (Persian), he (Hebrew), hi (Hindi), id (Indonesian), vi (Vietnamese), th (Thai), ja (Japanese), ko (Korean), zh-Hans (Simplified Chinese), zh-Hant (Traditional Chinese). The suggested file name follows it when the language is written in the Latin alphabet, and is in English otherwise.

en es fr de it pt nl pl sv tr ru uk ar fa he hi id vi th ja ko zh-Hans zh-Hant

Default: en
use_suggested_name
boolean
Rename the optimized copy to the suggested file name as soon as the alt text arrives, unless it already has a new name by then: yours, or an earlier suggestion. Default: false

Request

curl -X POST "https://www.iminify.com/api/v1/images/9d3c5b8e-6f0a-4c1e-9b7d-2a4e8f1c6b35/alt-text" \
  --connect-timeout 10 --max-time 30 \
  -H "Authorization: Bearer $IMINIFY_API_KEY" \
  -H "Accept: application/json" \
  -H "Content-Type: application/json" \
  -d '{"alt_text_language":"fr","use_suggested_name":true}'

Response 202

JSON
{
    "data": {
        "id": "9d3c5b8e-6f0a-4c1e-9b7d-2a4e8f1c6b35",
        "status": "completed",
        "name": "team-offsite.webp",
        "original": {
            "name": "team-offsite.jpg",
            "format": "jpg",
            "size": 2841205,
            "width": 4032,
            "height": 3024,
            "download_url": "https://www.iminify.com/api/v1/images/9d3c5b8e-6f0a-4c1e-9b7d-2a4e8f1c6b35/download?type=original"
        },
        "optimized": {
            "name": "team-offsite.webp",
            "format": "webp",
            "size": 212877,
            "width": 1600,
            "height": 1200,
            "download_url": "https://www.iminify.com/api/v1/images/9d3c5b8e-6f0a-4c1e-9b7d-2a4e8f1c6b35/download"
        },
        "saved_bytes": 2628328,
        "saved_percent": 92.51,
        "settings": {
            "level": "smart",
            "format": "webp",
            "keep_metadata": false,
            "width": 1600,
            "height": null,
            "scale": null,
            "size_limit": 250,
            "responsive_widths": [
                480,
                768,
                1200,
                1600
            ]
        },
        "size_limit_status": "under",
        "content_credentials": {
            "status": "removed",
            "generative_ai": false
        },
        "alt_text": {
            "status": "pending",
            "text": null,
            "language": "fr",
            "suggested_name": null
        },
        "responsive": {
            "status": "ready",
            "files": [
                {
                    "width": 480,
                    "height": 360,
                    "size": 24118,
                    "name": "team-offsite-480w.webp",
                    "download_url": "https://www.iminify.com/api/v1/images/9d3c5b8e-6f0a-4c1e-9b7d-2a4e8f1c6b35/responsive/480"
                },
                {
                    "width": 768,
                    "height": 576,
                    "size": 55904,
                    "name": "team-offsite-768w.webp",
                    "download_url": "https://www.iminify.com/api/v1/images/9d3c5b8e-6f0a-4c1e-9b7d-2a4e8f1c6b35/responsive/768"
                },
                {
                    "width": 1200,
                    "height": 900,
                    "size": 128330,
                    "name": "team-offsite-1200w.webp",
                    "download_url": "https://www.iminify.com/api/v1/images/9d3c5b8e-6f0a-4c1e-9b7d-2a4e8f1c6b35/responsive/1200"
                },
                {
                    "width": 1600,
                    "height": 1200,
                    "size": 212877,
                    "name": "team-offsite-1600w.webp",
                    "download_url": "https://www.iminify.com/api/v1/images/9d3c5b8e-6f0a-4c1e-9b7d-2a4e8f1c6b35/responsive/1600"
                }
            ],
            "download_url": "https://www.iminify.com/api/v1/images/9d3c5b8e-6f0a-4c1e-9b7d-2a4e8f1c6b35/responsive.zip",
            "html": "<img\n  src=\"team-offsite-1600w.webp\"\n  srcset=\"team-offsite-480w.webp 480w, team-offsite-768w.webp 768w, team-offsite-1200w.webp 1200w, team-offsite-1600w.webp 1600w\"\n  sizes=\"(max-width: 1600px) 100vw, 1600px\"\n  width=\"1600\"\n  height=\"1200\"\n  alt=\"\"\n  style=\"max-width: 100%; height: auto\"\n  decoding=\"async\"\n>"
        },
        "scan_id": null,
        "source_url": null,
        "folder": null,
        "share_url": null,
        "created_at": "2026-10-01T09:30:00+00:00",
        "updated_at": "2026-10-01T09:30:09+00:00"
    }
}

Share an image

POST /api/v1/images/{id}/share

Gives a finished image a public page at an address nobody can guess, returned as share_url. Anyone with the link can see the optimized copy, compare it with the original, download either one, and run the original through Iminify with their own settings. The page is kept out of search engines. Sharing an image that is already shared keeps its link.

Path parameters

id
string (id) required
The image's id.

Request

curl -X POST "https://www.iminify.com/api/v1/images/9d3c5b8e-6f0a-4c1e-9b7d-2a4e8f1c6b35/share" \
  --connect-timeout 10 --max-time 30 \
  -H "Authorization: Bearer $IMINIFY_API_KEY" \
  -H "Accept: application/json"

Response 200

JSON
{
    "data": {
        "id": "9d3c5b8e-6f0a-4c1e-9b7d-2a4e8f1c6b35",
        "status": "completed",
        "name": "team-offsite.webp",
        "original": {
            "name": "team-offsite.jpg",
            "format": "jpg",
            "size": 2841205,
            "width": 4032,
            "height": 3024,
            "download_url": "https://www.iminify.com/api/v1/images/9d3c5b8e-6f0a-4c1e-9b7d-2a4e8f1c6b35/download?type=original"
        },
        "optimized": {
            "name": "team-offsite.webp",
            "format": "webp",
            "size": 212877,
            "width": 1600,
            "height": 1200,
            "download_url": "https://www.iminify.com/api/v1/images/9d3c5b8e-6f0a-4c1e-9b7d-2a4e8f1c6b35/download"
        },
        "saved_bytes": 2628328,
        "saved_percent": 92.51,
        "settings": {
            "level": "smart",
            "format": "webp",
            "keep_metadata": false,
            "width": 1600,
            "height": null,
            "scale": null,
            "size_limit": 250,
            "responsive_widths": [
                480,
                768,
                1200,
                1600
            ]
        },
        "size_limit_status": "under",
        "content_credentials": {
            "status": "removed",
            "generative_ai": false
        },
        "alt_text": {
            "status": "written",
            "text": "Six colleagues laughing around a picnic table on a lakeside lawn",
            "language": "en",
            "suggested_name": "colleagues-picnic-table-lakeside"
        },
        "responsive": {
            "status": "ready",
            "files": [
                {
                    "width": 480,
                    "height": 360,
                    "size": 24118,
                    "name": "team-offsite-480w.webp",
                    "download_url": "https://www.iminify.com/api/v1/images/9d3c5b8e-6f0a-4c1e-9b7d-2a4e8f1c6b35/responsive/480"
                },
                {
                    "width": 768,
                    "height": 576,
                    "size": 55904,
                    "name": "team-offsite-768w.webp",
                    "download_url": "https://www.iminify.com/api/v1/images/9d3c5b8e-6f0a-4c1e-9b7d-2a4e8f1c6b35/responsive/768"
                },
                {
                    "width": 1200,
                    "height": 900,
                    "size": 128330,
                    "name": "team-offsite-1200w.webp",
                    "download_url": "https://www.iminify.com/api/v1/images/9d3c5b8e-6f0a-4c1e-9b7d-2a4e8f1c6b35/responsive/1200"
                },
                {
                    "width": 1600,
                    "height": 1200,
                    "size": 212877,
                    "name": "team-offsite-1600w.webp",
                    "download_url": "https://www.iminify.com/api/v1/images/9d3c5b8e-6f0a-4c1e-9b7d-2a4e8f1c6b35/responsive/1600"
                }
            ],
            "download_url": "https://www.iminify.com/api/v1/images/9d3c5b8e-6f0a-4c1e-9b7d-2a4e8f1c6b35/responsive.zip",
            "html": "<img\n  src=\"team-offsite-1600w.webp\"\n  srcset=\"team-offsite-480w.webp 480w, team-offsite-768w.webp 768w, team-offsite-1200w.webp 1200w, team-offsite-1600w.webp 1600w\"\n  sizes=\"(max-width: 1600px) 100vw, 1600px\"\n  width=\"1600\"\n  height=\"1200\"\n  alt=\"Six colleagues laughing around a picnic table on a lakeside lawn\"\n  style=\"max-width: 100%; height: auto\"\n  decoding=\"async\"\n>"
        },
        "scan_id": null,
        "source_url": null,
        "folder": null,
        "share_url": "https://www.iminify.com/s/k3Xw9QmT2vLp8RzN4bYc6HdJ",
        "created_at": "2026-10-01T09:30:00+00:00",
        "updated_at": "2026-10-01T09:30:09+00:00"
    }
}

Stop sharing an image

DELETE /api/v1/images/{id}/share

Switches the public link off. The page and both of its files answer 404 from the next request on. Sharing the image again later gives it a new link.

Path parameters

id
string (id) required
The image's id.

Request

curl -X DELETE "https://www.iminify.com/api/v1/images/9d3c5b8e-6f0a-4c1e-9b7d-2a4e8f1c6b35/share" \
  --connect-timeout 10 --max-time 30 \
  -H "Authorization: Bearer $IMINIFY_API_KEY" \
  -H "Accept: application/json"

Response 204

No content.

Rename several images

POST /api/v1/images/rename

Gives every finished image in ids the same name followed by its place in upload order, oldest first: trip-01, trip-02. The number has at least two digits, more when the count needs them. A single image gets the name alone. Images that haven't finished are passed over, and if none has, the call is refused. It is all or nothing: when one of the names would be too long, none changes. Every id has to be one of your images; the ones that aren't are named in errors.

Body (JSON)

ids
array of ids required
The images, by id. 1 to 150.
name
string required
The name they share, without an extension.

Request

curl -X POST "https://www.iminify.com/api/v1/images/rename" \
  --connect-timeout 10 --max-time 30 \
  -H "Authorization: Bearer $IMINIFY_API_KEY" \
  -H "Accept: application/json" \
  -H "Content-Type: application/json" \
  -d '{"ids":["9d3c5b8e-6f0a-4c1e-9b7d-2a4e8f1c6b35","9d3c5b91-0b2e-4a7f-8c1d-5e6f7a8b9c0d"],"name":"team-offsite"}'

Response 200

JSON
{
    "data": [
        {
            "id": "9d3c5b8e-6f0a-4c1e-9b7d-2a4e8f1c6b35",
            "status": "completed",
            "name": "team-offsite-01.webp",
            "original": {
                "name": "team-offsite.jpg",
                "format": "jpg",
                "size": 2841205,
                "width": 4032,
                "height": 3024,
                "download_url": "https://www.iminify.com/api/v1/images/9d3c5b8e-6f0a-4c1e-9b7d-2a4e8f1c6b35/download?type=original"
            },
            "optimized": {
                "name": "team-offsite-01.webp",
                "format": "webp",
                "size": 212877,
                "width": 1600,
                "height": 1200,
                "download_url": "https://www.iminify.com/api/v1/images/9d3c5b8e-6f0a-4c1e-9b7d-2a4e8f1c6b35/download"
            },
            "saved_bytes": 2628328,
            "saved_percent": 92.51,
            "settings": {
                "level": "smart",
                "format": "webp",
                "keep_metadata": false,
                "width": 1600,
                "height": null,
                "scale": null,
                "size_limit": 250,
                "responsive_widths": [
                    480,
                    768,
                    1200,
                    1600
                ]
            },
            "size_limit_status": "under",
            "content_credentials": {
                "status": "removed",
                "generative_ai": false
            },
            "alt_text": {
                "status": "written",
                "text": "Six colleagues laughing around a picnic table on a lakeside lawn",
                "language": "en",
                "suggested_name": "colleagues-picnic-table-lakeside"
            },
            "responsive": {
                "status": "ready",
                "files": [
                    {
                        "width": 480,
                        "height": 360,
                        "size": 24118,
                        "name": "team-offsite-01-480w.webp",
                        "download_url": "https://www.iminify.com/api/v1/images/9d3c5b8e-6f0a-4c1e-9b7d-2a4e8f1c6b35/responsive/480"
                    },
                    {
                        "width": 768,
                        "height": 576,
                        "size": 55904,
                        "name": "team-offsite-01-768w.webp",
                        "download_url": "https://www.iminify.com/api/v1/images/9d3c5b8e-6f0a-4c1e-9b7d-2a4e8f1c6b35/responsive/768"
                    },
                    {
                        "width": 1200,
                        "height": 900,
                        "size": 128330,
                        "name": "team-offsite-01-1200w.webp",
                        "download_url": "https://www.iminify.com/api/v1/images/9d3c5b8e-6f0a-4c1e-9b7d-2a4e8f1c6b35/responsive/1200"
                    },
                    {
                        "width": 1600,
                        "height": 1200,
                        "size": 212877,
                        "name": "team-offsite-01-1600w.webp",
                        "download_url": "https://www.iminify.com/api/v1/images/9d3c5b8e-6f0a-4c1e-9b7d-2a4e8f1c6b35/responsive/1600"
                    }
                ],
                "download_url": "https://www.iminify.com/api/v1/images/9d3c5b8e-6f0a-4c1e-9b7d-2a4e8f1c6b35/responsive.zip",
                "html": "<img\n  src=\"team-offsite-01-1600w.webp\"\n  srcset=\"team-offsite-01-480w.webp 480w, team-offsite-01-768w.webp 768w, team-offsite-01-1200w.webp 1200w, team-offsite-01-1600w.webp 1600w\"\n  sizes=\"(max-width: 1600px) 100vw, 1600px\"\n  width=\"1600\"\n  height=\"1200\"\n  alt=\"Six colleagues laughing around a picnic table on a lakeside lawn\"\n  style=\"max-width: 100%; height: auto\"\n  decoding=\"async\"\n>"
            },
            "scan_id": null,
            "source_url": null,
            "folder": null,
            "share_url": null,
            "created_at": "2026-10-01T09:30:00+00:00",
            "updated_at": "2026-10-01T09:30:09+00:00"
        },
        {
            "id": "9d3c5b91-0b2e-4a7f-8c1d-5e6f7a8b9c0d",
            "status": "completed",
            "name": "team-offsite-02.webp",
            "original": {
                "name": "IMG_4471.jpg",
                "format": "jpg",
                "size": 2841205,
                "width": 4032,
                "height": 3024,
                "download_url": "https://www.iminify.com/api/v1/images/9d3c5b91-0b2e-4a7f-8c1d-5e6f7a8b9c0d/download?type=original"
            },
            "optimized": {
                "name": "team-offsite-02.webp",
                "format": "webp",
                "size": 212877,
                "width": 1600,
                "height": 1200,
                "download_url": "https://www.iminify.com/api/v1/images/9d3c5b91-0b2e-4a7f-8c1d-5e6f7a8b9c0d/download"
            },
            "saved_bytes": 2628328,
            "saved_percent": 92.51,
            "settings": {
                "level": "smart",
                "format": "webp",
                "keep_metadata": false,
                "width": 1600,
                "height": null,
                "scale": null,
                "size_limit": 250,
                "responsive_widths": [
                    480,
                    768,
                    1200,
                    1600
                ]
            },
            "size_limit_status": "under",
            "content_credentials": {
                "status": "removed",
                "generative_ai": false
            },
            "alt_text": {
                "status": "written",
                "text": "Six colleagues laughing around a picnic table on a lakeside lawn",
                "language": "en",
                "suggested_name": "colleagues-picnic-table-lakeside"
            },
            "responsive": {
                "status": "ready",
                "files": [
                    {
                        "width": 480,
                        "height": 360,
                        "size": 24118,
                        "name": "team-offsite-02-480w.webp",
                        "download_url": "https://www.iminify.com/api/v1/images/9d3c5b91-0b2e-4a7f-8c1d-5e6f7a8b9c0d/responsive/480"
                    },
                    {
                        "width": 768,
                        "height": 576,
                        "size": 55904,
                        "name": "team-offsite-02-768w.webp",
                        "download_url": "https://www.iminify.com/api/v1/images/9d3c5b91-0b2e-4a7f-8c1d-5e6f7a8b9c0d/responsive/768"
                    },
                    {
                        "width": 1200,
                        "height": 900,
                        "size": 128330,
                        "name": "team-offsite-02-1200w.webp",
                        "download_url": "https://www.iminify.com/api/v1/images/9d3c5b91-0b2e-4a7f-8c1d-5e6f7a8b9c0d/responsive/1200"
                    },
                    {
                        "width": 1600,
                        "height": 1200,
                        "size": 212877,
                        "name": "team-offsite-02-1600w.webp",
                        "download_url": "https://www.iminify.com/api/v1/images/9d3c5b91-0b2e-4a7f-8c1d-5e6f7a8b9c0d/responsive/1600"
                    }
                ],
                "download_url": "https://www.iminify.com/api/v1/images/9d3c5b91-0b2e-4a7f-8c1d-5e6f7a8b9c0d/responsive.zip",
                "html": "<img\n  src=\"team-offsite-02-1600w.webp\"\n  srcset=\"team-offsite-02-480w.webp 480w, team-offsite-02-768w.webp 768w, team-offsite-02-1200w.webp 1200w, team-offsite-02-1600w.webp 1600w\"\n  sizes=\"(max-width: 1600px) 100vw, 1600px\"\n  width=\"1600\"\n  height=\"1200\"\n  alt=\"Six colleagues laughing around a picnic table on a lakeside lawn\"\n  style=\"max-width: 100%; height: auto\"\n  decoding=\"async\"\n>"
            },
            "scan_id": null,
            "source_url": null,
            "folder": null,
            "share_url": null,
            "created_at": "2026-10-01T09:30:00+00:00",
            "updated_at": "2026-10-01T09:30:09+00:00"
        }
    ]
}

Download several images as a zip

POST /api/v1/images/download

One zip holding the optimized copy of every finished image in ids, oldest first. An image uploaded with a folder goes in that folder, and one without at the top of the zip. Two images with the same name in one folder are kept apart as name.webp and name (2).webp. Images that haven't finished are left out, and if none has, the call is refused.

Body (JSON)

ids
array of ids required
The images, by id. 1 to 150.

Request

curl -X POST --fail-with-body -o images.zip "https://www.iminify.com/api/v1/images/download" \
  --connect-timeout 10 --max-time 1800 \
  -H "Authorization: Bearer $IMINIFY_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"ids":["9d3c5b8e-6f0a-4c1e-9b7d-2a4e8f1c6b35","9d3c5b91-0b2e-4a7f-8c1d-5e6f7a8b9c0d"]}'

Response 200

The file itself, not JSON.