# Asset lifecycle and moderation

An asset is a file, remote URL, or extracted child submitted for classification. Its `status` describes where it is in the moderation lifecycle.

| Status | Meaning |
| --- | --- |
| `uploading` | A multipart upload is open and expects the next sequential part. |
| `pending` | Upload is complete and asynchronous classification is queued or running. |
| `approved` | Classification completed and delivery is allowed. This includes `alert` actions, where `report.flagged` is still `true`. |
| `rejected` | A `hide` or `purge` action, a child-asset failure, or a reviewer rejected the asset. |
| `error` | Processing could not complete. |

## Wait in the request or receive an event

You can moderate in place and read the decision from the response, or queue moderation and receive it later. Text and images support either flow; audio and video always run asynchronously, even with `queue=false`.

With `queue=true` or `client.assets.create()`, save the returned asset ID and subscribe to [`asset.classified`](/docs/api/events#event-asset-classified) and [`asset.failed`](/docs/api/events#event-asset-failed) through [webhooks](/docs/guides/webhooks). With `queue=false` or `client.assets.moderate()`, the request remains open until classification finishes for content that supports synchronous processing. Multipart uploads keep the queue mode selected by the first part.

## Delivery while moderation runs

Whether the [CDN](/docs/guides/delivering-assets) serves retained content depends on the asset's status:

| Status | Served by the CDN |
| --- | --- |
| `uploading` | Never. |
| `pending` | Yes by default. No when the project enables [Block assets until moderation finishes](/portal/settings#block-unmoderated-assets). |
| `approved` | Yes. |
| `rejected` | Never. |
| `error` | Never. Retry processing to make the asset servable again. |

Assets under a safety hold or with removed content are never served either. Blocked requests return [`403 asset/not-available`](/docs/api/cdn#error-asset-not-available).

By default, content is servable as soon as the upload completes, before classification finishes. To serve only assets that have passed moderation, turn on [Block assets until moderation finishes](/portal/settings#block-unmoderated-assets) under **Content delivery**. The setting is stored as `settings.blockUnmoderatedAssets` and applies to content, previews, lenses, transforms and signed URLs.

## Retention and visibility

`processingOptions.keepContentAfterProcessing` defaults to `false`. When it is false, CalmLens classifies the asset and purges stored source content after successful processing. The asset record and report remain, but its content cannot be served from the CDN.

Set `keepContentAfterProcessing: true` when you intend to serve content, generate previews, retain extracted text, or apply CDN transforms.

`visibility` defaults to `private` and only controls access to retained content:

- `public` content is available without authentication.
- `private` content requires an owning browser session, a suitably privileged server-side API key, or a signed URL.

Visibility does not cause content to be retained. A public asset with `keepContentAfterProcessing: false` still has no source content to serve.

## Reports and rejection

Read `status` for the asset decision and `report.flagged` to see whether a policy action was applied. An approved, flagged asset may still need review. Use [Reading moderation reports](/docs/guides/moderation-reports) for scores and evaluation coverage, and [Policies and actions](/docs/guides/moderation-policies) for actions and exceptions.

Reviewers can reject an asset from the portal and attach a note. Composite assets can be rejected when one of their children is rejected.

## Child assets

Documents and websites can produce child assets for extracted content. The parent status reflects the overall outcome; inspect the children for their individual reports.

`client.assets.listChildren({ assetId })`

Images with OCR enabled can also produce a text child. See [OCR and image reports](/docs/guides/ocr) for inheritance, retention and combined results.

## Deletion choices

- **Remove content** deletes stored bytes while retaining the asset record, metadata, and moderation history. It also removes the content derived from those bytes in child assets, such as OCR text and the text and images extracted from documents and websites, while keeping the child records.
- **Delete asset** deletes the record itself, together with its child assets and their content.

The CDN stops serving removed or deleted content within seconds, including copies cached at the edge. Child assets under their own safety hold keep their content until the hold is resolved.

- **Batch operations** apply one of those operations to assets sharing a tag and run asynchronously.

Use immutable external IDs for integration-level idempotency. Creating a second asset with the same `externalId` in a project returns [`409 asset/duplicate-external-id`](/docs/api/assets#post-asset-error-asset-duplicate-external-id).
