The Limit action delivers an asset normally but marks it limited, so your app can keep it visible while ranking it lower and leaving it out of notifications.
·3 min read
Policies
Delivery
Events
Some content shouldn't be removed but shouldn't be pushed to more people either. A one-off insult in a heated thread is a common example: deleting it can feel heavy-handed, while ranking it alongside everything else rewards it. Release 2026.4 adds a policy action for that middle ground. Limit delivers the asset as usual and sets its moderation status to limited, so your app can decide how far it travels.
What Limit does
An asset whose policy decision is Limit has classification.moderation.status set to limited. The CDN serves it from its plain URL exactly like an allowed asset, so existing image tags, signed URLs and lenses keep working without changes. CalmLens also sends the asset.limited event when an asset becomes limited.
The difference is in what your app does with it. CalmLens doesn't know how your feeds or notifications work, so reducing reach is your app's job:
Your app has
What to do with limited content
Feeds or rankings
Rank it lower, and keep it out of recommendations, trending and "top" lists.
Notifications
Don't send notifications, mentions or digests for it.
A comment thread
Collapse it behind a "Show" control, or sort it to the end.
None of these
Show it like allowed content.
An app with no ranking or notifications can treat limited exactly like allowed, and nothing breaks.
Choosing Limit in a policy
Limit can be a category's action. When several categories act on the same asset, the strongest action wins, and Limit is the weakest one after Allow. A post that one category limits and another blocks is blocked.
Limit also works with the allowances added in this release. An allowance can use any action softer than its category's, so a category set to Block can use Limit for the content an allowance covers rather than allowing it outright. Content the allowance doesn't cover keeps the category's Block action. The policies guide covers how allowances and restrictions combine.
A person reviewing an asset in the portal or through the API can also set it to limited. Their decision takes precedence over the policy's and sends the same event.
Reacting in your app
Synchronous moderation returns the status in the response, so a comment endpoint can save it with the comment straight away. For uploads moderated in the background, or decisions that change later, the status events carry the asset with its new status. A handler that stores the status for every outcome, limited included, looks like this:
import { CalmLensError, parseWebhookEvent } from"calmlens/server";
const STATUS_EVENTS =newSet(["asset.allowed", "asset.limited", "asset.age-restricted", "asset.blocked", "asset.purged"]);
exportasyncfunctionPOST(request:Request):Promise<Response> {
let event;
try {
event =awaitparseWebhookEvent({
payload: await request.text(), headers: request.headers,
secret: (process.env.CALMLENS_WEBHOOK_SECRET ??""),
});
} catch (error) {
if (CalmLensError.isCalmLensError(error)) returnnewResponse(null, { status: 401 });
throw error;
}
const asset = event.asset;
if (asset?.externalId && STATUS_EVENTS.has(event.type)) {
// Apply only to this upload/version; reject stale events in your database.awaitupdateModerationStatus(asset.externalId, asset.classification.moderation.status, event.createdAt);
} elseif (asset?.externalId && event.type ==="asset.failed") {
awaitmarkModerationFailed(asset.externalId);
}
returnnewResponse(null, { status: 204 });
}
Store the status rather than a yes/no flag. Your feed query can then filter or down-rank on limited directly, and the asset.limited event tells you when to recompute a ranking you've already built. An asset can move from limited to allowed, or the other way, when someone reviews it, so apply the latest event for each asset rather than the first.
Limited assets in the delivery guide has the reference for how each status is served.
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