Changelog

Features and improvements in CalmLens. Current version: 2026.7.

2026.7

New

  • A new Examples page in the documentation links the Calmgram live demo and describes example apps that each show a different use case: a link board that checks shared web pages (Python), voice notes and video clips (Go), a thread that holds flagged replies for review (Ruby), marketplace listings with text inside their photos (Java) and a private media library (Rust).

  • Remove an asset's stored content while keeping its record and report, or delete an asset, from the JavaScript, Python, Go, Ruby, Java and Rust SDKs with assets.deleteContent and assets.delete (delete_content and delete in Python, Ruby and Rust, DeleteContent and Delete in Go). The SDKs' test clients support both.

  • The Java and Rust SDK guides show how to verify a webhook delivery from its raw request bytes and read it with the new webhook payload parsers, and the Rust testing guide covers passing a mock client to code that owns its client.

  • The Rust SDK's client is async, for Tokio applications such as axum and actix-web services, with the blocking client available through the blocking feature. It streams uploads from files and readers without holding them in memory, retries safe requests and uploads with an idempotency key, pages through assets and events, verifies webhooks from the request headers with construct_webhook_event, and reports each error's request ID and Retry-After delay. New statuses and fields from the API never fail decoding, and the test client is available through the testing feature.

  • AI assistants can discover published Markdown documentation and the OpenAPI contract through /llms.txt.

  • New accounts agree to the Terms of Service and Privacy Policy when they sign up, and confirm they're authorised to accept them for their organisation.

  • Existing users are asked to accept the updated Terms, which now name CalmLens Ltd, the next time they open the portal. You can review the Terms and Privacy Policy in a new tab before accepting, or sign out instead. API keys keep working throughout.

  • Search portal settings, features, documentation sections and assets from one search dialog.

  • The portal asks before discarding unsaved changes when you close a dialog, leave a page, reload or switch project. This covers moderation policies, connectors, project settings, metadata fields, support tickets, asset rejection notes and new assets.

  • Filter documentation search results to one SDK, such as Python or Go. Pages for other SDKs are hidden, and your choice is remembered when functional cookies are allowed.

  • Search retained, approved images in natural language through the portal, API and SDKs. Image search works in every project automatically: existing and new images are indexed for free, and missing index entries are repaired for free.

  • Turn on audio and video search per project, after reviewing its initial indexing estimate, to search approved audio by speech and videos by sampled frames and speech in the portal and API. Media indexing costs £1.20 per 1,000 units (one per started six seconds), once per content revision; automatic repairs are free.

  • Track and bill successful AI asset searches at £0.025 per 1,000 queries. Keyword, settings and docs search remain free.

  • Report a problem to the CalmLens team from an error page. A screenshot of the page and recent browser logs are attached unless you turn them off; images and videos are left out of the screenshot, and keys and tokens are removed from the logs. Unexpected errors are also reported to the CalmLens team automatically.

  • Custom access can grant separate view and change permissions for project settings, members, API keys, webhooks and connectors, metadata fields and lenses. Changing includes viewing, and Manage project includes every one of them.

  • Retry uploads safely with an Idempotency-Key header on the create, upload, multipart upload and upload part endpoints. A retry of a request that already succeeded returns its saved response for 24 hours, marked Idempotent-Replayed: true, instead of creating a second asset. Reusing a key for a different request returns idempotency/key-reused, and a retry while the first request is still running returns idempotency/request-in-progress with a Retry-After header.

  • Declare a multipart upload's full size with totalSizeInBytes on the first request. Uploads that could never finish, such as an image outside the multipart size range, are refused before any part is stored, and parts that don't add up to the declared size return upload/size-mismatch.

  • Every API response includes an X-Request-Id header to quote when you contact support.

  • The Java SDK streams uploads from files and input streams without loading them into memory, sends an Idempotency-Key with every upload and retries reads and uploads after network failures, throttling and temporary server errors. It pages through assets, child assets and events with assets.iterate, assets.iterateChildren and events.pages, verifies and parses a webhook delivery in one step with parseWebhookEvent, and its errors include the HTTP status, request ID and Retry-After delay.

  • The Python SDK retries reads and uploads after network failures, timeouts and 429, 502, 503 or 504 responses, waiting for Retry-After when it is sent. Uploads carry an Idempotency-Key, generated per call or passed as idempotency_key, so a retried upload never creates a second asset.

  • Python SDK errors have their own types (CalmLensAPIError, CalmLensTimeoutError, CalmLensTransportError and CalmLensValidationError) and include the response's request ID, headers and retry_after. Error codes are available as constants in calmlens.error_codes.

  • The Python SDK adds parse_webhook_event to verify and parse a webhook delivery in one call, assets.iter, assets.iter_children and events.iter to walk every page, streamed CDN downloads with iter_bytes, per-call timeouts and retries with client.with_options, and reads CALMLENS_API_KEY and CALMLENS_PROJECT_ID from the environment.

  • The JavaScript SDK retries reads, creates and uploads after network failures, throttling and gateway errors, waiting for Retry-After. Creates and uploads send an Idempotency-Key, so a retry never creates a second asset; pass your own idempotencyKey to retry across processes. Errors include the request ID, response headers and retry delay, and isNotFound() and isRetryable() classify them.

  • The JavaScript SDK verifies and parses a webhook delivery in one call with parseWebhookEvent, and pages through assets, extracted children and events with assets.iterate, assets.iterateChildren and events.pages. Its test client applies list filters and ordering, supports search and events, and returns errors with the API's status codes.

  • The Ruby SDK sends an Idempotency-Key with every upload and reuses it when it retries, and retries reads and uploads after connection failures, timeouts, 429, 502, 503, 504 and idempotency/request-in-progress, waiting for Retry-After. Set max_retries: on the client or per call.

  • The Ruby SDK streams uploads from files and other IO objects without reading them into memory, and cdn.serve with a block streams content to your code. Timeouts apply to each read and write, so large transfers are not cut off.

  • CalmLens.parse_webhook_event in the Ruby SDK verifies a webhook delivery and returns it as a CalmLens::WebhookEvent. The Ruby SDK guide shows how to read the raw body in Rails and Sinatra.

  • Ruby SDK errors include the request ID, response headers and retry_after, and have classes for each kind of failure, such as CalmLens::NotFoundError, RateLimitError and ConnectionError. CalmLens::ErrorCodes lists the API's error codes.

  • Iterate assets, an asset's children and events across pages in the Ruby SDK with assets.each, assets.each_child, events.each and events.each_page.

  • The Ruby SDK's MockClient stores uploads and folders in memory, applies list filters and ordering, serves stored content from its CDN, returns errors with the API's HTTP statuses, and accepts test events with enqueue_event. Queued responses still answer first.

  • The Go SDK retries reads and uploads after connection failures, timeouts, 429, 502, 503 and 504, honouring Retry-After. Uploads send an Idempotency-Key that is reused for every retry, so a retried upload never creates a second asset; set IdempotencyKey to retry across restarts and MaxRetries to change or turn off retries.

  • The Go SDK adds Assets.ListAll, Assets.ListChildrenAll and Events.ListAll to iterate over every page, VerifyWebhookRequest and ParseWebhookEvent to verify and decode webhook deliveries in one call, TotalSizeInBytes and a per-part Queue override for multipart uploads, and constants for every API error code. Errors include the request ID, response headers and Retry-After delay.

  • The Go SDK's test client returns the API's HTTP status for each error code, applies list filters and ordering, answers search with matching assets, replays idempotent requests, supports byte ranges on CDN responses and lets you add events to the feed with EnqueueEvent.

