Reference
Smart crop
POST /v1/smartcrop — subject-aware crop to an exact width and height.
A proportional resize fits an image inside a box. Smart crop instead
produces an exact width x height output by analyzing the image and
cropping around whatever's most visually important, instead of just cutting
from the center.
Request
POST /v1/smartcrop
POST /v1/smartcrop?async=true
multipart/form-data, same shape as /v1/optimize:
an image field, and a data field whose resize.width and
resize.height are required.
Terminal
curl -X POST https://api.helloimg.io/v1/smartcrop \
-H "Authorization: Bearer <your API key>" \
-F "[email protected]" \
-F 'data={"resize":{"width":800,"height":800}}'
resize.smartcrop is set to true for you — you don't need to send it.
Any other optimize option (level, convert,
keep_exif, lossless) can be included in the same data object.
Response
Same as /v1/optimize: a 202 with a
job to poll by default, or the result directly if you're not using
?async=true and the request finishes before the timeout.
Errors
| Status | Body | Cause |
|---|---|---|
400 | { "error": { "code": "invalid_request", "message": "Missing 'image' field" } } | No image file in the request. |
400 | { "error": { "code": "invalid_request", "message": "smartcrop requires resize.width and resize.height (positive integers)" } } | resize.width or resize.height is missing, zero, negative, or not an integer. |
400 | { "error": "resize.smartcrop cannot be combined with resize.percent: a smart crop is an exact width x height, not a proportion", "code": "invalid_resize" } | Both width/height and percent were sent. Note the different, flat shape — see the callout below. |
401 | { "error": "invalid api key" } | Missing or malformed Authorization header. Applies to every /v1/* route — one shared check in front of all of them. |
429 | { "error": "monthly image limit reached", "code": "limit_reached" } | Free plan, 1,000 images already processed this calendar month — see Plans & limits. |
Without both dimensions, smart crop would otherwise fall back silently to a
proportional resize instead of a crop — so this call rejects the request
outright rather than returning an image that was never actually cropped.
The two
400s above with nested error.message bodies are this endpoint's
own pre-checks. Every other error on this page — auth, the plan-gate 429,
and the percent-conflict case above — uses the flat
{ "error": "...", "code": "..." } shape instead, the same as
/v1/optimize. Don't assume every error
from /v1/smartcrop is nested.