Block or mute other users, list who you've blocked or muted, and report users or messages for review.
Unlike the export, GitHub, and LinkedIn integration endpoints, every endpoint on this page accepts either a session cookie or a Bearer token: they all authenticate via getCurrentUserOrSyncToken. Native, mobile, and CLI clients that authenticate with Authorization: Bearer <token> can implement the full moderation feature set.
Path parameter note. The block, mute, and user-report routes live under
/api/users/{username}/…, but the value in that segment is the target user's ID (a UUID), not their handle.
| Method | Path | Auth | Description |
|---|---|---|---|
| GET | /api/user/blocks | Session or Bearer | List users you've blocked. Supports limit, offset. |
| GET | /api/user/mutes | Session or Bearer | List users you've muted. Supports limit, offset. |
| GET | /api/users/{username}/block | Session or Bearer | Whether you currently block this user. |
| POST | /api/users/{username}/block | Session or Bearer | Block a user (idempotent). |
| DELETE | /api/users/{username}/block | Session or Bearer | Unblock a user (idempotent). |
| GET | /api/users/{username}/mute | Session or Bearer | Whether you currently mute this user. |
| POST | /api/users/{username}/mute | Session or Bearer | Mute a user (idempotent). |
| DELETE | /api/users/{username}/mute | Session or Bearer | Unmute a user (idempotent). |
| POST | /api/users/{username}/report | Session or Bearer | Report a user. |
| POST | /api/messages/{id}/report | Session or Bearer | Report a message. |
The reason field on both report endpoints must be one of:
spam · harassment · misinformation · inappropriate · other
Any other value returns 400.
GET /api/user/blocks?limit=20&offset=0
Response (200):
{
"blockedUsers": [
{ "id": "clx9user00002", "username": "someone", "displayName": "Some One", "avatar": null }
],
"pagination": { "total": 1, "limit": 20, "offset": 0, "hasMore": false }
}
limit defaults to 20 (max 100); offset defaults to 0.
GET /api/user/mutes?limit=20&offset=0
Response (200):
{
"mutedUsers": [
{ "id": "clx9user00003", "username": "another", "displayName": "An Other", "avatar": null }
],
"pagination": { "total": 1, "limit": 20, "offset": 0, "hasMore": false }
}
GET /api/users/clx9user00002/block
Response (200): { "blocked": true }
GET /api/users/clx9user00003/mute
Response (200): { "muted": true }
Both are directional: they report only whether you block or mute the target, not whether the target blocks or mutes you. They return 401 when unauthenticated. Use them to render the correct Block/Unblock and Mute/Unmute toggle state.
POST /api/users/clx9user00002/block
Response (200): { "blocked": true }
Blocking is mutual: you and the blocked user become invisible to each other (feeds, search, single messages, threads, and permalinks), neither can follow/dig/reply-to/push the other, and any existing follow in either direction is removed. Unblocking (DELETE) does not restore a removed follow.
DELETE /api/users/clx9user00002/block
Response (200): { "blocked": false }
Blocking is idempotent: blocking an already-blocked user still returns { "blocked": true }, and unblocking someone you haven't blocked still returns { "blocked": false }.
Errors:
| Status | Condition |
|---|---|
| 400 | cannot_block_self: you passed your own user ID. |
| 401 | Not authenticated. |
| 404 | Target user not found. |
POST /api/users/clx9user00003/mute
Response (200): { "muted": true }
DELETE /api/users/clx9user00003/mute
Response (200): { "muted": false }
Muting is idempotent. On DELETE an existing mute is removed and the call succeeds silently if none exists.
Errors:
| Status | Condition |
|---|---|
| 400 | You passed your own user ID (cannot mute yourself). |
| 401 | Not authenticated. |
| 404 | Target user not found. |
POST /api/users/clx9user00002/report
Content-Type: application/json
{ "reason": "harassment", "detail": "Optional free-text context." }
Response (200): { "reported": true }
detail is optional. Reports are idempotent per reporter/target pair: reporting the same user again updates the existing report rather than creating a duplicate.
Errors:
| Status | Condition |
|---|---|
| 400 | reason missing or not one of the valid report reasons. |
| 400 | You passed your own user ID (cannot report yourself). |
| 401 | Not authenticated. |
| 404 | Target user not found. |
POST /api/messages/clx9msg000001/report
Content-Type: application/json
{ "reason": "spam", "detail": "Optional free-text context." }
Response (200): { "reported": true }
detail is optional. Reports are idempotent per reporter/message pair.
Errors:
| Status | Condition |
|---|---|
| 400 | reason missing or not one of the valid report reasons. |
| 400 | You are reporting your own message. |
| 401 | Not authenticated. |
| 404 | Message not found. |