Skip to main content

Face Match Moderation

SDK

We provide a PHP SDK with an example of integration to make it easier and fast 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://faces.verifymyage.comfaces collection production
https://faces-sdx.verifymyage.comfaces collection sandbox
https://moderation.verifymycontent.commoderation production
https://moderation.sandbox.verifymycontent.commoderation sandbox

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!

Faces collection

Insert a new face to a collection. If the collection is not created this endpoint will create a new one.

Only one face at a time can be added to a collection.

Authorization Header

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

Request parameters

collection_id required

The collection identifier you send to correlate with the moderation.

face_id required

The face identifier you send to correlate with the moderation.

face_image required

Base 64 for the image that is being sent for each face_id.

Response parameters

total_faces

The number of faces present in the collection.

Error responses

CodeDescription
400
{"message": "field <field_name> not found", "status_code": 400}
Copy

Copied!

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

Copied!

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

Copied!

401
{"message": "Missing Api Key", "status_code": 401}
Copy

Copied!

409
{"message": "face id for this collection already exists", "status_code": 409}
Copy

Copied!

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

Copied!

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

{
    "collection_id": "a499a08c-b7ed-43ad-99c4-b9ce0f8b4a35",
    "face_id": "d1dc9be3-9a4b-4df2-a7fc-dec03d36ad94",
    "face_image": "ZDFkYzliZTMtOWE0Yi00ZGYyLWE3ZmMtZGVjMDNkMzZhZDk0"
}
Copy

Copied!

curl  \
    -H 'Content-Type: application/json' \
    -H "Authorization: hmac YOUR-API-KEY:GENERATE-HMAC-WITH-REQUEST-BODY" \
    -X 'https://faces-sdx.verifymyage.com/v1/collections'
    --data '{
        "collection_id": "a499a08c-b7ed-43ad-99c4-b9ce0f8b4a35",
        "face_id": "d1dc9be3-9a4b-4df2-a7fc-dec03d36ad94",
        "face_image": "ZDFkYzliZTMtOWE0Yi00ZGYyLWE3ZmMtZGVjMDNkMzZhZDk0"
    }'
Copy

Copied!

Response 201: (application/json)
{
  "total_faces": 0
}
Copy

Copied!

Get all faces from collection.

Returns the ids of all of the faces present in the collection.

Authorization Header

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

Response parameters

face_ids

An array of ids of all of the faces added to the collection.

Error responses

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

Copied!

403
{"message": "Permission denied", "status_code": 403}
Copy

Copied!

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

Copied!

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

Copied!

API Call
GET /v1/collections/{collection_id} HTTP/1.1
Content-Type: application/json
Authorization: hmac YOUR-API-KEY:GENERATE-HMAC-WITH-REQUEST-URI
Copy

Copied!

curl --location --globoff 'https://faces-sdx.verifymyage.com/v1/collections/{collection_id}'
Copy

Copied!

Response 200: (application/json)
{
  "face_ids": [
    "a54de98d-c139-45b7-97bf-7b525f19c794"
  ]
}
Copy

Copied!

Delete one face from collection.

Returns the number of faces left in the collection.

Authorization Header

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

Request parameters

collection_id

The collection identifier you send to correlate with the moderation.

face_id

Id of the face to be removed from the collection.

Response parameters

total_faces

The number of faces remaining in the collection.

Error responses

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

Copied!

403
{"message": "Permission denied", "status_code": 403}
Copy

Copied!

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

Copied!

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

Copied!

API Call
DELETE /v1/collections/{collection_id}/faces/{face_id} HTTP/1.1
Content-Type: application/json
Authorization: hmac YOUR-API-KEY:GENERATE-HMAC-WITH-REQUEST-BODY
Copy

Copied!

curl --location --globoff --request DELETE 'https://faces-sdx.verifymyage.com/v1/collections/{collection_id}/faces/{face_id}'
Copy

Copied!

Response 200: (application/json)
{
  "total_faces": 0
}
Copy

Copied!

Risky user faces collection

Insert new risky user faces to the collection (only one collection).

Only one face at a time can be added to a collection.

Authorization Header

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

Request parameters

face_id required

The face identifier you send to correlate with the moderation.

face_image required

Base 64 for the image that is being sent for each face_id.

Response parameters

total_faces

The number of faces present in the collection.

