# How CalmLens works

CalmLens checks user content against your rules and tells your app whether to show it. Every upload follows the same path:

1. **Upload → asset.** Your server sends text, an image, a document or a URL. CalmLens stores it as an asset, with your own ID in externalId.
2. **Classify → report.** CalmLens scores six categories (sexual, violence, self-harm, harassment, hate and criminal activity) and context qualifiers such as graphic or fictional.
3. **Decide → policy.** Your project's moderation policy turns the report into one action: ignore, alert, hide or purge.
4. **Act → status.** The asset becomes approved or rejected, report.flagged records whether the policy matched, and a webhook tells your app.
5. **Deliver (optional) → CDN.** If you kept the content, the CDN serves it and resizes images with lenses. Rejected assets are never served.

## Your app's decision

Publish only after `status` is `approved`. If `report.flagged` is also `true`, the policy allowed delivery but the content may need review. Keep `pending` content private to its author; do not publish `rejected` or `error` results.

See the [decision table](/docs#3-read-the-decision) for application behavior and [policy actions](/docs/guides/moderation-policies#actions) for ignore, alert, hide and purge.

## Synchronous or queued

Choose how your app receives the result; text and images support either flow:

- **Moderate in place:** use `client.assets.moderate()` (`queue=false` over HTTP) to wait for classification and read the decision from the response. `client.text.moderate()` is the text-specific convenience method.
- **Queue and receive an event:** use `client.assets.create()` (`queue=true` over HTTP). Save the returned asset ID, then handle [`asset.classified`](/docs/api/events#event-asset-classified) through a [webhook](/docs/guides/webhooks) when the decision is ready. Subscribe to [`asset.failed`](/docs/api/events#event-asset-failed) for processing failures.

Audio and video always run asynchronously, even with `queue=false`. In the queued flow, keep content unpublished until approved. The [quick start](/docs) demonstrates both approaches.

## Moderation only, or storage and delivery too

By default CalmLens classifies content and then deletes it (`keepContentAfterProcessing: false`), keeping only the record and report. Your own storage keeps serving your files.

Set `keepContentAfterProcessing: true` to let CalmLens host the file as well. Approved content is served from `cdn.calmlens.com`, rejected content is never served, and [lenses](/docs/guides/lenses#named-lenses) resize or convert images on the fly. Public assets can be fetched while they are still `pending`, so only show CDN URLs to other users after approval.

## Glossary

| Term | Meaning |
| --- | --- |
| Project | A workspace for one app or environment. API keys, policies, connectors and assets belong to a project. |
| Asset | One piece of submitted content: text, a file or a URL. Use `externalId` to link it to your own record. |
| Report | The classification result: scores for six categories plus `flagged`. See [Report format](/docs/guides/moderation-reports). |
| Category | One of six areas of harm: sexual, violence, self-harm, harassment, hate and criminal activity. See [Category definitions](/docs/guides/moderation-categories). |
| Qualifier | Extra detail within a category, such as `graphic`, `fictional` or `historical`. Policies can use qualifiers for exceptions. |
| Policy | Your rules for each category: which action to take and how strong the evidence must be. See [Policies and actions](/docs/guides/moderation-policies). |
| Action | What the policy decides: `ignore`, `alert`, `hide` or `purge`. |
| Lens | A named, versioned image preset for the CDN, such as a 400px WebP thumbnail. Lenses don't affect moderation. |
| Connector | Sends project events outside CalmLens. A webhook connector POSTs a signed HTTPS request to your server when an asset is uploaded, classified or flagged. |

## What CalmLens doesn't cover yet

- **Spam, scams and personal data** aren't moderation categories.
- Video (beta) and Audio (beta) use background moderation. See [Media reports](/docs/guides/moderation-reports#audio-and-video-reports) for supported formats and sampling limits.