Changed

  • The Editor role is called Editor everywhere it appears, including the team list, member-joined notifications and connector messages, which previously said Member.

  • Editors, including API keys with the Editor preset, can create, edit and delete lenses. Apps that set up their own lenses with ensureLenses no longer need an Administrator or Custom key.

  • The Go SDK's test client package is now github.com/Censkh/CalmLens/packages/go-sdk/calmlenstest. VerifyWebhookSignature takes WithTolerance and WithNow options. Invalid client options return sdk/invalid-config, and arguments rejected before a request return sdk/invalid-argument. Numbers inside Go JSON maps keep their full precision. Multipart parts no longer resend the queue mode, so CalmLens applies the one chosen when the upload started.

  • The Calmclips example (Go) only starts in demo mode when CALMLENS_DEMO=1 is set, and stops when its API credentials are missing.

  • A multipart upload keeps the queue choice sent when it starts and applies it when the final part arrives, so any client or process can finish the upload with the same result. Passing queue on the final part still overrides it.

  • Throttled API requests (429) include a Retry-After header.

  • Java SDK responses are immutable records with Instant timestamps. Statuses and fields added in newer API versions are kept instead of failing or reading as empty, and whole numbers in metadata keep their exact value. cdn.serve streams content, invalid arguments and client options report sdk/invalid-argument and sdk/invalid-config, and Java uploads no longer need the same client for every part of a multipart upload.

  • The Calmmarket example (Java) starts its demo only when asked with CALMLENS_DEMO=1 and otherwise requires API credentials.

  • In the Python SDK, verify_webhook_signature takes the signature, timestamp and secret as keyword arguments, or reads them from headers=, and accepts only the raw str or bytes body; parsed JSON raises TypeError, because it can't be verified reliably. Raw upload bytes use the data key, which also takes bytearray, memoryview and binary files; the buffer and uint8Array keys are removed. Invalid arguments and configuration use the sdk/invalid-argument and sdk/invalid-config codes. The default timeout is now 60 seconds without any data sent or received (previously 120), with a separate 10-second connect_timeout; neither limits how long a large upload or download takes.

  • The Python SDK's test client answers with the API's status codes, error bodies and headers, including request IDs and idempotent replays. It returns events added with enqueue_event, routes search, and applies list filters and ordering.

  • The Calmboard example refuses to start without credentials unless you ask for demo mode with --demo, only listens on loopback in demo mode, links every asset back to its link through externalId, and never shows SDK error text or text from the address bar on the page.

  • The JavaScript SDK takes a webhook body as a string or bytes and refuses parsed JSON, which can't be verified reliably. Webhook and test-code builders such as toWebhookEventPayload and generateMediaTestCode moved to @calmlens/sdk/testing, a fetch option replaces requestBackend, and invalid arguments and client options throw sdk/invalid-argument and sdk/invalid-config. The client refuses to run in a web page, where visitors could read the API key, and is much smaller to bundle.

  • JavaScript SDK uploads and CDN downloads are no longer cut off after 120 seconds, so large files transfer completely. Set uploadTimeoutMs to limit uploads.

  • The Calmgram example refuses to run without CalmLens keys unless demo mode is turned on, limits how often each visitor can post, and caps the CalmLens requests all visitors can make in a day.

  • The Ruby SDK accepts snake_case for every option name, including options it has no dedicated handling for, such as processing_options: {image: {ocr_enabled: true}}. Keys inside metadata are still sent unchanged.

  • The Ruby SDK no longer sends queue on later multipart parts, so the queue mode chosen when the upload started applies. Pass queue: to upload_part to override it.

  • Ruby SDK webhook helpers accept only the raw body String and raise CalmLens::InvalidArgumentError for a parsed Hash, which could never verify.

  • The Ruby SDK no longer depends on the base64 gem, and requests identify themselves with a calmlens-ruby/<version> User-Agent.

  • The Calmthread Ruby example requires CALMLENS_DEMO=1 to run in demo mode instead of falling back to it when credentials are missing, gives each browser its own form token, and acknowledges webhooks before applying them.

  • CalmLens is now provided by CalmLens Ltd (company number 17518409), registered in England and Wales. The Terms of Service, Privacy Policy, Cookie Policy and Data Processing Addendum name the new company.

  • While the waitlist is on, the homepage shows the full product overview, from services and pricing to the FAQ, with the waitlist sign-up wherever you would otherwise create an account. It also links to sign-in, so people with an access code can sign in from there.

  • The blog is public while the waitlist is on.

  • The documentation, its Markdown exports and the OpenAPI schema are public while the waitlist is on.

  • Status chips are more compact, and icon tiles use quieter surfaces with consistent icon sizing.

  • The homepage, documentation, sign-in pages and brand kit use the same colours and corner rounding as the portal.

  • Removed the policy configuration reference from public documentation; use the Policies and actions guide to configure policies in the portal.

  • Audio and video guides focus on processing behavior, coverage and usage without naming underlying models.

  • Opening a form dialog focuses its first available field so you can start entering or selecting values immediately.

  • The terms explain advance notice of material service, pricing and contractual changes, billing disputes, and refunds of unused prepaid fees in specified termination cases. The privacy policy explains AI provider processing, retention criteria, lawful bases and how to make a privacy complaint.

  • Usage charts show short dates, such as Oct 5, and use round axis values with more space between labels.

  • The connector dialog is larger and easier to scan. Choose the connector type from cards, with destination and filters on one side and events on the other. Events are grouped by category with a description each, and the dialog shows how many are selected.

  • Checkbox, switch and email recipient options use regular text instead of small capitals. Default checkboxes, radios and switches are larger and easier to see.

  • The activity log on Alerts & Events is more compact. Each entry shows its event icon, an unread dot, a severity chip and a relative time such as 3 hours ago (hover for the exact time), and its facts open from a Details link.

  • The usage page charts only meters with usage. Meters with nothing recorded for the period are listed together in a No usage section.

  • The billing buttons on the usage page show the same loading spinner as other buttons, and the in-app notifications connector no longer shows a redundant type label.

  • Form, detail and section labels use a consistent uppercase treatment.

  • Forms across the portal and admin use consistent spacing and headings. Related fields sit closer together, sections are clearly separated, groups of options such as folders, categories and recipients are labelled like other fields with their help text below, and fields keep a readable width in wide dialogs. Option descriptions sit directly under their option, and the access and scope menus in the permission editor are labelled. The member invitation form lists email and access as separate labelled fields. Forms and dialogs end with their buttons below a divider.

  • Copyable IDs and values use a compact snippet with a quiet copy button instead of a full-width bordered box.

  • Usage and billing charts use the same compact tooltip design as other controls. Tooltips use the dark theme's surface, text and border colours.

  • Event facts and asset metadata use consistent label-and-value rows, with dividers and a stacked layout in narrow panels.

  • Event facts, the compact documentation contents list and expandable asset fields use consistent accordion controls.

  • The site footer groups copyright with the logo and social links, with more compact brand spacing and a larger logo linking to the homepage.

  • Missing pages, access errors, unexpected errors, lost connections and maintenance now have redesigned status pages that explain what happened and offer a clear next step, such as trying again or returning to the portal. The 403 illustration shows a purple padlock slab with matching shaded sides blocking the route to an asset, with a dotted line beyond the lock.

  • Disabled fields, menus, checkboxes and switches now show a dashed outline instead of a grey fill, and borders look the same across cards, tables and controls in both themes. Empty and error messages in lists and tables use the same layout everywhere.

  • The Usage page now groups monthly costs and billing controls above usage trends, with expandable pricing details for each meter.

  • Portal menus, such as the account menu and row actions, support arrow keys and typing to jump to an item, and screen readers announce them as menus.

  • Pressing Escape in a dropdown field keeps your selection and closes the panel it sits in.

  • During the private preview, the sign-in page asks for an access code before showing the sign-in options. Once entered, the code is remembered on that browser for 30 days. Without a code, join the waitlist.

  • Adding an asset in the portal now shows your moderation policy's decision, the action taken, category scores and matched qualifiers once classification finishes. The separate Try moderation dialog on the Assets page is replaced by this, and the Text source includes example texts to try. The moderation playground remains available in the docs.

  • Reaching your free upload limit while adding an asset shows a link to set up billing.

  • The privacy policy and provider disclosures include semantic asset search and speech transcription.

  • The privacy policy explains server-side product analytics, the information excluded from those records, and their retention period.

  • Editors and viewers no longer see project settings, API keys, webhooks and connectors, or metadata fields. They can still view members and lenses. Administrators keep full access; use custom access to give someone specific pages.

  • Audio and video moderation uses native clip analysis for category-only profiles. Longer files are split into overlapping clips, with video and its soundtrack evaluated together.

  • Native media reports show clip evidence ranges. Profiles with qualifier rules retain their existing analysis; native processing does not produce a transcript or ordinary qualifier scores.

