Video Moderation Workflows make it easy to create your own custom rules and actions, directly from your online dashboard.
You decide how each video or stream is analyzed, and what rules should lead to a video being either accepted or rejected.
To create a new workflow, navigate to the Workflow page on your dashboard. You will be able to select the rules that should be applied, and what actions should be taken based on those rules: ACCEPT or REJECT.
For more information on the different detection models you can use, head to our Model reference.
You might want to create multiple workflows if you handle different types of videos with different rules. For instance, let's say you have a dating site and your users can upload a profile video, and can do video chats with other participants. You could create a workflow for Profile videos, where you reject videos containing children or celebrities, and another workflow for videochats with different rules.
Once your workflow has been created, you will get a workflow id that you can use to submit videos for moderation.
There are two ways to moderate a Stored Video. You can choose between synchronous moderation, where the moderation happens during your API request, or asynchronous moderation. While both yield the same results, they differ in their implementations. Synchronous Moderation is quicker to setup, but will only work for short videos (up to 60s).
Moderate short videos (up to 60s) with a simple mechanism. Everything happens within a single API request cycle.
Moderate stored videos of any length and any type. The moderation job happens outside of the API request cycle. Moderation results are sent back through callbacks.
The synchronous moderation API is quick and easy to use. Everything happens within a single API request cycle.
Since this has to fit within a single API request cycle, this approach will only work for videos that are less than 60 seconds long. To moderate longer videos, use the Asynchronous Video Moderation.
Once you have created and saved a workflow, you can retrieve the workflow id and use it to query the API. You can then submit a video either by sending the raw bytes or by sending a public URL pointing to the video.
curl -X POST 'https://api.sightengine.com/1.0/video/check-workflow-sync.json' \
-F 'media=@/path/to/video.mp4' \
-F 'workflow={workflow_id}' \
-F 'api_user={api_user}' \
-F 'api_secret={api_secret}'
# this example uses requests
import requests
import json
params = {
'workflow': '{workflow_id}',
'api_user': '{api_user}',
'api_secret': '{api_secret}'
}
files = {'media': open('/path/to/video.mp4', 'rb')}
r = requests.post('https://api.sightengine.com/1.0/video/check-workflow-sync.json', files=files, data=params)
output = json.loads(r.text)
$params = array(
'media' => new CurlFile('/path/to/video.mp4'),
'workflow' => '{workflow_id}',
'api_user' => '{api_user}',
'api_secret' => '{api_secret}',
);
// this example uses cURL
$ch = curl_init('https://api.sightengine.com/1.0/video/check-workflow-sync.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/video.mp4'));
data.append('workflow', '{workflow_id}');
data.append('api_user', '{api_user}');
data.append('api_secret', '{api_secret}');
axios({
method: 'post',
url:'https://api.sightengine.com/1.0/video/check-workflow-sync.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);
});
curl -X GET -G 'https://api.sightengine.com/1.0/video/check-workflow-sync.json' \
--data-urlencode 'stream_url=https://domain/path/video' \
-d 'workflow={workflow_id}' \
-d 'api_user={api_user}' \
-d 'api_secret={api_secret}'
# this example uses requests
import requests
import json
params = {
'stream_url': 'https://domain/path/video',
'workflow': '{workflow_id}',
'api_user': '{api_user}',
'api_secret': '{api_secret}'
}
r = requests.get('https://api.sightengine.com/1.0/video/check-workflow-sync.json', params=params)
output = json.loads(r.text)
if output['status'] == 'failure':
# handle failure
print(output['error'])
if output['summary']['action'] == 'reject':
# handle video rejection
# the rejection probability is provided in output['summary']['reject_prob']
# and user readable reasons for the rejection are in the array output['summary']['reject_reason']
pass
$params = array(
'stream_url' => 'https://domain/path/video',
'workflow' => '{workflow_id}',
'api_user' => '{api_user}',
'api_secret' => '{api_secret}',
);
// this example uses cURL
$ch = curl_init('https://api.sightengine.com/1.0/video/check-workflow-sync.json?'.http_build_query($params));
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$response = curl_exec($ch);
curl_close($ch);
$output = json_decode($response, true);
if($output['summary']['action']=='reject') {
// handle video rejection
// the rejection probability is provided in $output['summary']['reject_prob']
// and user readable reasons for the rejection are in the array $output['summary']['reject_reason']
}
// this example uses axios
const axios = require('axios');
axios.get('https://api.sightengine.com/1.0/video/check-workflow-sync.json', {
params: {
'stream_url': 'https://domain/path/video',
'workflow': '{workflow_id}',
'api_user': '{api_user}',
'api_secret': '{api_secret}',
}
})
.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);
});
The body of the response will be JSON-formatted. This response will contain a summary object with the moderation decision taken, along with reasons for rejection if the video has to be rejected
{
"status": "success",
"request": {
"id": "req_81pP7cRqEvbdZ457WNQ2O",
"timestamp": 1597952947.216626,
"operations": 10
},
"summary": {
"action": "reject",
"reject_prob": 0.82,
"reject_reason": [
{
"text": "Alcohol"
}
]
},
"data": {
"frames": [
...
]
}
"workflow": {
"id": "wfl_81jOFDxdI8un4sm38y4Kw"
}
}
Once you have created and saved a workflow, you can retrieve the workflow id and use it to query the API.
You can submit a video either by sending the raw bytes or by sending a public URL pointing to the video.
curl -X POST 'https://api.sightengine.com/1.0/video/check-workflow.json' \
-F 'media=@/path/to/video.mp4' \
-F 'workflow={workflow_id}' \
-F 'callback_url=https://your.callback/path' \
-F 'api_user={api_user}' \
-F 'api_secret={api_secret}'
# this example uses requests
import requests
import json
params = {
'workflow': '{workflow_id}',
# specify where you want to receive result callbacks (optional)
'callback_url': 'https://your.callback/path',
'api_user': '{api_user}',
'api_secret': '{api_secret}'
}
files = {'media': open('/path/to/video.mp4', 'rb')}
r = requests.post('https://api.sightengine.com/1.0/video/check-workflow.json', files=files, data=params)
output = json.loads(r.text)
$params = array(
'media' => new CurlFile('/path/to/video.mp4'),
'workflow' => '{workflow_id}',
// specify where you want to receive result callbacks (optional)
'callback_url' => 'https://your.callback/path',
'api_user' => '{api_user}',
'api_secret' => '{api_secret}',
);
// this example uses cURL
$ch = curl_init('https://api.sightengine.com/1.0/video/check-workflow.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/video.mp4'));
data.append('workflow', '{workflow_id}');
// specify where you want to receive result callbacks (optional)
data.append('callback_url', 'https://your.callback/path');
data.append('api_user', '{api_user}');
data.append('api_secret', '{api_secret}');
axios({
method: 'post',
url:'https://api.sightengine.com/1.0/video/check-workflow.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);
});
curl -X GET -G 'https://api.sightengine.com/1.0/video/check-workflow.json' \
--data-urlencode 'stream_url=https://domain/path/video' \
-d 'workflow={workflow_id}' \
-d 'callback_url=https://your.callback.url/path' \
-d 'api_user={api_user}' \
-d 'api_secret={api_secret}'
# this example uses requests
import requests
import json
params = {
'stream_url': 'https://domain/path/video',
'workflow': '{workflow_id}',
# specify where you want to receive result callbacks
'callback_url': 'https://your.callback.url/path',
'api_user': '{api_user}',
'api_secret': '{api_secret}'
}
r = requests.get('https://api.sightengine.com/1.0/video/check-workflow.json', params=params)
output = json.loads(r.text)
if output['status'] == 'failure':
# handle failure
print(output['error'])
$params = array(
'stream_url' => 'https://domain/path/video',
'workflow' => '{workflow_id}',
// specify where you want to receive callbacks
'callback_url' => 'https://your.callback.url/path',
'api_user' => '{api_user}',
'api_secret' => '{api_secret}',
);
// this example uses cURL
$ch = curl_init('https://api.sightengine.com/1.0/video/check-workflow.json?'.http_build_query($params));
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$response = curl_exec($ch);
curl_close($ch);
$output = json_decode($response, true);
// this example uses axios
const axios = require('axios');
axios.get('https://api.sightengine.com/1.0/video/check-workflow.json', {
params: {
'stream_url': 'https://domain/path/video',
// specify where you want to receive result callbacks
'callback_url': 'https://your.callback.url/path',
'workflow': '{workflow_id}',
'api_user': '{api_user}',
'api_secret': '{api_secret}',
}
})
.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);
});
If the request is successful, the response JSON will contain the media id that you can then use to listen for events through your callback URL or poll the API for updates.
{
"status": "success",
"request": {
"id": "req_81pP7cRqEvbdZ457WNQ2O",
"timestamp": 1597952947.216626,
"operations": 10
},
"media": {
"id": "med_81pP7cDAfjdALi73ff",
"uri": "...",
},
"callback": "https://your.callback/path"
}
Once Sightengine starts analyzing your video, you can retrieve moderation results in realtime through two separate channels: either through callbacks (this is the recommended approach as it is more efficient and faster) or by polling the API.
Was this page helpful?