# Lenses

Use a project API key to create or update versioned lens definitions.

| Endpoint | Description |
| --- | --- |
| [`PUT /lenses/:lensIdentifier`](#ensure-lens) | Create a lens or update it with a version greater than the current version |
| [`PUT /projects/:projectId/lenses`](#ensure-lenses) | Create lenses or update them with their next versions |

## The lens object

| Field | Type | Presence | Description |
| --- | --- | --- | --- |
| `id` | `string` | Required | Unique lens ID |
| `projectId` | `string` | Optional, nullable | ID of the project that owns the lens; `null` for built-in lenses |
| `userId` | `string` | Optional, nullable | ID of the user whose account created the lens |
| `version` | `integer` | Optional | Definition version. Updates must use a greater version; it is part of the CDN cache key. Default: `1`. |
| `identifier` | `string` | Required | Name used in CDN URLs after `@`. Lowercase letters, numbers and hyphens, at most 50 characters. |
| `name` | `string` | Required | Display name |
| `description` | `string` | Optional, nullable | Optional description of what the lens produces |
| `type` | `"image" \| "video" \| "audio" \| "document" \| "website"` | Required | Asset type the lens applies to |
| `active` | `boolean` | Required | Whether the CDN serves the lens |
| `transforms` | `object[]` | Optional, nullable | Transforms applied in order to produce the derived asset |
| `transforms[].type` | `string` | Required | Transform type, such as `imageTransform` |
| `transforms[].options` | `any` | Required | Options for the transform type, such as `width` and `format` |
| `createdAt` | `integer` | Required | When the lens was created, in milliseconds since the Unix epoch |
| `updatedAt` | `integer` | Optional | When the lens was last updated, in milliseconds since the Unix epoch |

## Endpoint details

### Ensure Lens

Create a lens or update it with a version greater than the current version

**Endpoint:** `PUT https://api.calmlens.com/v1/lenses/:lensIdentifier`

**Authentication:** API Key

#### Example request

```bash
curl -X PUT "https://api.calmlens.com/v1/lenses/thumbnail" \
  -H "X-Api-Key: your-api-key" \
  -H "Content-Type: application/json" \
  --data '{
  "identifier": "thumbnail",
  "name": "Thumbnail",
  "type": "image",
  "active": true,
  "version": 1,
  "transforms": [
    {
      "type": "imageTransform",
      "options": {
        "fit": "scale-down",
        "width": 640,
        "format": "webp"
      }
    }
  ]
}'
```

#### Request body

| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `identifier` | `string` | Yes | Name used in CDN URLs after `@`. Lowercase letters, numbers and hyphens, at most 50 characters. |
| `name` | `unknown` | Yes | Display name |
| `description` | `unknown \| null` | No | Optional description of what the lens produces |
| `type` | `image \| video \| audio \| document \| website` | Yes | Asset type the lens applies to |
| `active` | `boolean` | Yes | Whether the CDN serves the lens |
| `transforms` | `array<object> \| null` | No | Transforms applied in order to produce the derived asset |
| `version` | `integer` | Yes | Definition version. Updates must use a greater version; it is part of the CDN cache key. |

#### Response

| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `lens` | `object` | Yes |  |

#### Error codes

| Status | Code | Description |
| --- | --- | --- |
| 401 | <a id="ensure-lens-error-auth-missing-token" />`auth/missing-token` | Authentication required. Send your project API key in the X-Api-Key header. |
| 401 | <a id="ensure-lens-error-auth-invalid-api-key" />`auth/invalid-api-key` | The API key is invalid, revoked or expired. Create a key under Developer → API Keys. |
| 403 | <a id="ensure-lens-error-auth-project-mismatch" />`auth/project-mismatch` | This API key belongs to a different project. Use a key created for the project that owns this resource. |
| 409 | <a id="ensure-lens-error-lens-version-conflict" />`lens/version-conflict` | Lens updates require a version greater than the current version. |

***

### Ensure Lenses

Create lenses or update them with their next versions

**Endpoint:** `PUT https://api.calmlens.com/v1/projects/:projectId/lenses`

**Authentication:** API Key

#### Example request

```bash
curl -X PUT "https://api.calmlens.com/v1/projects/{projectId}/lenses" \
  -H "X-Api-Key: your-api-key" \
  -H "Content-Type: application/json" \
  --data '{
  "lenses": [
    {
      "identifier": "thumbnail",
      "name": "Thumbnail",
      "type": "image",
      "active": true,
      "version": 1,
      "transforms": [
        {
          "type": "imageTransform",
          "options": {
            "fit": "scale-down",
            "width": 640,
            "format": "webp"
          }
        }
      ]
    }
  ]
}'
```

#### Request body

| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `lenses` | `array<object>` | Yes |  |

#### Response

| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `lenses` | `array<object>` | Yes |  |

#### Error codes

| Status | Code | Description |
| --- | --- | --- |
| 401 | <a id="ensure-lenses-error-auth-missing-token" />`auth/missing-token` | Authentication required. Send your project API key in the X-Api-Key header. |
| 401 | <a id="ensure-lenses-error-auth-invalid-api-key" />`auth/invalid-api-key` | The API key is invalid, revoked or expired. Create a key under Developer → API Keys. |
| 403 | <a id="ensure-lenses-error-auth-project-mismatch" />`auth/project-mismatch` | This API key belongs to a different project. Use a key created for the project that owns this resource. |
| 409 | <a id="ensure-lenses-error-lens-version-conflict" />`lens/version-conflict` | Lens updates require a version greater than the current version. |
