Screen, describe and clean up user-uploaded images

Anything users can upload, someone will upload. Build a screening step that catches explicit content, checks for faces, drafts alt text and cleans product photos, and know where the models stop being trustworthy.

The day you add an image upload to your product, you become a publisher of whatever people send. Most of it will be fine: avatars, product photos, screenshots. Some of it will not, and the first explicit image that appears on a public profile page will be screenshotted and shared long after you remove it.

This lesson builds a screening step for uploads with four APIs, each answering a different question about an image:

QuestionAPICredits
Is this explicit?nsfwimagedetector10
Is there a person's face in it, and where?facedetect10
What does it show, in words?imagecaption20
Can I cut the subject out of the background?backgroundremover40

None of them is a judge. They are classifiers that are usually right and sometimes confidently wrong. The design question running through every section is the same: what happens to the user, and to you, when the model is wrong?

How these APIs take images

Input styles differ across the four, and it matters for how you wire them:

  • nsfwimagedetector and imagecaption take a file upload (multipart/form-data, field image), JPG, PNG or GIF.
  • facedetect and backgroundremover take either a file upload in image or a public image URL, as url or in image itself. They also accept WebP, and backgroundremover takes BMP.

For screening user uploads you will usually have the bytes in memory already, so uploading is natural. The URL style is convenient for images already in your bucket or returned by another API.

Screen for explicit content first

NSFW Image Detector returns two booleans on every plan, isNSFW and isSafe, which are always opposites. On plans that include them, confidence (0 to 1, how likely the image is NSFW) and category (sfw or nsfw) let you build a middle band.

Screen first because it is cheap and because it gates everything else: an image that fails here should never reach a captioning model, a public URL or a CDN cache.

The decision is not binary in a well-run system. Use three outcomes:

  • Reject clear violations, with a neutral message ("This image can't be used. Please choose another.").
  • Hold for review anything uncertain: the image is stored privately, the user sees "processing", and a person decides.
  • Publish the rest.

With only the booleans, "uncertain" has to come from context instead of a score: new accounts, accounts with previous rejections, or images going somewhere highly visible (a public profile, a marketplace listing) can be held for review even when isSafe is true, until the account has a track record. With confidence, set two thresholds and send the band between them to review.

False positives cost real users. Swimwear, medical images, breastfeeding photos, classical art and skin-toned products all trip explicit-content classifiers. If a false positive silently deletes a photo, the user has no idea why their upload vanished. Hold and review; never silently delete.

False negatives cost you. No classifier catches everything, so keep a "report this image" link on every user image and a takedown process behind it.

Check yourself

Your plan returns isNSFW and isSafe but not confidence. A new user's first upload comes back isSafe: true and is headed for a public marketplace listing. What is a reasonable policy?

Answer the check above to continue.

Run every example on your own key. Free plan, no card.

Scaling up?

Volume pricing, custom SLAs, and dedicated support for high-traffic teams.

Contact sales