Skip to main content

Live Stream Moderation

SDK

Below is a PHP SDK containing an example integration to make it easier and faster to get ready to moderate your content:

VerifyMyContent Content Moderation PHP SDK

Postman Workspace

We've created a Postman workspace specifically for our API, which contains example API calls that you can use to test and familiarise yourself with our API.

The workspace includes example API calls for each of our API endpoints, along with detailed descriptions of the request parameters and headers being used.

You can generate most of the client code to call our APIs using the Postman client code generator. With this feature, developers can select a range of programming languages, and generate the corresponding code with a few clicks.

Please note that while both the example API calls and the generated code can be a helpful starting point, it's important to thoroughly test your own API calls before deploying them in production. If you encounter any issues while using the example API calls, or if you have any questions about our API, please don't hesitate to reach out to our support team.

API Domain

Our API is designed to be used in two environments: a sandbox environment and a production environment.

The sandbox environment is intended for testing and development purposes, while the production environment is used for live data and real-world use cases.

To ensure the security and integrity of our API, we use separate API keys for each environment. This means that you will need to obtain different API keys for the sandbox and production environments, and should not use the same key for both.

DomainEnvironment
https://moderation.verifymycontent.comproduction
https://moderation.sandbox.verifymycontent.comsandbox

Generating the HMAC header

To improve the security of the communication between your implementation and the VerifyMyContent API, we require you to generate a unique hexadecimal encoded SHA256 HMAC hash for each request, based on the input parameters.

The process of generating it depends on the language of your implementation.

If you use our SDK, the HMAC step will be abstracted,
and you don't need to do anything related to it.
Copy

Copied!

<?php

hash_hmac('sha256', $input, 'API_SECRET');
Copy

Copied!

import { HmacSHA256 } from 'crypto-js';

HmacSHA256(JSON.stringify(input), 'API_SECRET').toString()
Copy

Copied!

Integration Steps

Our content moderation system is fully automated and requires no manual intervention or input from the user. The moderation process is performed entirely in the backend using browser automation technology allowing us to analyse and filter content at scale. When content is submitted for moderation, our system ingests it automatically and analyses it using a combination of machine learning algorithms and human-defined rules. The system then applies a series of filters to identify any content that violates our guidelines.

VerifyMyContent live stream moderation consists of 4 basic steps:

1st

Verifying the participants in the broadcast.

2nd

Account ownership confirmation.

3rd

Starting the broadcast.

4th

Moderating the broadcast itself.

1. Verifying the Participants

This comes before calling the live stream API where the participants of the broadcast must complete an Identity Verification or log in to their VerifyMyContent account.

The identity verification process is done only once, so you can add it to your sign-up process, for example. A simple sign-in is then used to start future broadcasts.

You will need to send the customer who started the live stream in the field “customer”, this customer is required.

This unique identifier will then be used in subsequent steps.

New: More participants can be added to a live stream.

2. Account Ownership Confirmation

Every time your users start a live stream, they will need to log in to VerifyMyContent to confirm ownership of their account through a face match.

On this endpoint, you will need to send the same customer.id that was sent in the previous step, for the customer.id field.

Authorization Header

Generate HMAC with: Request Body
Authorization: hmac YOUR-API-KEY:GENERATED-HMAC

Request parameters

external_id required

The unique identifier you send to correlate with the moderation.

embed_url optional

The URL where VerifyMyContent can watch the stream without an account on your site.

Important: Make sure this URL doesn't have any popups and/or ads that will overlap the video that will be watched by our moderation team.

title optional

The title of the content being moderated.

description optional

The text written by your customer to describe the content.

webhook required

The URL where we will post status updates on the moderation.

stream optional

The technology used by the Livestream.

protocol optional

One of rtmps, hls or webrtc.

url optional

We must always have access to the stream url.

Therefore, if your stream is private and depends on login using a username and password we must have access via a secret or signed url. Important: If you're struggling with this step, you can head to the troubleshooting section for more guidance.

The URL pointing to your stream has different validation rules based on the protocol you are using:

RTMPS Example: rmtps://example.com:5443

HLS It must point to an m3u8 file where we'll be able to retrieve the stream. Example: https://example.com/file.m3u8

WebRTC It must point to an embedded version of the stream. Example: https://example.com/embed-url

rule optional

It can be one of the values:

RuleDescription
defaultIt will look for content that is not allowed in the context of adult websites. This is also the default option when you don't send any value.
no-nudityIt will look for both content not allowed in the context of adult websites, but will also look for nudity.

customer required

Customer information

id required

Customer's unique ID

email required

Customer's email address

phone optional