Error responses

CodeDescription
400
{"message": "field <field_name> not found", "status_code": 400}
Copy

Copied!

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

Copied!

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

Copied!

401
{"message": "Missing Api Key", "status_code": 401}
Copy

Copied!

409
{"message": "face id for this collection already exists", "status_code": 409}
Copy

Copied!

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

Copied!

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

{
    "face_id": "d1dc9be3-9a4b-4df2-a7fc-dec03d36ad94",
    "face_image": "ZDFkYzliZTMtOWE0Yi00ZGYyLWE3ZmMtZGVjMDNkMzZhZDk0"
}
Copy

Copied!

curl -X POST 'https://faces-sdx.verifymyage.com/v1/collections/risky'     -H 'Content-Type: application/json' \
    -H "Authorization: hmac YOUR-API-KEY:GENERATE-HMAC-WITH-REQUEST-BODY" \
    -d '{
        "face_id": "d1dc9be3-9a4b-4df2-a7fc-dec03d36ad94",
        "face_image": "ZDFkYzliZTMtOWE0Yi00ZGYyLWE3ZmMtZGVjMDNkMzZhZDk0"
    }'
Copy

Copied!

Response 201: (application/json)
{
  "total_faces": 0
}
Copy

Copied!

Get all risky user faces from the collection.

Returns the ids of all of the faces present in the collection.

Authorization Header

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

Response parameters

face_ids

An array of ids of all of the faces added to the collection.

Error responses

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

Copied!

403
{"message": "Permission denied", "status_code": 403}
Copy

Copied!

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

Copied!

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

Copied!

API Call
GET /v1/collections/risky/ HTTP/1.1
Content-Type: application/json
Authorization: hmac YOUR-API-KEY:GENERATE-HMAC-WITH-REQUEST-URI
Copy

Copied!

curl --location --globoff 'https://faces-sdx.verifymyage.com/v1/collections/risky'
Copy

Copied!

Response 200: (application/json)
{
  "face_ids": [
    "a54de98d-c139-45b7-97bf-7b525f19c794"
  ]
}
Copy

Copied!

Delete risky user faces from the collection.

Returns the number of faces left in the collection. Only one face at a time can be removed from a collection.

Authorization Header

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

Request parameters

face_id

Id of the face to be removed from the collection.

Response parameters

total_faces

The number of faces remaining in the collection.

Error responses

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

Copied!

403
{"message": "Permission denied", "status_code": 403}
Copy

Copied!

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

Copied!

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

Copied!

API Call
DELETE /v1/collections/risky/{face_id} HTTP/1.1
Content-Type: application/json
Authorization: hmac YOUR-API-KEY:GENERATE-HMAC-WITH-REQUEST-BODY
Copy

Copied!

curl --location --globoff --request DELETE 'https://faces-sdx.verifymyage.com/v1/collections/risky/{face_id}'
Copy

Copied!

Response 200: (application/json)
{
  "total_faces": 0
}
Copy

Copied!

Face match for Content Moderation

The VerifyMyContent face match moderation consists of 2 basic steps:

  1. Verifying the uploader

  2. Moderating the content itself

When you call the Start Moderation endpoint, it will take care of both steps, and you will receive the moderation status updates on the URL you've set as a webhook.

Alternatively, the Current status of the moderation endpoint is available for you to get the status, if you prefer not to use a webhook.

The meaning of each status

When you start the moderation, the content will have the status Awaiting People, which will trigger our AI to moderate the content and check that it does not contain any content that should not be published. If we cannot download the video or image you sent, the content will finish the process with the status Failed.

As soon as the uploader is verified and they confirm they have received the consent of any participants, the content status will change to Awaiting Face match, which will trigger our AI to moderate the content and check that it does not contain any content that should not be published. If we cannot download the video or image you sent, the content will finish the process with the status Failed.

After the AI, the status will change to Awaiting Moderation, and the human moderation is triggered.

Once the content has passed human moderation the status will change to either Approved if the content can be published, but check the warning section to see if all participants match or Rejected if one or more participants in the content were unable or unwilling to verify their identity or consent.

Content Moderation Flow

Start Moderation

To start the moderation, you'll need to send us the original video or image uploaded by your customer, some data from your customer so we can trigger reminders and notifications during the process, and a webhook to notify you when the moderation status changes.

