# Filter Images

Returns a paginated collection of the tenant's images, filtered and sorted using OData query options (`$filter`, `$orderby`, `$top`, `$skip`).
## Authentication
Requires a valid API key in the `X-API-KEY` header.
## Response (200 OK)
The page is wrapped in the house collection envelope — the images are under `value`, never at the
top level:

```json
{
  "value": [
    {
      "id": 42,
      "reference": "product-main-front.jpg",
      "numLinks": 3,
      "status": "Ok",
      "modifiedOn": "2024-04-05T08:44:33",
      "fileType": "jpg",
      "createdOn": "2024-04-05T08:44:33",
      "tags": ["animales", "mascotas"],
      "originalUrl": "https://cdn.example.com/product-main-front.jpg",
      "thumbnailUrl": "https://cdn.example.com/product-main-front_TH.jpg",
      "thumbnailMediumUrl": "https://cdn.example.com/product-main-front_THM.jpg",
      "thumbnailPreviewUrl": "https://cdn.example.com/product-main-front_THP.jpg",
      "width": 800,
      "height": 600,
      "sizeInBytes": 102400
    }
  ],
  "@count": 137,
  "@readLink": "https://api2.saleslayer.com/dam/images?$top=50",
  "@nextLink": "https://api2.saleslayer.com/dam/images?$top=50&$skip=50"
}
```
Notes on the payload:
- `status` tells you whether the image is usable yet — see the status values documented on
`GET /images`. A freshly created or substituted image is `Up` until the worker finishes.
- `width`, `height` and `sizeInBytes` come from the stored metadata and are `0` until processing
has recorded them; the thumbnail URLs are empty until the renditions exist.
- `tags` is stored as a comma-separated string, so a tag that itself contains a comma comes back
split into several tags.
- `@count` is the total number of matches, ignoring `$top`/`$skip`.
- `@readLink` is the canonical URL of this collection — this request, echoed back.
- `@nextLink` is the URL of the next page and is omitted on the last page.

The `@`-prefixed hypermedia links (`@readLink`, `@nextLink`) are only emitted when hypermedia
enrichment is configured for the deployment; `@count` is always present. Where the links are
absent, page forward by incrementing `$skip` yourself until fewer than `$top` items come back.
## Supported fields
Only these fields can be used in `$filter` and `$orderby`:
`id`, `reference`, `numLinks`, `status`, `modifiedOn`, `fileType`, `createdOn`
Field names are case-insensitive. Every other field of the response — including `tags`,
`width`, `height`, `sizeInBytes` and the URL fields — is **not** queryable: naming one in
`$filter` or `$orderby` returns 400. `$orderby` honours only the first sort expression.
`$select` and `$expand` are not supported and are ignored.
## Supported operators and functions
- Comparison: `eq`, `ne`, `gt`, `ge`, `lt`, `le`
- Logical: `and`, `or`, `not`
- Sets: `in`
- Functions: `contains`, `startswith`, `endswith`

