Skip to content

Content moderation for Go

Arcjet content moderation detects harmful content in untrusted text before it is stored, displayed, or forwarded. It is a Guard rule – call it from guard() / Guard, not protect().

What is Arcjet? Arcjet is the AI agent runtime security platform. Discover the agents running in your organization, enforce policy across every action, prompt, and tool call, and keep the evidence to prove what happened. Detect prompt injection, authorize agent tool calls, redact PII, and block bots and abuse.

Screen inbound text with content moderation before you store or display it.

Content moderation is a Guard rule. Use NewGuardClient and Guard, not Protect.

For helper options and denial behavior, see the Agent guards guide.

Install the SDK:

Terminal window
# Export your Arcjet API key from https://console.arcjet.com
export ARCJET_KEY="ajkey_..."
go get github.com/arcjet/arcjet-go
main.go
package main
import (
"encoding/json"
"log"
"net/http"
"os"
"github.com/arcjet/arcjet-go"
)
var guard = must(arcjet.NewGuardClient(arcjet.GuardConfig{
Key: os.Getenv("ARCJET_KEY"),
}))
var moderate = must(arcjet.GuardModerateContent(arcjet.GuardModerateContentOptions{
Mode: arcjet.ModeLive,
}))
type messageRequest struct {
Message string `json:"message"`
}
func handler(w http.ResponseWriter, r *http.Request) {
var body messageRequest
if err := json.NewDecoder(r.Body).Decode(&body); err != nil {
http.Error(w, "bad request", http.StatusBadRequest)
return
}
decision, err := guard.Guard(r.Context(), arcjet.GuardRequest{
Label: "message.received",
Rules: []arcjet.GuardRuleInput{moderate.Text(body.Message)},
})
if err != nil {
log.Printf("arcjet: %v", err)
}
if decision.IsDenied() && decision.Reason == arcjet.ReasonModerateContent {
http.Error(w, "Harmful content detected – rephrase your message", http.StatusBadRequest)
return
}
_ = json.NewEncoder(w).Encode(map[string]bool{"ok": true})
}
func main() {
http.HandleFunc("/messages", handler)
log.Fatal(http.ListenAndServe(":8000", nil))
}
func must[T any](v T, err error) T {
if err != nil {
log.Fatal(err)
}
return v
}

Then send a test POST request to /messages.

Requests appear in your Arcjet dashboard in real time.

Terminal window
npm install @arcjet/guard
import { launchArcjet, moderateContent } from "@arcjet/guard";
const arcjet = launchArcjet({ key: process.env.ARCJET_KEY! });
const moderate = moderateContent();
const decision = await arcjet.guard({
label: "tools.chat",
rules: [moderate(userMessage)],
});
if (decision.conclusion === "DENY" && decision.reason === "MODERATE_CONTENT") {
throw new Error("Harmful content detected – rephrase your message");
}
const result = moderate.result(decision);
// `detected` is true when harmful content was found. Billing is undefined
// when the service does not report usage. Content moderation uses text_units.
console.log(result?.detected, result?.billing?.unit, result?.billing?.count);

Keep the response generic. Do not leak detector details or explain exactly what was flagged.

Discussion