Blog

Show content without amplifying it with Limit

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 hasWhat to do with limited content
Feeds or rankingsRank it lower, and keep it out of recommendations, trending and "top" lists.
NotificationsDon't send notifications, mentions or digests for it.
A comment threadCollapse it behind a "Show" control, or sort it to the end.
None of theseShow 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 = new Set(["asset.allowed", "asset.limited", "asset.age-restricted", "asset.blocked", "asset.purged"]);

export async function POST(request: Request): Promise<Response> {
  let event;
  try {
    event = await parseWebhookEvent({
      payload: await request.text(), headers: request.headers,
      secret: (process.env.CALMLENS_WEBHOOK_SECRET ?? ""),
    });
  } catch (error) {
    if (CalmLensError.isCalmLensError(error)) return new Response(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.
    await updateModerationStatus(asset.externalId, asset.classification.moderation.status, event.createdAt);
  } else if (asset?.externalId && event.type === "asset.failed") {
    await markModerationFailed(asset.externalId);
  }
  return new Response(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.

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