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