curl --request POST \
--url https://api.bodyguard.ai/feedback/v1/image \
--header 'Authorization: <api-key>' \
--header 'Content-Type: application/json' \
--data '
{
"analyzeRequest": {
"channelId": "__YOUR_CHANNEL_ID__",
"publishedAt": "2026-04-23T10:30:00.000Z",
"imageUrl": "https://cdn.example.com/uploads/photo.jpg"
},
"classificationsToRemove": [
"PARTIAL_NUDITY"
],
"notes": "Swimwear on a beach, not nudity.",
"confidence": "VERY_HIGH"
}
'import requests
url = "https://api.bodyguard.ai/feedback/v1/image"
payload = {
"analyzeRequest": {
"channelId": "__YOUR_CHANNEL_ID__",
"publishedAt": "2026-04-23T10:30:00.000Z",
"imageUrl": "https://cdn.example.com/uploads/photo.jpg"
},
"classificationsToRemove": ["PARTIAL_NUDITY"],
"notes": "Swimwear on a beach, not nudity.",
"confidence": "VERY_HIGH"
}
headers = {
"Authorization": "<api-key>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {Authorization: '<api-key>', 'Content-Type': 'application/json'},
body: JSON.stringify({
analyzeRequest: {
channelId: '__YOUR_CHANNEL_ID__',
publishedAt: '2026-04-23T10:30:00.000Z',
imageUrl: 'https://cdn.example.com/uploads/photo.jpg'
},
classificationsToRemove: ['PARTIAL_NUDITY'],
notes: 'Swimwear on a beach, not nudity.',
confidence: 'VERY_HIGH'
})
};
fetch('https://api.bodyguard.ai/feedback/v1/image', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://api.bodyguard.ai/feedback/v1/image",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => json_encode([
'analyzeRequest' => [
'channelId' => '__YOUR_CHANNEL_ID__',
'publishedAt' => '2026-04-23T10:30:00.000Z',
'imageUrl' => 'https://cdn.example.com/uploads/photo.jpg'
],
'classificationsToRemove' => [
'PARTIAL_NUDITY'
],
'notes' => 'Swimwear on a beach, not nudity.',
'confidence' => 'VERY_HIGH'
]),
CURLOPT_HTTPHEADER => [
"Authorization: <api-key>",
"Content-Type: application/json"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"strings"
"net/http"
"io"
)
func main() {
url := "https://api.bodyguard.ai/feedback/v1/image"
payload := strings.NewReader("{\n \"analyzeRequest\": {\n \"channelId\": \"__YOUR_CHANNEL_ID__\",\n \"publishedAt\": \"2026-04-23T10:30:00.000Z\",\n \"imageUrl\": \"https://cdn.example.com/uploads/photo.jpg\"\n },\n \"classificationsToRemove\": [\n \"PARTIAL_NUDITY\"\n ],\n \"notes\": \"Swimwear on a beach, not nudity.\",\n \"confidence\": \"VERY_HIGH\"\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("Authorization", "<api-key>")
req.Header.Add("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.post("https://api.bodyguard.ai/feedback/v1/image")
.header("Authorization", "<api-key>")
.header("Content-Type", "application/json")
.body("{\n \"analyzeRequest\": {\n \"channelId\": \"__YOUR_CHANNEL_ID__\",\n \"publishedAt\": \"2026-04-23T10:30:00.000Z\",\n \"imageUrl\": \"https://cdn.example.com/uploads/photo.jpg\"\n },\n \"classificationsToRemove\": [\n \"PARTIAL_NUDITY\"\n ],\n \"notes\": \"Swimwear on a beach, not nudity.\",\n \"confidence\": \"VERY_HIGH\"\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.bodyguard.ai/feedback/v1/image")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["Authorization"] = '<api-key>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"analyzeRequest\": {\n \"channelId\": \"__YOUR_CHANNEL_ID__\",\n \"publishedAt\": \"2026-04-23T10:30:00.000Z\",\n \"imageUrl\": \"https://cdn.example.com/uploads/photo.jpg\"\n },\n \"classificationsToRemove\": [\n \"PARTIAL_NUDITY\"\n ],\n \"notes\": \"Swimwear on a beach, not nudity.\",\n \"confidence\": \"VERY_HIGH\"\n}"
response = http.request(request)
puts response.read_body{
"id": "018f3b05-4d80-7b19-a6c2-71e4f0d8b331"
}Image analysis feedback
Sends feedback on a classification returned by POST /analyze/v1/image that you judge incorrect for a given image, with the classifications you would have expected instead.
Send the exact analyze request body you originally submitted in analyzeRequest so Bodyguard can reproduce the analysis your feedback refers to.
Before diving in, we recommend reading the image taxonomy to understand the classifications you can add or remove.
curl --request POST \
--url https://api.bodyguard.ai/feedback/v1/image \
--header 'Authorization: <api-key>' \
--header 'Content-Type: application/json' \
--data '
{
"analyzeRequest": {
"channelId": "__YOUR_CHANNEL_ID__",
"publishedAt": "2026-04-23T10:30:00.000Z",
"imageUrl": "https://cdn.example.com/uploads/photo.jpg"
},
"classificationsToRemove": [
"PARTIAL_NUDITY"
],
"notes": "Swimwear on a beach, not nudity.",
"confidence": "VERY_HIGH"
}
'import requests
url = "https://api.bodyguard.ai/feedback/v1/image"
payload = {
"analyzeRequest": {
"channelId": "__YOUR_CHANNEL_ID__",
"publishedAt": "2026-04-23T10:30:00.000Z",
"imageUrl": "https://cdn.example.com/uploads/photo.jpg"
},
"classificationsToRemove": ["PARTIAL_NUDITY"],
"notes": "Swimwear on a beach, not nudity.",
"confidence": "VERY_HIGH"
}
headers = {
"Authorization": "<api-key>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {Authorization: '<api-key>', 'Content-Type': 'application/json'},
body: JSON.stringify({
analyzeRequest: {
channelId: '__YOUR_CHANNEL_ID__',
publishedAt: '2026-04-23T10:30:00.000Z',
imageUrl: 'https://cdn.example.com/uploads/photo.jpg'
},
classificationsToRemove: ['PARTIAL_NUDITY'],
notes: 'Swimwear on a beach, not nudity.',
confidence: 'VERY_HIGH'
})
};
fetch('https://api.bodyguard.ai/feedback/v1/image', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://api.bodyguard.ai/feedback/v1/image",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => json_encode([
'analyzeRequest' => [
'channelId' => '__YOUR_CHANNEL_ID__',
'publishedAt' => '2026-04-23T10:30:00.000Z',
'imageUrl' => 'https://cdn.example.com/uploads/photo.jpg'
],
'classificationsToRemove' => [
'PARTIAL_NUDITY'
],
'notes' => 'Swimwear on a beach, not nudity.',
'confidence' => 'VERY_HIGH'
]),
CURLOPT_HTTPHEADER => [
"Authorization: <api-key>",
"Content-Type: application/json"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"strings"
"net/http"
"io"
)
func main() {
url := "https://api.bodyguard.ai/feedback/v1/image"
payload := strings.NewReader("{\n \"analyzeRequest\": {\n \"channelId\": \"__YOUR_CHANNEL_ID__\",\n \"publishedAt\": \"2026-04-23T10:30:00.000Z\",\n \"imageUrl\": \"https://cdn.example.com/uploads/photo.jpg\"\n },\n \"classificationsToRemove\": [\n \"PARTIAL_NUDITY\"\n ],\n \"notes\": \"Swimwear on a beach, not nudity.\",\n \"confidence\": \"VERY_HIGH\"\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("Authorization", "<api-key>")
req.Header.Add("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.post("https://api.bodyguard.ai/feedback/v1/image")
.header("Authorization", "<api-key>")
.header("Content-Type", "application/json")
.body("{\n \"analyzeRequest\": {\n \"channelId\": \"__YOUR_CHANNEL_ID__\",\n \"publishedAt\": \"2026-04-23T10:30:00.000Z\",\n \"imageUrl\": \"https://cdn.example.com/uploads/photo.jpg\"\n },\n \"classificationsToRemove\": [\n \"PARTIAL_NUDITY\"\n ],\n \"notes\": \"Swimwear on a beach, not nudity.\",\n \"confidence\": \"VERY_HIGH\"\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.bodyguard.ai/feedback/v1/image")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["Authorization"] = '<api-key>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"analyzeRequest\": {\n \"channelId\": \"__YOUR_CHANNEL_ID__\",\n \"publishedAt\": \"2026-04-23T10:30:00.000Z\",\n \"imageUrl\": \"https://cdn.example.com/uploads/photo.jpg\"\n },\n \"classificationsToRemove\": [\n \"PARTIAL_NUDITY\"\n ],\n \"notes\": \"Swimwear on a beach, not nudity.\",\n \"confidence\": \"VERY_HIGH\"\n}"
response = http.request(request)
puts response.read_body{
"id": "018f3b05-4d80-7b19-a6c2-71e4f0d8b331"
}Authorizations
API key authentication. Provide your key in the Authorization
header with the ApiKey scheme:
Authorization: ApiKey <your-api-key>
Body
Feedback on an image analysis. Provide at least one of classificationsToAdd, classificationsToRemove, or notes — a request with none of the three is considered invalid.
The analyze request body you originally sent to POST /analyze/v1/image. Send it unchanged so Bodyguard can identify the exact analysis your feedback refers to. It already carries the channel the image belongs to. If you analyzed the image by inline bytes, send the same base64 payload in imageData.
- Option 1
- Option 2
Show child attributes
Show child attributes
Classifications Bodyguard returned that you judge do not apply to this content. See the image taxonomy for the full list.
["PARTIAL_NUDITY"]
Classifications you judge apply to this content but that Bodyguard did not return. See the image taxonomy for the full list.
Whether there is an issue with OCR or not. Can be omitted if your feedback does not concern OCR at all
Free-text comment explaining why you judge the content differently. Counts on its own: a feedback carrying only notes, with no classification change, is valid.
How confident you are about the classifications you submitted. Bodyguard uses it to prioritise which feedback to review first. You can base it on who flagged the content on your side — for example LOW or MEDIUM for a report from an end-user, HIGH or VERY_HIGH for a decision from your Trust & Safety team. Optional — omit it if you cannot qualify your confidence.
LOW, MEDIUM, HIGH, VERY_HIGH Response
Feedback recorded.
Bodyguard's identifier for this feedback.