## Status field values
- `Vd` - Void (not yet started processing)
- `Up` - Updating (being uploaded/updated)
- `Ok` - Processed correctly (ready to use)
- `Re` - Reprocessing
- `Er` - Error (processing failed)
- `Dv` - Deleted/void (no longer counts towards the tenant's image-library quota)

Results are not filtered by status, so images in any of these states can be returned. Filter on
`status` explicitly if you only want usable images.
## Examples

```
GET /images?$filter=fileType eq 'jpg'
GET /images?$filter=status eq 'Ok'
GET /images?$filter=fileType eq 'png' and status eq 'Ok'
GET /images?$filter=status in ('Ok', 'Re')
GET /images?$filter=contains(reference, 'product')
GET /images?$filter=startswith(reference, 'product-') and numLinks gt 0
GET /images?$orderby=createdOn desc
GET /images?$filter=fileType ne 'gif'&$orderby=numLinks desc&$skip=0&$top=50
```
## Error Responses
- **400 Bad Request**: Invalid `$filter` syntax, a field that is not queryable in `$filter` or
`$orderby`, a negative `$skip`, or a `$top` that is not between 1 and 100
- **401 Unauthorized**: Missing or invalid API key. Returned by the API gateway as
`{ "message": "Unauthorized", "request_id": "d8aafa5b8f3e400b60bea0123dd33317" }`
- **403 Forbidden**: The API key does not have read permissions for this operation. Same body
shape as the 401
- **500 Internal Server Error**: Technical error (e.g. database unavailable)

A 400 uses the shared validation envelope, keyed by the offending parameter:

```json
{
  "validationFailures": {
    "$orderby": [
      {
        "PropertyName": "$orderby",
        "ErrorMessage": "Ordering by 'tags' is not supported. Supported fields: id, reference, numlinks, status, modifiedon, filetype, createdon (Parameter 'propertyName')",
        "AttemptedValue": null
      }
    ]
  }
}
```

Endpoint: GET /images
Version: 2.0.0

## Query parameters:

  - `$filter` (string)
    OData $filter expression — see the supported fields, operators and functions below

  - `$orderby` (string)
    OData $orderby expression — only the fields listed below are supported

  - `$top` (integer)
    Maximum number of records to return (default: 100, max: 100)

  - `$skip` (integer)
    Number of records to skip for pagination (default: 0)

## Header parameters:

  - `X-API-KEY` (string, required)
    Tenant's API key (required)

## Response 200 fields (application/json):

  - `value` (array)
    The images in this page, at most `$top` (default and maximum 100).

  - `value.id` (integer)
    Internal numeric identifier. Not stable as a public key — address images by `reference`.

  - `value.reference` (string)
    The image's filename, unique per tenant. This is the public key used to address the image and the
value entities use to reference it.

  - `value.numLinks` (integer)
    Number of entities (products, variants, categories, …) currently using this image.

  - `value.status` (string)
    Processing status: `Vd` (void), `Up` (uploading/updating), `Ok` (ready to use),
`Re` (reprocessing), `Er` (processing failed) or `Dv` (deleted). Only `Ok`
guarantees the renditions exist.

  - `value.modifiedOn` (string)
    When the image was last modified.

  - `value.fileType` (string)
    File extension of the image, without the dot (e.g. `jpg`, `png`). Derived from the
filename, not from the served Content-Type.

  - `value.createdOn` (string)
    When the image was created. Null for images predating creation-date tracking.

  - `value.tags` (array)
    Tags assigned to the image. Stored as a comma-separated string, so a tag containing a comma is
read back as several tags. Not usable in `$filter` or `$orderby`.

  - `value.originalUrl` (string)
    URL of the original, full-size image. Empty until processing has run.

  - `value.thumbnailUrl` (string)
    URL of the small thumbnail rendition. Empty until processing has generated it.

  - `value.thumbnailMediumUrl` (string)
    URL of the medium thumbnail rendition. Empty until processing has generated it.

  - `value.thumbnailPreviewUrl` (string)
    URL of the preview thumbnail rendition. Empty until processing has generated it.

  - `value.width` (integer)
    Width of the image in pixels; `0` until processing has recorded it. Not usable in
`$filter` or `$orderby`.

  - `value.height` (integer)
    Height of the image in pixels; `0` until processing has recorded it. Not usable in
`$filter` or `$orderby`.

  - `value.sizeInBytes` (integer)
    Size of the image file in bytes; `0` until processing has recorded it. Not usable in
`$filter` or `$orderby`.

  - `@count` (integer)
    Total number of images matching the filter, ignoring `$top`/`$skip`.

  - `@readLink` (string)
    Canonical URL of this collection — this request, echoed back. Present only when hypermedia
enrichment is enabled.

  - `@nextLink` (string)
    URL of the next page, omitted on the last page. Present only when hypermedia enrichment is
enabled; otherwise page forward by incrementing `$skip` yourself.

## Response 401 fields (application/json):

  - `message` (string)
    Error description, e.g. `Unauthorized`.

  - `request_id` (string)
    Gateway request identifier, to quote when contacting support.

## Response 403 fields (application/json):

  - `message` (string)

  - `request_id` (string)

## Response 500 fields (application/json):

  - `error` (string)

  - `details` (any)