Fixed

  • The JavaScript SDK works in Cloudflare Workers again. Every request from a Worker failed with sdk/transport-error.

  • The CDN stops serving an asset within seconds of it being rejected, safety held, having its content removed or being deleted, in every region. Previously a copy cached at the edge could still be served for a short time.

  • Removing an asset's content also removes the content derived from it in child assets, such as an image's OCR text and the text and images extracted from documents and websites. Deleting an asset deletes its child assets too. Child assets under their own safety hold are kept.

  • JavaScript SDK webhook verification accepts the Buffer that express.raw() provides; it previously reported every such delivery as invalid. instanceof CalmLensError works when both the ES module and CommonJS builds of the SDK are loaded, and asset statuses added to the API later no longer make uploads fail.

  • The Ruby SDK raises CalmLens::ConfigurationError when the client is created with an invalid base_url or API key, and CalmLens::InvalidArgumentError for header values with line breaks, instead of Ruby errors on the first request.

  • A Ruby SDK client used in a forked worker process (such as Puma or Unicorn) opens its own connections instead of sharing the parent's.

  • The Go SDK no longer cuts off large uploads and CDN downloads after 120 seconds: Timeout now bounds JSON API calls, while connecting and waiting for a response have their own limits. Failed calls return nil instead of an empty result, every failure is a *calmlens.Error, and webhook timestamps far in the future are rejected.

  • The JavaScript SDK sends list ordering correctly, encodes filters that contain commas, & or #, and lets you call assets.list() without options. IDs are always sent as a single encoded path segment, so an ID containing /, ? or # can no longer reach a different API route, and . or .. IDs are rejected before any request is sent.

  • The Calmgram demo updates a post as soon as a webhook delivers its decision, including decisions made by a reviewer in the portal. Previously it waited for the page to poll.

  • The Python SDK measures the size of seekable file streams, so uploading an open file without sizeInBytes works as the README shows; a stream that can't seek and has no sizeInBytes raises a clear error instead of being rejected by the API. A number passed as upload data is rejected instead of uploading empty bytes, webhook timestamps written with non-ASCII digits are rejected, a worker process started with fork no longer shares its parent's connections, and an https:// proxy address for HTTPS requests raises a clear configuration error.

  • The Python, Go, Rust, Ruby and Java SDK guides and the quick start no longer show install commands for SDKs that aren't available from their package registry yet; they say so instead.

  • The Local development guide loads again, including its events feed example, instead of showing an error page.

  • Opening the homepage or another page from a tab left open until your sign-in session expired loads the page instead of showing an error page.

  • Switching SDK languages in documentation keeps the example you are reading in place as code snippets change length.

  • Documentation and blog pages are smaller to download, and each documentation page's introduction uses its intended lead paragraph style.

  • Documentation pages no longer show a notifications button when you aren't signed in, and download less code for signed-out visitors. The usage page loads its charts only when there is usage to show, and the back office loads only the section you open.

  • Documentation pages load fewer files and appear sooner, and the Quick start downloads the moderation playground only when you have a project to try it with.

  • API reference pages respond to scrolling and clicks sooner while they load, and endpoint URLs no longer shift as the page finishes loading.

  • The first click on an API reference endpoint, such as expanding a response field or choosing a code example language, now works right after the page appears and when it comes from a screen reader, instead of sometimes doing nothing.

  • Preview images of plain-text documents show English and other Latin-script text instead of empty boxes, alongside Thai text, and no longer show stray indentation or escaped characters such as &lt;.

  • Pages reserve scrollbar space so moving between short and long pages does not shift the layout sideways.

  • Status page artwork stays visible when the page reloads or remounts, without replaying an entrance fade.

  • Code examples and SDK tabs use dark scrollbar tracks with muted thumbs in both page themes.

  • The flagged badge in the homepage moderation preview has readable text in both themes.

  • Asset checksum help has clearer spacing between explanations and more room around its content.

  • Short SDK code blocks fit their content, inline SDK calls use the same highlighting as code boxes, and status, visibility and event values use consistent chips across the docs.

  • Opening a tooltip or popover inside a dialog no longer adds extra space to the dialog.

  • Status page actions reflect your signed-in state on the first render, avoiding buttons appearing or changing after the page loads.

  • The portal sidebar shows every page your role can open as soon as the portal loads, instead of some entries appearing a moment later.

  • Clicking anywhere on a searchable dropdown or its label, or tabbing into it, now opens it and places the cursor in its search box. Focused dropdowns show the same focus ring as other fields. Searchable dropdowns show your choice as their text, so screen readers announce it, and their menus match the field width with long descriptions wrapping. Dropdowns also shrink to fit narrow phone screens instead of widening the page.

  • Inline links match the surrounding text size, including billing terms and privacy notices.

  • Dropdown menus near the bottom of the window open upward or shrink to fit, so every option can be reached.

  • Image qualifier presence no longer counts as proof for an Only policy exception. OCR text scope remains separate, with whole-image scope unavailable when relevant visual evidence lacks scope assessment.

  • Google sign-in no longer fails when authentication refresh tokens exceed standard field size limits.

  • The portal remembers your selected project again after reloading or signing in, whichever cookie choice you made. The cookie banner asks for your choice once more because the cookie list changed.

  • Dropdown menus inside dialogs, such as the search dialog, open and can be selected.

  • Connectors subscribed to upload limit or member joined events show those events by name again and receive them.

  • Text token usage shows exact counts below one million tokens, instead of 0M.

  • Toggle switches stay aligned in narrow layouts, and switch labels line up with the switch.

  • Danger, success and warning buttons and badges use light text on deeper colours, so their labels are readable in light and dark themes.

  • The assets dashboard and usage page show their data straight away instead of loading it a second time, and the asset statistics no longer flash a loading state.

  • An error in one portal or documentation page keeps the navigation available, so you can move to another page. A failed usage chart no longer hides the rest of the usage page.

  • Pressing Escape closes classification details and other popovers instead of reopening them straight away.

  • The asset filters panel stays within the window when there is little room below the Filters button, so every filter can be reached.

  • Documentation pages show code in your saved SDK language straight away, instead of sometimes showing another language first, and load faster with less layout movement while they load.

  • The "On this page" menu on phones is in place as soon as a documentation page loads, instead of appearing afterwards and pushing the article down.

  • API reference examples keep their code steady while the page loads, and the checkboxes in request field tables are announced by name to screen readers.

  • Long dialogs, such as test inputs, API key access and member permissions, scroll their content so the buttons at the bottom stay reachable on small screens.

  • Pressing Enter in the API key, member permissions, human reviewer and metadata field dialogs saves the form.

  • Status chips, the safety hold thumbnail, active steps in Add asset and path parameters in the API reference show their intended border colours.

  • Errors when accepting a project invitation, loading folders for custom access or loading a list use the same error style as the rest of the portal.

  • The disabled upload area uses a muted icon instead of a dark circle.

  • The asset filters, table column filters, notifications and classification details panels share one panel style, and the filters panel keeps Clear all and Done visible while its filters scroll.

  • Metadata groups, extracted text and other expandable sections have square corners where an open section joins its header, and the media analysis timeline has spaced, aligned columns.

  • The Billing card on the profile and usage pages no longer repeats its description, and the account deletion section on the profile page has even spacing above and below its divider.

