> ## Documentation Index
> Fetch the complete documentation index at: https://docs.uselayers.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Image Search: Upload Image

> Image Upload API endpoint that accepts a binary image and returns an image ID you can pass into the Image Search endpoint for visual product lookup.

## Authorization

**X-Storefront-Access-Token** `string` *required*

Token-based authentication header in the form of `<YOUR_LAYERS_TOKEN>`.

## Headers

**Content-Type** `string` *required* (default: multipart/form-data)

**Accept** `string` *required* (default: application/json)

## Body

**image** `file` *required*

Image file to upload. Supported formats: JPEG, JPG, PNG, WebP, HEIC, and HEIF. Maximum file size: 15MB (15,360 KB). Maximum dimensions: 8,192 pixels per side and 40,000,000 total pixels.

**crop\_x** `integer`

X-coordinate (in pixels) of the top-left corner of the crop region. Must be `0` or greater. When provided, all four crop parameters (`crop_x`, `crop_y`, `crop_width`, `crop_height`) are required.

**crop\_y** `integer`

Y-coordinate (in pixels) of the top-left corner of the crop region. Must be `0` or greater.

**crop\_width** `integer`

Width (in pixels) of the crop region. Must be `1` or greater.

**crop\_height** `integer`

Height (in pixels) of the crop region. Must be `1` or greater.

## Response

**status** `string`

Status of the upload operation. Returns "success" on successful upload.

**imageId** `string`

Unique UUID identifier for the uploaded image. Use this ID in the Image Search API to perform visual searches.

## Usage

The Image Upload endpoint enables a two-step process for visual search:

1. **Upload the image** using this endpoint to receive an `imageId`
2. **Search with the image** using the `imageId` in the [Image Search API](https://docs.uselayers.com/api-reference/search-image.md)

This approach offers several advantages:

* **Better performance**: Avoids repeated base64 encoding/decoding
* **Caching**: Processed image data is cached for faster subsequent searches
* **Reduced payload size**: Use lightweight UUID instead of large base64 strings

## Rate limits

Layers rate limits uploads to protect image processing capacity:

* **10 requests per minute** per client (IP address) per store
* **120 requests per minute** per store across all clients

If you exceed either limit, the endpoint returns `429 Too Many Requests`. Wait the number of seconds given in the `Retry-After` response header before retrying. To stay under the limit, upload each image once and reuse the returned `imageId` for subsequent [Image Search](https://docs.uselayers.com/api-reference/search-image.md) requests instead of re-uploading.

## Error responses

**errors** `object`

Validation errors returned when the request fails validation.

Common validation errors:

* **File required**: No image file provided
* **Invalid file type**: File format not supported (must be JPEG, JPG, PNG, WebP, HEIC, or HEIF)
* **File too large**: Image exceeds 15MB size limit
* **Missing crop parameters**: All four crop parameters must be provided together

### Image dimension limits

Layers checks the declared dimensions of every upload before accepting it. The endpoint returns `422 Unprocessable Content` and does not store the image when:

* Either side exceeds **8,192 pixels**, or the total pixel count exceeds **40,000,000** (width × height). The response message is `Image dimensions exceed the maximum of 8192px per side or 40000000 total pixels`.
* The file cannot be decoded as an image. The response message is `Image could not be decoded`.

These limits apply to the source image's declared dimensions, not the file size. Layers rejects a small file that declares oversized dimensions. If your source image is larger than the limits, downscale it client-side before uploading. Layers resizes accepted images to 1000px for processing, so downscaling to 1000px on the longest side loses no search quality.

```json Response theme={null}
{
    "status": "success",
    "imageId": "550e8400-e29b-41d4-a716-446655440000"
}
```

```json Error Response theme={null}
{
    "message": "The given data was invalid.",
    "errors": {
        "image": [
            "The image field is required."
        ]
    }
}
```