Customer's phone number

participants optional

Information about other participants of the livestream.

Type: Array of customers

id required

Customer's unique ID

email required

Customer's email address

phone optional

Customer's phone number

type optional

It can be one of these values. It defaults to moderation.

TypeDescription
moderationWe will look for any illegal harmful content. This is also the default option when you don’t send any value.
face-matchWe will look to see if the expected people are present in the content.
combinedWe will look for any illegal harmful content and to see if the expected people are present in the content via face-match.

Response parameters

id

The unique identifier generated by the VerifyMyContent API.

login_url

The URL you’ll need to redirect the user to confirm ownership.

external_id

The unique identifier you send to correlate with the moderation.

status

The current status of the moderation flow. It will change depending on the step of the live stream moderation.

Account Ownership Confirmation

StatusDescription
WaitingWaiting for the model/s to prove their identity
AuthorisedThe model/s could prove their identity. You can start the stream
DeniedThe model/s could not prove their identity, so you cannot start the stream

Moderating the content

StatusDescription
StartedThe moderation process has started to detect any illegal or non-consensual content
FinishedThe live stream has ended and no issues were found
Stop RequestedIllegal content found, you need to stop the live stream
HaltedThe livestream has ended due to illegal content being found
FailedAn error occurred during the processing of the live stream

Pause live stream

StatusDescription
Pause RequestedThe live stream was requested to be paused
PausedThe moderation process has paused
Resume RequestedThe live stream was requested to be resumed
ResumedThe moderation process has been resumed
Finished due to InactivityThe moderation was stopped after being paused for too long (10+ hours)

notes

Any notes associated with the moderation when the moderation status is Failed or Stop Requested.

tags

Any tags associated with the moderation when the moderation status is Stop Requested.

created_at

The date and time in the UTC timezone when the livestream was created

updated_at

The date and time in the UTC timezone when the livestream was updated

Error responses

CodeDescription
400
{"message": "the request could not be understood by the server due to malformed syntax", "status_code": 400}
Copy

Copied!

401
{"message": "invalid authentication", "status_code": 401}
Copy

Copied!

422
{"message": "invalid parameters", "status_code": 422}
Copy

Copied!

500
{"message": "Internal Server Error","status_code": 500}
Copy

Copied!

API Call
POST /api/v1/livestream HTTP/1.1
Content-Type: application/json
Authorization: hmac YOUR-API-KEY:GENERATE-HMAC-WITH-REQUEST-BODY

{
    "external_id": "YOUR-LIVESTREAM-ID",
    "embed_url": "https://example.com/live-stream-embed",
    "title": "Your title",
    "description": "Your description",
    "stream": {
        "protocol": "rtmps",
        "url": "rtmps://your-server:443/your-video-stream"
    },
    "rule": "default",
    "customer": {
        "id": "YOUR-USER-ID",
        "email": "person@example.com",
        "phone": "+4412345678"
    },
    "participants": [
        {
            "id": "YOUR-PARTICIPANT-ID",
            "email": "person2@example.com",
            "phone": "+4412345678"
        }
    ],
    "webhook": "https://example.com/webhook"
}
Copy

Copied!

curl -d '{"external_id": "YOUR-LIVESTREAM-ID", "rule": "default", "embed_url": "https://example.com/live-stream-embed", "title": "Your title", "description": "Your description", "stream": {"protocol": "rtmps", "url": "rtmps://your-server:443/your-video-stream"}, "webhook": "https://example.com/webhook",  "face_ids": ["a54de98d-c139-45b7-97bf-7b525f19c794"], "collection_id": "0910abd9-0507-4f7c-9ddf-e3b52b042472", "type": "moderation", "rule": "default",  "customer": {"id": "YOUR-USER-ID", "email": "person@example.com", "phone": "+4412345678"} "participants": [{"id": "YOUR-PARTICIPANT-ID","email": "person2@example.com","phone": "+4412345678"}]}' \
-H "Content-Type: application/json" \
-H "Authorization: hmac YOUR-API-KEY:GENERATE-HMAC-WITH-REQUEST-BODY" \
-X POST https://moderation.sandbox.verifymycontent.com/api/v1/livestream
Copy

Copied!

<?php
require(__DIR__ . "/vendor/autoload.php");

use \VerifyMyContent\VideoModeration\Moderation;
use \VerifyMyContent\SDK\ContentModeration\Entity\Requests\CreateLiveContentModerationRequest;

$moderation = new Moderation(getenv('VMC_API_KEY'), getenv('VMC_API_SECRET'));
//$moderation->useSandbox();

