Social Graph API
The Social Graph API lets you build follower networks, bidirectional friendships, and user moderation (block/ignore) on top of AINative community data.
Base path: https://api.ainative.studio/api/v1/social
Authentication: All endpoints require Authorization: Bearer <your_api_key>
Follow operations
Follow a user
POST /api/v1/social/follow/{user_id}
Follow another user. Their public content will appear in the follower's feed.
Path parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
user_id | string (UUID) | Yes | ID of the user to follow |
Response 201 Created
{
"id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
"follower_id": "550e8400-e29b-41d4-a716-446655440000",
"followed_id": "650e8400-e29b-41d4-a716-446655440001",
"created_at": "2026-04-25T14:00:00Z"
}
Errors
| Code | Reason |
|---|---|
400 | Already following, or cannot follow yourself |
Example
curl -X POST https://api.ainative.studio/api/v1/social/follow/650e8400-e29b-41d4-a716-446655440001 \
-H "Authorization: Bearer $API_KEY"
import requests
resp = requests.post(
"https://api.ainative.studio/api/v1/social/follow/650e8400-e29b-41d4-a716-446655440001",
headers={"Authorization": f"Bearer {api_key}"}
)
print(resp.json())
Unfollow a user
DELETE /api/v1/social/follow/{user_id}
Stop following a user.
Path parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
user_id | string (UUID) | Yes | ID of the user to unfollow |
Response 200 OK
{
"message": "Successfully unfollowed user",
"user_id": "650e8400-e29b-41d4-a716-446655440001"
}
Errors
| Code | Reason |
|---|---|
404 | Not following this user |
Friend request operations
Send a friend request
POST /api/v1/social/friend-request/{user_id}
Send a bidirectional friend request to another user. The recipient must accept before a friendship is created.
Path parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
user_id | string (UUID) | Yes | ID of the recipient |
Request body
{
"message": "Hey, let's connect!"
}
| Field | Type | Required | Description |
|---|---|---|---|
message | string | No | Optional personal message with the request |
Response 201 Created
{
"id": "7a1b2c3d-4e5f-6789-abcd-ef0123456789",
"requester_id": "550e8400-e29b-41d4-a716-446655440000",
"recipient_id": "650e8400-e29b-41d4-a716-446655440001",
"status": "pending",
"message": "Hey, let's connect!",
"created_at": "2026-04-25T14:01:00Z"
}
Errors
| Code | Reason |
|---|---|
400 | Already friends, request already pending, or cannot request yourself |
Example
curl -X POST https://api.ainative.studio/api/v1/social/friend-request/650e8400-e29b-41d4-a716-446655440001 \
-H "Authorization: Bearer $API_KEY" \
-H "Content-Type: application/json" \
-d '{"message": "Hey, lets connect!"}'
resp = requests.post(
"https://api.ainative.studio/api/v1/social/friend-request/650e8400-e29b-41d4-a716-446655440001",
headers={"Authorization": f"Bearer {api_key}"},
json={"message": "Hey, lets connect!"}
)
Accept a friend request
POST /api/v1/social/friend-request/{request_id}/accept
Accept a pending friend request. Creates a bidirectional friendship record.
Path parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
request_id | string (UUID) | Yes | ID of the friend request to accept |
Response 200 OK
{
"id": "9b2c3d4e-5f6a-7890-bcde-f01234567890",
"user1_id": "550e8400-e29b-41d4-a716-446655440000",
"user2_id": "650e8400-e29b-41d4-a716-446655440001",
"created_at": "2026-04-25T14:05:00Z"
}
Errors
| Code | Reason |
|---|---|
400 | Request not in pending state, or you are not the recipient |
Decline a friend request
POST /api/v1/social/friend-request/{request_id}/decline
Decline a pending friend request. The requester can send a new request later.
Path parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
request_id | string (UUID) | Yes | ID of the friend request to decline |
Response 200 OK
{
"id": "7a1b2c3d-4e5f-6789-abcd-ef0123456789",
"requester_id": "550e8400-e29b-41d4-a716-446655440000",
"recipient_id": "650e8400-e29b-41d4-a716-446655440001",
"status": "declined",
"message": "Hey, lets connect!",
"created_at": "2026-04-25T14:01:00Z"
}
Cancel a friend request
DELETE /api/v1/social/friend-request/{request_id}
Cancel a friend request you sent (before it is accepted or declined).
Path parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
request_id | string (UUID) | Yes | ID of the friend request to cancel |
Response 200 OK
{
"message": "Friend request canceled"
}
Block operations
Block a user
POST /api/v1/social/block/{user_id}
Block a user to prevent all interactions between you. Existing follow/friend relationships are severed.
Path parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
user_id | string (UUID) | Yes | ID of the user to block |
Request body
{
"reason": "Spam"
}
| Field | Type | Required | Description |
|---|---|---|---|
reason | string | No | Optional reason for blocking |
Response 201 Created
{
"id": "aa1bb2cc-3dd4-5ee6-ff77-889900aabbcc",
"blocker_id": "550e8400-e29b-41d4-a716-446655440000",
"blocked_id": "650e8400-e29b-41d4-a716-446655440001",
"reason": "Spam",
"created_at": "2026-04-25T14:10:00Z"
}
Errors
| Code | Reason |
|---|---|
400 | User is already blocked, or cannot block yourself |
Unblock a user
DELETE /api/v1/social/block/{user_id}
Remove a block. The unblocked user can interact again.
Path parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
user_id | string (UUID) | Yes | ID of the user to unblock |
Response 200 OK
{
"message": "Successfully unblocked user",
"user_id": "650e8400-e29b-41d4-a716-446655440001"
}
Errors
| Code | Reason |
|---|---|
404 | User is not blocked |
Ignore operations
Ignoring a user hides their content from your feed without notifying them, unlike blocking which prevents all interaction.
Ignore a user
POST /api/v1/social/ignore/{user_id}
Ignore a user to hide their content from your feed.
Path parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
user_id | string (UUID) | Yes | ID of the user to ignore |
Response 201 Created
{
"id": "bb2cc3dd-4ee5-6ff7-aa88-99bb00ccddee",
"ignorer_id": "550e8400-e29b-41d4-a716-446655440000",
"ignored_id": "650e8400-e29b-41d4-a716-446655440001",
"created_at": "2026-04-25T14:12:00Z"
}
Unignore a user
DELETE /api/v1/social/ignore/{user_id}
Stop ignoring a user — their content will reappear in your feed.
Path parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
user_id | string (UUID) | Yes | ID of the user to unignore |
Response 200 OK
{
"message": "Successfully unignored user",
"user_id": "650e8400-e29b-41d4-a716-446655440001"
}
Errors
| Code | Reason |
|---|---|
404 | User is not ignored |
List operations
Get followers
GET /api/v1/social/{user_id}/followers
Get the list of users following a given user.
Path parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
user_id | string (UUID) | Yes | User whose followers to retrieve |
Query parameters
| Parameter | Type | Default | Description |
|---|---|---|---|
offset | integer | 0 | Number of items to skip |
limit | integer | 20 | Items to return (1–100) |
Response 200 OK
{
"followers": [
{
"id": "650e8400-e29b-41d4-a716-446655440001",
"email": "alice@example.com",
"full_name": "Alice Chen",
"avatar_url": "https://cdn.ainative.studio/avatars/alice.jpg"
}
],
"total": 142,
"offset": 0,
"limit": 20
}
Example
curl "https://api.ainative.studio/api/v1/social/550e8400-e29b-41d4-a716-446655440000/followers?limit=20&offset=0" \
-H "Authorization: Bearer $API_KEY"
resp = requests.get(
"https://api.ainative.studio/api/v1/social/550e8400-e29b-41d4-a716-446655440000/followers",
headers={"Authorization": f"Bearer {api_key}"},
params={"limit": 20, "offset": 0}
)
data = resp.json()
print(f"{data['total']} total followers")
Get following
GET /api/v1/social/{user_id}/following
Get the list of users that a given user is following.
Path parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
user_id | string (UUID) | Yes | User whose following list to retrieve |
Query parameters
| Parameter | Type | Default | Description |
|---|---|---|---|
offset | integer | 0 | Number of items to skip |
limit | integer | 20 | Items to return (1–100) |
Response 200 OK
{
"following": [
{
"id": "750e8400-e29b-41d4-a716-446655440002",
"email": "bob@example.com",
"full_name": "Bob Martinez",
"avatar_url": null
}
],
"total": 55,
"offset": 0,
"limit": 20
}
Get friends
GET /api/v1/social/{user_id}/friends
Get the list of confirmed (bidirectional) friends for a user.
Path parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
user_id | string (UUID) | Yes | User whose friend list to retrieve |
Query parameters
| Parameter | Type | Default | Description |
|---|---|---|---|
offset | integer | 0 | Number of items to skip |
limit | integer | 20 | Items to return (1–100) |
Response 200 OK
{
"friends": [
{
"id": "650e8400-e29b-41d4-a716-446655440001",
"email": "alice@example.com",
"full_name": "Alice Chen",
"avatar_url": "https://cdn.ainative.studio/avatars/alice.jpg"
}
],
"total": 12,
"offset": 0,
"limit": 20
}
Get pending friend requests
GET /api/v1/social/me/friend-requests
Get incoming friend requests pending your response.
Query parameters
| Parameter | Type | Default | Description |
|---|---|---|---|
offset | integer | 0 | Number of items to skip |
limit | integer | 20 | Items to return (1–100) |
Response 200 OK
{
"requests": [
{
"id": "7a1b2c3d-4e5f-6789-abcd-ef0123456789",
"sender_id": "750e8400-e29b-41d4-a716-446655440002",
"receiver_id": "550e8400-e29b-41d4-a716-446655440000",
"status": "pending",
"message": "Hey, lets connect!",
"created_at": "2026-04-25T14:01:00Z",
"responded_at": null
}
],
"total": 3,
"offset": 0,
"limit": 20
}
Get social stats
GET /api/v1/social/me/stats
Get aggregated social statistics for the authenticated user.
Response 200 OK
{
"follower_count": 142,
"following_count": 55,
"friend_count": 12,
"pending_requests_count": 3
}
Example
curl https://api.ainative.studio/api/v1/social/me/stats \
-H "Authorization: Bearer $API_KEY"
resp = requests.get(
"https://api.ainative.studio/api/v1/social/me/stats",
headers={"Authorization": f"Bearer {api_key}"}
)
stats = resp.json()
print(f"You have {stats['follower_count']} followers")
Community search
GET /api/v1/community/search/
Search across users, posts, groups, and events in a single request.
Query parameters
| Parameter | Type | Default | Required | Description |
|---|---|---|---|---|
q | string | — | Yes | Search query (2–200 characters) |
search_type | string | "all" | No | users, posts, groups, events, or all |
tenant_id | string (UUID) | — | No | Restrict results to a specific tenant |
offset | integer | 0 | No | Pagination offset |
limit | integer | 20 | No | Results per page (1–100) |
Response 200 OK
{
"query": "machine learning",
"search_type": "all",
"users": {
"items": [
{
"id": "550e8400-e29b-41d4-a716-446655440000",
"username": "mlresearcher",
"full_name": "Jane Doe",
"bio": "ML engineer at AINative",
"avatar_url": null
}
],
"total": 5,
"offset": 0,
"limit": 20
},
"posts": { "items": [], "total": 0, "offset": 0, "limit": 20 },
"groups": { "items": [], "total": 0, "offset": 0, "limit": 20 },
"events": {
"items": [
{
"id": "abc12345-0000-0000-0000-000000000001",
"title": "ML Workshop 2026",
"description": "Hands-on machine learning workshop",
"start_time": "2026-05-15T09:00:00Z",
"location": "San Francisco"
}
],
"total": 1,
"offset": 0,
"limit": 20
}
}
You can also search individual content types with dedicated endpoints:
| Endpoint | Description |
|---|---|
GET /api/v1/community/search/users?q=... | Search users only |
GET /api/v1/community/search/posts?q=... | Search posts only |
GET /api/v1/community/search/groups?q=... | Search groups only |
GET /api/v1/community/search/events?q=... | Search events only |
All dedicated endpoints accept the same q, tenant_id, offset, and limit parameters.
Search behavior
- Results respect tenant scoping — users see only content within their tenant unless
tenant_idis overridden - Blocked and ignored users are excluded from results
- Post body previews are truncated to 200 characters
- Minimum query length: 2 characters