v2 - Dashboard API Reference (Multi Model Submission)

The Moderation API is the interface you will use to send user generated data to the Dashboard. It will then return a response with the rules that were auto-triggered along with additional data depending on your needs.

This docs page will specifically go over the v2 submission endpoint, required for Multi-model submissions.

📘

What is Multi-model?

  • Multi-model allows you to send content to multiple models in a single API request, streamlining your moderation process.
  • For instance, when handling a video task, you can simultaneously submit it to our visual moderation, audio, demographics, and AI-generated media detection models.
  • This then enabled you to create sophisticated rules that leverage signals from each of the models.
  • For example, you can automatically remove a video and ban the user if the visual moderation model detects sexual content AND the demographics model identifies individuals under 18 years old.
  • This page has detailed guidance on how to submit to the v2 submission endpoint to fully utilize the capabilities of the multi-model feature.

Authentication

Each Dashboard application has a unique API key that will need to be included in the API request. The API key will be sent via email after getting access to the Dashboard.

📘

Authentication

Include the API Key in the header of your POST request ('authorization: token <YOUR_API_KEY>')

Submitting a Task to the Dashboard via API

The Dashboard supports both synchronous (sync) and asynchronous (async) API interface protocols.
Our technical team is happy to help you determine the submission process that best fits your use case.

As a general guideline:

Sync APIAsync API
A synchronous endpoint is preferred for users who have real-time needs, low latency requirements, and are submitting continuous / cyclical requests.

The synchronous endpoint keeps the HTTP request open until results have finished processing and then sends the results directly in the response message.
The asynchronous endpoint is preferred for users who are submitting their volume in large batches users submitting tasks containing large files (i.e. longer videos or audio clips).

The asynchronous endpoint immediately sends a response acknowledging receipt of the task, along with a unique ‘task_id’. It then closes the connection. Once the task is completed, Hive will send a POST request to the provided callback_url containing the completed task’s results.

Sync Request

https://api.hivemoderation.com/api/v2/task/sync

Form Data

Field (*required)TypeDescription
text_data*StringRaw text data.

If no models field is specified, text content will be sent to the Text Moderation API by default.
url*StringPublicly accessible url for sending images and videos (max 1 hr).

If no models field is specified, visual content will be sent to the Visual Moderation API by default.
user_id*StringID of the user that published the content. (No "_", ";" in the ID)
post_id*StringID tied to the post that was published. (unique for each submission, No "_", ";" in the ID)
group_idStringTo group a series of posts together, they should all be submitted with the same group_id. The group_id is a unique id that is different from the post_id and parent_id. This is especially useful to group together images and their captions, comments that include an image, or AI-generated images and their prompts. Refer to https://docs.thehive.ai/docs/types-of-submissions for more information.
parent_idStringThe parent_id field captures the hierarchy between different posts by indicating a post's parent. For example, when grouping together a comment and a reply to that comment, the parent_id of the reply will be the post_id of the comment it is replying to. This hierarchy can span multiple levels — a post that has a parent can itself be a parent to a different post. Refer to https://docs.thehive.ai/docs/types-of-submissions for more information.
content_metadataJSON ObjectContent metadata (can be different for each post). View this metadata on the Dashboard when you click into a piece of content.
content_variantStringDifferentiate different types on content published on your platform through content variants. Once you create your content variants on the Settings page, you can send this optional field in the API request and create rules using this field
user_metadataJSON ObjectUser metadata tied to each userID on the Dashboard (send with every API request). View this metadata on the Dashboard when you open the User Detailed View.
modelsArraySpecify the models you want to use in the models array:

Visual Moderation array element : "visual"

Text Moderation array element : "text"

AI-Generated Media Recognition array element : "ai_generated_media"

AI-Generated Text Detection array element : "ai_generated_text"

OCR array element: "ocr"

Deepfake array element: "deepfake"

Demographics array element: "demographic"

Audio array element: "audio"

Custom Index array element: "<your_custom_index_id>" (defined when Index is created from the Dashboard)