2026.6

New

  • Dedicated guides for multipart uploads, asset organisation, OCR, audio and video, notifications and local development.
  • Rust, Ruby and Java SDK guides, alongside JavaScript, Python and Go.
  • A collapsible table of contents on smaller screens.
  • Python and Go SDKs support the same core capabilities as the JavaScript SDK, with mocks and integration examples.

Changed

  • The CalmLens CLI is distributed separately from the SDKs, with standalone downloads and Homebrew installation alongside npm. Python and Go SDKs no longer install or include their own CLI commands.

  • Every SDK guide links to a dedicated testing subpage with offline mock examples.

  • Clarified how to wait for moderation in a request or queue it and receive completion and failure events. Asset polling is documented as a fallback for integrations that cannot receive webhooks.

  • Documentation is grouped by task, with shorter walkthroughs and separate reference material.

  • More compact headings, lists and examples improve readability across screen sizes.

  • Documentation header links use the same navigation button style as the landing page.

  • Documentation navigation starts with all sections expanded and uses compact spacing with icons for the main sections.

  • Documentation pages now include the site footer below the entire docs layout, reached by continuing to scroll past the article.

  • Footer links are grouped into Menu, Legal and Resources, with documentation, SDKs and the changelog easier to find.

  • SDK guides include language selection across code examples and inline calls, with your preference remembered between visits.

  • Event documentation describes typed facts for each event, making webhook payloads easier to understand and integrate.

  • Remote uploads and webhook destinations have stronger URL validation.

