Run multiple independent image jobs in one parent request and return grouped outputs.
independent child jobs
grouped async dispatch
aggregate output packaging
convert one file, filter another, OCR another
bulk multi-tool orchestration
group download workflows
Todos os terminais de processamento ImageHQ são assíncronos. Após um POST bem-sucedido, você recebe um 202 Acceptedresposta com um job_id. Pesquise o endpoint de status até que o estado atinja succeeded.
Exemplo de solicitação
import requests
url = "https://api.imagehq.io/batch"
payload = {
"tool_slug": "batch-mixed-ops",
"jobs": [
{
"operation": "convert",
"request": {
"input_format": "png",
"output_format": "jpg",
"tool_slug": "png-to-jpg"
}
},
{
"operation": "filter",
"request": {
"filters": [
{
"type": "warm_film",
"intensity": 70
}
],
"tool_slug": "warm-film-filter"
}
},
{
"operation": "ocr",
"request": {
"operation": "extract_text",
"tool_slug": "image-to-text",
"options": {
"language": "eng"
}
}
}
]
}
files = [("files[]", open("image.png", "rb"))]
data = {"request": json.dumps(payload)}
response = requests.post(url, files=files, data=data)
print(response.json())const form = new FormData();
form.append("files[]", file);
form.append("request", JSON.stringify({
"tool_slug": "batch-mixed-ops",
"jobs": [
{
"operation": "convert",
"request": {
"input_format": "png",
"output_format": "jpg",
"tool_slug": "png-to-jpg"
}
},
{
"operation": "filter",
"request": {
"filters": [
{
"type": "warm_film",
"intensity": 70
}
],
"tool_slug": "warm-film-filter"
}
},
{
"operation": "ocr",
"request": {
"operation": "extract_text",
"tool_slug": "image-to-text",
"options": {
"language": "eng"
}
}
}
]
}));
const response = await fetch("https://api.imagehq.io/batch", {
method: "POST",
headers: { "Idempotency-Key": crypto.randomUUID() },
body: form
});
const data = await response.json();
console.log(data);const form = new FormData();
form.append("files[]", file);
form.append("request", JSON.stringify({
"tool_slug": "batch-mixed-ops",
"jobs": [
{
"operation": "convert",
"request": {
"input_format": "png",
"output_format": "jpg",
"tool_slug": "png-to-jpg"
}
},
{
"operation": "filter",
"request": {
"filters": [
{
"type": "warm_film",
"intensity": 70
}
],
"tool_slug": "warm-film-filter"
}
},
{
"operation": "ocr",
"request": {
"operation": "extract_text",
"tool_slug": "image-to-text",
"options": {
"language": "eng"
}
}
}
]
}));
const response = await fetch("https://api.imagehq.io/batch", {
method: "POST",
headers: { "Idempotency-Key": crypto.randomUUID() },
body: form
});
const data = await response.json();
console.log(data);curl -X POST "https://api.imagehq.io/batch" \
-H "Idempotency-Key: $(uuidgen)" \
-F "files[]=@image.png" \
-F 'request={"tool_slug":"batch-mixed-ops","jobs":[{"operation":"convert","request":{"input_format":"png","output_format":"jpg","tool_slug":"png-to-jpg"}},{"operation":"filter","request":{"filters":[{"type":"warm_film","intensity":70}],"tool_slug":"warm-film-filter"}},{"operation":"ocr","request":{"operation":"extract_text","tool_slug":"image-to-text","options":{"language":"eng"}}}]}'$client = new GuzzleHttp\Client();
$response = $client->post("https://api.imagehq.io/batch", [
"multipart" => [
["name" => "files[]", "contents" => fopen("image.png", "r")],
["name" => "request", "contents" => '{"tool_slug":"batch-mixed-ops","jobs":[{"operation":"convert","request":{"input_format":"png","output_format":"jpg","tool_slug":"png-to-jpg"}},{"operation":"filter","request":{"filters":[{"type":"warm_film","intensity":70}],"tool_slug":"warm-film-filter"}},{"operation":"ocr","request":{"operation":"extract_text","tool_slug":"image-to-text","options":{"language":"eng"}}}]}']
]
]);require "faraday"
response = Faraday.post("https://api.imagehq.io/batch") do |req|
req.headers["Idempotency-Key"] = SecureRandom.uuid
req.body = { "files[]" => Faraday::UploadIO.new("image.png", "image/png"), "request" => '{"tool_slug":"batch-mixed-ops","jobs":[{"operation":"convert","request":{"input_format":"png","output_format":"jpg","tool_slug":"png-to-jpg"}},{"operation":"filter","request":{"filters":[{"type":"warm_film","intensity":70}],"tool_slug":"warm-film-filter"}},{"operation":"ocr","request":{"operation":"extract_text","tool_slug":"image-to-text","options":{"language":"eng"}}}]}' }
endbody := &bytes.Buffer{}
writer := multipart.NewWriter(body)
writer.WriteField("request", `{"tool_slug":"batch-mixed-ops","jobs":[{"operation":"convert","request":{"input_format":"png","output_format":"jpg","tool_slug":"png-to-jpg"}},{"operation":"filter","request":{"filters":[{"type":"warm_film","intensity":70}],"tool_slug":"warm-film-filter"}},{"operation":"ocr","request":{"operation":"extract_text","tool_slug":"image-to-text","options":{"language":"eng"}}}]}`)
file, _ := writer.CreateFormFile("files[]", "image.png")
_ = file
writer.Close()
http.Post("https://api.imagehq.io/batch", writer.FormDataContentType(), body)HttpRequest request = HttpRequest.newBuilder()
.uri(URI.create("https://api.imagehq.io/batch"))
.header("Idempotency-Key", UUID.randomUUID().toString())
.POST(HttpRequest.BodyPublishers.ofString("multipart form data"))
.build();using var form = new MultipartFormDataContent();
form.Add(new StringContent('{"tool_slug":"batch-mixed-ops","jobs":[{"operation":"convert","request":{"input_format":"png","output_format":"jpg","tool_slug":"png-to-jpg"}},{"operation":"filter","request":{"filters":[{"type":"warm_film","intensity":70}],"tool_slug":"warm-film-filter"}},{"operation":"ocr","request":{"operation":"extract_text","tool_slug":"image-to-text","options":{"language":"eng"}}}]}'), "request");
form.Add(new StreamContent(File.OpenRead("image.png")), "files[]", "image.png");
await httpClient.PostAsync("https://api.imagehq.io/batch", form);var request = URLRequest(url: URL(string: "https://api.imagehq.io/batch")!) request.httpMethod = "POST" request.setValue(UUID().uuidString, forHTTPHeaderField: "Idempotency-Key") // Attach multipart files[] and request fields before sending.
{
"queued": {
"id": "job_123",
"status": "queued",
"operation": "batch",
"tool_slug": "png-to-jpg",
"client_reference_id": "example-123",
"progress": 0,
"current_stage": "queued",
"poll_url": "/jobs/job_123",
"created_at": "2026-05-02T00:00:00Z",
"expires_at": "2026-05-03T00:00:00Z"
},
"completed": {
"id": "job_123",
"status": "succeeded",
"progress": 100,
"inputs": [
{
"filename": "input.png",
"format": "png",
"mime_type": "image/png",
"size_bytes": 420122
}
],
"outputs": [
{
"id": "0",
"filename": "output.jpg",
"format": "jpg",
"mime_type": "image/jpeg",
"size_bytes": 161002
}
],
"warnings": [],
"stages": [
{
"name": "queued",
"status": "succeeded",
"progress": 100
},
{
"name": "processing",
"status": "succeeded",
"progress": 100
}
],
"download_url": "/jobs/job_123/download",
"retention_policy": {
"ttl_hours": 24,
"clamp": true
},
"expires_at": "2026-05-03T00:00:00Z"
}
}Batch runs independent child operations, while pipeline chains operations together.
Yes. Convert, filter, OCR, and other supported operations can coexist in a single batch.
Use output archive options where supported to package grouped outputs.