Example submission to Visual, OCR, Audio Moderation Models (Sync)

curl --request POST \
  --url https://api.hivemoderation.com/api/v2/task/sync \
  --header 'authorization: token 123' \
  --header 'content-type: application/json' \
  --data '{
    "user_id":"hive-test-patron-392932",
    "post_id": "v2-hive-test-392932",
    "url": "https://d24edro6ichpbm.thehive.ai/demo_static_media/nsfw/nsfw_1.mp4",
  "models":["ocr","visual","audio"],
    "content_metadata":{
        "content": "paying"
    },
    "patron_metadata": {
        "user_age": 20
    }
}'
import requests

url = "https://api.hivemoderation.com/api/v2/task/sync"

payload = {
  "user_id": "hive-test-patron-392932",
  "post_id": "v2-hive-test-392932",
  "url": "https://d24edro6ichpbm.thehive.ai/demo_static_media/nsfw/nsfw_1.mp4",
  "models": ["ocr", "visual", "audio"],
  "content_metadata": { "content": "paying" },
  "patron_metadata": { "user_age": 20 }
}
headers = {
  "content-type": "application/json",
  "authorization": "token 123"
}

response = requests.post(url, json=payload, headers=headers)

print(response.json())
OkHttpClient client = new OkHttpClient();

MediaType mediaType = MediaType.parse("application/json");
RequestBody body = RequestBody.create(mediaType, "{\n    \"user_id\":\"hive-test-patron-392932\",\n    \"post_id\": \"v2-hive-test-392932\",\n    \"url\": \"https://d24edro6ichpbm.thehive.ai/demo_static_media/nsfw/nsfw_1.mp4\",\n  \"models\":[\"ocr\",\"visual\",\"audio\"],\n    \"content_metadata\":{\n        \"content\": \"paying\"\n    },\n    \"patron_metadata\": {\n        \"user_age\": 20\n    }\n}");
Request request = new Request.Builder()
  .url("https://api.hivemoderation.com/api/v2/task/sync")
  .post(body)
  .addHeader("content-type", "application/json")
  .addHeader("authorization", "token 123")
  .build();

Response response = client.newCall(request).execute();

Submitting to Custom Index Search (Sync)

Adding an Image to your Index

curl --request POST \
  --url https://api.hivemoderation.com/api/v1/custom_index/your_custom_index_id/add/sync \
  --header 'authorization: token 123' \
  --header 'content-type: application/json' \
  --data '{
    "url": "https://d24edro6ichpbm.thehive.ai/demo_static_media/nsfw/nsfw_2.jpg",
    "metadata": {"my_key2": "my_value2"},
    "content_variant": "bio_pic"
}'

Removing an Image from your Index

curl --request POST \
  --url https://api.hivemoderation.com/api/v1/custom_index/test-id/remove/sync \
  --header 'authorization: token 123' \
  --header 'content-type: application/json' \
  --data '{
  "custom_index_item_id": "5RgNW8ZGUQxn5Pgklh3AhV_828bc2f3-a604-4856-bd2f-e8fec93b7a25_121_350fc92b8db1062fddcfafaaa0d12493615c31a71089d3104ccd06686961e9cb"
}'

Task Submission to Custom Index Model (Please use v2 endpoint)

curl --request POST  
  --url <https://api.hivemoderation.com/api/v2/task/sync>  
  --header 'authorization: token 123'  
  --header 'content-type: application/json'  
  --data '{  
    "user_id":"945455793",  
    "post_id": "7756488575",  
    "url": "https://d24edro6ichpbm.thehive.ai/demo_static_media/nsfw/nsfw_2.jpg",
    "models": ["your_custom_index_id"],  
    "content_metadata":{  
        "content": "paying"  
    },  
    "user_metadata": {  
        "user_age": 20  
    }  
}'

Async Request

https://api.hivemoderation.com/api/v2/task/async

Form Data

