Manage configuration in code

Keep a project's configuration in your repository, and change it the way you change code: review the differences, then deploy them. Everything here is also in the portal, and a change made in one place shows in the other.

There are two ways to do it:

  • The calmlens CLI reads one file per project, prints the differences and makes them.
  • The configuration API and the SDKs' uploadPresets, projectSettings and metadataFields methods, for your own deploy scripts.

The configuration file

Add calmlens.config.json to your repository. Each project has its own file; use --config to choose one.

{
  "policies": {
    "Community rules": { "presetId": "general-community" }
  },
  "policy": "Community rules",
  "uploadPresets": {
    "profile-photos": {
      "name": "Profile photos",
      "allowedContentTypes": ["image/*"],
      "maxSizeInBytes": 10000000,
      "visibility": "public",
      "revealDecision": true,
      "allowedOrigins": ["https://example.com"]
    },
    "feedback-form": {
      "name": "Feedback form",
      "access": "anyone",
      "dailyUploadLimit": 20,
      "policy": "Community rules"
    }
  },
  "lenses": {
    "card": { "name": "Card", "transform": { "width": 640, "format": "webp" } }
  },
  "metadataFields": {
    "userId": { "title": "User", "type": "string", "icon": "user", "color": "#2563eb" }
  },
  "settings": {
    "blockUnmoderatedAssets": true,
    "optOutJurisdictions": ["EU"]
  }
}

A section you leave out isn't managed, so you can start with one section and add others later.

SectionItems are named byWhat the file sets
policiesThe policy's namepresetId to create it as a copy of a built-in policy, settings for its complete settings, and description. A policy that exists already is matched by name, and only its settings and description are compared.
policyA policy's nameThe policy the project moderates with. It can be in policies or be any of the organisation's policies.
uploadPresetsThe preset's keyThe preset's whole definition. Fields you leave out take their defaults. policy names a policy instead of giving its ID.
lensesThe lens's identifierThe lens's whole definition. type defaults to image and active to true.
metadataFieldsThe field's IDThe field's title, type, icon and colour.
settingsThe setting's nameOnly the settings you list. Others keep their values. See the project settings object.

Plan and apply

calmlens plan compares the file with the project, prints the differences and changes nothing.

calmlens plan
  + policy "Community rules"
  ~ project policy "Community rules"
  ~ upload preset "profile-photos" (allowedOrigins)
  + lens "card"

2 to create, 2 to update, 0 to delete, 3 unchanged.

calmlens apply makes those changes.

calmlens apply

apply reads the project again and sends each change with the revision it read. If someone changes an item in the portal or another deploy changes it first, that change is refused with upload-preset/revision-conflict, project-settings/revision-conflict or policy/revision-conflict rather than overwritten. Run calmlens plan to see the latest differences, then decide which to keep. apply stops at the first refusal, and changes made before it stay, so running it again finishes the rest.

Delete what the file doesn't list

By default nothing is deleted. Add --prune to delete upload presets, lenses and metadata fields that the file's section doesn't list. Check the plan first:

calmlens plan --prune

A section you leave out is never pruned. Policies are never pruned, because other projects in the organisation can use them. Delete a policy in the portal or with the policies API.

What can't be set from the file

  • Through a project's key you can change only the policies no other project uses. A policy that another project uses is refused with policy/used-by-another-project, so change it in the portal.
  • Turning on aiMediaSearchEnabled is billed for indexing the project's existing media, so it needs a budget you agree to. Turn it on in the portal or with Update Project Settings and searchIndexingBudgetUnits, then list it in the file.

Deploy from CI

Create a key for your deploys in Portal › API keys with the Configurator role. It can manage this project's configuration, but not its members, API keys or connectors. A custom key needs only the write permission for each section your file lists: policies:write, upload-presets:write, lenses:write, metadata:write or settings:write. plan reads only those sections, so a key that only plans needs just the matching :read permissions.

Store the key as a secret, check the plan on pull requests and apply it on your main branch. For GitHub Actions:

name: CalmLens configuration
on:
  pull_request:
    paths: [calmlens.config.json]
  push:
    branches: [main]
    paths: [calmlens.config.json]

env:
  CALMLENS_API_KEY: ${{ secrets.CALMLENS_CONFIG_API_KEY }}
  CALMLENS_PROJECT_ID: ${{ vars.CALMLENS_PROJECT_ID }}

jobs:
  configuration:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - run: npx calmlens plan
      - if: github.event_name == 'push'
        run: npx calmlens apply

Use a separate project and key for each environment, each with its own file or the same one.

From your own code

The SDKs have the same operations, for deploy scripts of your own. uploadPresets.ensure creates or replaces presets by key and returns them with their revisions, projectSettings.get and update read and replace the settings, and metadataFields.ensure creates or replaces fields by ID. The configuration API reference shows each endpoint in every SDK.

Last updated

Signing in

Signing out

Cookies on CalmLens

We use essential cookies for sign-in and security. With your permission, functional cookies remember your preferences and Google Analytics measures website use and signups. Optional ad measurement cookies link Google ad clicks to signups. Personalised advertising stays off. Manage cookies