Automate UGC Moderation Before Publication
Route uploads into a moderation flow that holds each asset in a pending state and promotes it only after a check passes, so the delivery URL is never public while undecided. Because classification returns a confidence score rather than a verdict, define an explicit middle band for human review, then sample what the automation approved.
Before you start
You need three things settled before you open the canvas.
A moderation add-on enabled on your product environment. Automated classification is an add-on, and add-ons bill separately from base-plan credits and appear as their own invoice line. That matters for forecasting: your storage and bandwidth spend tracks the size of your library, but moderation spend tracks the number of uploads — including the ones you reject and delete, which never contribute a byte of storage or delivery. A gallery with 5,000 stored assets and 500 uploads a day costs very differently from one with 5,000 stored assets and 20 uploads a day. Meter it against upload volume, not library size.
A decision about rejected content, made by whoever owns legal risk. How long you keep material you refused to publish is a retention question, not a workflow question, and the answer differs by jurisdiction and by what the content is. Do not encode a guess into the moderation flow. This gets its own step below.
An upload path that does not deliver. Everything here depends on the asset being unreachable while it is undecided, so know how your app currently constructs delivery URLs before you change anything.
Steps
-
Route uploads into a pending state, and confirm nothing serves from it.
The whole point of a moderation flow is that the upload is held rather than published: the asset lands, the check runs, and only a pass promotes it to a delivered state. The moderation PowerFlow is built around that hold.
The hold is only real if the delivery URL was never public in the interim. Verify this before you build anything else on top: upload a test asset, and while it is still pending, request its delivery URL from a machine and a network that has nothing to do with your build — no session, no signed URL, no local cache. If it returns the image, your flow is decorative. A moderation step that runs after a URL is already fetchable protects nothing, because the failure mode you care about is a scraper or a link-sharer reaching the asset in the seconds before a human sees it.
This is also where deployment shape bites. If you are wiring the flow from an agent or a no-code environment, check what your delivery is actually locked to — IP-locked delivery is a quiet failure mode that makes a pending asset look correctly blocked when it is really blocked for an unrelated reason, and will keep looking blocked after you promote it.
-
Read the classification output as a score, not an answer.
Automated classification returns a confidence score, not a verdict. That distinction is the single most consequential thing on this page, because it means a flow with one cutoff — approve above, reject below — is a flow that silently assigns its hardest cases to whichever side of the line they happen to land on. The cases nearest the threshold are precisely the ones where the model has told you it does not know.
The mechanism is worth holding onto: a classifier is estimating a probability, and its error is concentrated in the middle of its own range. A single cutoff throws away that information. Two cutoffs keep it.
-
Define three bands, and give the middle one to a person.
Configure the flow with an upper threshold and a lower threshold rather than one. Above the upper: auto-approve and promote. Below the lower: auto-reject. Between them: hold, and queue for a human decision. The band is not a fallback for when the model fails — it is the part of the range where the model has correctly reported uncertainty, and a human is the right handler for it.
Two costs to price in. The band consumes human attention in proportion to how wide you make it, so a band covering half the score range means half your uploads are manually reviewed and you have automated nothing. And every asset in the band sits pending, which is latency the uploader sees — for a profile picture that is fine, for a live marketplace listing it may not be.
Where to put the boundaries is an empirical question, and you will not know until step 5. Start deliberately wide, narrow it with evidence.
-
Publish deletion of rejected content as a separate flow.
Build it as its own flow, on its own trigger, using the UGC deletion PowerFlow rather than bolting a delete step onto the end of the moderation branch.
The reason is not tidiness. Retention of rejected material is a legal question, not a workflow one — some categories you are obliged to delete promptly, some you may be obliged to preserve for a period, and the answer is set by counsel and by jurisdiction rather than by whoever is editing the canvas. Keeping it separate means the retention rule can be changed, audited, and pointed at by someone who is not going to touch your moderation logic, and that the moderation flow’s own history stays a record of decisions rather than of deletions.
The practical consequence: your moderation flow ends at rejected. What happens to a rejected asset after that is the other flow’s job, on the other flow’s schedule.
-
Sample the approvals, not the flags.
Once the flow runs, set up a recurring review — a fixed number of assets per day, or a fixed percentage of throughput. Draw that sample from what the automation approved, not from what it flagged.
This inverts most people’s instinct, and it is the most important operational habit here. Flagged items already get a human look; reviewing them again measures nothing you did not already know. The failure that matters is the false negative: content the classifier scored as clean, that your flow promoted, that is now publicly delivered under your domain. Nothing in the system will surface it. No alert fires. You find it when a user does, or when a journalist does.
Sampling approvals is the only mechanism that turns that invisible failure into a number. It also gives you the evidence for step 3: if false negatives cluster just above your upper threshold, raise it; if approvals near the threshold are consistently clean, you can lower it and buy back review time. Without this sample you are tuning thresholds on vibes.
-
Wire the trigger and hand over the operational parts.
Attach the flow to the event that fires on upload rather than running it on a schedule — a nightly sweep leaves a full day of unreviewed assets in whatever state your upload path put them, which defeats step 1. The trigger types available to a hosted automation differ in what they can see about the asset, so pick before you finish the canvas rather than after.
The same event-shaped structure is what other media automations use — alt-text generation on upload is the same trigger with a different action, and it is worth deciding whether it runs before or after moderation, because generating alt text for content you are about to reject is spend on an asset that will not exist.
What done looks like
An upload is unreachable at its delivery URL until it passes. Assets scoring above your upper threshold publish without a human touching them; assets below the lower one are rejected; assets in between wait in a queue that a person works through. A separate published flow, owned by whoever owns the retention decision, handles rejected material on its own schedule. A daily sample drawn from approved assets tells you your false-negative rate, and your thresholds move when that number moves rather than when someone has an opinion. The moderation line on your invoice tracks upload volume, and is legible as a per-upload cost rather than as part of storage and bandwidth.
Sources
- add-ons bill separately from base-plan credits cloudinary.com
- moderation PowerFlow cloudinary.com
- UGC deletion PowerFlow cloudinary.com
See also
-
Webhook, schedule and upload triggers in MediaFlows: how each one fires, what it costs downstream, and why live and reconciling flows are often built twice.
-
How to run a one-off bulk media migration from a spreadsheet using a published CSV upload flow: validation, metadata, rate limits and resumable rows.
-
How no-code builders upload and deliver media: pre-built integrations, plain transformation URLs, one shared credential, and where signed requests stop.
-
PowerFlows give canvas-level control over branching and third-party calls; EasyFlows trade that for speed. Which MediaFlows form fits which automation.