Upload groups API
Send one image and get every size and format your site keeps made from it, counted as one image. Open a group, send its source, poll it and download the files.
An upload group is one image and every size and format you keep of it, the way a WordPress site keeps a thumbnail, a medium and a large copy of each upload, often in WebP too. You describe the image and the outputs you want, send the image once, and Iminify makes every output from it. The whole group counts as one image.
Groups are for a site or an app that stores several sizes of each upload. To compress one file as it is, send it as an image instead.
How a group counts
A group spends one of your daily images and one of your compressions a minute, whatever it makes. Each output in each format is one file, and files have a daily limit of their own: a group with five outputs in its own format and WebP makes ten files. The files a day for every plan are on the pricing page, and yours are in GET /account under limits.files_per_day and usage.files.
Every limit is checked when the group opens, all at once: the source against your plan's file size and 64 megapixels, the outputs against the rules below, the image, the minute and the files. A group past any of them is refused whole and nothing is counted. A group that opens is never refused part-way, and it spends its image and its files there and then. An AI alt text, when you ask for one, is written for the main output only and counts one against your daily AI alt texts.
Your groups can also only have so many files waiting to be made at once. Past that, a new group is refused with rate_limited and a Retry-After header; wait that long and open it again.
The life of a group
awaiting_source ──► in_progress ──► finished
│
└──► expired
A group opens awaiting_source, and takes its image until upload_by, 60 minutes after it opened. Once the image arrives it turns in_progress, and finished once every file has ended. A group whose image never came reads expired: it makes nothing, and shortly afterwards it is deleted for you and the image and files it counted are given back.
Opening a group
POST /groups describes the image you are about to send in source (its format, bytes, width and height) and lists the outputs to make from it:
{
"name": "IMG_2041",
"source": { "format": "jpg", "size": 2841205, "width": 2560, "height": 1707 },
"outputs": [
{ "name": "full", "width": 2560, "height": 1707, "size": 2841205 },
{ "name": "medium", "width": 300, "height": 200, "size": 21204 },
{ "name": "thumbnail", "width": 150, "height": 150, "crop": ["center", "center"], "size": 7311 }
],
"formats": ["original", "webp"]
}
sourcehas to match the file you send exactly, its width and height as displayed (with its orientation applied). A group takes a JPG, PNG, WebP or GIF.outputsname each size, the main one first. An output withoutcropkeeps the source's shape and is scaled to its width and height. One withcropis scaled to cover its size and then cut at the anchors you give, across then down:start,centerorend. That's how WordPress crops a size, withcrop: trueas["center", "center"].sizeon an output is the bytes of the copy you already have, if any. A made file replaces your copy only when it is smaller.formatsare the formats to make each output in:originalis the source's own,webpandavifa copy beside it. Leave it out fororiginalalone.
The answer is the group with an upload_by. Next, send the image.
The rules
Iminify makes every output itself, so a group can only ever be one picture's work. A group that breaks any of these is refused with outputs_refused, and the message names the rule:
- each output at most the source's width and height, since nothing is enlarged;
- an output without
cropkeeps the source's shape, within the pixel its rounding takes; - at most 30 outputs, at most 12 of them cropped, and a cropped one no more than 2,560 pixels on its longer side;
- the outputs' pixels together at most 6 times the source's;
- every output named once, whatever the case: the names become file names.
Sending the image
POST /groups/{id}/source takes the file as a multipart file, once, before upload_by. It goes through the checks every upload does, and it has to be the image the group was opened for. A different file is refused and the group still takes the right one until upload_by. A second upload, or one after upload_by, is answered with group_closed.
The answer comes straight back in_progress. Poll GET /groups/{id} a few seconds apart until it is finished. Background work can take longer: see Bulk work for priority.
What comes back
outputs lists each output in each format with its own status, its made file's width, height and bytes, and replace. Write a file over your copy only where replace is true: it finished at the output's size and is smaller than the copy you have, or you have none. A WebP or AVIF is marked only when it is smaller than the file you keep for that size, so you never serve a format copy heavier than the image it stands in for.
A failed or cancelled file is never marked. One that ends already-optimized came out no smaller than the source, which is handed back as it is, so it is marked only for an output the source's own size and lighter than your copy.
The zip
GET /groups/{id}/download answers once the group has finished. It holds every file marked replace, named after its output and format (thumbnail.webp), and a manifest.csv with a row for every output in every format: output, format, file (empty when it isn't in the zip), status, width, height, bytes and replace. A group with nothing to replace answers with the manifest alone. Each file's file in outputs is its name in the zip.
Deleting a group
DELETE /groups/{id} deletes the group, every file it made and its source, for good. It gives back nothing the group counted; only an image that never arrived does that.
Send ephemeral when you open the group and it is deleted for you about 24 hours after its last file finished, if you haven't deleted it by then. Delete it yourself once you've saved its files: a download alone deletes nothing. See Deleting images once saved.
A group's files are its own: they're not in the image list, the website's results or a zip of several images, and the image calls answer their ids with not_found. No webhook is sent for a group; poll it.
The Group object
-
idstring - The group's id.
-
namestring - The image's name, as you sent it.
-
statusstring -
upload_bytimestamp or null -
The last moment the group takes its source, 60 minutes after it opened, or
nullonce it has it. -
sourceobject - The source the group was opened for.
-
source.formatstring - Its format.
-
source.sizeinteger - Its size in bytes.
-
source.widthinteger - Its width in pixels.
-
source.heightinteger - Its height in pixels.
-
settingsobject - The settings every output is made with, as they were sent.
-
settings.levelstring - The compression level.
-
settings.formatsarray - The formats each output is made in, the source's own first.
-
settings.keep_metadataboolean - Whether the EXIF metadata is kept.
-
settings.ephemeralboolean - Whether the group is deleted for you about 24 hours after its last file finished, if you haven't deleted it by then.
-
settings.prioritystring -
filesinteger - Files the group makes: every output in every format. Each counts one against your daily files.
-
outputsarray - Each output in each of its formats, the main one first, or an empty list until the source arrives.
-
alt_textobject or null -
The AI alt text and suggested file name for the main output, or
nullwhen none was asked for, or until the source arrives. -
alt_text.statusstring -
pending: being written; it arrives a few seconds after the main output finishes.written: ready.failed: the model gave no usable answer, or something broke.skipped: your daily AI alt texts were used up when the source arrived. -
alt_text.textstring or null -
One sentence for the image's
altattribute, ornulluntil it is written. -
alt_text.languagestring or null - The language tag it was written in.
-
alt_text.suggested_namestring or null -
A short descriptive file name without an extension, or
nulluntil it is written or when the model offered none. -
download_urlstring or null -
Where to download the group's files as one zip, once it has
finished;nulluntil then. -
created_attimestamp - When the group was opened.
-
received_attimestamp or null -
When its source arrived, or
null.
The GroupOutput object
-
namestring - The output's name.
-
formatstring -
The format asked for:
original,webporavif. -
statusstring -
Where this file is:
queued,optimizing,completed,already-optimized(nothing came out smaller than the source, which is handed back),failedorcancelled. -
filestring or null -
Its name in the group's zip, like
thumbnail.webp, ornullwhen it isn't there: only a file markedreplaceis. -
widthinteger or null -
The made file's width in pixels, or
nulluntil it has finished. -
heightinteger or null -
The made file's height in pixels, or
nulluntil it has finished. -
sizeinteger or null -
The made file's size in bytes, or
nulluntil it has finished. -
replaceboolean -
Whether to write this file over your copy: it finished at the output's width and height and is smaller than the copy you have (the
sizeyou sent), or you have none. A WebP or AVIF is marked only when it is smaller than the file you keep for that output.
Open an upload group
/api/v1/groups
Declares one image and the outputs to make from it: each a name, a width and a height, a crop for a cropped size, and the bytes of the copy you already have, in each of the formats. Nothing is uploaded yet. The group answers with the status awaiting_source and an upload_by 60 minutes away: send the image to POST /groups/{id}/source before then.
Every limit is checked here, at once: the source against your plan's file size and 64 megapixels, the outputs against the group's rules, one of your daily images and of your compressions a minute, a file for each output in each format against your daily files, and the files your groups already have waiting. A group past any of them is refused whole with nothing counted; one taken spends its image and its files now, and is never refused part-way. A source that never comes in time gives them back. See Upload groups.
Body (JSON)
-
namestring required -
The image's name, without its extension, like
IMG_2041. -
sourceobject required - The image you will send as the group's source, described exactly: the upload is refused unless its format, its bytes and its width and height (as displayed, with its orientation applied) are these.
-
source.formatstring required -
Its format:
jpg,png,webporgif.jpegis read asjpg.jpgjpegpngwebpgif -
source.sizeinteger required - Its size in bytes, at most your plan's file size.
-
source.widthinteger required - Its width in pixels. 1 to 65535
-
source.heightinteger required - Its height in pixels. 1 to 65535
-
outputsarray of objects required - The outputs to make, the main one first: up to 30, each at most the source's width and height. The first output in the source's own format is the one an alt text is written for.
-
outputs[].namestring required -
The output's name, like
thumbnailormedium_large: letters, digits, dots, hyphens and underscores, up to 64, unique in the group whatever their case. It names the output's files,thumbnail.webpin the zip. -
outputs[].widthinteger required - The output's width in pixels. 1 to 65535
-
outputs[].heightinteger required - The output's height in pixels. 1 to 65535
-
outputs[].croparray of strings -
Where to cut a cropped output, across then down:
start,centerorendeach, like["center", "center"]. The source is scaled to cover the output, then cut at these anchors, as WordPress crops a size. Leave it out for an output that keeps the source's shape. -
outputs[].sizeinteger - The bytes of the copy of this output you already have, if any. A file made for the output replaces your copy only when it is smaller.
-
formatsarray of strings -
The formats to make each output in:
originalis the source's own,webpandavifa copy beside it. A WebP source'swebpis its own format, made once. Leave it out fororiginalalone. -
levelstring -
How hard to compress every output.
smartfinds the lowest quality that still looks like the source,ultragoes further and softens fine texture a little,losslesschanges no pixel,noneonly resizes, crops and converts. See Compression settings.
Default: smartnonelosslessultrasmart -
keep_metadataboolean - Keep the EXIF metadata (camera, date, location) in the outputs. Off by default, which strips it; the orientation is applied to the pixels first. Default: false
-
alt_textboolean - Write an AI alt text and a suggested file name for the main output once the source arrives. Off by default for a group. A small copy of the image goes to Anthropic, whose Claude model writes both; it counts one against your daily AI alt texts, and once those are used up the group still runs, without one. See Alt text and file names. Default: false
-
alt_text_languagestring -
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.
Default: enenesfrdeitptnlplsvtrruukarfahehiidvithjakozh-Hanszh-Hant -
ephemeralboolean -
Delete the group once you've saved its files, for a caller that keeps its own copies. Send
DELETE /groups/{id}once you've written them; a group you leave is deleted for you about 24 hours after its last file finished, its files and its source with it. Off by default, which keeps the group until you delete it. See Deleting images once saved. Default: false -
prioritystring -
backgroundfor bulk work nobody waits on, such as a whole library: its files are made after every image sent without it, on every plan, and count against your limits the same. See Bulk work.
Default: interactiveinteractivebackground
Request
curl -X POST "https://www.iminify.com/api/v1/groups" \
--connect-timeout 10 --max-time 30 \
-H "Authorization: Bearer $IMINIFY_API_KEY" \
-H "Accept: application/json" \
-H "Content-Type: application/json" \
-d '{"name":"IMG_2041","source":{"format":"jpg","size":2841205,"width":2560,"height":1707},"outputs":[{"name":"full","width":2560,"height":1707,"size":2841205},{"name":"medium","width":300,"height":200,"size":21204},{"name":"thumbnail","width":150,"height":150,"crop":["center","center"],"size":7311}],"formats":["original","webp"],"ephemeral":true}'
import os
import requests
API = "https://www.iminify.com/api/v1"
HEADERS = {
"Authorization": f"Bearer {os.environ['IMINIFY_API_KEY']}",
"Accept": "application/json",
}
response = requests.post(
f"{API}/groups",
headers=HEADERS,
timeout=(10, 30),
json={
"name": "IMG_2041",
"source": {
"format": "jpg",
"size": 2841205,
"width": 2560,
"height": 1707,
},
"outputs": [
{
"name": "full",
"width": 2560,
"height": 1707,
"size": 2841205,
},
{
"name": "medium",
"width": 300,
"height": 200,
"size": 21204,
},
{
"name": "thumbnail",
"width": 150,
"height": 150,
"crop": ["center", "center"],
"size": 7311,
},
],
"formats": ["original", "webp"],
"ephemeral": True,
},
)
response.raise_for_status()
print(response.json())
<?php
require __DIR__ . '/vendor/autoload.php';
use GuzzleHttp\Client;
$client = new Client([
'base_uri' => 'https://www.iminify.com/api/v1/',
'connect_timeout' => 10,
'timeout' => 30,
'headers' => [
'Authorization' => 'Bearer ' . getenv('IMINIFY_API_KEY'),
'Accept' => 'application/json',
],
]);
$response = $client->post('groups', [
'json' => [
'name' => 'IMG_2041',
'source' => [
'format' => 'jpg',
'size' => 2841205,
'width' => 2560,
'height' => 1707,
],
'outputs' => [
[
'name' => 'full',
'width' => 2560,
'height' => 1707,
'size' => 2841205,
],
[
'name' => 'medium',
'width' => 300,
'height' => 200,
'size' => 21204,
],
[
'name' => 'thumbnail',
'width' => 150,
'height' => 150,
'crop' => ['center', 'center'],
'size' => 7311,
],
],
'formats' => ['original', 'webp'],
'ephemeral' => true,
],
]);
print_r(json_decode((string) $response->getBody(), true));
const response = await fetch('https://www.iminify.com/api/v1/groups', {
method: 'POST',
signal: AbortSignal.timeout(30_000),
headers: {
Authorization: `Bearer ${process.env.IMINIFY_API_KEY}`,
Accept: 'application/json',
'Content-Type': 'application/json',
},
body: JSON.stringify({
name: 'IMG_2041',
source: {
format: 'jpg',
size: 2841205,
width: 2560,
height: 1707,
},
outputs: [
{
name: 'full',
width: 2560,
height: 1707,
size: 2841205,
},
{
name: 'medium',
width: 300,
height: 200,
size: 21204,
},
{
name: 'thumbnail',
width: 150,
height: 150,
crop: ['center', 'center'],
size: 7311,
},
],
formats: ['original', 'webp'],
ephemeral: true,
}),
});
if (!response.ok) {
throw new Error(`${response.status}: ${(await response.json()).message}`);
}
console.log(await response.json());
Response 201
{
"data": {
"id": "9d3c5c02-4e1f-4a6b-8d2c-3f5a7b9c1e24",
"name": "IMG_2041",
"status": "awaiting_source",
"upload_by": "2026-10-01T10:40:00+00:00",
"source": {
"format": "jpg",
"size": 2841205,
"width": 2560,
"height": 1707
},
"settings": {
"level": "smart",
"formats": [
"original",
"webp"
],
"keep_metadata": false,
"ephemeral": true,
"priority": "interactive"
},
"files": 6,
"outputs": [],
"alt_text": null,
"download_url": null,
"created_at": "2026-10-01T09:40:00+00:00",
"received_at": null
}
}
Send a group's source
/api/v1/groups/{id}/source
The image the group was opened for, as a multipart file, once, before upload_by. It has to be that image exactly: its format, its bytes, and its width and height as displayed. It also goes through the checks every upload does. A file that differs is refused, and the group still takes the right one until upload_by. The answer comes straight back with the status in_progress and a Location header; every output is made in the background, so poll the group until its status is finished.
An animated WebP or PNG can't be resized: a group that makes any output at another size from one is refused with animation_not_resizable. An animated GIF's cropped outputs are its first frame.
Path parameters
-
idstring (id) required - The group's id.
Body (multipart/form-data, or JSON for a url)
-
filefile required - The source image: the format, bytes and dimensions the group was opened with.
Request
curl -X POST "https://www.iminify.com/api/v1/groups/9d3c5c02-4e1f-4a6b-8d2c-3f5a7b9c1e24/source" \
--connect-timeout 10 --max-time 1800 \
-H "Authorization: Bearer $IMINIFY_API_KEY" \
-H "Accept: application/json" \
-F "file=@IMG_2041.jpg"
import os
import requests
API = "https://www.iminify.com/api/v1"
HEADERS = {
"Authorization": f"Bearer {os.environ['IMINIFY_API_KEY']}",
"Accept": "application/json",
}
with open("IMG_2041.jpg", "rb") as file:
response = requests.post(
f"{API}/groups/9d3c5c02-4e1f-4a6b-8d2c-3f5a7b9c1e24/source",
headers=HEADERS,
timeout=(10, 300),
files={"file": file},
)
response.raise_for_status()
print(response.json())
<?php
require __DIR__ . '/vendor/autoload.php';
use GuzzleHttp\Client;
$client = new Client([
'base_uri' => 'https://www.iminify.com/api/v1/',
'connect_timeout' => 10,
'timeout' => 30,
'headers' => [
'Authorization' => 'Bearer ' . getenv('IMINIFY_API_KEY'),
'Accept' => 'application/json',
],
]);
$response = $client->post('groups/9d3c5c02-4e1f-4a6b-8d2c-3f5a7b9c1e24/source', [
'multipart' => [
['name' => 'file', 'contents' => fopen('IMG_2041.jpg', 'r'), 'filename' => 'IMG_2041.jpg'],
],
'timeout' => 1800,
]);
print_r(json_decode((string) $response->getBody(), true));
import { openAsBlob } from 'node:fs';
const form = new FormData();
form.append('file', await openAsBlob('IMG_2041.jpg'), 'IMG_2041.jpg');
const response = await fetch('https://www.iminify.com/api/v1/groups/9d3c5c02-4e1f-4a6b-8d2c-3f5a7b9c1e24/source', {
method: 'POST',
signal: AbortSignal.timeout(1800_000),
headers: {
Authorization: `Bearer ${process.env.IMINIFY_API_KEY}`,
Accept: 'application/json',
},
body: form,
});
if (!response.ok) {
throw new Error(`${response.status}: ${(await response.json()).message}`);
}
console.log(await response.json());
Response 202
{
"data": {
"id": "9d3c5c02-4e1f-4a6b-8d2c-3f5a7b9c1e24",
"name": "IMG_2041",
"status": "in_progress",
"upload_by": null,
"source": {
"format": "jpg",
"size": 2841205,
"width": 2560,
"height": 1707
},
"settings": {
"level": "smart",
"formats": [
"original",
"webp"
],
"keep_metadata": false,
"ephemeral": true,
"priority": "interactive"
},
"files": 6,
"outputs": [
{
"name": "full",
"format": "original",
"status": "completed",
"file": "full.jpg",
"width": 2560,
"height": 1707,
"size": 612480,
"replace": true
},
{
"name": "full",
"format": "webp",
"status": "completed",
"file": "full.webp",
"width": 2560,
"height": 1707,
"size": 401226,
"replace": true
},
{
"name": "medium",
"format": "original",
"status": "queued",
"file": null,
"width": null,
"height": null,
"size": null,
"replace": false
},
{
"name": "medium",
"format": "webp",
"status": "queued",
"file": null,
"width": null,
"height": null,
"size": null,
"replace": false
},
{
"name": "thumbnail",
"format": "original",
"status": "queued",
"file": null,
"width": null,
"height": null,
"size": null,
"replace": false
},
{
"name": "thumbnail",
"format": "webp",
"status": "queued",
"file": null,
"width": null,
"height": null,
"size": null,
"replace": false
}
],
"alt_text": {
"status": "pending",
"text": null,
"language": "en",
"suggested_name": null
},
"download_url": null,
"created_at": "2026-10-01T09:40:00+00:00",
"received_at": "2026-10-01T09:40:21+00:00"
}
}
Get an upload group
/api/v1/groups/{id}
One group with each output in each of its formats: its status, the made file's size and dimensions, and replace, whether to write it over your copy. Poll this while a group is in_progress; once a few seconds apart is plenty. A group whose source never came reads expired until it is deleted for you, shortly after.
Path parameters
-
idstring (id) required - The group's id.
Request
curl "https://www.iminify.com/api/v1/groups/9d3c5c02-4e1f-4a6b-8d2c-3f5a7b9c1e24" \
--connect-timeout 10 --max-time 30 \
-H "Authorization: Bearer $IMINIFY_API_KEY" \
-H "Accept: application/json"
import os
import requests
API = "https://www.iminify.com/api/v1"
HEADERS = {
"Authorization": f"Bearer {os.environ['IMINIFY_API_KEY']}",
"Accept": "application/json",
}
response = requests.get(
f"{API}/groups/9d3c5c02-4e1f-4a6b-8d2c-3f5a7b9c1e24",
headers=HEADERS,
timeout=(10, 30),
)
response.raise_for_status()
print(response.json())
<?php
require __DIR__ . '/vendor/autoload.php';
use GuzzleHttp\Client;
$client = new Client([
'base_uri' => 'https://www.iminify.com/api/v1/',
'connect_timeout' => 10,
'timeout' => 30,
'headers' => [
'Authorization' => 'Bearer ' . getenv('IMINIFY_API_KEY'),
'Accept' => 'application/json',
],
]);
$response = $client->get('groups/9d3c5c02-4e1f-4a6b-8d2c-3f5a7b9c1e24');
print_r(json_decode((string) $response->getBody(), true));
const response = await fetch('https://www.iminify.com/api/v1/groups/9d3c5c02-4e1f-4a6b-8d2c-3f5a7b9c1e24', {
signal: AbortSignal.timeout(30_000),
headers: {
Authorization: `Bearer ${process.env.IMINIFY_API_KEY}`,
Accept: 'application/json',
},
});
if (!response.ok) {
throw new Error(`${response.status}: ${(await response.json()).message}`);
}
console.log(await response.json());
Response 200
{
"data": {
"id": "9d3c5c02-4e1f-4a6b-8d2c-3f5a7b9c1e24",
"name": "IMG_2041",
"status": "finished",
"upload_by": null,
"source": {
"format": "jpg",
"size": 2841205,
"width": 2560,
"height": 1707
},
"settings": {
"level": "smart",
"formats": [
"original",
"webp"
],
"keep_metadata": false,
"ephemeral": true,
"priority": "interactive"
},
"files": 6,
"outputs": [
{
"name": "full",
"format": "original",
"status": "completed",
"file": "full.jpg",
"width": 2560,
"height": 1707,
"size": 612480,
"replace": true
},
{
"name": "full",
"format": "webp",
"status": "completed",
"file": "full.webp",
"width": 2560,
"height": 1707,
"size": 401226,
"replace": true
},
{
"name": "medium",
"format": "original",
"status": "completed",
"file": "medium.jpg",
"width": 300,
"height": 200,
"size": 14880,
"replace": true
},
{
"name": "medium",
"format": "webp",
"status": "completed",
"file": "medium.webp",
"width": 300,
"height": 200,
"size": 11402,
"replace": true
},
{
"name": "thumbnail",
"format": "original",
"status": "completed",
"file": "thumbnail.jpg",
"width": 150,
"height": 150,
"size": 6950,
"replace": true
},
{
"name": "thumbnail",
"format": "webp",
"status": "completed",
"file": null,
"width": 150,
"height": 150,
"size": 7402,
"replace": false
}
],
"alt_text": {
"status": "written",
"text": "A red tram crossing a stone bridge at dusk",
"language": "en",
"suggested_name": "red-tram-stone-bridge-dusk"
},
"download_url": "https://www.iminify.com/api/v1/groups/9d3c5c02-4e1f-4a6b-8d2c-3f5a7b9c1e24/download",
"created_at": "2026-10-01T09:40:00+00:00",
"received_at": "2026-10-01T09:40:21+00:00"
}
}
Delete an upload group
/api/v1/groups/{id}
Deletes the group, every file it made and its source, for good. A group with a file still queued or being made is refused; wait for it to finish. Deleting a group gives back nothing it counted: only a source that never came does that.
Path parameters
-
idstring (id) required - The group's id.
Request
curl -X DELETE "https://www.iminify.com/api/v1/groups/9d3c5c02-4e1f-4a6b-8d2c-3f5a7b9c1e24" \
--connect-timeout 10 --max-time 30 \
-H "Authorization: Bearer $IMINIFY_API_KEY" \
-H "Accept: application/json"
import os
import requests
API = "https://www.iminify.com/api/v1"
HEADERS = {
"Authorization": f"Bearer {os.environ['IMINIFY_API_KEY']}",
"Accept": "application/json",
}
response = requests.delete(
f"{API}/groups/9d3c5c02-4e1f-4a6b-8d2c-3f5a7b9c1e24",
headers=HEADERS,
timeout=(10, 30),
)
response.raise_for_status()
print(response.status_code) # 204, nothing in the body
<?php
require __DIR__ . '/vendor/autoload.php';
use GuzzleHttp\Client;
$client = new Client([
'base_uri' => 'https://www.iminify.com/api/v1/',
'connect_timeout' => 10,
'timeout' => 30,
'headers' => [
'Authorization' => 'Bearer ' . getenv('IMINIFY_API_KEY'),
'Accept' => 'application/json',
],
]);
$response = $client->delete('groups/9d3c5c02-4e1f-4a6b-8d2c-3f5a7b9c1e24');
echo $response->getStatusCode(), PHP_EOL; // 204, nothing in the body
const response = await fetch('https://www.iminify.com/api/v1/groups/9d3c5c02-4e1f-4a6b-8d2c-3f5a7b9c1e24', {
method: 'DELETE',
signal: AbortSignal.timeout(30_000),
headers: {
Authorization: `Bearer ${process.env.IMINIFY_API_KEY}`,
Accept: 'application/json',
},
});
if (!response.ok) {
throw new Error(`${response.status}: ${(await response.json()).message}`);
}
console.log(response.status); // 204, nothing in the body
Response 204
No content.
Download an upload group as a zip
/api/v1/groups/{id}/download
Every file marked replace, each named after its output and format (thumbnail.webp), and a manifest.csv listing every output in every format with its status, width, height, bytes and replace. A file that doesn't replace your copy isn't in the zip, and a group with nothing to replace answers with the manifest alone. It is ready once the group has finished, so a group still at work is refused.
Path parameters
-
idstring (id) required - The group's id.
Request
curl --fail-with-body -o group.zip "https://www.iminify.com/api/v1/groups/9d3c5c02-4e1f-4a6b-8d2c-3f5a7b9c1e24/download" \
--connect-timeout 10 --max-time 1800 \
-H "Authorization: Bearer $IMINIFY_API_KEY"
import os
import requests
API = "https://www.iminify.com/api/v1"
HEADERS = {
"Authorization": f"Bearer {os.environ['IMINIFY_API_KEY']}",
"Accept": "application/json",
}
response = requests.get(
f"{API}/groups/9d3c5c02-4e1f-4a6b-8d2c-3f5a7b9c1e24/download",
headers=HEADERS,
timeout=(10, 300),
)
response.raise_for_status()
with open("group.zip", "wb") as out:
out.write(response.content)
<?php
require __DIR__ . '/vendor/autoload.php';
use GuzzleHttp\Client;
$client = new Client([
'base_uri' => 'https://www.iminify.com/api/v1/',
'connect_timeout' => 10,
'timeout' => 30,
'headers' => [
'Authorization' => 'Bearer ' . getenv('IMINIFY_API_KEY'),
'Accept' => 'application/json',
],
]);
$response = $client->get('groups/9d3c5c02-4e1f-4a6b-8d2c-3f5a7b9c1e24/download', [
'sink' => 'group.zip',
'timeout' => 1800,
]);
echo 'Saved group.zip', PHP_EOL;
import { writeFile } from 'node:fs/promises';
const response = await fetch('https://www.iminify.com/api/v1/groups/9d3c5c02-4e1f-4a6b-8d2c-3f5a7b9c1e24/download', {
signal: AbortSignal.timeout(1800_000),
headers: {
Authorization: `Bearer ${process.env.IMINIFY_API_KEY}`,
Accept: 'application/json',
},
});
if (!response.ok) {
throw new Error(`${response.status}: ${(await response.json()).message}`);
}
await writeFile('group.zip', Buffer.from(await response.arrayBuffer()));
Response 200
The file itself, not JSON.