Field (*required)TypeDescription
text_data*StringRaw text data.
If no models field is specified, text content will be sent to the Text Moderation API by default.
url*StringPublicly accessible url for sending images and videos (max 1 hr).
If no models field is specified, visual content will be sent to the Visual Moderation API by default.
user_id*StringID of the user that published the content. (No "_", ";" in the ID)
post_id*StringID tied to the post that was published. (unique for each submission, No under"_", ";"scores in the ID)
group_idStringTo group a series of posts together, they should all be submitted with the same group_id. The group_id is a unique id that is different from the post_id and parent_id. This is especially useful to group together images and their captions, comments that include an image, or AI-generated images and their prompts. Refer to https://docs.thehive.ai/docs/types-of-submissions for more information.
parent_idStringThe parent_id field captures the hierarchy between different posts by indicating a post's parent. For example, when grouping together a comment and a reply to that comment, the parent_id of the reply will be the post_id of the comment it is replying to. This hierarchy can span multiple levels — a post that has a parent can itself be a parent to a different post. Refer to https://docs.thehive.ai/docs/types-of-submissions for more information.
content_metadataJSON ObjectContent metadata (can be different for each post). View this metadata on the Dashboard when you click into a piece of content.
content_variantStringDifferentiate different types on content published on your platform through content variants. Once you create your content variants on the Settings page, you can send this optional field in the API request and create rules using this field
user_metadataJSON ObjectUser metadata tied to each userID on the Dashboard (send with every API request). View this metadata on the Dashboard when you open the User Detailed View.
modelsArraySpecify the models you want to use in the models array:

Visual Moderation array element : "visual"

Text Moderation array element : "text"

AI-Generated Media Recognition array element : "ai_generated_media"

AI-Generated Text Detection array element : "ai_generated_text"

OCR array element: "ocr"

Deepfake array element: "deepfake"

Demographics array element: "demographic"

Audio array element: "audio"

Custom Index array element: "<your_custom_index_id>" (defined when Index is created from the Dashboard)

Example submission to Visual, OCR, Audio Moderation Models (Async)

curl --request POST \
  --url https://api.hivemoderation.com/api/v2/task/async \
  --header 'authorization: token 123' \
  --header 'content-type: application/json' \
  --data '{
    "user_id":"hive-test-patron-260410",
    "post_id": "v2-hive-test-260410",
  	"callback_url": "https://webhook.site/d07d9167-7aa3-4cfd-9e0c-06e4563dc1e3",
    "url": "https://d24edro6ichpbm.thehive.ai/demo_static_media/nsfw/nsfw_1.mp4",
  "models":["ocr","visual","audio"],
    "content_metadata":{
        "content": "paying"
    },
    "patron_metadata": {
        "user_age": 20
    }
}'
import requests

url = "https://api.hivemoderation.com/api/v2/task/async"

payload = {
  "user_id": "hive-test-patron-260410",
  "post_id": "v2-hive-test-260410",
  "callback_url": "https://webhook.site/d07d9167-7aa3-4cfd-9e0c-06e4563dc1e3",
  "url": "https://d24edro6ichpbm.thehive.ai/demo_static_media/nsfw/nsfw_1.mp4",
  "models": ["ocr", "visual", "audio"],
  "content_metadata": { "content": "paying" },
  "patron_metadata": { "user_age": 20 }
}
headers = {
  "content-type": "application/json",
  "authorization": "token 123"
}

response = requests.post(url, json=payload, headers=headers)

print(response.json())
OkHttpClient client = new OkHttpClient();

MediaType mediaType = MediaType.parse("application/json");
RequestBody body = RequestBody.create(mediaType, "{\n    \"user_id\":\"hive-test-patron-260410\",\n    \"post_id\": \"v2-hive-test-260410\",\n  \t\"callback_url\": \"https://webhook.site/d07d9167-7aa3-4cfd-9e0c-06e4563dc1e3\",\n    \"url\": \"https://d24edro6ichpbm.thehive.ai/demo_static_media/nsfw/nsfw_1.mp4\",\n  \"models\":[\"ocr\",\"visual\",\"audio\"],\n    \"content_metadata\":{\n        \"content\": \"paying\"\n    },\n    \"patron_metadata\": {\n        \"user_age\": 20\n    }\n}");
Request request = new Request.Builder()
  .url("https://api.hivemoderation.com/api/v2/task/async")
  .post(body)
  .addHeader("content-type", "application/json")
  .addHeader("authorization", "token 123")
  .build();

