All Products
Search
Document Center

AI Guardrails:Video moderation

Last Updated:Mar 31, 2026

Use AI Guardrails SDK for Go to moderate videos, live streams, and video frames for risky content.

How it works

The Video Moderation API supports two modes:

  • Asynchronous (recommended): Submit a video URL or a sequence of video frames. The service processes the content in the background and returns results via a webhook callback or polling.

  • Synchronous: Submit a sequence of video frames only. Results are returned immediately.

Constraints:

  • The SDK accepts only public video URLs. Local files and binary data are not supported.

  • Internet HTTP and HTTPS URLs up to 2048 characters in length are supported.

Prerequisites

Before you begin, ensure that you have:

  • Go dependencies installed. See Installation for the required Go version. Using a different version causes operation calls to fail.

Moderate a video (asynchronous)

VideoAsyncScanRequest submits asynchronous moderation tasks for videos and live streams. Supported scenarios include pornography, terrorist content, ad, undesirable scene, and logo detection. Specify multiple scenarios in a single request.

Supported regions: cn-shanghai (China (Shanghai)), cn-beijing (China (Beijing)), cn-shenzhen (China (Shenzhen)), ap-southeast-1 (Singapore)

All examples below use VideoAsyncScanRequest. The tasks array accepts a video URL or a streaming URL, and the scenes array controls which moderation scenarios to apply.

Submit a video URL

package main

import (
    "encoding/json"
    "fmt"
    "github.com/aliyun/alibaba-cloud-sdk-go/services/green"
    "strconv"
)

func main() {
    // Reuse the client across requests to improve performance and avoid repeated connections.
    // Get AccessKey credentials from environment variables — never hardcode them.
    //   AccessKey ID:     os.Getenv("ALIBABA_CLOUD_ACCESS_KEY_ID")
    //   AccessKey secret: os.Getenv("ALIBABA_CLOUD_ACCESS_KEY_SECRET")
    client, _err := green.NewClientWithAccessKey(
        "cn-shanghai",
        "Get your RAM user's AccessKey ID from an environment variable",
        "Get your RAM user's AccessKey secret from an environment variable")
    if _err != nil {
        fmt.Println(_err.Error())
        return
    }

    task := map[string]interface{}{"dataId": "Data ID", "url": "URL of the video to moderate"}
    // scenes: detection scenarios; specify one or more (e.g., "porn", "terrorism").
    // callback and seed are optional — use them to receive results via webhook instead of polling.
    content, _ := json.Marshal(
        map[string]interface{}{
            "tasks":    [...]map[string]interface{}{task},
            "scenes":   [...]string{"porn", "terrorism"},
            "bizType":  "Business scenario",
            "callback": "Webhook address",
            "seed":     "Random string",
        },
    )

    request := green.CreateVideoAsyncScanRequest()
    request.SetContent(content)
    response, _err := client.VideoAsyncScan(request)
    if _err != nil {
        fmt.Println(_err.Error())
        return
    }
    if response.GetHttpStatus() != 200 {
        fmt.Println("response not success. status:" + strconv.Itoa(response.GetHttpStatus()))
    }
    fmt.Println(response.GetHttpContentString())
}

Submit a live stream

Set live to "true" and provide the streaming URL as the url parameter.

package main

import (
    "encoding/json"
    "fmt"
    "github.com/aliyun/alibaba-cloud-sdk-go/services/green"
    "strconv"
)

func main() {
    // Reuse the client across requests to improve performance and avoid repeated connections.
    client, _err := green.NewClientWithAccessKey(
        "cn-shanghai",
        "Get your RAM user's AccessKey ID from an environment variable",
        "Get your RAM user's AccessKey secret from an environment variable")
    if _err != nil {
        fmt.Println(_err.Error())
        return
    }

    // Set url to the streaming URL.
    task := map[string]interface{}{"dataId": "Data ID", "url": "URL of the video to moderate"}
    // scenes: detection scenarios; specify one or more.
    // callback and seed are optional — use them to receive results via webhook instead of polling.
    content, _ := json.Marshal(
        map[string]interface{}{
            "tasks":    [...]map[string]interface{}{task},
            "scenes":   [...]string{"porn", "terrorism"},
            "live":     "true",
            "bizType":  "Business scenario",
            "callback": "Webhook address",
            "seed":     "Random string",
        },
    )

    request := green.CreateVideoAsyncScanRequest()
    request.SetContent(content)
    response, _err := client.VideoAsyncScan(request)
    if _err != nil {
        fmt.Println(_err.Error())
        return
    }
    if response.GetHttpStatus() != 200 {
        fmt.Println("response not success. status:" + strconv.Itoa(response.GetHttpStatus()))
    }
    fmt.Println(response.GetHttpContentString())
}

