Thorn's API returns matches for images and videos against their CSAM database.

Note: you can demarcate whether there were ANY matches if there exists a matched keyword under file -> reasons. For non-match, reasons won't exist.

The matched items from the database will be under the hashes field.

Note: startTimestamp and endTimestamp are null in this case since its an image. In the context of a video, the startTimestamp and endTimestamp demarcate when in the sent example the matched hash was found.

"output": [
    {
        "file": {
            "fileType": "image",
            "reasons": [
                "matched"
            ],
            "classifierPrediction": null
        },
        "hashes": [
            {
                "hashType": "saferhashv0",
              	"hashString": null,
                "matchTypes": [
                    "CSAM"
                ],
                "reasons": [
                    "matched"
                ],
                "sources": [
                    {
                        "hashSet": "test",
                        "matches": [
                            {
                                "sourceId": "5da081a7a0fc9970df3593841346e388",
                                "matchDistance": 43,
                                "matchMetadata": null,
                                "matchTransformations": []
                            }
                        ]
                    }
                ],
                "classifierPrediction": null,
                "isLetterboxed": false,
                "startTimestamp": null,
                "endTimestamp": null,
                "frameIndex": null
            }
        ]
    }
]

Here is a video that matched with a single scene. Note: the video matched for two different sets in MD5, and matched for a single scene using videoSaferhashv0. You can tell where the scene is in the video using, startTimestamp and endTimestamp The frameindex will tell you which frame the scene started.


"output": [
  {
    "file": {
      "fileType": "video",
      "reasons": [
        "matched"
      ],
      "classifierPrediction": null
    },
    "hashes": [
      {
        "hashType": "md5",
        "hashString": null,
        "matchTypes": [
          "CSAM",
          "SE"
        ],
        "reasons": [
          "matched"
        ],
        "sources": [
          {
            "hashSet": "test",
            "matches": [
              {
                "sourceId": "video",
                "matchDistance": 0,
                "matchMetadata": null,
                "matchTransformations": []
              },
              {
                "sourceId": "b6f493d9-2cf6-4c89-ae24-c824ad47c4ab",
                "matchDistance": 0,
                "matchMetadata": null,
                "matchTransformations": []
              }
            ]
          },
          {
            "hashSet": "test-se",
            "matches": [
              {
                "sourceId": "video",
                "matchDistance": 0,
                "matchMetadata": null,
                "matchTransformations": []
              }
            ]
          }
        ],
        "classifierPrediction": null,
        "isLetterboxed": false,
        "startTimestamp": null,
        "endTimestamp": null,
        "frameIndex": null
      },
      {
        "hashType": "videoSaferhashv0",
        "hashString": null,
        "matchTypes": [
          "CSAM",
          "SE"
        ],
        "reasons": [
          "matched"
        ],
        "sources": [
          {
            "hashSet": "test",
            "matches": [
              {
                "sourceId": "test video",
                "matchDistance": 308,
                "matchMetadata": null,
                "matchTransformations": []
              }
            ]
          }
        ],
        "classifierPrediction": null,
        "isLetterboxed": false,
        "startTimestamp": 3.9999999999999987,
        "endTimestamp": 4.599999999999999,
        "frameIndex": 120
      }
    ]
  }
]

This is a response for an image that did not match anything. Note: hashes is empty.

"output": [
    {
      "file": {
        "classifierPrediction": null,
        "fileType": "image",
        "reasons": []
       },
      "hashes": []
    }
]

Nearly identical for a non-matching video:

"output": [
    {
      "file": {
        "classifierPrediction": null,
        "fileType": "video",
        "reasons": []
       },
      "hashes": []
    }
]

Other Fields:

  • classifierPrediction : returns the score from the Thorn classifier on the
  • isLetterBoxed: returns whether an image is letterboxed.
  • matchDistance: returns the Euclidean distance and is only valid for the Safer hash.
  • matchTransformations: returns whether transformations were applied to match the hashes.
  • matchMetadata: returns additional information on the matches that are in the source database.