$response = $moderation->createLivestream(new CreateLiveContentModerationRequest([
  "external_id" => "YOUR-LIVESTREAM-ID",
  "embed_url" => "https://example.com/live/",
  "title" => "Live stream title",
  "description" => "Live stream description",
  "webhook" => "https://example.com/webhook",
  "stream" => [
      "protocol" => "webrtc",
      "url" => "https://example.com/live/",
  ],
  "rule" => "default",
  "customer" => [
    "id" => "YOUR-CUSTOMER-UNIQUE-ID",
    "email" => "person@example.com",
    "phone" => "+4412345678"
  ],
  "participants" => [
    {
        "id" => "YOUR-PARTICIPANT-ID",
        "email" => "person2@example.com",
        "phone" => "+4412345678"
    }
  ],
  "collection_id" => "0910abd9-0507-4f7c-9ddf-e3b52b042472",
  "face_ids" => ["a54de98d-c139-45b7-97bf-7b525f19c794"],
  "type" => "moderation"
]));
Copy

Copied!

Response 201: (application/json)
{
  "id": "ABC-123-5678-ABC",
  "login_url": "https://app.verifymycontent.com/v/ABC-123-5678-ABC",
  "external_id": "YOUR-CORRELATION-ID",
  "status": "Started",
  "notes": "Harmful content found.",
  "rule": "default",
  "tags": [
    "UNDERAGE"
  ],
  "created_at": "2020-11-12 19:06:00",
  "updated_at": "2020-11-12 19:06:00"
}
Copy

Copied!

3. Starting the Broadcast

When the broadcast starts on your side, you'll need to notify us, so we can start moderating the content. To do so you'll have to use the live stream ID returned on the previous API call and send a PATCH request to us.

Note: you'll need to send this request within 5 minutes from the point you receive the webhook notifying you the user was authorised to start the broadcast.

Important: request parameters will only be optional if you have already provided them on the Account Ownership Confirmation step. If not, request parameters will be required.

Authorization Header

Generate HMAC with: Request URI
Authorization: hmac YOUR-API-KEY:GENERATED-HMAC

Request parameters

embed_url optional

The URL where VerifyMyContent can watch the stream without an account on your site.

Important: Make sure this URL doesn't have any popups and/or ads that will overlap the video that will be watched by our moderation team.

stream optional

The technology used by the Livestream.

protocol optional

One of rtmps, hls or webrtc.

url optional

We must always have access to the stream url.

Therefore, if your stream is private and depends on login using a username and password we must have access via a secret or signed url. Important: If you're struggling with this step, you can head to the troubleshooting section for more guidance.

The URL pointing to your stream has different validation rules based on the protocol you are using:

RTMPS Example: rmtps://example.com:5443

HLS It must point to an m3u8 file where we'll be able to retrieve the stream. Example: https://example.com/file.m3u8

WebRTC It must point to an embedded version of the stream. Example: https://example.com/embed-url

Error responses

CodeDescription
401
{"message": "invalid authentication", "status_code": 401}
Copy

Copied!

404
{"message": "no results found", "status_code": 404}
Copy

Copied!

500
{"message": "Internal Server Error","status_code": 500}
Copy

Copied!

API Call
PATCH /api/v1/livestream/{ID}/start HTTP/1.1
Content-Type: application/json
Authorization: hmac YOUR-API-KEY:GENERATE-HMAC-WITH-REQUEST-URI

{
    "embed_url": "https://example.com/live-stream-embed",
    "stream": {
        "protocol": "rtmps",
        "url": "rtmps://your-server:443/your-video-stream"
    }
}
Copy

Copied!

curl -d '{"embed_url": "https://example.com/live-stream-embed", "stream": {"protocol": "rtmps", "url": "rtmps://your-server:443/your-video-stream"}}' \
-H "Content-Type: application/json" \
-H "Authorization: hmac YOUR-API-KEY:GENERATE-HMAC-WITH-REQUEST-BODY" \
-X PATCH https://moderation.sandbox.verifymycontent.com/api/v1/livestream/{ID}/start
Copy

Copied!

<?php
require(__DIR__ . "/vendor/autoload.php");

use \VerifyMyContent\VideoModeration\Moderation;
use \VerifyMyContent\SDK\ContentModeration\Entity\Requests\StartLiveContentModerationRequest;

$moderation = new Moderation(getenv('VMC_API_KEY'), getenv('VMC_API_SECRET'));
//$moderation->useSandbox();

$success = $moderation->startLivestream('ID', new StartLiveContentModerationRequest([
    "embed_url" => "https://example.com/live/",
    "stream" => [
        "protocol" => "webrtc",
        "url" => "https://example.com/live/",
    ]
  ])););