Important: Please generate a universally unique identifier (UUID v4) for each customer on your site. You should then use this same customer ID every time you call one of our APIs on behalf of that customer. This UUID should never change. For example, if the customer's username on your site changes, their UUID shouldn't.

Authorization Header

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

Request parameters

content required

Information about the content being moderated.

type optional

It can be video or image. Defaults to video.

external_id required

A unique identifier on your side to correlate with this moderation.

url required

The URL where we can download the original video or image uploaded by your customer.

title optional

The title of the content being moderated.

description optional

The text written by your customer to describe the content.

redirect_url optional

The URL where we are going to redirect your customer after the moderation is done.

webhook required

This is the URL where we are going to post status updates of the moderation

customer required

Customer information

id required

Customer's unique ID

email required

Customer's email address

phone optional

Customer's phone number

collection_id optional

The collection identifier you send to correlate with the moderation.

face_ids optional

An array of ids of the faces appearing in the content.

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

Unique identifier generated by the VerifyMyContent API

redirect_url

URL you’ll need to redirect the user to start the moderation process

external_id

The unique identifier you have sent to correlate this moderation

status

It represents the current status of the moderation flow. It can be one of the following:

StatusDescription
Awaiting PeopleWaiting to verify the identity of the uploader.
Face AnalysisOur AI is about to process the content to detect any unknown person and request the uploader for participant information.
Awaiting ParticipantWaiting for the uploader to confirm the participants and provide the necessary information.
Awaiting ConsentWaiting to verify the identity of the participants and confirm they have given consent to the content being published.
Awaiting Face MatchOur AI is about to process the content to detect any person who should not be in the content.
Awaiting ModerationThe moderators are about to confirm the moderation decision.
ApprovedAll participants consented to the publishing of the content. Please check the warning section to see if any unexpected people were detected in the content.
FailedAn error occurred during the content processing.
RejectedThe content cannot be published as one or more of the participants in the content were unable or unwilling to verify their identity or consent.

notes

Any notes associated with the moderation.

tags

Any tags associated with the moderation when a face match warning is found.

created_at

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

updated_at

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

Error responses

CodeDescription
400
{"message": "field <field_name> not found", "status_code": 400}
Copy

Copied!

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

Copied!

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

Copied!

401
{"message": "Missing Api Key", "status_code": 401}
Copy

Copied!

409
{"message": "request to moderate content ID <content_id> with URL <url> for customer ID <customer_id> already made", "status_code": 409}
Copy

Copied!

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

Copied!

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

{
    "content": {
        "type": "video",
        "external_id": "YOUR-VIDEO-ID",
        "url": "https://example.com/video.mp4",
        "title": "Your title",
        "description": "Your description"
    },
    "webhook": "https://example.com/webhook",
    "redirect_url": "https://app.verifymycontent.com/v/ABC-123-5678-ABC",
    "customer": {
        "id": "YOUR-USER-ID",
        "email": "person@example.com",
        "phone": "+4412345678"
    },
    "collection_id": "a499a08c-b7ed-43ad-99c4-b9ce0f8b4a35",
    "face_ids": ["a54de98d-c139-45b7-97bf-7b525f19c794"],
    "type": "face-match"
}
Copy

Copied!

curl -d '{"content": {"type": "video", "external_id": "YOUR-VIDEO-ID", "url": "https://example.com/video.mp4", "title": "Your title", "description": "Your description"}, "webhook": "https://example.com/webhook", "redirect_url": "https://app.verifymycontent.com/v/ABC-123-5678-ABC", customer": {"id": "YOUR-USER-ID", "email": "person@example.com", "phone": "+4412345678"}, "collection_id": "a499a08c-b7ed-43ad-99c4-b9ce0f8b4a35", "type": "moderation", "face_ids": ["a54de98d-c139-45b7-97bf-7b525f19c794"]}' \
-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/moderation
Copy

Copied!

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

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

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

