# Sending images

> The three ways to supply an image, supported formats, the 30 MB cap, and what the quality gate rejects.

Source: https://sightradar.com/docs/images

Index, search, detect and selfie registration all take **exactly one** image source per request.

## Three ways to send an image

_JSON url_
A public HTTPS URL. SightRadar fetches it server-side. This is the only input batch accepts.

```bash
curl -X POST "$SR_BASE/v1/collections/demo/index" \
  -H "Authorization: Bearer $SR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"url": "https://cdn.example.com/photos/1234.jpg", "photoId": "1234"}'
```

_JSON gcsKey_
A Google Cloud Storage object key, for buckets you have shared with SightRadar.

```json
{ "gcsKey": "events/2026/wedding/1234.jpg", "photoId": "1234" }
```

_multipart file_
Upload the file directly. Extra fields (`photoId`, `threshold`, `limit`, `userId`) travel as form fields.

```bash
curl -X POST "$SR_BASE/v1/collections/demo/index" \
  -H "Authorization: Bearer $SR_API_KEY" \
  -F "file=@./photo.jpg" \
  -F "photoId=1234"
```

_raw bytes_
Post the image body with `Content-Type: application/octet-stream`. Pass `photoId` as a query parameter.

```bash
curl -X POST "$SR_BASE/v1/collections/demo/index?photoId=1234" \
  -H "Authorization: Bearer $SR_API_KEY" \
  -H "Content-Type: application/octet-stream" \
  --data-binary @./photo.jpg
```

Search additionally accepts a precomputed `embedding` (512 numbers) instead of an image, and compare accepts `source_embedding` / `target_embedding`. An embedding side is not a processed photo and is not charged as one.

## Formats

JPEG, PNG, WebP, HEIC/HEIF, TIFF, GIF and BMP are decoded natively. iPhone HEIC and WebP work without pre-conversion. Animated GIFs use the first frame.

## Size

The encoded image may be at most **30 MB**; larger returns `413`. Faces smaller than the quality gate's minimum are skipped, so downscaling a 40 MB photo to 4,000 px on its longest side loses nothing useful and uploads faster.

## The quality gate

Detection finds every face; the quality gate decides which are worth keeping. A face is rejected when it is too small (`min_px` below the threshold), too blurry, too oblique, or the detector's confidence (`det_score`) is low. Index reports `detected_face_count` and `rejected_face_count` so you can see both numbers; Detect returns every face with a `quality_passed` flag, which makes it the right pre-check for upload validation ("is there exactly one clear face?").

**Zero faces is a success.**
A valid image with no usable face returns `200` with `indexed: 0` and is charged like any other photo. Only decode failures (`400`) and engine errors (`502`, refunded automatically) are free.

## Bounding boxes

Boxes are absolute pixels (`x`, `y`, `w`, `h`) in the decoded image's coordinate space, EXIF orientation applied. Rekognition returns ratios; if you are porting code, divide by the image dimensions (the [Rekognition shim](/docs/sdks/rekognition-shim) does this for you when given the size).
