Docs / Image Analysis & OCR / Image Recapture Detection

Image Recapture Detection

BETA recapture

The Recapture Detection model evaluates whether a photo is original, or if it is a photo of a printed or displayed image.

Overview

The Recapture Detection model analyzes an image and determines whether it was captured directly from a real-world scene or re-photographed from an existing image such as a screen, printout, magazine or poster.

Recapture (also known as a presentation attack or second-capture attack) is one of the most common techniques used to bypass originality checks, strip provenance signals and impersonate legitimate content.

When to use this model

  • Marketplace & listing integrity. Flag sellers uploading photos of products displayed on a monitor, or re-photographed catalog pages, instead of authentic product shots.
  • User-generated content originality. Identify images passed off as original that are in fact re-photographed from another source (screens, magazines, posters, printed photos).
  • Document & proof-of-identity workflows. Ensure that receipts, invoices, IDs or certificates were captured directly from the physical document, not re-photographed from another display or printout.
  • Dataset hygiene. Filter recaptured images out of training sets, stock libraries and user-generated content archives.
  • Watermark & provenance evasion. Catch attempts to strip watermarks or C2PA-style signatures by printing or displaying an image and re-photographing it.

When to use something else

  • For face-specific spoofing during selfies or identity checks (printed face photos, screen replays, 3D masks), use Face Liveness Detection — it is optimized for that narrower task and returns richer signals.
  • For detecting AI-generated or synthetic images, use AI-generated Image Detection. Recapture detection and AI detection are complementary and often combined.
  • To detect face swaps, see Deepfake Detection.

Definitions & Examples

What is a recaptured image?

The following types of images are detected as being recaptures:

Photo of an image displayed on a screen

Displayed images

Photos of images displayed on phones, tablets, or monitors. This includes cases where the edge of the screen or monitor is not visible.

Photo of a printed image

Printed images

Photos of printed images, photos, magazine covers, posters, etc. This includes cases where the edge of the photo/magazine/poster is not visible.

Original images

Original image

Images that do not fall under the "recapture" category are considered original. This includes:

  • Photos where a screen or printed image is visible but is not the primary subject (e.g. a laptop on a desk, a poster on a wall).
  • Screenshots captured digitally (no physical re-photographing step).
  • Original photos with post-processing edits such as overlays or collages.
  • AI-generated images (see the GenAI detection model for this)

How it works

The model looks for the subtle visual artifacts that recapturing an image almost always introduces, including:

  • Moiré and aliasing patterns from photographing a pixel grid.
  • Screen-door and sub-pixel structure visible at the sensor level.
  • Reflections, glare and screen bezels even when cropped out of the main subject.
  • Halftone and dithering patterns typical of printed material and magazine pages.
  • Paper texture, folding and lighting inconsistencies on printed photos and posters.
  • Double-compression and frequency-domain artifacts that persist after re-encoding.

These signals are fused into a single calibrated score between 0 and 1.

Robustness

The model is designed to remain accurate under common real-world transformations, including:

  • JPEG re-encoding at moderate-to-high quality settings.
  • Resizing down to ~512 px on the shortest edge.
  • Mild color adjustments, auto-brightness and auto-contrast.
  • EXIF stripping and standard social-platform recompression pipelines.

Best practices

To maximize accuracy, send the image as close to the original as possible. Skip manual resizing or aggressive compression before the API call when feasible, avoid stacking multiple re-encodings (e.g. JPEG → PNG → JPEG).

Code examples

Upload a file or send an image URL, pick your language, and receive a JSON response. Need credentials first? Create a free account →

POST api.sightengine.com/1.0/check.json
Response: JSON

curl -X POST 'https://api.sightengine.com/1.0/check.json' \
    -F 'media=@/path/to/image.jpg' \
    -F 'models=recapture' \
    -F 'api_user={api_user}' \
    -F 'api_secret={api_secret}'


# this example uses requests
import requests
import json