$response = $moderation->start(new CreateStaticContentModerationRequest([
    "content" => [
      "type" => "video",
      "external_id" => "YOUR-VIDEO-ID",
      "url" => "https://example.com/video.mp4",
      "title" => "Uploaded video title",
      "description" => "Uploaded video description",
    ],
    "request_url" => "https://app.verifymycontent.com/v/ABC-123-5678-ABC",
    "webhook" => "https://example.com/webhook",
    "customer" => [
      "id" => "YOUR-CUSTOMER-UNIQUE-ID",
      "email" => "person@example.com",
      "phone" => "+4412345678"
    ],
    "collection_id" => "a499a08c-b7ed-43ad-99c4-b9ce0f8b4a35",
    "face_ids" => ["a54de98d-c139-45b7-97bf-7b525f19c794"],
    "type" => "face-match"
]));
Copy

Copied!

Response 201: (application/json)
{
  "id": "ABC-123-5678-ABC",
  "redirect_url": "https://app.verifymycontent.com/v/ABC-123-5678-ABC",
  "external_id": "YOUR-CORRELATION-ID",
  "status": "Awaiting Face Match",
  "notes": "",
  "tags": null,
  "created_at": "2020-11-12 19:06:00",
  "updated_at": "2020-11-12 19:06:00",
  "consent_type": "participant"
}
Copy

Copied!

Get current status of the moderation

When you already have the id of a moderation you can see the current details of the moderation.

Authorization Header

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

Response parameters

id

Unique identifier generated by the VerifyMyContent API

redirect_url

URL you’ll need to redirect the user to start the moderation process

external_id

The unique identifier you have sent to correlate this moderation

status

It represents the current status of the moderation flow. It can be one of the following:

StatusDescription
Awaiting PeopleWaiting to verify the identity of the uploader.
Face AnalysisOur AI is about to process the content to detect any unknown person and request the uploader for participant information.
Awaiting ParticipantWaiting for the uploader to confirm the participants and provide the necessary information.
Awaiting ConsentWaiting to verify the identity of the participants and confirm they have given consent to the content being published.
Awaiting Face matchOur AI is about to process the content to detect any person who should not be in the content.
Awaiting ModerationThe moderators are about to confirm the moderation decision.
ApprovedAll participants consented to the publishing of the content. Please check the warning section to see if any unexpected people were detected in the content.
FailedAn error occurred during the content processing.
RejectedThe content cannot be published as one or more of the participants in the content were unable or unwilling to verify their identity or consent.

notes

Any notes associated with the moderation.

tags

Any tags associated with the moderation when a face match warning is found.

created_at

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

updated_at

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

Error responses

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

Copied!

403
{"message": "Permission denied", "status_code": 403}
Copy

Copied!

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

Copied!

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

Copied!

API Call
GET /api/v1/moderation/{ID} 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" \
https://moderation.sandbox.verifymycontent.com/api/v1/moderation/{ID}
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();

$response = $moderation->get('ID');
Copy

Copied!

Response 200: (application/json)
{
  "id": "ABC-123-5678-ABC",
  "redirect_url": "https://app.verifymycontent.com/v/ABC-123-5678-ABC",
  "external_id": "YOUR-CORRELATION-ID",
  "status": "Approved",
  "notes": "",
  "tags": null,
  "created_at": "2020-11-12 19:06:00",
  "updated_at": "2020-11-12 19:06:00",
  "consent_type": "participant"
}
Copy

Copied!

Receive the current status of the moderation

The same information that you can get on the moderation detail API can also be sent via webhook to your domain if you send it to us when you create a moderation.

Authorization Header

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

Request parameters

id

Unique identifier generated by the VerifyMyContent API

redirect_url

URL you’ll need to redirect the user to start the moderation process

external_id

The unique identifier you have sent to correlate this moderation

status

It represents the current status of the moderation flow. It can be one of the following:

StatusDescription
Awaiting PeopleWaiting to verify the identity of the uploader.
Face AnalysisOur AI is about to process the content to detect any unknown person and request the uploader for participant information.
Awaiting ParticipantWaiting for the uploader to confirm the participants and provide the necessary information.
Awaiting ConsentWaiting to verify the identity of the participants and confirm they have given consent to the content being published.
Awaiting Face matchOur AI is about to process the content to detect any person who should not be in the content.
Awaiting ModerationThe moderators are about to confirm the moderation decision.
ApprovedAll participants consented to the publishing of the content. Please check the warning section to see if any unexpected people were detected in the content.
FailedAn error occurred during the content processing.
RejectedThe content cannot be published as one or more of the participants in the content were unable or unwilling to verify their identity or consent.

notes

Any notes associated with the moderation.