Submit a live stream with audio moderation

Add audioScenes to moderate both video images and audio in a live stream.

package main

import (
    "encoding/json"
    "fmt"
    "github.com/aliyun/alibaba-cloud-sdk-go/services/green"
    "strconv"
)

func main() {
    // Reuse the client across requests to improve performance and avoid repeated connections.
    client, _err := green.NewClientWithAccessKey(
        "cn-shanghai",
        "Get your RAM user's AccessKey ID from an environment variable",
        "Get your RAM user's AccessKey secret from an environment variable")
    if _err != nil {
        fmt.Println(_err.Error())
        return
    }

    // Set url to the streaming URL.
    task := map[string]interface{}{"dataId": "Data ID", "url": "URL of the video to moderate"}
    // scenes: video moderation scenarios.
    // audioScenes: audio moderation scenarios (e.g., "antispam").
    // callback and seed are optional — use them to receive results via webhook instead of polling.
    content, _ := json.Marshal(
        map[string]interface{}{
            "tasks":       [...]map[string]interface{}{task},
            "scenes":      [...]string{"porn", "terrorism"},
            "live":        "true",
            "audioScenes": [...]string{"antispam"},
            "bizType":     "Business scenario",
            "callback":    "Webhook address",
            "seed":        "Random string",
        },
    )

    request := green.CreateVideoAsyncScanRequest()
    request.SetContent(content)
    response, _err := client.VideoAsyncScan(request)
    if _err != nil {
        fmt.Println(_err.Error())
        return
    }
    if response.GetHttpStatus() != 200 {
        fmt.Println("response not success. status:" + strconv.Itoa(response.GetHttpStatus()))
    }
    fmt.Println(response.GetHttpContentString())
}

Get asynchronous moderation results

VideoAsyncScanResultsRequest queries results by task ID.

Supported regions: cn-shanghai (China (Shanghai)), cn-beijing (China (Beijing)), cn-shenzhen (China (Shenzhen)), ap-southeast-1 (Singapore)

Set the callback parameter when submitting tasks to receive results via webhook. Use VideoAsyncScanResultsRequest only when polling is necessary.
package main

import (
    "encoding/json"
    "fmt"
    "github.com/aliyun/alibaba-cloud-sdk-go/services/green"
    "strconv"
)

func main() {
    // Reuse the client across requests to improve performance and avoid repeated connections.
    client, _err := green.NewClientWithAccessKey(
        "cn-shanghai",
        "Get your RAM user's AccessKey ID from an environment variable",
        "Get your RAM user's AccessKey secret from an environment variable")
    if _err != nil {
        fmt.Println(_err.Error())
        return
    }

    content, _ := json.Marshal(
        [...]string{"Task ID of the asynchronous video moderation task"},
    )

    request := green.CreateVideoAsyncScanResultsRequest()
    request.SetContent(content)
    response, _err := client.VideoAsyncScanResults(request)
    if _err != nil {
        fmt.Println(_err.Error())
        return
    }
    if response.GetHttpStatus() != 200 {
        fmt.Println("response not success. status:" + strconv.Itoa(response.GetHttpStatus()))
    }
    fmt.Println(response.GetHttpContentString())
}

Moderate video frames (synchronous)

VideoSyncScanRequest moderates a sequence of frames captured from a video. Each frame object requires an offset (in seconds) and a url.

Supported regions: cn-shanghai (China (Shanghai)), cn-beijing (China (Beijing)), cn-shenzhen (China (Shenzhen)), ap-southeast-1 (Singapore)

