Abuse Reports
The Abuse Reports queue collects copyright abuse reports submitted by end users against a specific track. Admins triage each report and mark it resolved (the report was valid) or rejected (the report was spurious). Resolving a report also writes a global block for that track; rejecting it removes any block a prior resolution created.
Where to find it
Admin sidebar → Abuse Reports (/abuse-reports).
Quick start
- Open Admin → Abuse Reports.
- Filter by status using the tabs — default is Pending.
- Read the Reason text and follow the Proof link, if provided.
- Click Resolve to accept the report (and block the track globally), or Reject to dismiss it.
- Check the All tab to audit past decisions.
Detailed walkthrough
Status filters
A tab bar at the top toggles between:
- Pending — default; unreviewed reports.
- Resolved — reports an admin accepted and acted on.
- Rejected — reports an admin dismissed as invalid.
- All — everything.
Report rows
Reports render as cards, not table rows. Each card shows:
- Song — Artist — the reported track, as the card headline.
- Reported by — the reporter's display name and email address.
- Reason — free-text field the user submitted.
- Proof — optional URL (YouTube link, screenshot host, etc.). Rendered as a clickable link when present, passed through a URL sanitiser that only allows
http/https. - A status pill (
pending/resolved/rejected). - Submission timestamp.
Resolve and Reject buttons appear only on cards whose status is pending. Resolved and rejected cards are read-only — the resolving admin (resolved_by) and the resolved_at timestamp are stored but not rendered.
Decision actions
Both Resolve and Reject call the same PATCH endpoint with a different status value, then refetch the list so the card moves to the matching tab.
Beyond flipping the status, the backend acts on the verdict:
- Resolve inserts a global block for the reported song / artist / Spotify track ID.
- Reject deletes the block again when the report carries a Spotify track ID, undoing a prior resolution.
Common scenarios
- Copyright false-positive — user reports a song flagged as unsafe that they believe is actually safe; investigate on the Copyright Review page, then resolve the abuse report.
- Coordinated report spam — if multiple users submit near-identical reports against the same track, cross-reference with the song in the Copyright Reports queue before acting.
- Bad-faith report — reject with no action and the row moves to the Rejected tab for later audit.
Permissions
| Action | Permission |
|---|---|
| View reports (all statuses) | support:read |
| Resolve / reject a report | support:edit |
Dashboard entry requires admin:access. System admins (is_system: true) get every admin permission implicitly.
API
| UI action | GraphQL | REST |
|---|---|---|
| List abuse reports (filtered) | — (REST only) | GET /v1/admin/abuse-reports?status={pending|resolved|rejected} (omit status for all) |
| Submit an abuse report (user side) | — (REST only) | POST /v1/abuse-reports |
| Resolve / reject a report | — (REST only) | PATCH /v1/admin/abuse-reports/\{id\} with { status: "resolved" | "rejected" } |
Abuse reports are a REST-only surface today — no GraphQL resolver is exposed.
Tips & gotchas
- There is no "undo" button — once resolved or rejected, the buttons disappear from the card. Flipping a resolved report back to rejected (or the reverse) requires a direct
PATCHagainst the endpoint. - The Proof link is user-supplied and untrusted. Open it in an incognito window, never paste it into an authenticated tab.
- The UI does not surface how many times the reported entity has been reported previously. Cross-reference manually using Copyright Reports.
- The list endpoint pages at 25 items by default (max 100 via
limit); the UI reads only the first page and renders no pagination controls.
Related
- Copyright Reports — user reports against specific tracks
- Copyright Recommendations — user suggestions that a track is safe
- Audit Log — full audit trail including support actions