params = {
  'models': 'recapture',
  'api_user': '{api_user}',
  'api_secret': '{api_secret}'
}
files = {'media': open('/path/to/image.jpg', 'rb')}
r = requests.post('https://api.sightengine.com/1.0/check.json', files=files, data=params)

output = json.loads(r.text)


$params = array(
  'media' => new CurlFile('/path/to/image.jpg'),
  'models' => 'recapture',
  'api_user' => '{api_user}',
  'api_secret' => '{api_secret}',
);

// this example uses cURL
$ch = curl_init('https://api.sightengine.com/1.0/check.json');
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, $params);
$response = curl_exec($ch);
curl_close($ch);

$output = json_decode($response, true);


// this example uses axios and form-data
const axios = require('axios');
const FormData = require('form-data');
const fs = require('fs');

data = new FormData();
data.append('media', fs.createReadStream('/path/to/image.jpg'));
data.append('models', 'recapture');
data.append('api_user', '{api_user}');
data.append('api_secret', '{api_secret}');

axios({
  method: 'post',
  url:'https://api.sightengine.com/1.0/check.json',
  data: data,
  headers: data.getHeaders()
})
.then(function (response) {
  // on success: handle response
  console.log(response.data);
})
.catch(function (error) {
  // handle error
  if (error.response) console.log(error.response.data);
  else console.log(error.message);
});

Required: media, models, api_user, api_secret. See full parameter reference →
ParameterTypeDescription
mediafileimage to analyze
modelsstringcomma-separated list of models to apply
api_userstringyour API user id
api_secretstringyour API secret

API response

The API returns a JSON response with the following structure:

        
        
{
  "status": "success",
  "request": {
    "id": "req_1SJJxJjUHnSVWreApx9fF",
    "timestamp": 1693574119.571633,
    "operations": 3
  },
  "recapture": {
    "score": 0.99
  },
  "media": {
    "id": "med_1SJJEFuLqeSedThQjhNoS",
    "uri": "https://sightengine.com/assets/img/examples/example-fac-1000.jpg"
  }
}


      

See response description

Successful Response
Status code: 200, Content-Type: application/json
FieldTypeDescription
statusstringstatus of the request, either "success" or "failure"
requestobjectinformation about the processed request
request.idstringunique identifier of the request
request.timestampfloattimestamp of the request in Unix time
request.operationsintegernumber of operations consumed by the request
recaptureobjectresults for the model
mediaobjectinformation about the media analyzed
media.idstringunique identifier of the media
media.uristringURI of the media analyzed: either the URL or the filename
Error
Status codes: 4xx and 5xx. See how error responses are structured.

The model returns a recapture object containing a score (recapture.score). This score is a float ranging from 0 to 1; the closer to 1, the more certain the model is of a recaptured image. Scores above 0.5 indicate a likely recapture; tune the threshold to your precision/recall preference.

Frequently asked questions

Does the model detect screenshots as recaptures?

No. A screenshot is captured digitally, without the visual artifacts introduced by re-photographing a physical or displayed image, so it is classified as original. If you also want to filter screenshots, combine this model with Image Type Detection.

Does it work if the screen or paper edges are cropped out?

Yes. The model relies primarily on frequency-domain and texture cues that persist even when the obvious framing signals (bezels, paper edges) are removed from the shot.

Will AI-generated or heavily edited images be flagged?

Not by this model. AI-generated images, filtered photos, collages and overlays are treated as original. If you need to detect AI-generated content, add AI-generated Image Detection to the same API call.

Will the model detect a recaptured image if the recaptured portion only occupies a small part of the image?

No. The model is designed to detect a recapture only when it occupies most or all of the image. If a screen or printout appears in just a small portion of the image, it will not be flagged.

Can I call this model together with other Sightengine models?

Yes. Pass a comma-separated list in the models parameter: models=recapture,genai,nudity-2.1 and the API will return all results in a single response. This is the recommended pattern for production pipelines.

Next steps