curl --request POST \
--url https://apix.us.amity.co/api/v4/me/flags/{userId} \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '
{
"reason": "<string>",
"comment": "<string>"
}
'import requests
url = "https://apix.us.amity.co/api/v4/me/flags/{userId}"
payload = {
"reason": "<string>",
"comment": "<string>"
}
headers = {
"Authorization": "Bearer <token>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {Authorization: 'Bearer <token>', 'Content-Type': 'application/json'},
body: JSON.stringify({reason: '<string>', comment: '<string>'})
};
fetch('https://apix.us.amity.co/api/v4/me/flags/{userId}', 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://apix.us.amity.co/api/v4/me/flags/{userId}",
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([
'reason' => '<string>',
'comment' => '<string>'
]),
CURLOPT_HTTPHEADER => [
"Authorization: Bearer <token>",
"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://apix.us.amity.co/api/v4/me/flags/{userId}"
payload := strings.NewReader("{\n \"reason\": \"<string>\",\n \"comment\": \"<string>\"\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("Authorization", "Bearer <token>")
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://apix.us.amity.co/api/v4/me/flags/{userId}")
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/json")
.body("{\n \"reason\": \"<string>\",\n \"comment\": \"<string>\"\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://apix.us.amity.co/api/v4/me/flags/{userId}")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["Authorization"] = 'Bearer <token>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"reason\": \"<string>\",\n \"comment\": \"<string>\"\n}"
response = http.request(request)
puts response.read_body{
"users": [
{
"userId": "<string>",
"createdAt": "2023-11-07T05:31:56Z",
"updatedAt": "2023-11-07T05:31:56Z",
"_id": "<string>",
"path": "<string>",
"userInternalId": "<string>",
"userPublicId": "<string>",
"roles": [
"<string>"
],
"permissions": [
"MUTE_CHANNEL"
],
"displayName": "<string>",
"profileHandle": "<string>",
"description": "<string>",
"avatarFileId": "<string>",
"avatarCustomUrl": "<string>",
"flagCount": 123,
"hashFlag": {
"bits": 123,
"hashes": 123,
"hash": [
"<string>"
]
},
"metadata": {},
"isGlobalBan": true,
"isBrand": true,
"isDeleted": true
}
],
"files": [
{
"fileId": "<string>",
"fileUrl": "<string>",
"type": "image",
"accessType": "public",
"altText": "<string>",
"createdAt": "2023-11-07T05:31:56Z",
"updatedAt": "2023-11-07T05:31:56Z",
"attributes": {
"name": "<string>",
"extension": "<string>",
"size": 123,
"mimeType": "<string>",
"metadata": {
"exif": {},
"gps": {},
"height": 123,
"width": 123,
"isFull": true
}
}
}
]
}{
"status": "error",
"code": 400300,
"message": "Number of flag already exceed."
}{
"status": "error",
"code": 400400,
"message": "User Not Found."
}{
"status": "error",
"code": 500000,
"message": "Parameters error.",
"data": {
"detail": [
"The 'data.text' field length must be less than or equal to 20000 characters long."
]
}
}{
"status": "error",
"code": 500000,
"message": "Unexpected error"
}Report a User
Report a User by User ID (Flag User).
Optionally include reportType, reason, and comment in the body to categorize the
report. Sending no body flags the target as a legacy/unspecified (typeless) report and
behaves exactly as before — fully backward compatible, no version bump.
curl --request POST \
--url https://apix.us.amity.co/api/v4/me/flags/{userId} \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '
{
"reason": "<string>",
"comment": "<string>"
}
'import requests
url = "https://apix.us.amity.co/api/v4/me/flags/{userId}"
payload = {
"reason": "<string>",
"comment": "<string>"
}
headers = {
"Authorization": "Bearer <token>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {Authorization: 'Bearer <token>', 'Content-Type': 'application/json'},
body: JSON.stringify({reason: '<string>', comment: '<string>'})
};
fetch('https://apix.us.amity.co/api/v4/me/flags/{userId}', 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://apix.us.amity.co/api/v4/me/flags/{userId}",
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([
'reason' => '<string>',
'comment' => '<string>'
]),
CURLOPT_HTTPHEADER => [
"Authorization: Bearer <token>",
"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://apix.us.amity.co/api/v4/me/flags/{userId}"
payload := strings.NewReader("{\n \"reason\": \"<string>\",\n \"comment\": \"<string>\"\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("Authorization", "Bearer <token>")
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://apix.us.amity.co/api/v4/me/flags/{userId}")
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/json")
.body("{\n \"reason\": \"<string>\",\n \"comment\": \"<string>\"\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://apix.us.amity.co/api/v4/me/flags/{userId}")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["Authorization"] = 'Bearer <token>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"reason\": \"<string>\",\n \"comment\": \"<string>\"\n}"
response = http.request(request)
puts response.read_body{
"users": [
{
"userId": "<string>",
"createdAt": "2023-11-07T05:31:56Z",
"updatedAt": "2023-11-07T05:31:56Z",
"_id": "<string>",
"path": "<string>",
"userInternalId": "<string>",
"userPublicId": "<string>",
"roles": [
"<string>"
],
"permissions": [
"MUTE_CHANNEL"
],
"displayName": "<string>",
"profileHandle": "<string>",
"description": "<string>",
"avatarFileId": "<string>",
"avatarCustomUrl": "<string>",
"flagCount": 123,
"hashFlag": {
"bits": 123,
"hashes": 123,
"hash": [
"<string>"
]
},
"metadata": {},
"isGlobalBan": true,
"isBrand": true,
"isDeleted": true
}
],
"files": [
{
"fileId": "<string>",
"fileUrl": "<string>",
"type": "image",
"accessType": "public",
"altText": "<string>",
"createdAt": "2023-11-07T05:31:56Z",
"updatedAt": "2023-11-07T05:31:56Z",
"attributes": {
"name": "<string>",
"extension": "<string>",
"size": 123,
"mimeType": "<string>",
"metadata": {
"exif": {},
"gps": {},
"height": 123,
"width": 123,
"isFull": true
}
}
}
]
}{
"status": "error",
"code": 400300,
"message": "Number of flag already exceed."
}{
"status": "error",
"code": 400400,
"message": "User Not Found."
}{
"status": "error",
"code": 500000,
"message": "Parameters error.",
"data": {
"detail": [
"The 'data.text' field length must be less than or equal to 20000 characters long."
]
}
}{
"status": "error",
"code": 500000,
"message": "Unexpected error"
}Authorizations
Bearer authentication header of the form Bearer <token>, where <token> is your auth token.
Path Parameters
User public id
Body
Optional report details. Sending no body flags the target as a legacy/unspecified (typeless) report — fully backward compatible.
reportType uses the internal field vocabulary; the client owns the display labels:
reportType | Label to show |
|---|---|
displayName | Username |
description | Bio |
avatarFileId | Avatar |
behavior | Behavior |
Send the internal values above, not the labels.
Validation (failures are 422 ValidationError):
| Request | Result |
|---|---|
reportType: behavior + reason | 200 |
reportType: behavior, no reason | 422 |
reportType: displayName / description / avatarFileId, no reason | 200 |
any of the three field types + reason | 422 |
no reportType + reason | 422 |
reportType outside the enum | 422 |
reason or comment > 300 chars | 422 |
reason or comment empty string ("") | 422 |
comment on any type, <= 300 chars | 200 |
Semantics — one report per (reporter, reportType):
- A reporter holds at most one report per
reportTypeon a target (up to 4 typed + 1 typeless). - Same reporter + same
reportTypeagain is a merge-update: providedreason/commentoverwrite; omitted fields keep their prior values. - Identical resubmission is a no-op — safe to retry, but does not re-alert moderators.
- Same reporter + different
reportTypecreates a new report. - Typeless requests (no
reportType) dedup only against the reporter's existing typeless report; typed and typeless reports never block each other. - Reports are anonymous to the reported user; reporter identity is not exposed to them.
The new fields are not echoed back in the response.
Internal field being reported. Omit for a legacy/unspecified (typeless) report. Display labels: displayName=Username, description=Bio, avatarFileId=Avatar, behavior=Behavior.
displayName, description, avatarFileId, behavior Required if and only if reportType is behavior; rejected on every other request (profile-field types and typeless). Use a value from the predefined ReportReasons taxonomy (the same list used by content flags); it is a free string on the wire, but off-list values make moderation grouping unreliable.
1 - 300Optional free-text note, allowed on all report types (including typeless).
1 - 300