Regional delivery rules for the countries you serve
Choose the jurisdictions a project serves, pass each viewer's country with media requests, and CalmLens applies the stricter regional outcome where one exists.
·5 min read
Delivery
Policies
CDN
Some content rules depend on where the viewer is: German rules on Nazi symbols, for example, or age checks for pornographic images and video in the UK, Australia and Brazil. One global decision per asset can't express that: either the asset is withheld for everyone, or it is served to viewers in countries where the rule applies. Release 2026.7 adds jurisdiction rules, so a project can serve one asset differently depending on the viewer's country.
Choose the jurisdictions you serve
Each project now has a list of jurisdictions it serves. global always applies. The others are opt-in:
Jurisdiction
Additional outcome
Germany (DE)
Withhold qualifying Nazi symbols and public Holocaust denial.
Austria (AT)
Withhold qualifying Nazi symbols and public Holocaust denial.
France (FR)
Withhold qualifying public Holocaust denial.
United Kingdom (GB)
Age-restrict pornographic images and video.
European Union (EU)
Age-restrict pornographic images and video, as an opted-in product standard.
Australia (AU)
Age-restrict pornographic images and video, qualifying high-impact violent media, and material promoting or instructing suicide, self-injury or disordered eating.
Brazil (BR)
Age-restrict pornographic images and video.
Each rule's exceptions and official sources are in the jurisdiction rules guide. The catalogue covers these specific content and delivery rules; it doesn't automate every duty a service has in a jurisdiction.
Regional rules sit beside the global mandatory rules, which apply to every project and every policy: sexualised minors, intimate image abuse, extreme pornography and violent extremism are blocked everywhere. The policy editor shows both groups, read-only, with a country or EU badge on each regional rule.
How a regional decision is made
Regional rules only ever make a decision stricter. Each asset keeps its base decision, from your policy and the global rules. Stricter regional outcomes are recorded beside it in classification.moderation.regions, without changing the base decision or the asset's status.
When a viewer requests the asset, CalmLens takes the strongest of three outcomes: the base decision, the entry for the viewer's country if the project serves it, and the EU entry if the project serves the EU and the viewer is in a member state. A country entry wins a tie with the EU. A regional block in Germany doesn't delete the content or hide it from viewers in France, and a regional age restriction never weakens a policy block.
A regional block withholds the asset even from a request with a signed URL or an API key. A regional age restriction uses the same opt-in as any age-restricted asset: the asset is served only when the request confirms the viewer's age.
Pass the viewer's country
Media requests take optional viewerClaims:
Claim
When omitted
When supplied
region
Country of the connection that reaches CalmLens.
Your viewer's uppercase ISO country code, such as DE or GB.
ageConfirmed
false, even with an API key or signed URL.
Your app's confirmation that this viewer passed its age check.
When the browser loads media straight from the CDN, the connection country is usually the viewer's, and the SDK media components pass any claims you give them:
importtype { Asset } from"calmlens/app";
import { CalmLensMedia } from"calmlens/react";
// Claims are optional customer assertions evaluated by the CDN.// ageConfirmed stays false until your app completes the required age check.exportfunctionRegionalPhoto({
asset,
region,
ageConfirmed,
}: {
asset:Asset;
region:string;
ageConfirmed:boolean;
}) {
return (
<CalmLensMedia asset={asset} viewerClaims={{ region, ageConfirmed }} alt="Uploaded photo" />
);
}
A request through your own backend is different. The connection then comes from your server, so the fallback country is your server's, not the viewer's. Forward the viewer's country explicitly. At the HTTP level, claims go in a JSON-encoded viewerClaims query parameter or the X-CalmLens-Viewer-Claims header:
The query parameter takes precedence if both are present. Image elements use the URL form; proxies can use the header. For signed URLs, pass viewerClaims when you create the URL: they become part of the signature, so they can't be changed afterwards.
Claims are your assertions. CalmLens doesn't verify a viewer's location or age, and it can't see through a VPN. Your app performs the age check and decides when to set ageConfirmed. The UK, EU, Australian and Brazilian rules expect a reliable check rather than a self-declared age. A claimed country also never opts the project into more jurisdictions; only the jurisdictions it serves apply.
When delivery is refused
The CDN returns an error instead of restricted media, with a JSON error code a proxy or the SDK's CDN methods can read:
Error code
Meaning
viewer/invalid-claims
The claims are malformed or the country is invalid.
viewer/region-required
Regional rules apply, but neither a claimed nor a connection country is available.
viewer/age-confirmation-required
The content is age-restricted for this viewer and ageConfirmed isn't true.
asset/regional-evidence-required
The asset still needs classification evidence for a jurisdiction the viewer is in.
asset/not-available
Delivery is refused, including by a regional block.
An image element only sees a failed load, so show a neutral unavailable state rather than guessing the reason.
Once a project serves a regional jurisdiction, viewer responses are sent with Cache-Control: private, no-store, since the same URL can have different answers for different viewers. CalmLens still checks each request before reusing its own cached copy, so a proxy should forward requests rather than cache by country.
Turning on a jurisdiction for existing assets
Changing the jurisdictions served starts a background refresh of completed assets that still have their stored content or extracted text. Existing evidence may already cover a newly applicable rule. Where it doesn't, requests from that jurisdiction return asset/regional-evidence-required until the refresh finishes. That code doesn't mean the asset is harmful, and it doesn't block it for anyone else. Assets whose content was removed aren't refreshed, so keep the originals you'll need before enabling a jurisdiction on a live library.
If you serve files from your own storage instead of the CDN, your app has to apply the base and regional decisions itself before returning them. The asset.region-restricted event tells you when an asset gets a stricter regional decision.
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