Synchronous moderation accepts only video frame sequences. To submit a full video or a live stream, use VideoAsyncScanRequest.
package main

import (
    "encoding/json"
    "fmt"
    "github.com/aliyun/alibaba-cloud-sdk-go/services/green"
    "strconv"
)

func main() {
    // Reuse the client across requests to improve performance and avoid repeated connections.
    client, _err := green.NewClientWithAccessKey(
        "cn-shanghai",
        "Get your RAM user's AccessKey ID from an environment variable",
        "Get your RAM user's AccessKey secret from an environment variable")
    if _err != nil {
        fmt.Println(_err.Error())
        return
    }

    // frames: snapshot information. offset is the time offset in seconds.
    frame1 := map[string]interface{}{"offset": "0", "url": "URL of your video snapshot 1"}
    frame2 := map[string]interface{}{"offset": "5", "url": "URL of your video snapshot 2"}
    frame3 := map[string]interface{}{"offset": "10", "url": "URL of your video snapshot 3"}
    task := map[string]interface{}{"dataId": "Data ID", "frames": [...]map[string]interface{}{frame1, frame2, frame3}}
    // scenes: detection scenarios; specify one or more.
    content, _ := json.Marshal(
        map[string]interface{}{
            "tasks":   [...]map[string]interface{}{task},
            "scenes":  [...]string{"porn", "terrorism"},
            "bizType": "Business scenario",
        },
    )

    request := green.CreateVideoSyncScanRequest()
    request.SetContent(content)
    response, _err := client.VideoSyncScan(request)
    if _err != nil {
        fmt.Println(_err.Error())
        return
    }
    if response.GetHttpStatus() != 200 {
        fmt.Println("response not success. status:" + strconv.Itoa(response.GetHttpStatus()))
    }
    fmt.Println(response.GetHttpContentString())
}

Give feedback on moderation results

If a moderation result is incorrect, use VideoFeedbackRequest to correct it. AI Guardrails adds the moderated frames to the similar image blacklist or whitelist based on your feedback. When a similar frame is submitted later, AI Guardrails returns results based on the label you provided.

For parameter details, see Detection result feedback.

Supported regions: cn-shanghai (China (Shanghai)), cn-beijing (China (Beijing)), cn-shenzhen (China (Shenzhen)), ap-southeast-1 (Singapore)

package main

import (
    "encoding/json"
    "fmt"
    "github.com/aliyun/alibaba-cloud-sdk-go/services/green"
    "strconv"
)

func main() {
    // Reuse the client across requests to improve performance and avoid repeated connections.
    client, _err := green.NewClientWithAccessKey(
        "cn-shanghai",
        "Get your RAM user's AccessKey ID from an environment variable",
        "Get your RAM user's AccessKey secret from an environment variable")
    if _err != nil {
        fmt.Println(_err.Error())
        return
    }

    frame1 := map[string]interface{}{"url": "URL of the moderated video snapshot 1", "offset": "UNIX timestamp for offset 1"}
    frame2 := map[string]interface{}{"url": "URL of the moderated video snapshot 2", "offset": "UNIX timestamp for offset 2"}
    frames := [...]map[string]interface{}{frame1, frame2}

    // suggestion: the expected result. "pass" means normal content; "block" means violating content.
    // scenes: the moderation scenarios the feedback applies to.
    content, _ := json.Marshal(
        map[string]interface{}{
            "taskId":     "Video moderation task ID",
            "dataId":     "Data ID",
            "url":        "Video URL",
            "frames":     frames,
            "suggestion": "block",
            "scenes":     [...]string{"ad", "terrorism"},
            "note":       "Notes",
        },
    )

    request := green.CreateVideoFeedbackRequest()
    request.SetContent(content)
    response, err := client.VideoFeedback(request)
    if err != nil {
        fmt.Println(err.Error())
        return
    }
    if response.GetHttpStatus() != 200 {
        fmt.Println("response not success. status:" + strconv.Itoa(response.GetHttpStatus()))
    }
    fmt.Println(response.GetHttpContentString())
}