REST: Social Graph
This page documents the social-graph REST surface in BuddyNext free: following, connections (mutual/two-way relationships), and the block/mute/restrict privacy controls. All routes live under the buddynext/v1 namespace and are registered by FollowController, ConnectionController, and BlockController in includes/SocialGraph/.

Overview / Contract
Section titled “Overview / Contract”- Base namespace:
buddynext/v1. Full base URL:/wp-json/buddynext/v1. - Authentication is cookie + nonce (
X-WP-Nonce) for first-party requests, or any standard WordPress REST auth (Application Passwords, etc.). Routes marked Public use__return_trueand need no auth. Routes marked Auth require a logged-in user (require_auth). - All write routes apply a capability gate in addition to the auth check: follow/unfollow gate on
buddynext-connections/follow, connect/withdraw gate onbuddynext-connections/connect. A user whose role is denied the capability gets a403even when logged in. - Block state is enforced on relationship writes: following or connecting with a user who blocks (or is blocked by) you returns
403 buddynext_blocked. - Targeting a non-existent user id returns
404 buddynext_user_not_found. - List routes take
per_page;/users/{id}/followers,/users/{id}/following, and/me/connectionsare keyset-paginated - passcursorfrom the previous response’snext_cursor- while/me/connection-requestsstill usespage.
See the REST contract page (14-rest-contract) for the shared envelope, pagination headers, error shape, and nonce handling that apply to every route below.
Follow routes
Section titled “Follow routes”Follow is a one-directional relationship. When the target account is private (account type gated), a follow becomes a pending follow-request the target approves or rejects.
| Method | Path | Auth | Purpose |
|---|---|---|---|
| POST | /users/{id}/follow |
Auth (cap follow) |
Follow the user, or create a pending follow-request for a private account. |
| DELETE | /users/{id}/follow |
Auth (cap follow) |
Unfollow the user (or cancel a pending request). |
| GET | /users/{id}/followers |
Public | List the user’s followers (paginated). |
| GET | /users/{id}/following |
Public | List who the user follows (paginated). |
| GET | /users/{id}/follow/status |
Auth | The current user’s follow state with this user (following / pending / none). |
| GET | /users/{id}/account-type |
Auth | The target’s account type (public/private), so the UI can decide follow vs request. |
| GET | /follow-suggestions |
Auth | Suggested accounts to follow for the current user. |
| GET | /me/follow-requests |
Auth | Incoming follow-requests awaiting the current user’s approval. |
| GET | /me/follow-requests/count |
Auth | Count of pending incoming follow-requests (for badges). |
| POST | /me/follow-requests/{follower_id}/approve |
Auth | Approve an incoming follow-request. |
| POST | /me/follow-requests/{follower_id}/reject |
Auth | Reject an incoming follow-request. |
Connection routes
Section titled “Connection routes”A connection is a mutual, two-sided relationship (request, then accept). An optional note (capped at 280 characters, tags stripped) can accompany the request.
| Method | Path | Auth | Purpose |
|---|---|---|---|
| POST | /users/{id}/connect |
Auth (cap connect) |
Send a connection request. Optional note body field. |
| DELETE | /users/{id}/connect |
Auth (cap connect) |
Withdraw a connection request you sent. |
| POST | /users/{id}/connect/accept |
Auth | Accept an incoming connection request from this user. |
| POST | /users/{id}/connect/decline |
Auth | Decline an incoming connection request from this user. |
| GET | /users/{id}/connection/status |
Auth | The current user’s connection status with this user. |
| GET | /users/{id}/mutual-connections |
Auth | User ids connected to both the viewer and this user. |
| GET | /me/connections |
Auth | The current user’s connections (keyset-paginated; cursor, per_page). |
| GET | /me/connection-requests |
Auth | Incoming connection requests awaiting the current user (paginated). |
Note: Connection requests are approved or declined through the per-peer
/users/{id}/connect/acceptand/users/{id}/connect/declineroutes. There are no separate/me/connection-requests/{id}/approve|rejectendpoints; the peer id in the connect path is the actor on the other side of the request.
Block, mute, and restrict routes
Section titled “Block, mute, and restrict routes”These are the per-user privacy controls. Block is mutual-cut (neither party sees the other), mute hides someone’s content from you only, and restrict limits their interaction with you. Each control has a POST (apply) and DELETE (remove) on the same path, plus a list route.
| Method | Path | Auth | Purpose |
|---|---|---|---|
| POST | /users/{id}/block |
Auth | Block the user. |
| DELETE | /users/{id}/block |
Auth | Unblock the user. |
| POST | /users/{id}/mute |
Auth | Mute the user (hide their content from you). |
| DELETE | /users/{id}/mute |
Auth | Unmute the user. |
| POST | /users/{id}/restrict |
Auth | Restrict the user. |
| DELETE | /users/{id}/restrict |
Auth | Remove the restriction. |
| GET | /me/blocked |
Auth | List users the current user has blocked. |
| GET | /me/muted |
Auth | List users the current user has muted. |
| GET | /me/restricted |
Auth | List users the current user has restricted. |
Examples
Section titled “Examples”Follow a user
Section titled “Follow a user”curl -X POST "https://example.com/wp-json/buddynext/v1/users/42/follow" \ -H "X-WP-Nonce: <wp_rest_nonce>" \ --cookie "<auth cookies>"Response when the target is a public account (followed immediately):
{ "following": true, "pending": false}Response when the target is private (a pending follow-request was created):
{ "following": false, "pending": true}A blocked relationship returns:
{ "code": "buddynext_blocked", "message": "You cannot follow this user.", "data": { "status": 403 }}Send a connection request
Section titled “Send a connection request”curl -X POST "https://example.com/wp-json/buddynext/v1/users/42/connect" \ -H "X-WP-Nonce: <wp_rest_nonce>" \ -H "Content-Type: application/json" \ --cookie "<auth cookies>" \ -d '{ "note": "We met at the community meetup - would like to connect." }'Response:
{ "status": "pending"}The recipient then accepts with POST /users/{your_id}/connect/accept or declines with POST /users/{your_id}/connect/decline.
Notes / gotchas
Section titled “Notes / gotchas”- Capability gates are symmetric. Unfollow is gated on the same
followcapability as follow, and withdraw on the sameconnectcapability as connect, so a role denied the action cannot mutate state in either direction. - Block precedence.
is_blocking_either()is checked before any follow or connect write; a block by either party short-circuits the relationship with403 buddynext_blocked. - Public vs Auth listing. Follower/following lists and follow-suggestions reflect public-graph reads;
/users/{id}/followersand/users/{id}/followingare public, while/follow-suggestionsis per-user and requires auth. - Account type drives the UI flow. Read
/users/{id}/account-type(or thependingflag in the follow response) to decide whether to show “Follow” or “Request to follow”. - Pagination. The followers, following, and
/me/connectionsroutes are keyset-paginated: passcursor(from the prior response’snext_cursor) andper_page, and readnext_cursorandtotalfrom the response./me/connection-requestsstill usespage(default 1) andper_page(default 20). Do not assume the full set in one call.