Fixed

  • Site checks using HEAD requests no longer fail with a server error.

  • Policy pages have specific search titles and descriptions, and the sitemap includes all published blog posts.

  • Documentation navigation keeps the selected page visible when opening or switching pages.

  • Corrected webhook field descriptions and JavaScript SDK method coverage.

  • Markdown downloads include every documentation page and SDK examples.

  • Page contents stay in sync when headings change.

  • Image moderation reports save correctly when no OCR text is found.


2026.5

New

  • Project teams support scoped permissions, and API keys belong to individual projects.
  • Branded email notifications keep people informed about project activity.
  • A moderation playground lets you paste content and inspect its results.
  • The CalmLens CLI and events feed help you test webhook integrations locally.
  • Published unit prices and a cost calculator help you estimate usage costs.

Changed

  • Invalid API keys return clearer errors.

Fixed

  • Failed webhook deliveries are retried.

2026.4

New

  • Qualifier-based policies give you more control over how moderation results trigger actions.
  • Shared account policies keep moderation settings consistent across projects.

Changed

  • Category-specific qualifiers and clearer injury and death definitions make reports easier to interpret.
  • Classification details are easier to copy, with clearer confidence displays and category explanations.
  • Improved asset review controls make it easier to inspect content and apply rejection actions.

Fixed

  • Category tooltips stay readable without overlapping, and image certainty scores display correctly.

