GET
/
api
/
v1
/
admin
/
reports
Admin reports feed
curl --request GET \
  --url https://api.example.com/api/v1/admin/reports
import requests

url = "https://api.example.com/api/v1/admin/reports"

response = requests.get(url)

print(response.text)
const options = {method: 'GET'};

fetch('https://api.example.com/api/v1/admin/reports', 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.example.com/api/v1/admin/reports",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "GET",
]);

$response = curl_exec($curl);
$err = curl_error($curl);

curl_close($curl);

if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}
package main

import (
"fmt"
"net/http"
"io"
)

func main() {

url := "https://api.example.com/api/v1/admin/reports"

req, _ := http.NewRequest("GET", url, nil)

res, _ := http.DefaultClient.Do(req)

defer res.Body.Close()
body, _ := io.ReadAll(res.Body)

fmt.Println(string(body))

}
HttpResponse<String> response = Unirest.get("https://api.example.com/api/v1/admin/reports")
.asString();
require 'uri'
require 'net/http'

url = URI("https://api.example.com/api/v1/admin/reports")

http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true

request = Net::HTTP::Get.new(url)

response = http.request(request)
puts response.read_body

Overview

The moderation feed of user-submitted abuse reports. Defaults to status=OPEN (the unresolved state). Each row embeds the immutable transcript snapshot captured at report time so the moderator sees exactly what the reporter saw, plus reporter and accused user summaries. Available to any admin role — read-only.
The moderation actions (dismiss / warn / ban-from-report) are deferred to Phase 7. Phase 6 ships the read-only feed only. To act on a report today, use ban user against the accused.

Authentication

Bearer <accessToken> with scope: 'admin' required (requireAdmin).

Path parameters

None.

Query parameters

NameTypeRequiredNotesExample
statusenumnoOPEN (default), DISMISSED, WARNED, BANNED.OPEN
cursorstringnoOpaque base64url pagination cursor, 1..512 chars.eyJjcmVhdGVkQXQ…
limitintegernoPage size, 1..100. Default 25.50

Request body

None.

Response — 200 OK

FieldTypeNotes
itemsarrayArray of report rows (below).
nextCursorstring | nullCursor for the next page, or null on the last page.

Report row

FieldTypeNotes
idstringReport ObjectId.
reporterIdstringUser who filed the report.
accusedIdstringUser being reported.
conversationIdstring | nullThe conversation the report relates to, or null.
messageIdstring | nullThe specific message reported, or null.
reasonenumHARASSMENT | SCAM | INCORRECT_PROPERTY | OTHER.
freeTextstring | nullReporter’s free-text note, or null.
transcriptSnapshotarrayImmutable list of { senderId, text, sentAt } captured at report time.
statusenumOPEN | DISMISSED | WARNED | BANNED.
resolvedBystring | nullAdmin id who resolved it (Phase 7), or null.
resolvedAtstring | nullISO timestamp of resolution, or null.
createdAtstringISO timestamp.
reporterobject | null{ id, email, firstName, lastName }, or null.
accusedobject | null{ id, email, firstName, lastName }, or null.
{
  "items": [
    {
      "id": "66400a8f1c2b4d5e6f7ae000",
      "reporterId": "66400a8f1c2b4d5e6f7a8b01",
      "accusedId": "66400a8f1c2b4d5e6f7a8b02",
      "conversationId": "66400a8f1c2b4d5e6f7a9000",
      "messageId": "66400a8f1c2b4d5e6f7aa000",
      "reason": "HARASSMENT",
      "freeText": "Repeated abusive messages.",
      "transcriptSnapshot": [
        { "senderId": "66400a8f1c2b4d5e6f7a8b02", "text": "…", "sentAt": "2026-05-22T14:35:12.001Z" }
      ],
      "status": "OPEN",
      "resolvedBy": null,
      "resolvedAt": null,
      "createdAt": "2026-05-22T14:40:00.000Z",
      "reporter": { "id": "66400a8f1c2b4d5e6f7a8b01", "email": "jane@example.com", "firstName": "Jane", "lastName": "Doe" },
      "accused": { "id": "66400a8f1c2b4d5e6f7a8b02", "email": "spammer@example.com", "firstName": "Sam", "lastName": "Spam" }
    }
  ],
  "nextCursor": null
}

Error responses

StatusCodeMeaning
400VALIDATION_FAILEDlimit out of 1..100 or status unknown.
401UNAUTHENTICATEDMissing, malformed, expired, or non-admin-scope token.

See also

  • Ban user — the current way to act on an accused user.
  • Report user — the user-facing endpoint that creates these rows.

curl

curl "https://api.swappr.co.uk/api/v1/admin/reports?status=OPEN&limit=50" \
  -H "Authorization: Bearer $ADMIN_ACCESS_TOKEN"

Postman

See docs/postman/swappr.postman_collection.jsonAdmin Reports → List.