Fix brightness & contrast
A backlit product shot or a dim warehouse photo doesn't need a full retouch, it needs its brightness and contrast pushed back into range. This endpoint takes numeric adjustment values and applies them to any supported image in one call, turning exposure correction into a repeatable step instead of a manual slider drag done a thousand times over.
Run it online
Run this on our servers with your account. Free tools run in your browser; this one bills your KIT balance per the price above.
The gap this fills
Bulk photo intake, whether from field agents, warehouse scanners or user uploads, produces wildly inconsistent exposure because lighting conditions are never controlled. A human editor can fix one image in seconds, but nobody wants to open Photoshop for the ten thousandth listing photo of the week, which is exactly the gap this endpoint closes.
Brightness and contrast as separate controls
Brightness shifts every pixel value up or down uniformly, lightening or darkening the whole frame, while contrast stretches or compresses the range between the darkest and lightest pixels, making shadows deeper and highlights punchier without changing the average exposure. Sending both values together, rather than one blended 'auto-fix' number, is what lets you correct a specific known problem, like a flash-washed photo, instead of guessing at a generic enhancement.
How the call works
Submit the image along with brightness and contrast values to POST /image/brightness-contrast, and the response returns a task_id immediately since the adjustment runs asynchronously in the background. The corrected image is delivered through a signed webhook, best for pipelines that need to react automatically, or a signed link that stays valid for 24 hours for manual retrieval.
A control as old as image sensors
Brightness and contrast adjustment predates digital photography entirely, camera exposure compensation dials and darkroom dodge-and-burn techniques were solving the same problem on film decades before pixels existed. The math changed, from chemical exposure time to numeric pixel remapping, but the underlying need, making a poorly lit capture legible, never went away.
Built for repeatable pipelines
Every call is billed only on a successful correction; the system retries automatically up to three times before surfacing a clear error, so transient failures never turn into a charge with nothing to show for it. There's no free tier and no trial period standing between you and the endpoint, prepaid balance runs your job immediately and a 402 response tells you plainly when it can't, keeping the queue predictable for high-volume automation. That reliability is what turns a one-off correction into a step you can schedule and forget.
What you can do with it
Field photo standardization
A field-service app corrects brightness and contrast on technician-submitted photos automatically, since lighting in basements, attics and outdoor sites varies wildly.
E-commerce listing cleanup
A marketplace boosts contrast on low-light seller photos in bulk so product listings meet a minimum visual quality bar without manual review.
Document legibility fixes
A scanning pipeline nudges brightness up on underexposed page captures before OCR runs, improving text recognition without a separate manual pass.
Archive restoration prep
A digitization project applies consistent contrast correction across a batch of faded scanned photographs before cataloging them.
FAQ
How does the brightness and contrast API work?
You send an image with numeric brightness and contrast values to POST /image/brightness-contrast, and the corrected file is returned asynchronously via webhook or a 24-hour signed link.
Is the brightness and contrast API free to use?
There's no free tier — free tiers get abused and slow everyone down. Access runs on a prepaid ForHosting KIT balance: top up from $10.00 (it never expires) and each request is charged at its published price, so a call with no balance returns HTTP 402. No subscription, no tokens, no invented credits, and a failed task is never charged.
What does it cost to adjust image brightness?
Each call is $0.002 per request plus $0.005 per image, charged only when the adjustment completes successfully.
Can I set brightness and contrast independently?
Yes, they're separate numeric parameters, so you can adjust one, the other, or both together in a single call depending on the correction needed.
What happens if the adjustment fails?
You're never charged for a failed task. It retries automatically up to three times before returning a clear, actionable error.
Can this fix badly underexposed or overexposed photos?
It can correct moderate exposure problems effectively; extremely underexposed or blown-out images have less recoverable detail, so results depend on how much information the original capture preserved.
Is there a limit on how many images I can process at once?
Each image is submitted as its own asynchronous call, so you can process large batches by issuing many calls in parallel rather than hitting a hard per-request image limit.
How long is the result available for download?
The signed link is valid for 24 hours after the task completes, and files are deleted after the retention window, never used for training.
For developers — API access
Everything on this page is available programmatically. This section is for teams who want to wire it into their own systems; everyone else can just use the tool above.
API endpoint
Prefer to automate it? One authenticated POST creates the task; the result comes back by webhook or a signed link. The same capability also runs here on the web, and soon from our app, email and Telegram.
Call it from your stack
curl -X POST https://api.kit.forhosting.com/image/brightness-contrast \
-H "Authorization: Bearer $KIT_KEY" \
-H "Content-Type: application/json" \
-d '{"image":"https://ejemplo.com/imagen.jpg"}'const res = await fetch("https://api.kit.forhosting.com/image/brightness-contrast", {
method: "POST",
headers: {
"Authorization": `Bearer ${process.env.KIT_KEY}`,
"Content-Type": "application/json"
},
body: JSON.stringify({
"image": "https://ejemplo.com/imagen.jpg"
})
});
const { task_id } = await res.json();import os, requests
res = requests.post(
"https://api.kit.forhosting.com/image/brightness-contrast",
headers={"Authorization": f"Bearer {os.environ['KIT_KEY']}"},
json={
"image": "https://ejemplo.com/imagen.jpg"
},
)
task_id = res.json()["task_id"]<?php
$res = file_get_contents("https://api.kit.forhosting.com/image/brightness-contrast", false, stream_context_create([
"http" => [
"method" => "POST",
"header" => "Authorization: Bearer " . getenv("KIT_KEY") . "\r\nContent-Type: application/json",
"content" => '{"image":"https://ejemplo.com/imagen.jpg"}',
],
]));
$task = json_decode($res, true);body := bytes.NewBufferString(`{"image":"https://ejemplo.com/imagen.jpg"}`)
req, _ := http.NewRequest("POST", "https://api.kit.forhosting.com/image/brightness-contrast", body)
req.Header.Set("Authorization", "Bearer "+os.Getenv("KIT_KEY"))
req.Header.Set("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)Example request
{
"image": "https://ejemplo.com/imagen.jpg"
}Example response
{
"task_id": "tsk_a1b2c3d4e5f6a1b2c3d4e5f6",
"type": "image.brightness_contrast",
"status": "queued",
"_links": {
"result": "/tasks/tsk_…/result"
}
}The API is asynchronous: the call returns a task_id immediately and the result arrives by webhook. Polling is capped at 1 req/s per task.
Pricing
Published price — no tokens, no invented credits. A failed task is never charged.
Limits
max_mb | 15 |
max_megapixels | 12 |
Errors
| HTTP | Code | Meaning |
|---|---|---|
401 | unauthorized | Missing or invalid API key. |
402 | insufficient_balance | Your balance doesn't cover the task price. |
404 | unknown_type | That task type doesn't exist. |
429 | rate_limited | Too many requests. Use the webhook instead of polling. |