Response response = client.newCall(request).execute();

Submitting to Custom Index Search (Async)

Adding an Image to your Index

curl --request POST \
  --url https://api.hivemoderation.com/api/v1/custom_index/your_custom_index_id/add/async \
  --header 'authorization: token 123' \
  --header 'content-type: application/json' \
  --data '{
    "url": "https://d24edro6ichpbm.thehive.ai/demo_static_media/nsfw/nsfw_2.jpg",
    "callback_url": "https://webhook.site/c9480f48-9df1-4681-947d-1fa19aeb461c",
    "metadata": {"my_key2": "my_value2"},
    "content_variant": "bio_pic"
}'

Removing an Image from your Index

curl --request POST \
  --url https://api.hivemoderation.com/api/v1/custom_index/test-id/remove/async \
  --header 'authorization: token 123' \
  --header 'content-type: application/json' \
  --data '{
  "custom_index_item_id": "5RgNW8ZGUQxn5Pgklh3AhV_828bc2f3-a604-4856-bd2f-e8fec93b7a25_121_350fc92b8db1062fddcfafaaa0d12493615c31a71089d3104ccd06686961e9cb",
  "callback_url": "https://webhook.site/c9480f48-9df1-4681-947d-1fa19aeb461c"
}'

Task Submission to Custom Index Model (Please note to use v2 endpoint)

curl --request POST  
  --url <https://api.hivemoderation.com/api/v2/task/async>  
  --header 'authorization: token 123'  
  --header 'content-type: application/json'  
  --data '{  
    "user_id":"945455793",  
    "post_id": "7756488575",  
    "url": "https://d24edro6ichpbm.thehive.ai/demo_static_media/nsfw/nsfw_2.jpg",
    "callback_url": "https://webhook.site/c9480f48-9df1-4681-947d-1fa19aeb461c",
    "models": ["your_custom_index_id"],  
    "content_metadata":{  
        "content": "paying"  
    },  
    "user_metadata": {  
        "user_age": 20  
    }  
}'

Responses

Dashboard API Sample Response (v2 endpoint):

{
  "task_ids": [
    "6a58efe1-58f5-11ef-b329-89415a617885",
    "6a596510-58f5-11ef-8e25-bba79503b56a",
    "6a598c20-58f5-11ef-8add-79fa312c54f3"
  ],
  "post_id": "v2-hive-test-645808",
  "user_id": "hive-test-patron-645808",
  "project_status_map": {
    "32952": {
      "moderation_type": "visual",
      "task_id": "6a596510-58f5-11ef-8e25-bba79503b56a",
      "status": "success"
    },
    "41410": {
      "moderation_type": "ocr",
      "task_id": "6a58efe1-58f5-11ef-b329-89415a617885",
      "status": "success"
    },
    "43789": {
      "moderation_type": "audio",
      "task_id": "6a598c20-58f5-11ef-8add-79fa312c54f3",
      "status": "success"
    }
  },
  "content_id": "1ms1mMtrz45ntWZrUqdNYT_2024-08-12T21:54:14.602Z_0U0TVGlciG0X2elhbKOSb8",
  "triggered_rules": [
    {
      "rule_id": "6QAg1Vemg0nHjd2e8wMW4M",
      "rule_name": "Rule Test Mode",
      "action_id": "send_post_to_review"
    },
    {
      "rule_id": "4P2lHViNAZdeQa9CIRnZQB",
      "rule_name": "If post contains Violence, Sexual, then remove post",
      "action_id": "4OVAJyKBUsnmJAO5sMc0VA"
    }
  ],
  "triggered_background_rules": []
}