You can set up webhooks for common events and actions from the moderation queue . This is useful if you want to integrate the queue with your own systems. Webhooks are configured under integrations in your dashboard
The webhook payload will be sent as a POST
request to the URL you specify.
The webhooks require your server to respond with a 200 status code within 5 seconds, otherwise they will be retried. Webhooks are tried at most 5 times.
Webhook payload
The unique id of the event.
The type of the webhook. Can be QUEUE_ITEM_NEW
, QUEUE_ITEM_ACTION
or
QUEUE_ITEM_COMPLETED
.
The timestamp of when the webhook was sent.
The content item that triggered the webhook.
The id of the content item.
Whether or not the content item has been flagged by your project
configuration.
An array of labels that the content item has been analyzed for - comes
from your project configuration.
The ISO2 language code of the content item.
The original content of the content item.
The timestamp of when the content item was submitted.
The metadata of the content item. Specified by you when sending the
content for moderation .
The context id of the content item. Specified by you when sending the
content for moderation .
The author id of the content item. Specified by you when sending the
content for moderation .
The queue that the content item is in.
The action that was taken on the content item if the type is
QUEUE_ITEM_ACTION
.
{
"id" : "123" ,
"type" : "QUEUE_ITEM_ACTION" ,
"timestamp" : 1691496019049 ,
"item" : {
"id" : "644718a7fc78a41ec9f34a6d" ,
"flagged" : true ,
"labels" : [
{
"label" : "nsfw/UNSAFE" ,
"score" : 0.7266457980882517 ,
"flagged" : true ,
"manual" : false
},
{
"label" : "nsfw/SENSITIVE" ,
"score" : 0.01 ,
"flagged" : false ,
"manual" : false
}
],
"language" : "en" ,
"content" : "Example content" ,
"timestamp" : 1691496019049 ,
"metadata" : {
"key" : "value"
}
},
"queue" : {
"id" : "123" ,
"name" : "My queue"
},
"action" : {
"id" : "123" ,
"name" : "Remove content" ,
"value" : "spam"
},
"contextId" : "demo-context" ,
"authorId" : "author-123"
}
Webhook signing
You can verify that the webhook is coming from us by comparing the signature of the payload with the signature provided in the modapi-signature
header.
The signature is a HMAC SHA256
hash of the payload using your webhook secret as the key. Find you webhook secret under integrations in your dashboard .
Next.js SDK (app router)
Next.js SDK (pages router)
Next.js webhook manual verification
import ModerationApi from "@moderation-api/sdk" ;
const moderationApi = new ModerationApi ({
key: PROJECT_API_KEY ,
});
export async function POST ( request : Request ) {
try {
const body = await request . text ();
const headersList = await headers ();
const webhookSignatureHeader = headersList . get ( "modapi-signature" );
if (! webhookSignatureHeader ) {
return NextResponse . json (
{ error: "No signature header" },
{ status: 400 }
);
}
const payload = await moderationApi . webhooks . constructEvent (
Buffer . from ( body ),
webhookSignatureHeader ,
process . env . MODAPI_WEBHOOK_SECRET !
);
return NextResponse . json ({ received: true });
} catch ( error ) {
console . error ( "Error processing webhook:" , error );
return NextResponse . json (
{ error: "Error processing webhook" },
{ status: 400 }
);
}
}
Preventing replay attacks
To prevent replay attacks, you can use the timestamp in the payload of the webhook to ensure that the webhook is not older than 5 minutes.