POST /v1/optimize
Image Optimization API
Compress images, reduce file size, convert to web formats, and target specific output sizes.
Opérations clés
compress
optimize
reduce_to_target_size
convert_to_webp
convert_to_avif
Cas d’utilisation
CDN optimization
E-commerce media compression
Bandwidth reduction
Cycle de vie de la tâche async
Tous les endpoints de traitement ImageHQ sont asynchrones. Après un POST réussi, vous recevez une réponse 202 Acceptedavec un job_id. Interrogez l’endpoint de statut jusqu’à ce que l’état atteigne succeeded.
Exemple de requête
import requests
url = "https://api.imagehq.io/v1/optimize"
payload = {
"input_format": "png",
"operation": "compress",
"options": {
"quality": 85,
"strip_metadata": True
},
"output_format": "same_as_input",
"tool_slug": "compress-png"
}
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({
"input_format": "png",
"operation": "compress",
"options": {
"quality": 85,
"strip_metadata": true
},
"output_format": "same_as_input",
"tool_slug": "compress-png"
}));
const response = await fetch("https://api.imagehq.io/v1/optimize", {
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({
"input_format": "png",
"operation": "compress",
"options": {
"quality": 85,
"strip_metadata": true
},
"output_format": "same_as_input",
"tool_slug": "compress-png"
}));
const response = await fetch("https://api.imagehq.io/v1/optimize", {
method: "POST",
headers: { "Idempotency-Key": crypto.randomUUID() },
body: form
});
const data = await response.json();
console.log(data);curl -X POST "https://api.imagehq.io/v1/optimize" \
-H "Idempotency-Key: $(uuidgen)" \
-F "files[]=@image.png" \
-F 'request={"input_format":"png","operation":"compress","options":{"quality":85,"strip_metadata":true},"output_format":"same_as_input","tool_slug":"compress-png"}'$client = new GuzzleHttp\Client();
$response = $client->post("https://api.imagehq.io/v1/optimize", [
"multipart" => [
["name" => "files[]", "contents" => fopen("image.png", "r")],
["name" => "request", "contents" => '{"input_format":"png","operation":"compress","options":{"quality":85,"strip_metadata":true},"output_format":"same_as_input","tool_slug":"compress-png"}']
]
]);require "faraday"
response = Faraday.post("https://api.imagehq.io/v1/optimize") do |req|
req.headers["Idempotency-Key"] = SecureRandom.uuid
req.body = { "files[]" => Faraday::UploadIO.new("image.png", "image/png"), "request" => '{"input_format":"png","operation":"compress","options":{"quality":85,"strip_metadata":true},"output_format":"same_as_input","tool_slug":"compress-png"}' }
endbody := &bytes.Buffer{}
writer := multipart.NewWriter(body)
writer.WriteField("request", `{"input_format":"png","operation":"compress","options":{"quality":85,"strip_metadata":true},"output_format":"same_as_input","tool_slug":"compress-png"}`)
file, _ := writer.CreateFormFile("files[]", "image.png")
_ = file
writer.Close()
http.Post("https://api.imagehq.io/v1/optimize", writer.FormDataContentType(), body)HttpRequest request = HttpRequest.newBuilder()
.uri(URI.create("https://api.imagehq.io/v1/optimize"))
.header("Idempotency-Key", UUID.randomUUID().toString())
.POST(HttpRequest.BodyPublishers.ofString("multipart form data"))
.build();using var form = new MultipartFormDataContent();
form.Add(new StringContent('{"input_format":"png","operation":"compress","options":{"quality":85,"strip_metadata":true},"output_format":"same_as_input","tool_slug":"compress-png"}'), "request");
form.Add(new StreamContent(File.OpenRead("image.png")), "files[]", "image.png");
await httpClient.PostAsync("https://api.imagehq.io/v1/optimize", form);var request = URLRequest(url: URL(string: "https://api.imagehq.io/v1/optimize")!) request.httpMethod = "POST" request.setValue(UUID().uuidString, forHTTPHeaderField: "Idempotency-Key") // Attach multipart files[] and request fields before sending.
Réponse réussie
{
"completed": {
"download_url": "/v1/jobs/job_123/download",
"expires_at": "2026-05-03T00:00:00Z",
"id": "job_123",
"inputs": [
{
"filename": "input.png",
"format": "png",
"mime_type": "image/png",
"size_bytes": 420122
}
],
"outputs": [
{
"filename": "output.jpg",
"format": "jpg",
"id": "0",
"mime_type": "image/jpeg",
"size_bytes": 161002
}
],
"progress": 100,
"retention_policy": {
"clamp": true,
"ttl_hours": 24
},
"stages": [
{
"name": "queued",
"progress": 100,
"status": "succeeded"
},
{
"name": "processing",
"progress": 100,
"status": "succeeded"
}
],
"status": "succeeded",
"warnings": []
},
"queued": {
"client_reference_id": "example-123",
"created_at": "2026-05-02T00:00:00Z",
"current_stage": "queued",
"expires_at": "2026-05-03T00:00:00Z",
"id": "job_123",
"operation": "optimize",
"poll_url": "/v1/jobs/job_123",
"progress": 0,
"status": "queued",
"tool_slug": "png-to-jpg"
}
}Questions fréquentes
Can I target smaller file size?
Yes, optimize jobs can be configured to reduce to target size where practical.
Does optimization remove metadata?
You can control metadata stripping through output options.
Is optimize separate from convert?
Yes. Optimize focuses on quality/size controls while convert focuses on format changes.