Let's Enhance makes your images better in sense of resolution, weight and colours. Our image rendering API utilizes the latest AI technologies to eliminate image compression artifacts, upsample, retouch, resize and encode images to align every single image to your specific quality requirements.
We are constantly working on improving of our API and came up with decision to completely rework it. This documentation represent current version API, it's stable, used but lot of customers, but a bit complex. We will cover everything you need to get Let’s Enhance running and start developing your Let’s Enhance integration.
The Quick start will guide you how to get api key and process your first image.
Check our Presets for a list of available operations.
- Quick start
- Get API key
- Authentication
- Process your image
- Making a request
- Reading response
- Retrieve the result
- Save the result
- Webhooks
- API In-depth
- API Reference
- Base URL
- API Requests
- Sending requests
- Retreiving results
- Presets
- Restoration Levels
- Real Estate
- Printing
- Marketplace
- Management API
- Monitor API Usage
- Quota Costs
- Rate Limits
- Edge Cases — TBD
- FAQ
- Supported Images
Quick start
This development quickstart should get you up and running with the Let's Enhance API. In most cases, that should be enough, however, more in-depth information can be found at API In-depth
Keep reading, we will provide request samples once you need it.
Get API key
Open Let's Enhance account profile , hit the Request API Key
and follow the instructions.
For this guide, we will assume your API key is 1234567890
Authentication
The Let's Enhance API uses an API key to authenticate requests. You can view and manage your API key in the Let's Enhance account profile. Authentication to the API is performed via HTTP Headers. Provide your API key as the X-API-KEY
value. You do not need to provide a password.
Process your image
Let's take the reference image to our right and enhance it.
The resolution of our reference is 900 x 600
pixels. It is underexposed and it is missing details as a result of compression. We're going to clean it from compression artifacts, restore details, increase its resolution, correct colors, and encode it for output using one of our presets.
Reference image
https://letsenhance.io/docs/assets/samples/burger.jpg
Making a request
To process any image, you should make a POST request to the endpoint with header X-API-KEY
being set to API key you got on authentication (assume it's 1234567890
), and JSON body, describing input image with operations to apply.
Let's try it out using the request body below. Submitting that request will send the image you specified to processing and will create a pipeline.
Depending on image size, processing may take some time, we will describe it better in other sections. For now, you need to read the response of your request.
API endpoint
https://api.letsenhance.io/v1/pipeline
don't forget to set the correct X-API-KEY
header
Request body
curl -X POST "https://api.letsenhance.io/v1/pipeline" \
-H "X-API-KEY: 1234567890" \
-H "Content-Type: application/json" \
-d '
{
"source": {
"http": {
"url": "https://letsenhance.io/docs/assets/samples/burger.jpg"
}
},
"operations": [
{
"op": "preset/marketplace",
"width": 1800,
"height": 1200,
"restoration_level": 4,
"lightai_intensity": 1.0,
"toneai_intensity": 0.5,
"image_format": "JPEG",
"quality": 75
}
],
"sink": {
"temp_store": true
}
}
Detailed description of request bodies can be found here
Reading response
Once you have made the request to https://api.letsenhance.io/v1/pipeline
you will get a response, containing information about your image.
There are two key things to look after
status
field – if everything is ok, it will beACCEPTED
. In case of some errors, it will beREJECTED
and you will not be withdrawn with a credit.
pipeline.id
field – only if the status isACCEPTED
describes id of your request, save it, you will need it to collect the result. In our case, it's26082838
Response body
{
"status": "ACCEPTED",
"pipeline": {
...
},
"id": 26082838,
"notify_url": null
}
}
Detailed description of response can be found here
Retrieve the result
To get pipeline status, you need to submit GET request endpoint https://api.letsenhance.io/v1/pipeline/<pipeline.id>
with header X-API-KEY
being set to API key you got on authentication (assume it's 1234567890
) and <pipeline.id>
replaced with value you get during previous step (26082838
)
The irst field you must check is status
where there are three possible values you should take into account
"status": "PROCESSING"
- image is still processing, you should wait a bit and make GET
request again.
"status": "DONE"
- your image is processed and you can grab the result url from field results[0].output_object.temp_url
That link contains processed image, we store it for 24 hours once it's done. In order to get processed image simply grab it with GET
(see save the result section).
"status": "ERROR"
- something bad happened, sometimes it's enough just to process it again. It can also be due to bad image format field.
errors
may provide details about what has gone wrong, but it's intent is to help with troubleshooting, not to show user-friendly messages.
Pipeline request body
curl -X GET https://api.letsenhance.io/v1/pipeline/26082838 -H "X-API-KEY: 1234567890"
Pipeline response body
{
"pipeline": {
"id": 26082838,
...
"status": "DONE",
"results": [
{
"created_at": "2021-04-06T11:22:57.72606",
"input_object": {
...
},
"output_object": {
...
"tmp_url": "https://s3.amazonaws.com/leapi-tmp-us-east-1/p/26082838/1200x727-1_KThGB7.jpg?response-content-type=image%2Fjpeg&X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Credential=AKIAIFU5PY2YVSAGMK3Q%2F20210406%2Fus-east-1%2Fs3%2Faws4_request&X-Amz-Date=20210406T112257Z&X-Amz-Expires=86400&X-Amz-SignedHeaders=host&X-Amz-Signature=c984b3f6d237031bc9300abdb87963be8b5712bedd3dafc8568ac4758bbefe26",
}
}
],
"notify_url": null,
"operations": [
....
],
"started_at": "2021-04-06T11:22:53.664904",
"finished_at": "2021-04-06T11:22:57.940067",
"submitted_at": "2021-04-06T11:22:53.610298"
}
}
We poll the request periodically to get fresh status. Its a convenient method while working on a few requests, but it isn't ideal as you scale up. Webhooks are recommended once you consider developing your integration.
Save the result
Once status is DONE
, you should grab the resulting image via url from the field results[0].output_object.temp_url
, like:
Saving a processed image
curl -X GET "https://s3.amazonaws.com/leapi-tmp-us-east-1/p/26082838/1200x727-1_KThGB7.jpg?response-content-type=image%2Fjpeg&X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Credential=AKIAIFU5PY2YVSAGMK3Q%2F20210406%2Fus-east-1%2Fs3%2Faws4_request&X-Amz-Date=20210406T112257Z&X-Amz-Expires=86400&X-Amz-SignedHeaders=host&X-Amz-Signature=c984b3f6d237031bc9300abdb87963be8b5712bedd3dafc8568ac4758bbefe26"
Image result
Webhooks
To use webhook, callback in other words, you should modify POST
request from our initial request body
All you need is to set notify_url
field to point to your webserver. This value may differ for each request, allowing you even to put some own data in it. This url can be http or https. e.g:
Once image is processed, we will send a POST
request to endpoint you specified with notify_url
.
Webhook retry logic
If your server responds with error (status code ≥ 400), next retries will occur in the following order
1st attempt 3 minutes after first webhook wasn't acknowledged
2nd attempt 6 minutes after previous attempt
3rd attempt 10 minutes after previous attempt
If all attempts are not acknowledged, the only way to get the processing status is by querying pipeline endpoint below
https://api.letsenhance.io/v1/pipeline/<pipeline.id>
curl -X POST "https://api.letsenhance.io/v1/pipeline" \
-H "X-API-KEY: 1234567890" \
-H "Content-Type: application/json" \
-d '
{
"source": {
"http": {
"url": "https://letsenhance.io/docs/assets/samples/burger.jpg"
}
},
"notify_url": "https://your.domain/path/to/webhook",
"operations": [
{
"op": "preset/marketplace",
"width": 1800,
"height": 1200,
"restoration_level": 4,
"lightai_intensity": 1.0,
"toneai_intensity": 0.5,
"image_format": "JPEG",
"quality": 75
}
],
"sink": {
"temp_store": true
}
}
API In-depth
API Reference
The Let's Enhance API is organized around REST. It accepts JSON-encoded request bodies, and returns JSON-encoded responses.
Our API provides various automated image processing workflows to enhance images. It supports image URLs as inputs, which are requested via JSON objects that contain the image processing operations. It is asynchronous, allowing you to process multiple images at a time asynchronously without having to block.
Base URL
https://api.letsenhance.io/v1/pipeline/
By default, the Let's Enhance API Docs demonstrate using curl to interact with the API over HTTP.
API Requests
Sending requests
Processing images with the Let's Enhance API is done through submitting POST requests for image processing. Each successful POST request will have a unique request identifier (id
) under the response body, which can later be used to retrieve a processed image.
Let's take the reference image to our right and enhance it. The resolution of our reference is 900 x 600
pixels. We're going to clean it from compression artifacts, restore details, increase its resolution, correct colors, and encode it for output using one of our presets that bundles different types of core operations into one simple operation. We will define the image to be upsampled above its original size with a desired output resolution of 1800 x 1200
. This will be done by setting up the desired parameters on the JSON body.
Insert an image url
we wish to process and define the type of image processing that will take place. For the reference image above, we're going to use our marketplaces preset and set our desired upsampling by giving the image a larger resolution than its initial resolution. To do so, we will use our width
and height
parameters under preset/marketplace
. We also will set the restoration_level
to 4
.
Configure the encoder and set the desired quality factors for encoding. This is done through the image_format
field. Let's set it to JPEG, and set the quality
to 75.
Set temp_store
as 'true' to generate a temporary download link
All of our presets are bundles of different core image processing operations, wrapped into one simple operation.
Reference image
https://letsenhance.io/docs/assets/samples/burger.jpg
Compression caused poor color and brightness, as well as loss of some of the details
Request body
curl -X POST https://api.letsenhance.io/v1/pipeline \
-H "X-API-KEY: yourkey" \
-H "Content-type: application/json" \
-d @filename.json \
Request fields
source
(object) determines the source of the image
http
(object) input image source type
url
(string) image URL (supports multiple URLs)
notify_url
(string) Receive a notification when the images in the request have been processed. This notifies the caller with a POST
and pipeline id
via webhook point to your webserver (see webhooks).
operations
indicates the operations used
op
(string) determines the image processing operation
height
(integer) desired output height in pixels
width
(integer) desired output width in pixels
The aspect ratio of the input image will always be perserved on output. This means the API will never stretch or squeeze an image beyond its initial aspect ratio.
sink
the output source of an image request
temp_store
(boolean) to generate a temporary URL valid for 24 hour
JSON object
{
"source": {
"http": {
"url": "https://letsenhance.io/docs/assets/samples/burger.jpg"
}
},
"notify_url": "https://your.domain/path/to/webhook",
"operations": [
{
"op": "preset/marketplace",
"width": 1800,
"height": 1200,
"restoration_level": 4,
"lightai_intensity": 1.0,
"toneai_intensity": 0.5,
"image_format": "JPEG",
"quality": 75
}
],
"sink": {
"temp_store": true
}
}
Response fields
POST requests will return a response that a pipeline has been submitted with status "ACCEPTED"
by default. The response contains a unique pipeline id
that will be used to retrieve the results.
pipeline
(object) indicates the request is part of a pipeline
id
(integer) id of async request, used for retrieving processing results
JSON object
{
"status": "ACCEPTED",
"pipeline": {
"source": {
...
},
"id": 26082838,
"notify_url": null
}
}
Retreiving results
Request body
The unique pipeline id
we recieved on our response above, is used to retrieve processing results of a specific async request.
Sending a GET request with a pipeline id will return a JSON object with the image metadata along with a temporary URL of the processed image.
curl -X GET https://api.letsenhance.io/v1/pipeline/26082838 \
-H "X-API-KEY: yourkey" \
Get response fields
pipeline
(object) indicates the request is part of a pipeline
id
(integer) id of async request
sink
the output source of an image request
temp_store
(boolean) indicates whether a temporary URL will be generated
errors
(int) error type if exists
source
(object) determines the source of the image
http
(object) input image source type
url
(string) input image URL (supports multiple URLs)
status
(string) status of the async request. Options:
- PROCESSING — Request is processing
- ERROR — Request finished and failed
- DONE — Request finished and succeeds
results
processing results metadata
created_at
(timestamp) indicates the time the metadata was parsed
ext
(string) filetype extension
input_object
input image metadata
mps
(float) input megapixel count
url
(string) input image URL
mime
(string) mime type
size
(integer) input image dimensions in pixels (width, height)
width
(integer) input image width in pixels
height
(integer) input image height in pixels
format
(string) image format
s3_key
(string) input s3 key (null by default)
tmp_url
(string) input image temporary storage (null by default)
basename
(string) file name without its filetype extension
filename
(string) file name with its filetype extension
interpret
s3_bucket
s3_key_prefix
output_object
output image metadata
ext
(string) filetype extension
mps
(float) output megapixel count
url
(string) output image URL
mime
(string) mime type
size
(integer) image dimensions in pixels (width, height)
width
(integer) output image width in pixels
height
(integer) output image height in pixels
format
(string) image format
s3_key
(string) input s3 key (null by default)
tmp_url
(string) output image temporary storage
basename
(string) file name without its filetype extension
filename
(string) file name with its filetype extension
interpret
(string) output colorspace interpretation
s3_bucket
(string) s3 output bucket (leapi-tmp-us-east-1 by default)
s3_key_prefix
started_at
(timestamp) the time the pipeline started processing
finished_at
(timestamp) the time the pipeline finished processing
submitted_at
(timestamp) the time of pipeline submission
JSON object
{
"pipeline": {
"id": 27312832,
"sink": {
"temp_store": true
},
"error": null,
"errors": [],
"source": {
"http": {
"url": [
"https://letsenhance.io/docs/assets/samples/burger.jpg"
]
}
},
"status": "DONE",
"results": [
{
"created_at": "2021-04-26T13:46:09.145864",
"input_object": {
"ext": "jpg",
"mps": 0.54,
"url": "https://letsenhance.io/docs/assets/samples/burger.jpg",
"mime": "image/jpeg",
"size": [
900,
600
],
"width": 900,
"format": "JPEG",
"height": 600,
"s3_key": null,
"tmp_url": null,
"basename": "burger",
"filename": "burger.jpg",
"interpret": null,
"s3_bucket": null,
"s3_key_prefix": ""
},
"output_object": {
"ext": "jpg",
"mps": 2.16,
"url": null,
"mime": "image/jpeg",
"size": [
1800,
1200
],
"width": 1800,
"format": "JPEG",
"height": 1200,
"s3_key": "p/27312832/burger_j63Bv5.jpg",
"tmp_url": "https://s3.amazonaws.com/leapi-tmp-us-east-1/p/27312832/burger_j63Bv5.jpg?response-content-type=image%2Fjpeg&X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Credential=AKIAIFU5PY2YVSAGMK3Q%2F20210426%2Fus-east-1%2Fs3%2Faws4_request&X-Amz-Date=20210426T134609Z&X-Amz-Expires=86400&X-Amz-SignedHeaders=host&X-Amz-Signature=8b821e5f2d14ef6358921bef3212801cb309d6caa168a4823e05db427f8b5e77",
"basename": "burger_j63Bv5",
"filename": "burger_j63Bv5.jpg",
"interpret": "srgb",
"s3_bucket": "leapi-tmp-us-east-1",
"s3_key_prefix": ""
}
}
],
"notify_url": "https://your.domain/path/to/webhook",
"operations": [
{
"op": "preset/marketplace",
"width": 1600,
"height": 900,
"restoration_level": 4,
"lightai_intensity": 1.0,
"toneai_intensity": 0.5,
"image_format": "JPEG",
"quality": 75
}
],
"started_at": "2021-04-26T13:46:01.358819",
"finished_at": "2021-04-26T13:46:09.361341",
"submitted_at": "2021-04-26T13:46:01.309535"
}
}
Presets
Our presets contain ready-for-use recipes by calling multiple image processing operations, hand-tailored to specific verticals. Each preset contains different variants for rapid testing at scale to find the highest rate of processing consistencies for your images. Under the hood, there are deep neural networks that have been built from the ground up to recover low quality images.
Restoration Levels
Each preset has a restoration_level
associated to it, ranging from 1
being to lightest in intensity, to 10
, being the strongest in intensity.
Knowing which restoration level to apply depends on the condition of the input images, primarily in resolution and how badly compressed they are. The higher the restoration_level, the more aggressive the upsampling approach will be.
The higher the image quality, the lower the restoration_level
.
The lower the image quality, the higher the restoration_level
.
We purposely selected very low quality input images for all of our comparisons as baselines. This includes low resolution (< 1 megapixel) with heavy JPEG compression.
The lower the input resolution, the more difficult the upsampling process is. We recommend you to test all presets and their variants. This will increase the chances of finding consistent, quality results.
All image comparisons under this section are further optimized and served through our end-to-end imaging product. Drop us a line at sales@letsenhance.io for more info
Real Estate
Preset fields:
op
(string) - operation name preset/realestate
width
(integer) - output width in pixels
restoration_level
(integer) - intensity of detail restoration (see here)
height
(integer) - output height in pixels
lightai_intensity
(float, 0.1 - 0.99
) - color and brightness correction
toneai_intensity
(float, 0.1 - 0.99
) - image tones (contrast, shadows)
image_format
(string JPEG
, PNG
) - sets the image filetype
quality
(integer) - sets the encoding quality of a JPEG image.
Sample for realestate
preset
JSON Body
{
"op": "preset/realestate",
"width": 1600,
"height": 900,
"restoration_level": 4,
"lightai_intensity": 1.0,
"toneai_intensity": 0.5,
"image_format": "JPEG",
"quality": 75
}
Input Image 960 x 540, 566 kB
Output Image 1600 x 900 , 240 kB
Printing
Preset fields:
op
(string) - operation name preset/print
width
(integer) - output width in pixels
height
(integer) - output height in pixels
restoration_level
(integer) - intensity of detail restoration (see here)
tone_intensity
(float, 0.1 - 0.99
) - image tones (contrast, shadows)
lightai_intensity
(float) 0.1 - 0.99
- color and brightness correction
dpi
(integer) - output DPI
image_format
(string JPEG
, PNG
) - sets the image filetype
quality
(integer) - sets the encoding quality of a JPEG image.
Sample for printing
preset
JSON Body
{
"op": "preset/print",
"width": 1600,
"height": 1065,
"restoration_level": 2,
"lightai_intensity": 1.0,
"toneai_intensity": 0.5,
"dpi": 300,
"image_format": "JPEG",
"quality": 85
}
Input Image 1080 x 719 , 67 kB
Output Image 1600 x 1065 , 67 kB
Zoomed Input
Zoomed Output
Marketplace
Preset fields:
op
(string) - operation name preset/marketplace
width
(integer) - output width in pixels
height
(integer) - output height in pixels
restoration_level
(integer) - intensity of detail restoration (see here)
lightai_intensity
(float, 0.1 - 0.99
) - color and brightness correction
tone_intensity
(float, 0.1 - 0.99
) - image tones (contrast, shadows)
image_format
(string JPEG
, PNG
) - sets the image filetype
quality
(integer) - sets the encoding quality of a JPEG image.
JSON Body
{
"op": "preset/marketplace",
"width": 1200,
"height": 1600,
"restoration_level": 2,
"lightai_intensity": 1.0,
"toneai_intensity": 0.5,
"image_format": "JPEG",
"quality": 75
}
Sample for marketplace
preset
Input Image 450 x 600 , 76 kB
Output Image 1200 x 1600, 76 kB
Management API
Monitor API Usage
API quotas protect the Let's Enhance infrastructure from excessive API requests. Traffic is blocked when the level of requests reaches the monthly API quota level or a per-user rate limit.
Your monthly usage and quotas can be directly checked via through the following URL
https://api.letsenhance.io/v1/me/usage/
Request body
curl -X GET "https://api.letsenhance.io/v1/me/usage/" \
-H "X-API-KEY: 1234567890" \
Unused credits do not roll-over and will reset at the beginning of each month
Quota Costs
Every API request made counts the amount of images processed under a given request. For example, an API request with 3 URLs will count 3 credits. Invalid requests will not incur any quota cost.
Rate Limits
A rate limiter that limits the number of requests received by the API within any given minute.
The Let's Enhance API employs a number of safeguards against bursts of incoming traffic to help maximize its stability. Users who send many requests in quick succession may see error responses that show up as status "REJECTED"
Too many requests. Rate limit exceeded.
Rate limit message
{
"status": "REJECTED",
"reason": "Too Many Requests. Rate limit exceeded."
}
Edge Cases — TBD
FAQ
Supported Images
Our API supports images file types that are either JPEG
, TIFF
, PNG
, BMP
, or WEBP
.
webho