var_dump($success === true);
Copy

Copied!

Response 204

4. Moderating the Content

During the broadcast, our AI and moderation team will be monitoring the video looking for content that cannot be streamed. In this case, you’ll receive a webhook in one of 3 situations:

  1. When the user finishes the login step:

    a. We’ll notify you with the Authorised status if all the users (customer + participants) can prove account ownership, only after all users complete a successful validation, you can start broadcasting the live stream at this moment.

    b. Otherwise, we’ll notify you of the Denied status and the broadcast cannot start.

After login

  1. When there is non-permissible content, we’ll notify you with a Stop Requested status so you can take action.

Invalid content

  1. When the live stream ends with an Finished status.

End of broadcast

We’ll send the same JSON as the Request body of the webhook that we return as the Response Body when you start a live stream.

In the same way that you send an HMAC header during the requests, we’ll be sending it to your webhook so you can confirm that we have sent the request.

Response

You’ll need to return any of the 200, 201, or 204 status codes.

Any different status code will be interpreted as you couldn’t handle the webhook, and we’ll try 3 more times in the proceeding minutes.

Authorization Header

Generate HMAC with: Request Body
Authorization: hmac YOUR-API-KEY:GENERATED-HMAC

Request parameters

id

The unique identifier generated by the VerifyMyContent API.

login_url

The URL you’ll need to redirect the user to confirm ownership.

external_id

The unique identifier you send to correlate with the moderation.

status

The current status of the moderation flow. It will change depending on the step of the live stream moderation.

Account Ownership Confirmation

StatusDescription
WaitingWaiting for the model/s to prove their identity
AuthorisedThe model/s could prove their identity. You can start the stream
DeniedThe model/s could not prove their identity, so you cannot start the stream

Moderating the content

StatusDescription
StartedThe moderation process has started to detect any illegal or non-consensual content
FinishedThe live stream has ended and no issues were found
Stop RequestedIllegal content found, you need to stop the live stream
HaltedThe livestream has ended due to illegal content being found
FailedAn error occurred during the processing of the live stream

Pause live stream

StatusDescription
Pause RequestedThe live stream was requested to be paused
PausedThe moderation process has paused
Resume RequestedThe live stream was requested to be resumed
ResumedThe moderation process has been resumed
Finished due to InactivityThe moderation was stopped after being paused for too long (10+ hours)

notes

Any notes associated with the moderation when the moderation status is Failed or Stop Requested.

tags

Any tags associated with the moderation when the moderation status is Stop Requested.

created_at

The date and time in the UTC timezone when the livestream was created

updated_at

The date and time in the UTC timezone when the livestream was updated

Webhook Call
POST /your-path HTTP/1.1
Host: https://your-domain.com
Content-Type: application/json
Authorization: hmac YOUR-API-KEY:GENERATE-HMAC-WITH-REQUEST-BODY

{
    "id": "ABC-123-5678-ABC",
    "login_url": "https://app.verifymycontent.com/v/ABC-123-5678-ABC",
    "external_id": "YOUR-CORRELATION-ID",
    "status": "Started",
    "notes": "Harmful content found.",
    "tags": [
        "UNDERAGE"
    ],
    "created_at": "2020-11-12 19:06:00",
    "updated_at": "2020-11-12 19:06:00"
}
Copy

Copied!

curl -d '{"id": "ABC-123-5678-ABC", "login_url": "https://app.verifymycontent.com/v/ABC-123-5678-ABC", "external_id": "YOUR-CORRELATION-ID", "status": "Started", "notes": "Harmful content found.", "tags": ["UNDERAGE"], "created_at": "2020-11-12 19:06:00", "updated_at": "2020-11-12 19:06:00"}' \
-H "Content-Type: application/json" \
-H "Authorization: hmac YOUR-API-KEY:GENERATE-HMAC-WITH-REQUEST-BODY" \
-X POST https://your-domain.com/your-path
Copy

Copied!

Response 200, 201 or 204

Updating Live Stream moderation rules

This endpoint allows you to update the moderation rules for a specific live stream. By default, all live streams are moderated using a set of predefined rules that are designed to minimize the risk of harmful or offensive content being broadcast to viewers. However, there may be cases where you need to include aditional rules to suit your business requirements.

Example: You can create a livestream with the 'no-nudity' rule, but after a couple of minutes, send a PATCH request to change it to the 'default' rules depending on the privacy level of this broacast.

Authorization Header

Generate HMAC with: Request Body
Authorization: hmac YOUR-API-KEY:GENERATED-HMAC

Request parameters

rule required

It can be one of the values:

RuleDescription
defaultIt will look for content that is not allowed in the context of adult websites. This is also the default option when you don't send any value.
no-nudityIt will look for both content not allowed in the context of adult websites, but will also look for nudity.

Error responses

CodeDescription
400
{"message": "Invalid rule", "status_code": 400}
Copy

Copied!

401
{"message": "invalid authentication", "status_code": 401}
Copy

Copied!

404
{"message": "no results found", "status_code": 404}
Copy

Copied!

500
{"message": "Internal Server Error","status_code": 500}
Copy

Copied!

API Call
PATCH /api/v1/livestream/{ID}/rule HTTP/1.1
Content-Type: application/json
Authorization: hmac YOUR-API-KEY:GENERATE-HMAC-WITH-REQUEST-BODY

{
    "rule": "default"
}
Copy

Copied!

curl -d '{"rule": "default"}' \
-H "Content-Type: application/json" \
-H "Authorization: hmac YOUR-API-KEY:GENERATE-HMAC-WITH-REQUEST-BODY" \
-X PATCH https://moderation.sandbox.verifymycontent.com/api/v1/livestream/{ID}/rule
Copy

Copied!

Response 204

Pausing Live Stream moderation

This endpoint allows you to pause the moderation for a specific live stream.

Note: the status has to be either started or resumed to pause a live stream.

Example: If your live stream has a pause feature, use this endpoint to pause the moderation until the live stream resumes.

Authorization Header

Generate HMAC with: Request Body
Authorization: hmac YOUR-API-KEY:GENERATED-HMAC

Request parameters

id required

The ID of the Live stream to be paused.

Error responses

CodeDescription
401
{"message": "invalid authentication", "status_code": 401}
Copy

Copied!

404
{"message": "no results found", "status_code": 404}
Copy

Copied!

500
{"message": "Internal Server Error","status_code": 500}
Copy

Copied!

API Call
PATCH /api/v1/livestream/{ID}/pause HTTP/1.1
Content-Type: application/json
Authorization: hmac YOUR-API-KEY:GENERATE-HMAC-WITH-REQUEST-URI
Copy

Copied!

curl -H "Content-Type: application/json" \
-H "Authorization: hmac YOUR-API-KEY:GENERATE-HMAC-WITH-REQUEST-URI" \
-X PATCH https://moderation.sandbox.verifymycontent.com/api/v1/livestream/{ID}/pause
Copy

Copied!

<?php
require(__DIR__ . "/vendor/autoload.php");

use \VerifyMyContent\VideoModeration\Moderation;

$moderation = new Moderation(getenv('VMC_API_KEY'), getenv('VMC_API_SECRET'));
//$moderation->useSandbox();

$moderation->pauseLivestream("YOUR-LIVESTREAM-ID");
Copy

Copied!

Response 204

Resuming Live Stream moderation

This endpoint allows you to resume the moderation for a specific live stream.

Note: the status has to be paused to resume a live stream

Authorization Header

Generate HMAC with: Request Body
Authorization: hmac YOUR-API-KEY:GENERATED-HMAC

Request parameters

id required

The ID of the live stream to be resumed.

Error responses

CodeDescription
401
{"message": "invalid authentication", "status_code": 401}
Copy

Copied!

404
{"message": "no results found", "status_code": 404}
Copy

Copied!

500
{"message": "Internal Server Error","status_code": 500}
Copy

Copied!

API Call
PATCH /api/v1/livestream/{ID}/resume HTTP/1.1
Content-Type: application/json
Authorization: hmac YOUR-API-KEY:GENERATE-HMAC-WITH-REQUEST-URL
Copy

Copied!

curl -X PATCH https://moderation.sandbox.verifymycontent.com/api/v1/livestream/{ID}/resume \
-H "Content-Type: application/json" \
-H "Authorization: hmac YOUR-API-KEY:GENERATE-HMAC-WITH-REQUEST-URL"
Copy

Copied!

Response 204

Troubleshooting

The video on my website can only be viewed by a logged-in user

For our AI and team of Moderators to be able to watch your videos, you'll need to provide us with a URL that can be accessed without a username and password.

To do this, you can use a signed URL that will skip your default authentication system whilst still restricting access and keeping the URL secure.

When you sign an URL, it adds new query parameters to the original URL. One of them will be a signature generated based on the URL and a secret only your website will have. This way, only your website could generate and validate it later.

Some frameworks like Laravel already provide helper functions for you to sign a url.

We've created an example of an express.js application that signs and validates a URL using the signed-url npm package in the following repository: https://github.com/verifymycontent/sign-url-example.

Signed URL

Restricted Access