2026.3

New

  • Create lenses in the portal to configure content transformations.
  • HEIC previews and document thumbnails make more uploaded formats easier to review.

Changed

  • Asset previews load ahead of time on hover.
  • Faster dashboard loading and private thumbnail delivery improve browsing large asset collections.
  • Content delivery improvements reduce asset lookup and delivery latency.

Fixed

  • Cached asset previews no longer get stuck on placeholders.
  • Refreshed authentication cookies and thumbnail fallbacks work more reliably.

2026.2

New

  • Multipart uploads improve how larger content is sent for processing.
  • Expanded SDK methods make asset operations easier to integrate.

Changed

  • Upload and synchronous asset creation improvements reduce processing overhead.
  • Text classification caching speeds up repeated checks.
  • API key management and authentication caching improve integration workflows.

Fixed

  • Corrected asset metadata handling.

2026.1

New

  • Asset filtering and grouping help you find and organise content in the portal.
  • Asset pages bring events and webhook activity together for easier troubleshooting.

Changed

  • Updated metadata controls make asset information easier to manage.
  • Portal navigation and media tables improve day-to-day asset review.

Fixed

  • Corrected event ordering and asset caching.

See the documentation for integration guides and API details.

Signing in

Signing out

Cookies on CalmLens

We use essential cookies to keep you signed in and the site secure. With your permission, we'll also use functional cookies to remember preferences such as your layout and documentation language, and to offer Google One Tap sign-in. We don't use analytics or advertising cookies. Manage cookies