JendZ Posts & Comments System - Complete API Documentation¶
Overview¶
The JendZ Posts system provides a comprehensive content platform supporting 7 post types, secure location handling, hybrid feed architecture, and a fully separated comments system with unlimited nesting support.
Authentication¶
All authenticated endpoints require a Bearer token in the Authorization header:
Enhanced Post Types¶
JendZ supports 7 different post types:
| Post Type | Description | Location Handling |
|---|---|---|
text |
Basic text post | Auto-assigned to user's location |
image |
Text with media files | Auto-assigned to user's location |
product_share |
Share a marketplace product | Auto-assigned to user's location |
store_share |
Share a marketplace store | Auto-assigned to user's location |
community_share |
Share a community | Auto-assigned to user's location |
poll |
Interactive poll with options | Auto-assigned to user's location |
audio |
Voice note/audio post | Auto-assigned to user's location |
Post Management API¶
Create Post¶
Endpoint: POST /api/feed/posts/
Authentication: Required
Content-Type: multipart/form-data (for media uploads) or application/json
Create Text Post (Neighbourhood)¶
Request:
POST /api/feed/posts/
Content-Type: application/json
Authorization: Bearer <token>
{
"post_type": "text",
"content": "Hello neighbourhood! Beautiful day today.",
"title": "Good Morning" // optional
}
Response:
{
"id": "550e8400-e29b-41d4-a716-446655440000",
"user": {
"username": "john_doe",
"display_name": "John Doe",
"profile_picture": "https://media.jendz.xyz/profiles/john.jpg"
},
"post_type": "text",
"title": "Good Morning",
"content": "Hello neighbourhood! Beautiful day today.",
"media": [],
"location": "550e8400-e29b-41d4-a716-446655440001",
"location_name": "Downtown Lagos",
"community": null,
"community_name": null,
"has_liked": false,
"has_bookmarked": false,
"likes_count": 0,
"comments_count": 0,
"views_count": 0,
"created_at": "2024-01-15T10:30:00Z",
"updated_at": "2024-01-15T10:30:00Z"
}
Create Community Post¶
Request:
{
"post_type": "text",
"content": "Excited about our upcoming community event!",
"community_id": "550e8400-e29b-41d4-a716-446655440002"
}
Response:
{
"id": "550e8400-e29b-41d4-a716-446655440003",
"user": {
"username": "community_member",
"display_name": "Community Member",
"profile_picture": "https://media.jendz.xyz/profiles/member.jpg"
},
"post_type": "text",
"title": null,
"content": "Excited about our upcoming community event!",
"media": [],
"location": null,
"location_name": null,
"community": "550e8400-e29b-41d4-a716-446655440002",
"community_name": "Tech Enthusiasts Lagos",
"has_liked": false,
"has_bookmarked": false,
"likes_count": 0,
"comments_count": 0,
"views_count": 0,
"created_at": "2024-01-15T10:35:00Z",
"updated_at": "2024-01-15T10:35:00Z"
}
Create Product Share¶
Request:
{
"post_type": "product_share",
"content": "Just found this amazing product! Perfect for our neighbourhood.",
"shared_product_id": "550e8400-e29b-41d4-a716-446655440004"
}
Response:
{
"id": "550e8400-e29b-41d4-a716-446655440005",
"user": {
"username": "product_sharer",
"display_name": "Product Sharer",
"profile_picture": "https://media.jendz.xyz/profiles/sharer.jpg"
},
"post_type": "product_share",
"content": "Just found this amazing product! Perfect for our neighbourhood.",
"shared_product": {
"id": "550e8400-e29b-41d4-a716-446655440004",
"name": "Organic Honey 500ml",
"price": "2500.00",
"images": [
{
"id": "550e8400-e29b-41d4-a716-446655440006",
"url": "https://media.jendz.xyz/products/honey.jpg"
}
],
"store": {
"id": "550e8400-e29b-41d4-a716-446655440007",
"name": "Natural Foods Lagos"
}
},
"location": "550e8400-e29b-41d4-a716-446655440001",
"location_name": "Downtown Lagos",
"community": null,
"community_name": null,
"likes_count": 0,
"comments_count": 0,
"views_count": 0,
"created_at": "2024-01-15T11:00:00Z"
}
Create Poll¶
Request:
{
"post_type": "poll",
"content": "Community input needed for the new park development!",
"poll_question": "What should be the main feature of our new community park?",
"poll_options": [
"Children's playground",
"Sports field",
"Garden area",
"Community center"
],
"poll_allows_multiple": false,
"poll_expires_at": "2024-01-22T10:30:00Z"
}
Response:
{
"id": "550e8400-e29b-41d4-a716-446655440008",
"user": {
"username": "community_leader",
"display_name": "Community Leader",
"profile_picture": "https://media.jendz.xyz/profiles/leader.jpg"
},
"post_type": "poll",
"content": "Community input needed for the new park development!",
"poll_data": {
"id": "550e8400-e29b-41d4-a716-446655440009",
"question": "What should be the main feature of our new community park?",
"allows_multiple_choices": false,
"expires_at": "2024-01-22T10:30:00Z",
"total_votes": 0,
"user_voted": false,
"is_expired": false,
"options": [
{
"id": "550e8400-e29b-41d4-a716-446655440010",
"option_text": "Children's playground",
"votes_count": 0,
"order": 0,
"user_voted": false,
"percentage": 0
},
{
"id": "550e8400-e29b-41d4-a716-446655440011",
"option_text": "Sports field",
"votes_count": 0,
"order": 1,
"user_voted": false,
"percentage": 0
}
]
},
"location": "550e8400-e29b-41d4-a716-446655440001",
"location_name": "Downtown Lagos",
"likes_count": 0,
"comments_count": 0,
"views_count": 0,
"created_at": "2024-01-15T12:00:00Z"
}
Create Audio Post¶
Request:
POST /api/feed/posts/
Content-Type: multipart/form-data
Authorization: Bearer <token>
post_type=audio
content=My thoughts on today's community meeting
audio_file=<audio_file_binary_data>
Response:
{
"id": "550e8400-e29b-41d4-a716-446655440012",
"user": {
"username": "audio_poster",
"display_name": "Audio Poster",
"profile_picture": "https://media.jendz.xyz/profiles/audio.jpg"
},
"post_type": "audio",
"content": "My thoughts on today's community meeting",
"audio_data": {
"id": "550e8400-e29b-41d4-a716-446655440013",
"audio_file": "https://media.jendz.xyz/posts/audio/meeting_thoughts.mp3",
"duration_seconds": 125,
"transcription": null,
"waveform_data": null
},
"location": "550e8400-e29b-41d4-a716-446655440001",
"location_name": "Downtown Lagos",
"likes_count": 0,
"comments_count": 0,
"views_count": 0,
"created_at": "2024-01-15T14:00:00Z"
}
Error Responses¶
Location Not Set (400 Bad Request):
{
"error": "Location Required",
"message": "Please set your location in profile settings before creating neighbourhood posts.",
"action": "update_location"
}
Community Membership Required (400 Bad Request):
{
"error": "Community Membership Required",
"message": "You must join this community before you can post in it.",
"action": "join_community",
"community_id": "550e8400-e29b-41d4-a716-446655440002"
}
Validation Errors (400 Bad Request):
{
"shared_product_id": ["This field is required for product share posts."],
"poll_options": ["At least 2 poll options are required."]
}
Get Single Post¶
Endpoint: GET /api/feed/posts/{post_id}/
Authentication: Optional
Response:
{
"id": "550e8400-e29b-41d4-a716-446655440000",
"user": {
"username": "john_doe",
"display_name": "John Doe",
"profile_picture": "https://media.jendz.xyz/profiles/john.jpg"
},
"post_type": "text",
"title": "Good Morning",
"content": "Hello neighbourhood! Beautiful day today.",
"media": [],
"location": "550e8400-e29b-41d4-a716-446655440001",
"location_name": "Downtown Lagos",
"community": null,
"community_name": null,
"has_liked": false,
"has_bookmarked": true,
"likes_count": 15,
"comments_count": 8,
"views_count": 142,
"created_at": "2024-01-15T10:30:00Z",
"updated_at": "2024-01-15T10:30:00Z"
}
Post Interactions¶
Like/Unlike Post¶
Endpoint: POST /api/feed/posts/{post_id}/like/
Authentication: Required
Request: Empty body
Response (Like Added):
Response (Like Removed):
Bookmark/Unbookmark Post¶
Endpoint: POST /api/feed/posts/{post_id}/bookmark/
Authentication: Required
Response (Bookmark Added):
Response (Bookmark Removed):
Track Post View¶
Endpoint: POST /api/feed/posts/{post_id}/track_view/
Authentication: Optional
Request (Optional):
Response (View Recorded):
Response (Cooldown Active):
Vote on Poll¶
Endpoint: POST /api/feed/posts/{post_id}/vote_poll/
Authentication: Required
Request (Single Choice):
Request (Multiple Choice):
{
"option_ids": [
"550e8400-e29b-41d4-a716-446655440010",
"550e8400-e29b-41d4-a716-446655440011"
]
}
Response:
Error Responses:
Hybrid Feed API¶
Neighbourhood Feed¶
Endpoint: GET /api/feed/hybrid/neighbourhood/
Authentication: Required
Query Parameters:
page(integer): Page number (default: 1)page_size(integer): Items per page (default: 15, max: 50)
Response:
{
"items": [
{
"id": "550e8400-e29b-41d4-a716-446655440000",
"user": {
"username": "local_user",
"display_name": "Local User",
"profile_picture": "https://media.jendz.xyz/profiles/local.jpg"
},
"post_type": "text",
"content": "New coffee shop just opened on Main Street!",
"location": "550e8400-e29b-41d4-a716-446655440001",
"location_name": "Downtown Lagos",
"community": null,
"likes_count": 5,
"comments_count": 2,
"views_count": 28,
"created_at": "2024-01-15T09:00:00Z"
}
],
"has_more": true,
"feed_type": "neighbourhood",
"location_info": {
"name": "Downtown Lagos",
"location_id": "550e8400-e29b-41d4-a716-446655440001"
},
"enhancement_endpoints": [
"/api/feed/enhancements/users/?location_id=550e8400-e29b-41d4-a716-446655440001",
"/api/feed/enhancements/stores/?location_id=550e8400-e29b-41d4-a716-446655440001",
"/api/feed/enhancements/communities/?location_id=550e8400-e29b-41d4-a716-446655440001"
]
}
General Feed¶
Endpoint: GET /api/feed/hybrid/general/
Authentication: Required
Response:
{
"items": [
{
"id": "550e8400-e29b-41d4-a716-446655440020",
"user": {
"username": "global_user",
"display_name": "Global User",
"profile_picture": "https://media.jendz.xyz/profiles/global.jpg"
},
"post_type": "product_share",
"content": "Amazing local artisan crafts!",
"shared_product": {
"id": "550e8400-e29b-41d4-a716-446655440021",
"name": "Handwoven Basket",
"price": "3500.00"
},
"location": "550e8400-e29b-41d4-a716-446655440022",
"location_name": "Victoria Island",
"likes_count": 12,
"comments_count": 4,
"views_count": 89,
"created_at": "2024-01-15T08:30:00Z"
}
],
"has_more": true,
"feed_type": "general",
"enhancement_endpoints": [
"/api/feed/enhancements/users/",
"/api/feed/enhancements/stores/",
"/api/feed/enhancements/communities/"
]
}
Location-Specific Feed¶
Endpoint: GET /api/feed/hybrid/location/{location_id}/
Authentication: Required
Response:
{
"items": [
{
"id": "550e8400-e29b-41d4-a716-446655440030",
"user": {
"username": "visitor",
"display_name": "Visitor User",
"profile_picture": "https://media.jendz.xyz/profiles/visitor.jpg"
},
"post_type": "poll",
"content": "What's the best restaurant in this area?",
"poll_data": {
"question": "What's the best restaurant in this area?",
"total_votes": 25,
"user_voted": false,
"options": [
{
"option_text": "Lagos Kitchen",
"votes_count": 15,
"percentage": 60.0
}
]
},
"location": "550e8400-e29b-41d4-a716-446655440031",
"location_name": "Ikeja",
"created_at": "2024-01-15T07:15:00Z"
}
],
"has_more": false,
"feed_type": "location_specific",
"can_post": false,
"location_info": {
"name": "Ikeja",
"location_id": "550e8400-e29b-41d4-a716-446655440031"
},
"enhancement_endpoints": [
"/api/feed/enhancements/users/?location_id=550e8400-e29b-41d4-a716-446655440031",
"/api/feed/enhancements/stores/?location_id=550e8400-e29b-41d4-a716-446655440031",
"/api/feed/enhancements/communities/?location_id=550e8400-e29b-41d4-a716-446655440031"
]
}
Feed Enhancement Endpoints¶
Nearby Users¶
Endpoint: GET /api/feed/enhancements/users/
Authentication: Required
Query Parameters:
location_id(UUID, optional): Filter by specific location
Response:
{
"type": "users",
"items": [
{
"id": "550e8400-e29b-41d4-a716-446655440040",
"username": "nearby_user1",
"display_name": "Nearby User One",
"profile_picture": "https://media.jendz.xyz/profiles/nearby1.jpg",
"bio": "Local photographer and coffee enthusiast"
},
{
"id": "550e8400-e29b-41d4-a716-446655440041",
"username": "nearby_user2",
"display_name": "Nearby User Two",
"profile_picture": "https://media.jendz.xyz/profiles/nearby2.jpg",
"bio": "Community organizer"
}
],
"inject_at_positions": [5, 15, 25],
"title": "People nearby"
}
Trending Stores¶
Endpoint: GET /api/feed/enhancements/stores/
Authentication: Required
Query Parameters:
location_id(UUID, optional): Filter by specific location
Response:
{
"type": "stores",
"items": [
{
"id": "550e8400-e29b-41d4-a716-446655440050",
"name": "Fresh Market Lagos",
"description": "Organic fruits and vegetables from local farms",
"logo": "https://media.jendz.xyz/stores/fresh_market_logo.jpg",
"location_name": "Downtown Lagos",
"owner": {
"username": "market_owner",
"display_name": "Market Owner"
}
}
],
"inject_at_positions": [8, 20],
"title": "Trending stores"
}
Suggested Communities¶
Endpoint: GET /api/feed/enhancements/communities/
Authentication: Required
Query Parameters:
location_id(UUID, optional): Filter by specific location
Response:
{
"type": "communities",
"items": [
{
"id": "550e8400-e29b-41d4-a716-446655440060",
"name": "Lagos Fitness Group",
"description": "Weekly workouts and healthy living discussions",
"avatar": "https://media.jendz.xyz/communities/fitness_avatar.jpg",
"members_count": 156,
"posts_count": 42,
"category": {
"id": "550e8400-e29b-41d4-a716-446655440061",
"name": "Health & Fitness"
}
}
],
"inject_at_positions": [12, 24],
"title": "Suggested communities"
}
Comments API¶
Get Comments for Post¶
Endpoint: GET /api/posts/posts/{post_id}/comments/
Authentication: Optional
Query Parameters:
page(integer): Page number (default: 1)page_size(integer): Items per page (default: 20, max: 100)
Response:
{
"count": 45,
"next": "http://api.example.com/api/posts/posts/550e8400-e29b-41d4-a716-446655440000/comments/?page=2",
"previous": null,
"results": [
{
"id": "550e8400-e29b-41d4-a716-446655440070",
"user": {
"username": "commenter1",
"display_name": "First Commenter",
"profile_picture": "https://media.jendz.xyz/profiles/commenter1.jpg"
},
"post": "550e8400-e29b-41d4-a716-446655440000",
"content": "Great neighbourhood post! Thanks for sharing.",
"parent": null,
"replies_count": 3,
"likes_count": 5,
"bookmarks_count": 1,
"views_count": 25,
"has_liked": false,
"has_bookmarked": false,
"created_at": "2024-01-15T11:00:00Z",
"updated_at": "2024-01-15T11:00:00Z"
},
{
"id": "550e8400-e29b-41d4-a716-446655440071",
"user": {
"username": "commenter2",
"display_name": "Second Commenter",
"profile_picture": "https://media.jendz.xyz/profiles/commenter2.jpg"
},
"post": "550e8400-e29b-41d4-a716-446655440000",
"content": "I totally agree! The community spirit is amazing here.",
"parent": null,
"replies_count": 0,
"likes_count": 2,
"bookmarks_count": 0,
"views_count": 18,
"has_liked": true,
"has_bookmarked": false,
"created_at": "2024-01-15T11:15:00Z",
"updated_at": "2024-01-15T11:15:00Z"
}
]
}
Get Replies to Comment¶
Endpoint: GET /api/posts/comments/replies/
Authentication: Optional
Query Parameters:
parent_id(UUID, required): ID of parent commentpage(integer): Page number (default: 1)page_size(integer): Items per page (default: 20, max: 100)
Response:
{
"count": 8,
"next": null,
"previous": null,
"results": [
{
"id": "550e8400-e29b-41d4-a716-446655440080",
"user": {
"username": "replier1",
"display_name": "Reply User One",
"profile_picture": "https://media.jendz.xyz/profiles/replier1.jpg"
},
"post": "550e8400-e29b-41d4-a716-446655440000",
"content": "I completely agree with your comment!",
"parent": "550e8400-e29b-41d4-a716-446655440070",
"replies_count": 1,
"likes_count": 2,
"bookmarks_count": 0,
"views_count": 12,
"has_liked": true,
"has_bookmarked": false,
"created_at": "2024-01-15T11:30:00Z",
"updated_at": "2024-01-15T11:30:00Z"
},
{
"id": "550e8400-e29b-41d4-a716-446655440081",
"user": {
"username": "replier2",
"display_name": "Reply User Two",
"profile_picture": "https://media.jendz.xyz/profiles/replier2.jpg"
},
"post": "550e8400-e29b-41d4-a716-446655440000",
"content": "Thanks for the positive feedback!",
"parent": "550e8400-e29b-41d4-a716-446655440070",
"replies_count": 0,
"likes_count": 1,
"bookmarks_count": 0,
"views_count": 8,
"has_liked": false,
"has_bookmarked": false,
"created_at": "2024-01-15T11:45:00Z",
"updated_at": "2024-01-15T11:45:00Z"
}
]
}
Create Comment or Reply¶
Endpoint: POST /api/posts/comments/
Authentication: Required
Create Top-Level Comment¶
Request:
{
"post": "550e8400-e29b-41d4-a716-446655440000",
"content": "This is a great neighbourhood post!",
"parent": null
}
Create Reply to Comment¶
Request:
{
"post": "550e8400-e29b-41d4-a716-446655440000",
"content": "I totally agree with your comment!",
"parent": "550e8400-e29b-41d4-a716-446655440070"
}
Response:
{
"id": "550e8400-e29b-41d4-a716-446655440090",
"user": {
"username": "current_user",
"display_name": "Current User",
"profile_picture": "https://media.jendz.xyz/profiles/current.jpg"
},
"post": "550e8400-e29b-41d4-a716-446655440000",
"content": "This is a great neighbourhood post!",
"parent": null,
"replies_count": 0,
"likes_count": 0,
"bookmarks_count": 0,
"views_count": 0,
"has_liked": false,
"has_bookmarked": false,
"created_at": "2024-01-15T12:00:00Z",
"updated_at": "2024-01-15T12:00:00Z"
}
Validation Error (400 Bad Request):
Like/Unlike Comment¶
Endpoint: POST /api/posts/comments/{comment_id}/like/
Authentication: Required
Request: Empty body
Response (Like Added):
Response (Like Removed):
Bookmark/Unbookmark Comment¶
Endpoint: POST /api/posts/comments/{comment_id}/bookmark/
Authentication: Required
Response (Bookmark Added):
Response (Bookmark Removed):
User Collections¶
Get Liked Posts¶
Endpoint: GET /api/feed/posts/liked/
Authentication: Required
Response:
{
"count": 23,
"next": "http://api.example.com/api/feed/posts/liked/?page=2",
"previous": null,
"results": [
{
"id": "550e8400-e29b-41d4-a716-446655440100",
"user": {
"username": "liked_author",
"display_name": "Liked Author",
"profile_picture": "https://media.jendz.xyz/profiles/liked.jpg"
},
"post_type": "text",
"content": "Amazing sunset today!",
"location_name": "Victoria Island",
"has_liked": true,
"likes_count": 45,
"comments_count": 12,
"created_at": "2024-01-14T18:30:00Z"
}
]
}
Get Bookmarked Posts¶
Endpoint: GET /api/feed/posts/bookmarked/
Authentication: Required
Response:
{
"count": 15,
"next": null,
"previous": null,
"results": [
{
"id": "550e8400-e29b-41d4-a716-446655440110",
"user": {
"username": "bookmarked_author",
"display_name": "Bookmarked Author",
"profile_picture": "https://media.jendz.xyz/profiles/bookmarked.jpg"
},
"post_type": "product_share",
"content": "Perfect for home organization!",
"shared_product": {
"id": "550e8400-e29b-41d4-a716-446655440111",
"name": "Storage Containers Set",
"price": "4500.00"
},
"has_bookmarked": true,
"likes_count": 28,
"comments_count": 6,
"created_at": "2024-01-13T15:20:00Z"
}
]
}
Analytics & Discovery¶
Popular Locations¶
Endpoint: GET /api/feed/posts/popular_locations/
Authentication: Optional
Response:
{
"count": 20,
"locations": [
{
"id": "550e8400-e29b-41d4-a716-446655440120",
"name": "Downtown Lagos",
"post_count": 245,
"country": "Nigeria",
"state": "Lagos State",
"city": "Lagos",
"neighbourhood": "Downtown Lagos"
},
{
"id": "550e8400-e29b-41d4-a716-446655440121",
"name": "Victoria Island",
"post_count": 189,
"country": "Nigeria",
"state": "Lagos State",
"city": "Lagos",
"neighbourhood": "Victoria Island"
},
{
"id": "550e8400-e29b-41d4-a716-446655440122",
"name": "Ikeja",
"post_count": 156,
"country": "Nigeria",
"state": "Lagos State",
"city": "Lagos",
"neighbourhood": "Ikeja"
}
]
}
User Analytics¶
Endpoint: GET /api/feed/posts/user_analytics/
Authentication: Required
Response:
{
"total_views": 1250,
"unique_posts_viewed": 892,
"repeat_view_ratio": 0.286,
"popular_locations": [
{
"post__location__name": "Downtown Lagos",
"view_count": 145
},
{
"post__location__name": "Victoria Island",
"view_count": 89
},
{
"post__location__name": "Ikeja",
"view_count": 67
}
],
"avg_views_per_day": 12.5
}
Error Handling¶
HTTP Status Codes¶
200 OK- Successful request201 Created- Resource created successfully400 Bad Request- Validation errors or malformed request401 Unauthorized- Authentication required or invalid token403 Forbidden- Permission denied404 Not Found- Resource not found429 Too Many Requests- Rate limit exceeded500 Internal Server Error- Server error
Common Error Response Format¶
{
"detail": "Error message describing what went wrong",
"field_errors": {
"field_name": ["Specific validation error for this field"]
}
}
Authentication Errors¶
401 Unauthorized:
403 Forbidden:
Validation Errors¶
400 Bad Request:
{
"content": ["This field is required."],
"poll_options": ["At least 2 poll options are required."],
"shared_product_id": ["Invalid UUID format."]
}
Rate Limiting¶
429 Too Many Requests:
Implementation Examples¶
cURL Examples¶
Create Text Post¶
curl -X POST "https://api.jendz.xyz/api/feed/posts/" \
-H "Authorization: Bearer your_access_token" \
-H "Content-Type: application/json" \
-d '{
"post_type": "text",
"content": "Hello neighbourhood!",
"title": "Good morning"
}'
Create Poll¶
curl -X POST "https://api.jendz.xyz/api/feed/posts/" \
-H "Authorization: Bearer your_access_token" \
-H "Content-Type: application/json" \
-d '{
"post_type": "poll",
"poll_question": "What should we do about the park?",
"poll_options": ["Add playground", "More trees", "Sports area"],
"poll_allows_multiple": false,
"content": "Community input needed!"
}'
Get Neighbourhood Feed¶
curl -X GET "https://api.jendz.xyz/api/feed/hybrid/neighbourhood/" \
-H "Authorization: Bearer your_access_token"
Track Post View¶
curl -X POST "https://api.jendz.xyz/api/feed/posts/550e8400-e29b-41d4-a716-446655440000/track_view/" \
-H "Authorization: Bearer your_access_token" \
-H "Content-Type: application/json" \
-d '{
"device_type": "mobile",
"referrer_type": "feed"
}'
Create Comment¶
curl -X POST "https://api.jendz.xyz/api/posts/comments/" \
-H "Authorization: Bearer your_access_token" \
-H "Content-Type: application/json" \
-d '{
"post": "550e8400-e29b-41d4-a716-446655440000",
"content": "Great post!",
"parent": null
}'
JavaScript/React Examples¶
Fetch Neighbourhood Feed¶
const fetchNeighbourhoodFeed = async () => {
try {
const response = await fetch("/api/feed/hybrid/neighbourhood/", {
headers: {
Authorization: `Bearer ${accessToken}`,
"Content-Type": "application/json",
},
});
const data = await response.json();
if (response.ok) {
setFeedItems(data.items);
// Load enhancements in parallel
loadEnhancements(data.enhancement_endpoints);
} else {
console.error("Feed loading failed:", data);
}
} catch (error) {
console.error("Network error:", error);
}
};
Create Post with Error Handling¶
const createPost = async (postData) => {
try {
const response = await fetch("/api/feed/posts/", {
method: "POST",
headers: {
Authorization: `Bearer ${accessToken}`,
"Content-Type": "application/json",
},
body: JSON.stringify(postData),
});
const data = await response.json();
if (response.ok) {
console.log("Post created:", data);
return data;
} else if (response.status === 400) {
if (data.action === "update_location") {
showLocationDialog();
} else if (data.action === "join_community") {
showCommunityDialog(data.community_id);
} else {
showValidationErrors(data);
}
}
} catch (error) {
console.error("Error creating post:", error);
}
};
Vote on Poll¶
const voteOnPoll = async (postId, optionIds) => {
try {
const response = await fetch(`/api/feed/posts/${postId}/vote_poll/`, {
method: "POST",
headers: {
Authorization: `Bearer ${accessToken}`,
"Content-Type": "application/json",
},
body: JSON.stringify({ option_ids: optionIds }),
});
const data = await response.json();
if (response.ok) {
console.log("Vote recorded:", data.voted_options);
refreshPost(postId); // Refresh post to show updated results
} else {
console.error("Voting failed:", data.error);
}
} catch (error) {
console.error("Error voting:", error);
}
};
Python Requests Examples¶
Create Audio Post¶
import requests
def create_audio_post(access_token, content, audio_file_path):
url = "https://api.jendz.xyz/api/feed/posts/"
headers = {
"Authorization": f"Bearer {access_token}"
}
data = {
"post_type": "audio",
"content": content
}
files = {
"audio_file": open(audio_file_path, "rb")
}
try:
response = requests.post(url, headers=headers, data=data, files=files)
if response.status_code == 201:
return response.json()
else:
print(f"Error: {response.status_code} - {response.json()}")
return None
except Exception as e:
print(f"Request failed: {e}")
return None
finally:
files["audio_file"].close()
Get Comments with Pagination¶
def get_all_comments(post_id, access_token=None):
url = f"https://api.jendz.xyz/api/posts/posts/{post_id}/comments/"
headers = {}
if access_token:
headers["Authorization"] = f"Bearer {access_token}"
all_comments = []
while url:
response = requests.get(url, headers=headers)
if response.status_code == 200:
data = response.json()
all_comments.extend(data["results"])
url = data["next"] # Next page URL or None
else:
print(f"Error fetching comments: {response.status_code}")
break
return all_comments
Data Models Summary¶
Post Model Fields¶
| Field | Type | Description |
|---|---|---|
id |
UUID | Unique identifier |
user |
Object | Post author information |
post_type |
String | Type of post (text, image, product_share, etc.) |
title |
String | Optional post title |
content |
String | Post text content |
media |
Array | Attached media files |
location |
UUID | Auto-assigned location (neighbourhood posts) |
location_name |
String | Location display name |
community |
UUID | Community ID (community posts) |
community_name |
String | Community display name |
shared_product |
Object | Shared product details (product_share posts) |
shared_store |
Object | Shared store details (store_share posts) |
shared_community |
Object | Shared community details (community_share posts) |
poll_data |
Object | Poll details and options (poll posts) |
audio_data |
Object | Audio file and metadata (audio posts) |
likes_count |
Integer | Number of likes |
comments_count |
Integer | Number of comments |
views_count |
Integer | Number of views |
has_liked |
Boolean | Current user liked status |
has_bookmarked |
Boolean | Current user bookmark status |
created_at |
DateTime | Creation timestamp |
updated_at |
DateTime | Last modification timestamp |
Comment Model Fields¶
| Field | Type | Description |
|---|---|---|
id |
UUID | Unique identifier |
user |
Object | Comment author information |
post |
UUID | Associated post ID |
content |
String | Comment text |
parent |
UUID | Parent comment ID (null for top-level) |
replies_count |
Integer | Number of replies |
likes_count |
Integer | Number of likes |
bookmarks_count |
Integer | Number of bookmarks |
views_count |
Integer | Number of views |
has_liked |
Boolean | Current user liked status |
has_bookmarked |
Boolean | Current user bookmark status |
created_at |
DateTime | Creation timestamp |
updated_at |
DateTime | Last modification timestamp |
Key Features & Characteristics¶
✅ 7 Enhanced Post Types - Text, image, product share, store share, community share, polls, audio
✅ Secure Location Handling - Backend automatically assigns location, no frontend location data required
✅ Hybrid Feed Architecture - Fast primary feed load (~200ms) with parallel enhancements
✅ Separated Comments System - Independent loading with unlimited nesting depth
✅ Real-time Interactions - Like, bookmark, vote with immediate feedback
✅ Performance Optimized - Aggressive caching, lazy loading, efficient pagination
✅ Comprehensive Error Handling - Clear error messages with actionable guidance
✅ Analytics Integration - Essential view tracking for feed algorithms
✅ Mobile-First Design - Optimized for mobile app performance and UX
✅ RESTful API Design - Standard HTTP methods with predictable URL structure
This API provides a complete social platform foundation with advanced features for community engagement, content sharing, and real-time interaction while maintaining excellent performance and user experience.