facematch

It represents the results of the face match moderation. It can be the following:

StatusDescription
KnownAn array of face_ids that contain the expected faces seen in the content.
UnknownAn array of objects that contain the bounding box and the time when the unexpected face was seen in the content.
RiskyAn array of objects that contain the face_id, bounding box and the time when the risky user face was seen in the content.

tags

Any tags associated with the moderation when a face match warning is found.

created_at

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

updated_at

The date and time in the UTC timezone when the moderation 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",
    "redirect_url": "https://app.verifymycontent.com/v/ABC-123-5678-ABC",
    "external_id": "YOUR-CORRELATION-ID",
    "status": "Approved",
    "notes": "",
    "facematch": {
        "known": ["010203"],
        "unknown": [
            {
                "face_id": "",
                "time": 1,
                "bounding_box": {
                    "x": 2123,
                    "y": 1230,
                    "height" : 123,
                    "width": 123,
                }
            }
        ],
        "risky": [
            {
                "face_id": "John Doe",
                "time": 1,
                "bounding_box": {
                    "x": 2123,
                    "y": 1230,
                    "height" : 123,
                    "width": 123,
                }
            }
        ],
    },
    "tags": [
      "UNKNOWN_PERSON",
      "RISKY_USER"
    ],
    "created_at": "2020-11-12 19:06:00",
    "updated_at": "2020-11-12 19:06:00",
    "consent_type": "participant"  
}
Copy

Copied!

curl -d '{"id": "ABC-123-5678-ABC", "redirect_url": "https://app.verifymycontent.com/v/ABC-123-5678-ABC", "external_id": "YOUR-CORRELATION-ID", "status": "Rejected", "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 2xx

Face match for Live Stream Moderation

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.

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

webhook required

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

face_ids optional

An array of ids of the faces appearing in the content.

collection_id optional

The collection identifier you send to correlate with the moderation.

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.

notes

Any notes associated with the moderation.

tags

Any tags associated with the moderation when a face match warning is found.

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

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
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)

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",
    "face_ids": ["a54de98d-c139-45b7-97bf-7b525f19c794"],
    "collection_id": "0910abd9-0507-4f7c-9ddf-e3b52b042472",
    "type": "face-match"
}
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": "face-match", "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",
  "collection_id" => "0910abd9-0507-4f7c-9ddf-e3b52b042472",
  "face_ids" => ["a54de98d-c139-45b7-97bf-7b525f19c794"],
  "type" => "moderation",
  "customer" => [
      "id" => "YOUR-CUSTOMER-UNIQUE-ID",
      "email" => "person@example.com",
      "phone" => "+4412345678"
  ]
]));
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": "",
  "rule": "default",
  "tags": null,
  "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.

  2. When all the people listed are currently present on livestream.

  3. When a face match warning is found, we’ll notify you so you can take action.

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.

notes

Any notes associated with the moderation.

tags

Any tags associated with the moderation when a face match warning is found.

facematch

It represents the results of the face match moderation. It can be the following:

StatusDescription
KnownAn array of face_ids that contain the expected faces seen in the content.
UnknownAn array of objects that contain the bounding box and the time when the unexpected face was seen in the content.
RiskyAn array of objects that contain the face_id, bounding box and the time when the risky user face was seen in the content.

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

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
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)
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",
    "external_id": "YOUR-CORRELATION-ID",
    "status": "Approved",
    "notes": "",
    "facematch": {
        "known": ["010203"],
        "unknown": [
            {
                "face_id": "",
                "time": 1,
                "bounding_box": {
                    "x": 2123,
                    "y": 1230,
                    "height" : 123,
                    "width": 123,
                }
            }
        ],
        "risky": [
            {
                "face_id": "John Doe",
                "time": 1,
                "bounding_box": {
                    "x": 2123,
                    "y": 1230,
                    "height" : 123,
                    "width": 123,
                }
            }
        ],
    },
    "tags": [
      "UNKNOWN_PERSON",
      "RISKY_USER"
    ],
    "created_at": "2020-11-12 19:06:00",
    "updated_at": "2020-11-12 19:06:00",
    "consent_type": "participant"  
}
Copy

Copied!

curl -d '{"id": "ABC-123-5678-ABC", "external_id": "YOUR-CORRELATION-ID", "status": "Rejected", "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