Posts Management API
Base URL: https://api.nexgate.com/api/v1
Short Description: The Posts Management API provides comprehensive social media posting functionality including creating posts, polls, quote posts, drafts management, media attachments, commerce integrations, collaboration features, and engagement interactions (likes, bookmarks, reposts, comments). This API enables users to create rich content with privacy controls and scheduled publishing.
Hints:
- All endpoints require authentication via Bearer token unless specified
- Draft posts follow a "one draft at a time" rule - publish or discard before creating new
- Posts support text content, media (images/videos), polls, and commerce attachments
- Privacy settings control visibility, comment permissions, and repost permissions
- Collaborative posts require accepted invitations from collaborators
- Pagination is 1-indexed (page=1 for first page), default size is 20 items
- Poll votes can be changed if poll allows it (allowVoteChange setting)
Standard Response Format
All API responses follow a consistent structure using our Globe Response Builder pattern:
Success Response Structure
{
"success": true,
"httpStatus": "OK",
"message": "Operation completed successfully",
"action_time": "2025-09-23T10:30:45",
"data": {
// Actual response data goes here
}
}
Error Response Structure
{
"success": false,
"httpStatus": "BAD_REQUEST",
"message": "Error description",
"action_time": "2025-09-23T10:30:45",
"data": "Error description"
}
Standard Response Fields
| Field | Type | Description |
|---|---|---|
success |
boolean | Always true for successful operations, false for errors |
httpStatus |
string | HTTP status name (OK, BAD_REQUEST, NOT_FOUND, etc.) |
message |
string | Human-readable message describing the operation result |
action_time |
string | ISO 8601 timestamp of when the response was generated |
data |
object/string | Response payload for success, error details for failures |
HTTP Method Badge Standards
For better visual clarity, all endpoints use colored badges for HTTP methods with the following standard colors:
- GET - GET - Green (Safe, read-only operations)
- POST - POST - Blue (Create new resources)
- PUT - PUT - Yellow (Update/replace entire resource)
- DELETE - DELETE - Red (Remove resources)
Common Response Structure for POST/PUT Operations
Most POST and PUT operations return a PostResponse object. For brevity, this documentation references the detailed PostResponse structure defined below instead of repeating it for each endpoint.
Standard Success Response for Post Creation/Update:
{
"success": true,
"httpStatus": "OK",
"message": "[Operation-specific message]",
"action_time": "2025-12-11T10:30:45",
"data": {
// PostResponse object - see "PostResponse Structure" section below
}
}
PostResponse Structure
This is the standard response structure returned by most post-related endpoints:
{
"id": "550e8400-e29b-41d4-a716-446655440000",
"author": {
"id": "123e4567-e89b-12d3-a456-426614174000",
"userName": "john_doe",
"firstName": "John",
"lastName": "Doe",
"profilePictureUrl": "https://cdn.nexgate.com/profiles/john_doe.jpg",
"isVerified": true
},
"content": "Check out this amazing product! @jane_doe #shopping",
"contentParsed": {
"text": "Check out this amazing product! @jane_doe #shopping",
"entities": [
{
"type": "MENTION",
"text": "@jane_doe",
"startIndex": 33,
"endIndex": 42,
"user": {
"id": "987e6543-e21b-12d3-a456-426614174999",
"userName": "jane_doe",
"firstName": "Jane",
"lastName": "Doe",
"profilePictureUrl": "https://cdn.nexgate.com/profiles/jane_doe.jpg"
}
},
{
"type": "HASHTAG",
"text": "#shopping",
"startIndex": 43,
"endIndex": 52,
"hashtag": "shopping"
}
]
},
"postType": "REGULAR",
"status": "PUBLISHED",
"media": [
{
"id": "media-123",
"mediaType": "IMAGE",
"originalUrl": "https://cdn.nexgate.com/posts/image1.jpg",
"thumbnailUrl": "https://cdn.nexgate.com/posts/image1_thumb.jpg",
"placeholderBase64": "base64-string-here",
"width": 1920,
"height": 1080,
"order": 1,
"imageTags": []
}
],
"attachments": {
"products": [],
"shops": [],
"events": [],
"buyTogetherGroups": [],
"installmentPlans": [],
"externalLink": null
},
"collaboration": {
"isCollaborative": false,
"collaborators": [],
"byline": null
},
"privacySettings": {
"visibility": "PUBLIC",
"whoCanComment": "EVERYONE",
"whoCanRepost": "EVERYONE",
"hideLikesCount": false,
"hideCommentsCount": false
},
"engagement": {
"likesCount": 0,
"commentsCount": 0,
"repostsCount": 0,
"quotesCount": 0,
"bookmarksCount": 0,
"sharesCount": 0,
"viewsCount": 0,
"canLike": true,
"canComment": true,
"canRepost": true,
"canShare": true
},
"userInteraction": {
"hasLiked": false,
"hasBookmarked": false,
"hasReposted": false,
"hasCommented": false,
"hasViewed": false
},
"createdAt": "2025-12-11T10:30:45",
"publishedAt": "2025-12-11T10:30:45",
"scheduledAt": null
}
Endpoints
1. Create Post
Purpose: Create a new post (draft or scheduled) with optional content, media, poll, attachments, and collaboration
Endpoint: POST {base_url}/e-social/posts
Access Level: 🔒 Protected (Requires Bearer Token Authentication)
Authentication: Bearer Token
Behavior:
- Creates a post with status DRAFT (unless scheduledAt is provided, then SCHEDULED)
- Enforces "one draft at a time" rule - user must publish or discard existing draft first
- Automatically parses @mentions, $shop tags, and #hashtags from content
- Validates all attached products, shops, events exist and are active
- Sends collaboration invitations to specified users via notifications
- For scheduled posts, validates scheduledAt is at least 5 minutes in the future
- Media files must already be uploaded to file service before creating post
- Collaborative posts remain in PENDING status until all invitees accept/reject
Business Rules:
- Draft System: Only one draft allowed per user at a time
- Content Requirements: Either content text OR media OR poll must be provided (not all optional)
- Poll Requirements: If postType is POLL, poll object with 2-10 options is required
- Media Limits: Maximum 10 media items per post
- Commerce Limits: Max 10 products, 5 shops, 3 events per post
- Collaboration Limits: Maximum 5 collaborators per post
- Scheduling Rules: Scheduled time must be at least 5 minutes in future, max 6 months ahead
- Mention Extraction: System automatically detects and links @username and $shopname mentions
- Hashtag Indexing: All #hashtags automatically indexed for search and trending
- Privacy Inheritance: MENTIONED visibility requires at least one @mention in content
Request Headers:
| Header | Type | Required | Description |
|---|---|---|---|
| Authorization | string | Yes | Bearer token for authentication (format: Bearer <token>) |
| Content-Type | string | Yes | Must be application/json |
Request JSON Sample:
{
"content": "Excited to share my latest project! @john_doe check this out #coding",
"postType": "REGULAR",
"media": [
{
"mediaType": "IMAGE",
"mediaUrl": "https://cdn.nexgate.com/uploads/image1.jpg",
"placeholderBase64": "base64-string",
"width": 1920,
"height": 1080
}
],
"privacySettings": {
"visibility": "PUBLIC",
"whoCanComment": "EVERYONE",
"whoCanRepost": "EVERYONE",
"hideLikesCount": false,
"hideCommentsCount": false
},
"scheduledAt": null
}
Request Body Parameters:
| Parameter | Type | Required | Description | Validation |
|---|---|---|---|---|
| content | string | No* | Post text content | Max: 5000 characters. *Required if no media/poll |
| postType | string | Yes | Type of post | enum: REGULAR, POLL |
| media | array | No | Array of media objects (images/videos) | Max: 10 items |
| media[].mediaType | string | Yes (if media provided) | Type of media | enum: IMAGE, VIDEO |
| media[].mediaUrl | string | Yes (if media provided) | URL of the media file | Valid URL format, must be from approved CDN |
| media[].placeholderBase64 | string | No | BlurHash or base64 placeholder | Used for progressive image loading |
| media[].width | integer | No | Media width in pixels | Min: 1, Max: 8000 |
| media[].height | integer | No | Media height in pixels | Min: 1, Max: 8000 |
| media[].duration | integer | No | Video duration in seconds | Required for videos, Max: 600 (10 minutes) |
| poll | object | No | Poll configuration | Required if postType is POLL |
| poll.title | string | Yes (if poll provided) | Poll question/title | Min: 5, Max: 500 characters |
| poll.description | string | No | Additional poll description | Max: 1000 characters |
| poll.options | array | Yes (if poll provided) | Array of poll options | Min: 2, Max: 10 |
| poll.options[].optionText | string | Yes | Text for the poll option | Min: 1, Max: 200 characters |
| poll.options[].optionImageUrl | string | No | Optional image for the option | Valid URL format, must be from approved CDN |
| poll.allowMultipleVotes | boolean | No | Allow selecting multiple options | Default: false |
| poll.isAnonymous | boolean | No | Hide voter identities | Default: true. If false, voters visible to post author |
| poll.allowVoteChange | boolean | No | Allow users to change their vote | Default: true. If false, votes are final |
| poll.expiresAt | string | No | Poll expiration datetime | ISO 8601 format, must be future, max 30 days from now |
| attachments | object | No | Commerce attachments | |
| attachments.productIds | array | No | Array of product UUIDs to attach | Max: 10. Products must be ACTIVE status |
| attachments.shopIds | array | No | Array of shop UUIDs to attach | Max: 5. Shops must be VERIFIED |
| attachments.eventIds | array | No | Array of event UUIDs to attach | Max: 3. Events must be PUBLISHED |
| attachments.buyTogetherGroupIds | array | No | Array of group purchase UUIDs | Groups must be ACTIVE, not COMPLETED |
| attachments.installmentPlanIds | array | No | Array of installment plan UUIDs | Plans must be ACTIVE, not EXPIRED |
| attachments.externalLink | object | No | External link object | Only one external link allowed per post |
| attachments.externalLink.url | string | Yes (if externalLink provided) | URL to attach | Valid URL format, supports http/https only |
| collaboration | object | No | Collaboration settings | |
| collaboration.collaboratorIds | array | No | Array of user UUIDs to invite | Max: 5. Users must not be blocked by author |
| privacySettings | object | No | Privacy configuration | |
| privacySettings.visibility | string | No | Post visibility level | enum: PUBLIC, FOLLOWERS, MENTIONED, PRIVATE. Default: PUBLIC |
| privacySettings.whoCanComment | string | No | Comment permission level | enum: EVERYONE, FOLLOWERS, MENTIONED, DISABLED. Default: EVERYONE |
| privacySettings.whoCanRepost | string | No | Repost permission level | enum: EVERYONE, FOLLOWERS, DISABLED. Default: EVERYONE |
| privacySettings.hideLikesCount | boolean | No | Hide like count from others | Default: false. Author always sees true count |
| privacySettings.hideCommentsCount | boolean | No | Hide comment count from others | Default: false. Author always sees true count |
| scheduledAt | string | No | Schedule post for future publication | ISO 8601 format, must be 5+ minutes future, max 6 months ahead |
Validation Notes:
- At least one of: content, media, or poll must be provided
- If postType is POLL, content is optional but poll object is required
- Media files must be pre-uploaded to file service and URLs must be from approved CDN domains
- All UUIDs (products, shops, events, users) are validated for existence and status
- Mentions (@username, $shopname) and hashtags (#tag) are automatically extracted from content
- MENTIONED visibility requires at least one @mention in content
- Scheduled posts cannot be in the past; minimum 5 minutes buffer required
- Collaborative posts send real-time notifications to all invited users
- External links are validated for protocol (http/https only) and reachability
Success Response: Returns standard PostResponse structure (see "PostResponse Structure" section above)
Success Response Message: "Post created successfully"
Error Response JSON Sample:
{
"success": false,
"httpStatus": "BAD_REQUEST",
"message": "You already have a draft post",
"action_time": "2025-12-11T10:30:45",
"data": "You already have a draft post. Please update or publish your existing draft before creating a new one."
}
Standard Error Types:
Application-Level Exceptions (400-499)
400 BAD_REQUEST: Already have a draft post, invalid post data, or validation errors401 UNAUTHORIZED: Authentication issues (empty, invalid, expired, or malformed tokens)422 UNPROCESSABLE_ENTITY: Validation errors with detailed field information500 INTERNAL_SERVER_ERROR: Unexpected server errors
Error Response Examples:
Bad Request - Existing Draft (400):
{
"success": false,
"httpStatus": "BAD_REQUEST",
"message": "You already have a draft post",
"action_time": "2025-12-11T10:30:45",
"data": "You already have a draft post. Please update or publish your existing draft before creating a new one."
}
Validation Error - Content Too Long (422):
{
"success": false,
"httpStatus": "UNPROCESSABLE_ENTITY",
"message": "Validation failed",
"action_time": "2025-12-11T10:30:45",
"data": {
"content": "Content exceeds maximum length of 5000 characters"
}
}
Validation Error - Invalid Poll (422):
{
"success": false,
"httpStatus": "UNPROCESSABLE_ENTITY",
"message": "Validation failed",
"action_time": "2025-12-11T10:30:45",
"data": {
"poll.options": "Poll must have at least 2 options"
}
}
Validation Error - Empty Post (422):
{
"success": false,
"httpStatus": "UNPROCESSABLE_ENTITY",
"message": "Post must have content, media, or poll",
"action_time": "2025-12-11T10:30:45",
"data": "At least one of content, media, or poll must be provided"
}
Validation Error - Invalid Product Attachment (404):
{
"success": false,
"httpStatus": "NOT_FOUND",
"message": "Product not found",
"action_time": "2025-12-11T10:30:45",
"data": "Product with ID 550e8400-e29b-41d4-a716-446655440000 not found or inactive"
}
Validation Error - Scheduled Time in Past (400):
{
"success": false,
"httpStatus": "BAD_REQUEST",
"message": "Invalid scheduled time",
"action_time": "2025-12-11T10:30:45",
"data": "Scheduled time must be at least 5 minutes in the future"
}
Validation Error - Blocked Collaborator (403):
{
"success": false,
"httpStatus": "FORBIDDEN",
"message": "Cannot collaborate with blocked user",
"action_time": "2025-12-11T10:30:45",
"data": "User 770e8400-e29b-41d4-a716-446655440001 has blocked you or you have blocked them"
}
Use Case Examples:
Example 1: Simple Text Post
{
"content": "Just launched my new product! Check it out at nexgate.com/myshop",
"postType": "REGULAR"
}
Result: Creates a PUBLIC draft post with text only, no attachments.
Example 2: Product Showcase Post
{
"content": "New arrivals! 🎉 Amazing deals on electronics. $TechWorld #shopping #deals",
"postType": "REGULAR",
"media": [
{
"mediaType": "IMAGE",
"mediaUrl": "https://cdn.nexgate.com/uploads/product1.jpg",
"width": 1920,
"height": 1080
}
],
"attachments": {
"productIds": ["550e8400-e29b-41d4-a716-446655440001", "550e8400-e29b-41d4-a716-446655440002"],
"shopIds": ["660e8400-e29b-41d4-a716-446655440003"]
}
}
Result: Creates draft with image, attaches 2 products and 1 shop, extracts $TechWorld mention and #shopping/#deals hashtags.
Example 3: Poll Post
{
"content": "What feature should we build next? Vote below! 👇",
"postType": "POLL",
"poll": {
"title": "Next Feature Priority",
"description": "Help us decide what to build for Q1 2026",
"options": [
{"optionText": "Dark Mode"},
{"optionText": "Video Upload"},
{"optionText": "Live Streaming"},
{"optionText": "Advanced Analytics"}
],
"allowMultipleVotes": true,
"isAnonymous": false,
"allowVoteChange": true,
"expiresAt": "2025-12-25T23:59:59Z"
}
}
Result: Creates poll allowing multiple votes, non-anonymous (voters visible), votes can be changed, expires Dec 25.
Example 4: Scheduled Collaborative Event Post
{
"content": "Excited to announce our tech conference! @john_doe and I are hosting. Join us! 🚀 #TechConf2026",
"postType": "REGULAR",
"attachments": {
"eventIds": ["880e8400-e29b-41d4-a716-446655440004"]
},
"collaboration": {
"collaboratorIds": ["770e8400-e29b-41d4-a716-446655440001"]
},
"scheduledAt": "2025-12-20T08:00:00Z"
}
Result: Creates scheduled post for Dec 20, attaches event, sends collaboration invite to john_doe, extracts @john_doe mention and #TechConf2026 hashtag.
2. Publish Draft Post
Purpose: Publish the current user's draft post
Endpoint: POST {base_url}/e-social/posts/publish
Access Level: 🔒 Protected (Requires Bearer Token Authentication)
Authentication: Bearer Token
Behavior:
- Finds user's current draft post (status = DRAFT)
- Changes post status from DRAFT to PUBLISHED
- Sets publishedAt timestamp to current time
- Sends notifications to all mentioned users (@username, $shopname)
- For collaborative posts, only publishes if all collaborators have accepted
- Increments engagement counters for all attached products/shops/events
- Triggers feed distribution to all followers
- No request body required - system automatically finds the user's draft
Business Rules:
- Draft Requirement: User must have exactly one draft post
- Collaboration Status: All invited collaborators must have accepted (status = ACCEPTED)
- Content Validation: Draft must pass all content validation rules before publishing
- Attachment Validation: All attached products/shops/events must still be active/valid
- Scheduled Posts: Cannot publish a scheduled post (status = SCHEDULED) using this endpoint
- Feed Distribution: Published posts immediately appear in followers' feeds
- Notification Triggers: Sends notifications to @mentioned users and collaborators
- Engagement Initialization: All engagement counters (likes, comments, etc.) start at 0
Validation Checks on Publish:
- Draft exists and belongs to current user
- All collaborators have accepted (if collaborative post)
- All attached products are still ACTIVE
- All attached shops are still VERIFIED
- All attached events are still PUBLISHED
- Content still meets length requirements (5000 chars)
- Media URLs still valid and accessible
- Poll configuration valid (if poll post)
Request Headers:
| Header | Type | Required | Description |
|---|---|---|---|
| Authorization | string | Yes | Bearer token for authentication (format: Bearer <token>) |
| Content-Type | string | Yes | Must be application/json |
Success Response: Returns standard PostResponse structure with status changed to PUBLISHED
Success Response Message: "Post published successfully"
Standard Error Types:
Application-Level Exceptions (400-499)
400 BAD_REQUEST: No draft found, draft incomplete, or only draft posts can be published401 UNAUTHORIZED: Authentication issues403 FORBIDDEN: Collaborative post pending approval from collaborators404 NOT_FOUND: No draft post found for user422 UNPROCESSABLE_ENTITY: Draft validation failed (invalid attachments, etc.)500 INTERNAL_SERVER_ERROR: Unexpected server errors
Error Response Examples:
No Draft Found (404):
{
"success": false,
"httpStatus": "NOT_FOUND",
"message": "No draft post found",
"action_time": "2025-12-11T10:30:45",
"data": "You don't have a draft post to publish"
}
Pending Collaborator Approval (403):
{
"success": false,
"httpStatus": "FORBIDDEN",
"message": "Cannot publish collaborative post",
"action_time": "2025-12-11T10:30:45",
"data": "Waiting for collaborator acceptance. 2 of 3 collaborators have accepted."
}
Invalid Attached Product (422):
{
"success": false,
"httpStatus": "UNPROCESSABLE_ENTITY",
"message": "Invalid product attachment",
"action_time": "2025-12-11T10:30:45",
"data": "Product 550e8400-e29b-41d4-a716-446655440001 is no longer active and must be removed before publishing"
}
Use Case Examples:
Example 1: Simple Draft Publish
POST /e-social/posts/publish
User has draft: "Hello world! This is my first post"
Result: Draft published, appears in followers' feeds, status = PUBLISHED, publishedAt set to current time
Example 2: Collaborative Draft Publish (All Accepted)
POST /e-social/posts/publish
User has draft with 2 collaborators
Both collaborators have accepted (status = ACCEPTED)
Result: Draft published, all 3 authors credited, appears on all 3 profiles, notifications sent
Example 3: Collaborative Draft Publish (Pending Approval)
POST /e-social/posts/publish
User has draft with 3 collaborators
Only 2 have accepted, 1 still pending
Result: Error 403 - Cannot publish until all collaborators accept
Example 4: Draft with Product Attachment
POST /e-social/posts/publish
User has draft with attached product
Product validation checks:
- Product exists? ✓
- Product status ACTIVE? ✓
- Product belongs to active shop? ✓
Result: Draft published, product card appears in post, shop gets notification
3. Delete Post
Purpose: Soft delete a post (marks as deleted, doesn't remove from database)
Endpoint: DELETE {base_url}/e-social/posts/{postId}
Access Level: 🔒 Protected (Requires Bearer Token Authentication)
Authentication: Bearer Token
Behavior:
- Performs soft delete: Sets isDeleted flag to true, doesn't remove from database
- Removes post from all users' feeds immediately
- Preserves post data for analytics and audit purposes
- All comments, likes, bookmarks remain in database but are hidden
- Decrements engagement counters for attached products/shops/events
- Sends notification to collaborators (if collaborative post)
- Post no longer appears in searches, hashtag feeds, or explore pages
- Only post author can delete their own posts (not collaborators)
Business Rules:
- Post itself (no longer visible to anyone)
- All comments and replies on the post
- All likes, bookmarks, reposts
- Post no longer appears in:
- User's profile
- Followers' feeds
- Hashtag pages
- Search results
- Product/shop/event pages (if attached)
What Gets Preserved (in database for analytics):
- Original post content and metadata
- All engagement metrics (historical counts)
- All comments and their content
- All likes, bookmarks, and reposts
- Author and timestamp information
- Attachment relationships
Request Headers:
| Header | Type | Required | Description |
|---|---|---|---|
| Authorization | string | Yes | Bearer token for authentication (format: Bearer <token>) |
| Content-Type | string | Yes | Must be application/json |
Path Parameters:
| Parameter | Type | Required | Description | Validation |
|---|---|---|---|---|
| postId | string | Yes | UUID of the post to delete | Must be valid UUID format |
Success Response JSON Sample:
{
"success": true,
"httpStatus": "OK",
"message": "Post deleted successfully",
"action_time": "2025-12-11T10:30:45",
"data": null
}
Success Response Fields:
| Field | Description |
|---|---|
| data | Always null for this endpoint |
Standard Error Types:
Application-Level Exceptions (400-499)
400 BAD_REQUEST: Can only delete your own posts401 UNAUTHORIZED: Authentication issues403 FORBIDDEN: Not the post author (collaborators cannot delete)404 NOT_FOUND: Post not found or already deleted500 INTERNAL_SERVER_ERROR: Unexpected server errors
Error Response Examples:
{
"success": false,
"httpStatus": "FORBIDDEN",
"message": "Cannot delete post",
"action_time": "2025-12-11T10:30:45",
"data": "Only the post author can delete this post. Collaborators cannot delete."
}
Post Not Found (404):
{
"success": false,
"httpStatus": "NOT_FOUND",
"message": "Post not found",
"action_time": "2025-12-11T10:30:45",
"data": "Post with ID 550e8400-e29b-41d4-a716-446655440000 not found or already deleted"
}
Use Case Examples:
Example 1: Delete Regular Post
DELETE /e-social/posts/550e8400-e29b-41d4-a716-446655440000
Post has: 50 likes, 10 comments, 5 reposts
Result: Post soft deleted, all engagement hidden, removed from feeds, data preserved in DB
Example 2: Delete Post with Product Attachments
DELETE /e-social/posts/660e8400-e29b-41d4-a716-446655440001
Post attached to 2 products
Result: Post deleted, product engagement counters decremented, post removed from product pages
Example 3: Collaborator Tries to Delete (Fails)
DELETE /e-social/posts/770e8400-e29b-41d4-a716-446655440002
User is collaborator, not author
Result: Error 403 - Only original author can delete collaborative posts
4. Get Post by ID
Purpose: Retrieve a single post by its ID with full details
Endpoint: GET {base_url}/e-social/posts/{postId}
Access Level: 🔒 Protected (Requires Bearer Token Authentication)
Authentication: Bearer Token
Behavior:
- Returns full post details including author info, content, media, attachments, engagement
- Respects post visibility settings (PUBLIC, FOLLOWERS, MENTIONED, PRIVATE)
- Checks if requesting user has permission to view based on privacy settings
- Includes user interaction state (hasLiked, hasBookmarked, etc.)
- For poll posts, includes user's voting status and results if visible
- Increments view counter if this is first view by this user
- Returns parsed content with @mentions, $shops, and #hashtags highlighted
- Includes collaboration info if collaborative post
Visibility Logic:
- PUBLIC: Anyone can view
- FOLLOWERS: Only followers of author can view
- MENTIONED: Only users mentioned in post (@username) can view
- PRIVATE: Only author can view
Additional Access Rules:
- Blocked users cannot view each other's posts (even if PUBLIC)
- Deleted posts (isDeleted = true) return 404 NOT_FOUND
- Scheduled posts (status = SCHEDULED) only visible to author before scheduled time
- Draft posts (status = DRAFT) only visible to author
- Collaborative posts visible to all collaborators regardless of visibility setting
Response Includes:
- Full post content with parsed entities (mentions, hashtags, shops)
- Author information with profile picture and verification status
- All media with URLs, dimensions, placeholders (BlurHash)
- All commerce attachments (products, shops, events, groups, installments)
- Collaboration details (if collaborative post)
- Privacy settings
- Engagement metrics (likes, comments, reposts counts)
- User's interaction state (liked?, bookmarked?, reposted?, etc.)
- Poll results (if poll post and user can see results)
- Creation and publication timestamps
Request Headers:
| Header | Type | Required | Description |
|---|---|---|---|
| Authorization | string | Yes | Bearer token for authentication (format: Bearer <token>) |
| Content-Type | string | Yes | Must be application/json |
Path Parameters:
| Parameter | Type | Required | Description | Validation |
|---|---|---|---|---|
| postId | string | Yes | UUID of the post to retrieve | Must be valid UUID format |
Success Response: Returns standard PostResponse structure
Success Response Message: "Post retrieved successfully"
Standard Error Types:
Application-Level Exceptions (400-499)
Error Response Examples:
Post Not Found (404):
{
"success": false,
"httpStatus": "NOT_FOUND",
"message": "Post not found",
"action_time": "2025-12-11T10:30:45",
"data": "Post with ID 550e8400-e29b-41d4-a716-446655440000 not found"
}
Insufficient Permissions - Followers Only (403):
{
"success": false,
"httpStatus": "FORBIDDEN",
"message": "Cannot view this post",
"action_time": "2025-12-11T10:30:45",
"data": "This post is visible to followers only. Follow the author to view."
}
Blocked User (403):
{
"success": false,
"httpStatus": "FORBIDDEN",
"message": "Cannot view this post",
"action_time": "2025-12-11T10:30:45",
"data": "You cannot view posts from this user"
}
Use Case Examples:
Example 1: View Public Post
GET /e-social/posts/550e8400-e29b-41d4-a716-446655440000
Post visibility: PUBLIC
Result: Full post details returned, view counter incremented, engagement visible
Example 2: View Followers-Only Post (Not Following)
GET /e-social/posts/660e8400-e29b-41d4-a716-446655440001
Post visibility: FOLLOWERS
User is not following author
Result: Error 403 - Must follow author to view
Example 3: View Mentioned Post (Not Mentioned)
GET /e-social/posts/770e8400-e29b-41d4-a716-446655440002
Post visibility: MENTIONED
User not mentioned in post
Result: Error 403 - Only mentioned users can view
Example 4: View Own Draft Post
GET /e-social/posts/880e8400-e29b-41d4-a716-446655440003
Post status: DRAFT
User is post author
Result: Full post details returned with status = DRAFT
Example 5: View Collaborative Post (As Collaborator)
GET /e-social/posts/990e8400-e29b-41d4-a716-446655440004
Post visibility: PRIVATE
User is accepted collaborator
Result: Full post details returned (collaborators can always view)
5. Get Published Posts
Purpose: Retrieve all published posts with pagination (for discovery/explore feed)
Endpoint: GET {base_url}/e-social/posts
Access Level: 🔒 Protected (Requires Bearer Token Authentication)
Authentication: Bearer Token
Request Headers:
| Header | Type | Required | Description |
|---|---|---|---|
| Authorization | string | Yes | Bearer token for authentication (format: Bearer <token>) |
| Content-Type | string | Yes | Must be application/json |
Query Parameters:
| Parameter | Type | Required | Description | Validation | Default |
|---|---|---|---|---|---|
| page | integer | No | Page number (1-indexed) | Min: 1 | 1 |
| size | integer | No | Number of items per page | Min: 1, Max: 100 | 20 |
Success Response JSON Sample:
{
"success": true,
"httpStatus": "OK",
"message": "Posts retrieved successfully",
"action_time": "2025-12-11T10:30:45",
"data": [
{
// PostResponse object
},
{
// PostResponse object
}
]
}
Success Response Fields:
| Field | Description |
|---|---|
| data | Array of PostResponse objects |
Standard Error Types:
Application-Level Exceptions (400-499)
6. Get Posts by Author
Purpose: Retrieve all posts from a specific author with pagination
Endpoint: GET {base_url}/e-social/posts/author/{authorId}
Access Level: 🔒 Protected (Requires Bearer Token Authentication)
Authentication: Bearer Token
Request Headers:
| Header | Type | Required | Description |
|---|---|---|---|
| Authorization | string | Yes | Bearer token for authentication (format: Bearer <token>) |
| Content-Type | string | Yes | Must be application/json |
Path Parameters:
| Parameter | Type | Required | Description | Validation |
|---|---|---|---|---|
| authorId | string | Yes | UUID of the author | Must be valid UUID format |
Query Parameters:
| Parameter | Type | Required | Description | Validation | Default |
|---|---|---|---|---|---|
| page | integer | No | Page number (1-indexed) | Min: 1 | 1 |
| size | integer | No | Number of items per page | Min: 1, Max: 100 | 20 |
Success Response: Returns array of PostResponse objects
Success Response Message: "Posts retrieved successfully"
Standard Error Types:
Application-Level Exceptions (400-499)
7. Get My Scheduled Posts
Purpose: Retrieve all scheduled posts for the authenticated user
Endpoint: GET {base_url}/e-social/posts/scheduled
Access Level: 🔒 Protected (Requires Bearer Token Authentication)
Authentication: Bearer Token
Request Headers:
| Header | Type | Required | Description |
|---|---|---|---|
| Authorization | string | Yes | Bearer token for authentication (format: Bearer <token>) |
| Content-Type | string | Yes | Must be application/json |
Success Response: Returns array of PostResponse objects with status SCHEDULED
Success Response Message: "Scheduled posts retrieved successfully"
Standard Error Types:
Application-Level Exceptions (400-499)
8. Get My Current Draft
Purpose: Retrieve the authenticated user's current draft post
Endpoint: GET {base_url}/e-social/posts/draft
Access Level: 🔒 Protected (Requires Bearer Token Authentication)
Authentication: Bearer Token
Request Headers:
| Header | Type | Required | Description |
|---|---|---|---|
| Authorization | string | Yes | Bearer token for authentication (format: Bearer <token>) |
| Content-Type | string | Yes | Must be application/json |
Success Response: Returns standard PostResponse structure with status DRAFT, or null if no draft exists
Success Response Message: "Draft retrieved successfully"
Standard Error Types:
Application-Level Exceptions (400-499)
9. Discard Draft
Purpose: Delete the current draft post permanently
Endpoint: DELETE {base_url}/e-social/posts/draft
Access Level: 🔒 Protected (Requires Bearer Token Authentication)
Authentication: Bearer Token
Request Headers:
| Header | Type | Required | Description |
|---|---|---|---|
| Authorization | string | Yes | Bearer token for authentication (format: Bearer <token>) |
| Content-Type | string | Yes | Must be application/json |
Success Response JSON Sample:
{
"success": true,
"httpStatus": "OK",
"message": "Draft discarded successfully",
"action_time": "2025-12-11T10:30:45",
"data": null
}
Standard Error Types:
Application-Level Exceptions (400-499)
400 BAD_REQUEST: No draft found or can only discard your own draft401 UNAUTHORIZED: Authentication issues500 INTERNAL_SERVER_ERROR: Unexpected server errors
10. Update Draft
Purpose: Update content, media, or privacy settings of the current draft
Endpoint: PUT {base_url}/e-social/posts
Access Level: 🔒 Protected (Requires Bearer Token Authentication)
Authentication: Bearer Token
Request Headers:
| Header | Type | Required | Description |
|---|---|---|---|
| Authorization | string | Yes | Bearer token for authentication (format: Bearer <token>) |
| Content-Type | string | Yes | Must be application/json |
Request JSON Sample:
{
"content": "Updated post content",
"media": [
{
"mediaType": "IMAGE",
"mediaUrl": "https://cdn.nexgate.com/uploads/new_image.jpg",
"width": 1920,
"height": 1080
}
],
"privacySettings": {
"visibility": "FOLLOWERS",
"whoCanComment": "FOLLOWERS"
}
}
Request Body Parameters:
| Parameter | Type | Required | Description | Validation |
|---|---|---|---|---|
| content | string | No | Updated post text content | Max: 5000 characters |
| media | array | No | Updated media array | Max: 10 items |
| privacySettings | object | No | Updated privacy settings |
Success Response: Returns standard PostResponse structure with updated values
Success Response Message: "Draft updated successfully"
Standard Error Types:
Application-Level Exceptions (400-499)
400 BAD_REQUEST: No draft found, can only update your own posts, or only draft posts can be updated401 UNAUTHORIZED: Authentication issues422 UNPROCESSABLE_ENTITY: Validation errors500 INTERNAL_SERVER_ERROR: Unexpected server errors
11-20. Draft Commerce Attachments (Attach/Remove Products, Shops, Events, Groups, Plans)
For brevity, these endpoints follow the same pattern:
Attach Endpoints: POST {base_url}/e-social/posts/draft/attach-{type}/{id}
/draft/attach-product/{productId}/draft/attach-shop/{shopId}/draft/attach-event/{eventId}/draft/attach-group/{groupId}/draft/attach-plan/{planId}
Remove Endpoints: DELETE {base_url}/e-social/posts/draft/remove-{type}/{id}
/draft/remove-product/{productId}/draft/remove-shop/{shopId}/draft/remove-event/{eventId}/draft/remove-group/{groupId}/draft/remove-plan/{planId}
All return standard PostResponse structure. Success messages follow pattern: "{Type} attached/removed to/from draft successfully"
21. Update Draft Content Only
Purpose: Update only the text content of the current draft
Endpoint: PUT {base_url}/e-social/posts/content
Request Body: Plain text string (not JSON object)
Success Response: Returns standard PostResponse structure
Success Response Message: "Draft content updated successfully"
22. Update Draft Media Only
Purpose: Update only the media attachments of the current draft
Endpoint: PUT {base_url}/e-social/posts/media
Request Body: Array of MediaRequest objects
Success Response: Returns standard PostResponse structure
Success Response Message: "Media added to draft successfully"
23. Update Draft Privacy Settings Only
Purpose: Update only the privacy settings of the current draft
Endpoint: PUT {base_url}/e-social/posts/privacy
Request Body: PrivacySettingsRequest object
Success Response: Returns standard PostResponse structure
Success Response Message: "Privacy settings updated successfully"
24. Update Draft Collaboration
Purpose: Update collaborator invitations for the current draft
Endpoint: PUT {base_url}/e-social/posts/collaboration
Request Body: CollaborationRequest object with collaboratorIds array
Success Response: Returns standard PostResponse structure
Success Response Message: "Collaboration settings updated successfully"
25. Accept Collaboration
Purpose: Accept a collaboration invitation on a published post
Endpoint: POST {base_url}/e-social/posts/{postId}/collaboration/accept
Success Response: Returns standard PostResponse structure
Success Response Message: "Collaboration accepted successfully"
26. Decline Collaboration
Purpose: Decline a collaboration invitation on a published post
Endpoint: POST {base_url}/e-social/posts/{postId}/collaboration/decline
Success Response: Returns standard PostResponse structure
Success Response Message: "Collaboration declined successfully"
27. Remove Collaborator
Purpose: Remove a collaborator from a published post (author or self only)
Endpoint: DELETE {base_url}/e-social/posts/{postId}/collaborators/{collaboratorId}
Success Response Message: "Collaborator removed successfully"
28. Create Quote Post
Purpose: Create a new post that quotes an existing post
Endpoint: POST {base_url}/e-social/posts/quote/{quotedPostId}
Request Body: CreateQuotePostRequest object (similar to CreatePostRequest but without poll support)
Success Response: Returns standard PostResponse structure with quotedPost field populated
Success Response Message: "Quote post created successfully"
Interaction Endpoints (29-38)
29. Like Post
Purpose: Add a like to a post
Endpoint: POST {base_url}/e-social/posts/{postId}/like
Access Level: 🔒 Protected (Requires Bearer Token Authentication)
Authentication: Bearer Token
Behavior:
- Adds current user's like to the specified post
- Increments post's likesCount by 1
- Creates like record with timestamp
- Sends notification to post author (unless liking own post)
- Updates user's userInteraction.hasLiked to true
- Idempotent: If already liked, returns success without changes
- Respects post visibility (must be able to view post to like it)
- For collaborative posts, all collaborators receive notification
Business Rules:
- Visibility Check: User must have permission to view post based on privacy settings
- Blocking: Cannot like posts from blocked users or if author blocked you
- Deleted Posts: Cannot like deleted posts (isDeleted = true)
- Draft/Scheduled: Cannot like unpublished posts (must be PUBLISHED status)
- Idempotent: Multiple like attempts don't create duplicate likes
- Notification: Author receives notification (unless self-like)
- Counter Update: Post's engagement counter incremented atomically
- User State: User's interaction state updated for this post
Request Headers:
| Header | Type | Required | Description |
|---|---|---|---|
| Authorization | string | Yes | Bearer token for authentication |
| Content-Type | string | Yes | Must be application/json |
Path Parameters:
| Parameter | Type | Required | Description | Validation |
|---|---|---|---|---|
| postId | string | Yes | UUID of the post to like | Must be valid UUID format |
Success Response JSON Sample:
{
"success": true,
"httpStatus": "OK",
"message": "Post liked successfully",
"action_time": "2025-12-11T10:30:45",
"data": null
}
Standard Error Types:
Error Response Examples:
Cannot Like - Blocked User (403):
{
"success": false,
"httpStatus": "FORBIDDEN",
"message": "Cannot like this post",
"action_time": "2025-12-11T10:30:45",
"data": "You cannot interact with posts from this user"
}
Post Not Found (404):
{
"success": false,
"httpStatus": "NOT_FOUND",
"message": "Post not found",
"action_time": "2025-12-11T10:30:45",
"data": "Post with ID 550e8400-e29b-41d4-a716-446655440000 not found"
}
30. Unlike Post
Purpose: Remove a like from a post
Endpoint: DELETE {base_url}/e-social/posts/{postId}/like
Access Level: 🔒 Protected (Requires Bearer Token Authentication)
Authentication: Bearer Token
Behavior:
- Removes current user's like from the specified post
- Decrements post's likesCount by 1
- Deletes like record from database
- No notification sent (unlike is silent)
- Updates user's userInteraction.hasLiked to false
- Idempotent: If not liked, returns success without changes
- Can unlike even if post is now deleted or user is blocked
Business Rules:
- Silent Operation: No notification sent to post author
- Always Allowed: Can unlike even if blocked or post deleted (to clean up state)
- Idempotent: Multiple unlike attempts don't cause errors
- Counter Decrement: Post's engagement counter decremented atomically
- State Cleanup: User's interaction state updated
Request Headers:
| Header | Type | Required | Description |
|---|---|---|---|
| Authorization | string | Yes | Bearer token for authentication |
| Content-Type | string | Yes | Must be application/json |
Path Parameters:
| Parameter | Type | Required | Description | Validation |
|---|---|---|---|---|
| postId | string | Yes | UUID of the post to unlike | Must be valid UUID format |
Success Response JSON Sample:
{
"success": true,
"httpStatus": "OK",
"message": "Post unliked successfully",
"action_time": "2025-12-11T10:30:45",
"data": null
}
Standard Error Types:
31. Bookmark Post
Purpose: Save a post to bookmarks for later viewing
Endpoint: POST {base_url}/e-social/posts/{postId}/bookmark
Access Level: 🔒 Protected (Requires Bearer Token Authentication)
Authentication: Bearer Token
Behavior:
- Adds post to user's bookmark collection
- Creates bookmark record with timestamp
- Post appears in user's bookmarks list (GET /posts/bookmarks)
- Increments post's bookmarksCount by 1
- No notification sent (bookmarking is private)
- Updates user's userInteraction.hasBookmarked to true
- Idempotent: If already bookmarked, returns success without changes
- Respects visibility (must be able to view post to bookmark it)
Business Rules:
- Private Action: Bookmarks are private, author doesn't get notified
- Visibility Required: Must have permission to view post based on privacy settings
- Persistent: Bookmarks persist even if post is deleted (for user's reference)
- Organization: Can be organized into collections (future feature)
- No Limit: Unlimited bookmarks allowed per user
- Idempotent: Multiple bookmark attempts don't create duplicates
- Counter Update: Post's engagement counter incremented
- Access Anytime: User can always access their bookmarked posts
Request Headers:
| Header | Type | Required | Description |
|---|---|---|---|
| Authorization | string | Yes | Bearer token for authentication |
| Content-Type | string | Yes | Must be application/json |
Path Parameters:
| Parameter | Type | Required | Description | Validation |
|---|---|---|---|---|
| postId | string | Yes | UUID of the post to bookmark | Must be valid UUID format |
Success Response JSON Sample:
{
"success": true,
"httpStatus": "OK",
"message": "Post bookmarked successfully",
"action_time": "2025-12-11T10:30:45",
"data": null
}
Standard Error Types:
Use Case Examples:
Example 1: Bookmark for Later Reading
POST /e-social/posts/550e8400-e29b-41d4-a716-446655440000/bookmark
User sees interesting post with products attached
Bookmarks to check products later
Result: Post saved to bookmarks, appears in GET /posts/bookmarks
Example 2: Bookmark Collaborative Post
POST /e-social/posts/660e8400-e29b-41d4-a716-446655440001/bookmark
Post has 3 collaborators
User bookmarks for reference
Result: Post bookmarked, visible in bookmarks even if one collaborator leaves
32. Unbookmark Post
Purpose: Remove a post from bookmarks
Endpoint: DELETE {base_url}/e-social/posts/{postId}/bookmark
Access Level: 🔒 Protected (Requires Bearer Token Authentication)
Authentication: Bearer Token
Behavior:
- Removes post from user's bookmark collection
- Deletes bookmark record from database
- Post no longer appears in user's bookmarks list
- Decrements post's bookmarksCount by 1
- No notification sent (unbookmarking is private)
- Updates user's userInteraction.hasBookmarked to false
- Idempotent: If not bookmarked, returns success without changes
Business Rules:
- Silent Operation: No notification sent
- Always Allowed: Can unbookmark anytime, even if post deleted
- Idempotent: Multiple unbookmark attempts don't cause errors
- Counter Decrement: Post's engagement counter decremented
Request Headers:
| Header | Type | Required | Description |
|---|---|---|---|
| Authorization | string | Yes | Bearer token for authentication |
| Content-Type | string | Yes | Must be application/json |
Path Parameters:
| Parameter | Type | Required | Description | Validation |
|---|---|---|---|---|
| postId | string | Yes | UUID of the post to unbookmark | Must be valid UUID format |
Success Response JSON Sample:
{
"success": true,
"httpStatus": "OK",
"message": "Post unbookmarked successfully",
"action_time": "2025-12-11T10:30:45",
"data": null
}
Standard Error Types:
33. Repost Post
Endpoint: POST {base_url}/e-social/posts/{postId}/repost
Access Level: 🔒 Protected (Requires Bearer Token Authentication)
Authentication: Bearer Token
Behavior:
- Creates a repost record linking user to original post
- Original post appears in user's profile with "reposted" indicator
- Original post appears in all followers' feeds attributed to reposter
- Increments original post's repostsCount by 1
- If comment provided, creates quote post instead (separate post with original embedded)
- Sends notification to original post author
- For collaborative posts, all collaborators receive notification
- Updates user's userInteraction.hasReposted to true
- Idempotent: If already reposted without comment, returns success
- Respects post's whoCanRepost privacy setting
Business Rules:
- Permission Check: Post must allow reposts (whoCanRepost setting)
- Visibility Check: Must have permission to view post
- Blocking: Cannot repost from blocked users
- With Comment: If comment provided, creates separate quote post
- Without Comment: Direct repost, original post shown on profile
- Notification: Original author notified
- Feed Distribution: Appears in reposter's followers' feeds
- Attribution: Always shows original author prominently
- Idempotent: Second repost without comment is no-op
- Counter Update: Original post's repost counter incremented
Request Headers:
| Header | Type | Required | Description |
|---|---|---|---|
| Authorization | string | Yes | Bearer token for authentication |
| Content-Type | string | Yes | Must be application/json |
Path Parameters:
| Parameter | Type | Required | Description | Validation |
|---|---|---|---|---|
| postId | string | Yes | UUID of the post to repost | Must be valid UUID format |
Request Body (Optional):
{
"comment": "This is amazing! Everyone should see this 🔥"
}
Request Body Parameters:
| Parameter | Type | Required | Description | Validation |
|---|---|---|---|---|
| comment | string | No | Optional comment for quote post | Max: 500 characters. If provided, creates quote post instead |
Success Response JSON Sample (Simple Repost):
{
"success": true,
"httpStatus": "OK",
"message": "Post reposted successfully",
"action_time": "2025-12-11T10:30:45",
"data": null
}
Success Response JSON Sample (Quote Post):
{
"success": true,
"httpStatus": "OK",
"message": "Quote post created successfully",
"action_time": "2025-12-11T10:30:45",
"data": {
// Returns full PostResponse for the new quote post
// with quotedPost field containing original post
}
}
Standard Error Types:
Error Response Examples:
Reposts Disabled (403):
{
"success": false,
"httpStatus": "FORBIDDEN",
"message": "Cannot repost this post",
"action_time": "2025-12-11T10:30:45",
"data": "The author has disabled reposts for this post"
}
Reposts Followers Only (403):
{
"success": false,
"httpStatus": "FORBIDDEN",
"message": "Cannot repost this post",
"action_time": "2025-12-11T10:30:45",
"data": "Only followers can repost this post. Follow the author to repost."
}
Use Case Examples:
Example 1: Simple Repost (No Comment)
POST /e-social/posts/550e8400-e29b-41d4-a716-446655440000/repost
Body: {} or no body
Result: Original post appears on user's profile with "reposted" badge
Appears in followers' feeds
Original author gets notification
Example 2: Quote Post (With Comment)
POST /e-social/posts/660e8400-e29b-41d4-a716-446655440001/repost
Body: {
"comment": "This is exactly what I've been saying! Great insight 🎯"
}
Result: Creates new quote post with comment
Original post embedded in quote
New post has own likes/comments
Both posts' repost counters incremented
34. Unrepost Post
Purpose: Remove a repost from your profile
Endpoint: DELETE {base_url}/e-social/posts/{postId}/repost
Access Level: 🔒 Protected (Requires Bearer Token Authentication)
Authentication: Bearer Token
Behavior:
- Removes repost from user's profile
- Original post no longer appears in user's profile reposts
- Decrements original post's repostsCount by 1
- No notification sent (unrepost is silent)
- Updates user's userInteraction.hasReposted to false
- Does NOT delete quote posts (those are separate posts, use delete endpoint)
- Idempotent: If not reposted, returns success without changes
Business Rules:
- Simple Reposts Only: Only removes simple reposts, not quote posts
- Quote Posts: To remove quote post, use DELETE /posts/{quotePostId}
- Silent Operation: No notification sent to original author
- Always Allowed: Can unrepost anytime, even if blocked or post deleted
- Counter Decrement: Original post's repost counter decremented
- Idempotent: Multiple unrepost attempts don't cause errors
Request Headers:
| Header | Type | Required | Description |
|---|---|---|---|
| Authorization | string | Yes | Bearer token for authentication |
| Content-Type | string | Yes | Must be application/json |
Path Parameters:
| Parameter | Type | Required | Description | Validation |
|---|---|---|---|---|
| postId | string | Yes | UUID of the original post to unrepost | Must be valid UUID format |
Success Response JSON Sample:
{
"success": true,
"httpStatus": "OK",
"message": "Post unreposted successfully",
"action_time": "2025-12-11T10:30:45",
"data": null
}
Standard Error Types:
35. Record View
Purpose: Track post views for analytics
Endpoint: POST {base_url}/e-social/posts/{postId}/view
Access Level: 🔒 Protected (Requires Bearer Token Authentication)
Authentication: Bearer Token
Behavior:
- Records that current user viewed the post
- Increments post's viewsCount by 1 (first view only)
- Creates view record with timestamp
- Idempotent: Multiple views from same user only count once
- Updates user's userInteraction.hasViewed to true
- No notification sent (views are private analytics)
- View counts visible to post author in analytics dashboard
- Automatic: Usually called by frontend when post enters viewport
Business Rules:
- One View Per User: Each user counted only once regardless of repeat views
- Private Metric: View counts not shown publicly (author sees in analytics)
- No Notification: Viewing doesn't notify author
- Automatic Tracking: Frontend typically calls this when post visible for 2+ seconds
- Respects Visibility: Must have permission to view post
- Author Excluded: Author's own views don't count
- Idempotent: Multiple calls from same user don't inflate count
Request Headers:
| Header | Type | Required | Description |
|---|---|---|---|
| Authorization | string | Yes | Bearer token for authentication |
| Content-Type | string | Yes | Must be application/json |
Path Parameters:
| Parameter | Type | Required | Description | Validation |
|---|---|---|---|---|
| postId | string | Yes | UUID of the post being viewed | Must be valid UUID format |
Success Response JSON Sample:
{
"success": true,
"httpStatus": "OK",
"message": "View recorded successfully",
"action_time": "2025-12-11T10:30:45",
"data": null
}
Standard Error Types:
36. Get My Bookmarks
Purpose: Retrieve all posts bookmarked by current user
Endpoint: GET {base_url}/e-social/posts/bookmarks
Access Level: 🔒 Protected (Requires Bearer Token Authentication)
Authentication: Bearer Token
Behavior:
- Returns all posts bookmarked by current user
- Sorted by bookmark date (newest first)
- Includes posts even if deleted or author blocked (user retains access)
- Paginated results for performance
- Each post includes full PostResponse structure
- Shows deleted posts with special indicator (for user reference)
- Includes posts from private/followers-only accounts if bookmarked when accessible
Business Rules:
- Personal Collection: Only user's own bookmarks visible
- Persists Deletions: Bookmarked posts remain accessible even if deleted
- Persists Blocking: Can view bookmarked posts even if author blocked
- Chronological: Sorted by bookmark time (newest first)
- Full Details: Each post includes complete information
- Pagination: Default 20 per page, max 100
Request Headers:
| Header | Type | Required | Description |
|---|---|---|---|
| Authorization | string | Yes | Bearer token for authentication |
| Content-Type | string | Yes | Must be application/json |
Query Parameters:
| Parameter | Type | Required | Description | Validation | Default |
|---|---|---|---|---|---|
| page | integer | No | Page number (1-indexed) | Min: 1 | 1 |
| size | integer | No | Items per page | Min: 1, Max: 100 | 20 |
Success Response JSON Sample:
{
"success": true,
"httpStatus": "OK",
"message": "Bookmarks retrieved successfully",
"action_time": "2025-12-11T10:30:45",
"data": [
{
// Full PostResponse object
"id": "550e8400-e29b-41d4-a716-446655440000",
"content": "Bookmarked post content...",
// ... rest of PostResponse
},
{
// Another PostResponse object
}
]
}
Standard Error Types:
37. Get My Reposts
Purpose: Retrieve all posts reposted by current user
Endpoint: GET {base_url}/e-social/posts/my-reposts
Access Level: 🔒 Protected (Requires Bearer Token Authentication)
Authentication: Bearer Token
Behavior:
- Returns all posts reposted by current user (simple reposts only)
- Does NOT include quote posts (those are separate posts in user's profile)
- Sorted by repost date (newest first)
- Paginated results for performance
- Each post shows original author and content
- Respects current visibility settings of original posts
Business Rules:
- Simple Reposts Only: Only shows direct reposts, not quote posts
- Quote Posts: Appear in regular "Get User Posts" endpoint as authored posts
- Current Visibility: If original post now private/deleted, it's excluded
- Chronological: Sorted by repost time (newest first)
- Full Details: Each post includes complete original information
Request Headers:
| Header | Type | Required | Description |
|---|---|---|---|
| Authorization | string | Yes | Bearer token for authentication |
| Content-Type | string | Yes | Must be application/json |
Query Parameters:
| Parameter | Type | Required | Description | Validation | Default |
|---|---|---|---|---|---|
| page | integer | No | Page number (1-indexed) | Min: 1 | 1 |
| size | integer | No | Items per page | Min: 1, Max: 100 | 20 |
Success Response JSON Sample:
{
"success": true,
"httpStatus": "OK",
"message": "Reposts retrieved successfully",
"action_time": "2025-12-11T10:30:45",
"data": [
{
// Full PostResponse object of reposted post
"id": "550e8400-e29b-41d4-a716-446655440000",
"author": {
// Original author info
},
"content": "Original post content...",
// ... rest of PostResponse
}
]
}
Standard Error Types:
38. Get User Reposts
Purpose: Retrieve all posts reposted by a specific user
Endpoint: GET {base_url}/e-social/posts/users/{userId}/reposts
Access Level: 🔒 Protected (Requires Bearer Token Authentication)
Authentication: Bearer Token
Behavior:
- Returns all posts reposted by specified user (simple reposts only)
- Does NOT include quote posts (those are in user's authored posts)
- Respects privacy settings of original posts
- Only shows reposts visible to requesting user based on:
- Original post visibility settings
- Blocking status
- Follow relationships
- Sorted by repost date (newest first)
- Paginated results for performance
Business Rules:
- Simple Reposts Only: Only shows direct reposts, not quote posts
- Visibility Filtering: Only shows original posts requesting user can see
- Privacy Respected: Follows same visibility rules as original posts
- Blocking: Hidden if original author blocked requesting user
- Chronological: Sorted by repost time (newest first)
Request Headers:
| Header | Type | Required | Description |
|---|---|---|---|
| Authorization | string | Yes | Bearer token for authentication |
| Content-Type | string | Yes | Must be application/json |
Path Parameters:
| Parameter | Type | Required | Description | Validation |
|---|---|---|---|---|
| userId | string | Yes | UUID of user whose reposts to retrieve | Must be valid UUID format |
Query Parameters:
| Parameter | Type | Required | Description | Validation | Default |
|---|---|---|---|---|---|
| page | integer | No | Page number (1-indexed) | Min: 1 | 1 |
| size | integer | No | Items per page | Min: 1, Max: 100 | 20 |
Success Response JSON Sample:
{
"success": true,
"httpStatus": "OK",
"message": "User reposts retrieved successfully",
"action_time": "2025-12-11T10:30:45",
"data": [
{
// Full PostResponse object of reposted post
"id": "550e8400-e29b-41d4-a716-446655440000",
"author": {
// Original author info
},
"content": "Original post content...",
// ... rest of PostResponse
}
]
}
Standard Error Types:
Summary: All interaction endpoints return data: null except GET endpoints (36-38) which return paginated PostResponse arrays.
Poll Endpoints (39-42)
39. Vote on Poll
Purpose: Cast a vote on a poll post
Endpoint: POST {base_url}/e-social/posts/{postId}/vote
Access Level: 🔒 Protected (Requires Bearer Token Authentication)
Authentication: Bearer Token
Behavior:
- Records user's vote on poll options
- Supports single or multiple option selection based on poll settings
- If allowVoteChange is true, replaces existing vote
- If allowVoteChange is false, rejects vote if user already voted
- Increments vote counts for selected options
- Updates poll's totalVotes count
- If non-anonymous, records voter identity
- If anonymous, records vote without identity
- Validates poll hasn't expired before accepting vote
- Respects post visibility (must be able to view post to vote)
Business Rules:
- Single vs Multiple: Respects poll's allowMultipleVotes setting
- Vote Changes: Allowed only if allowVoteChange is true
- Expiration: Cannot vote on expired polls
- Visibility: Must have access to view post
- Blocking: Cannot vote on polls from blocked users
- Option Validation: All optionIds must belong to this poll
- Single Vote Mode: If allowMultipleVotes false, only 1 optionId allowed
- Multiple Vote Mode: If allowMultipleVotes true, can select multiple options
- Anonymous: If isAnonymous true, voter identity hidden
- Non-Anonymous: If isAnonymous false, voter identity visible to post author
Request Headers:
| Header | Type | Required | Description |
|---|---|---|---|
| Authorization | string | Yes | Bearer token for authentication |
| Content-Type | string | Yes | Must be application/json |
Path Parameters:
| Parameter | Type | Required | Description | Validation |
|---|---|---|---|---|
| postId | string | Yes | UUID of the poll post | Must be valid UUID format |
Request JSON Sample (Single Vote):
{
"optionIds": ["option-uuid-1"]
}
Request JSON Sample (Multiple Votes):
{
"optionIds": ["option-uuid-1", "option-uuid-2", "option-uuid-4"]
}
Request Body Parameters:
| Parameter | Type | Required | Description | Validation |
|---|---|---|---|---|
| optionIds | array | Yes | Array of poll option UUIDs | Min: 1 option. If allowMultipleVotes false, max: 1. All IDs must belong to poll |
Success Response JSON Sample:
{
"success": true,
"httpStatus": "OK",
"message": "Vote recorded successfully",
"action_time": "2025-12-11T10:30:45",
"data": null
}
Standard Error Types:
400 BAD_REQUEST: Poll expired, vote change not allowed, or invalid options401 UNAUTHORIZED: Authentication required403 FORBIDDEN: Cannot vote (blocked, visibility restrictions)404 NOT_FOUND: Post or poll not found422 UNPROCESSABLE_ENTITY: Validation errors (too many options, invalid IDs)500 INTERNAL_SERVER_ERROR: Unexpected errors
Error Response Examples:
Poll Expired (400):
{
"success": false,
"httpStatus": "BAD_REQUEST",
"message": "Cannot vote on poll",
"action_time": "2025-12-11T10:30:45",
"data": "This poll has expired and is no longer accepting votes"
}
Vote Change Not Allowed (400):
{
"success": false,
"httpStatus": "BAD_REQUEST",
"message": "Cannot change vote",
"action_time": "2025-12-11T10:30:45",
"data": "You have already voted on this poll and vote changes are not allowed"
}
Too Many Options - Single Vote Mode (422):
{
"success": false,
"httpStatus": "UNPROCESSABLE_ENTITY",
"message": "Validation failed",
"action_time": "2025-12-11T10:30:45",
"data": {
"optionIds": "This poll allows only one vote. You selected 3 options."
}
}
Invalid Option ID (404):
{
"success": false,
"httpStatus": "NOT_FOUND",
"message": "Invalid poll option",
"action_time": "2025-12-11T10:30:45",
"data": "Option option-uuid-5 does not belong to this poll"
}
Use Case Examples:
Example 1: Single Vote Poll
POST /e-social/posts/550e8400-e29b-41d4-a716-446655440000/vote
Poll settings: allowMultipleVotes = false
Body: {
"optionIds": ["option-uuid-2"]
}
Result: Vote recorded for option 2, totalVotes++, option vote count++
Example 2: Multiple Vote Poll
POST /e-social/posts/660e8400-e29b-41d4-a716-446655440001/vote
Poll settings: allowMultipleVotes = true
Body: {
"optionIds": ["option-uuid-1", "option-uuid-3", "option-uuid-5"]
}
Result: Votes recorded for 3 options, totalVotes++, each option count++
Example 3: Change Vote (Allowed)
POST /e-social/posts/770e8400-e29b-41d4-a716-446655440002/vote
Poll settings: allowVoteChange = true
User already voted for option 1
Body: {
"optionIds": ["option-uuid-4"]
}
Result: Previous vote removed, new vote recorded, counts updated
Example 4: Change Vote (Not Allowed)
POST /e-social/posts/880e8400-e29b-41d4-a716-446655440003/vote
Poll settings: allowVoteChange = false
User already voted
Body: {
"optionIds": ["option-uuid-2"]
}
Result: Error 400 - Vote changes not allowed, original vote preserved
40. Remove Vote
Purpose: Remove your vote from a poll
Endpoint: DELETE {base_url}/e-social/posts/{postId}/vote
Access Level: 🔒 Protected (Requires Bearer Token Authentication)
Authentication: Bearer Token
Behavior:
- Removes all of user's votes from the poll
- Decrements vote counts for previously selected options
- Decrements poll's totalVotes count
- Only allowed if allowVoteChange is true
- Idempotent: If not voted, returns success without changes
- Can remove votes even if poll expired (cleanup)
Business Rules:
- Vote Change Required: Only works if allowVoteChange is true
- Complete Removal: Removes ALL votes (if multiple vote poll)
- Idempotent: Safe to call if not voted
- Expired Polls: Can remove votes even after expiration
- Counter Updates: All affected option counts decremented
- Silent Operation: No notification sent
Request Headers:
| Header | Type | Required | Description |
|---|---|---|---|
| Authorization | string | Yes | Bearer token for authentication |
| Content-Type | string | Yes | Must be application/json |
Path Parameters:
| Parameter | Type | Required | Description | Validation |
|---|---|---|---|---|
| postId | string | Yes | UUID of the poll post | Must be valid UUID format |
Success Response JSON Sample:
{
"success": true,
"httpStatus": "OK",
"message": "Vote removed successfully",
"action_time": "2025-12-11T10:30:45",
"data": null
}
Standard Error Types:
400 BAD_REQUEST: Vote removal not allowed (allowVoteChange is false)401 UNAUTHORIZED: Authentication required403 FORBIDDEN: Cannot access poll404 NOT_FOUND: Post or poll not found500 INTERNAL_SERVER_ERROR: Unexpected errors
Error Response Examples:
Vote Removal Not Allowed (400):
{
"success": false,
"httpStatus": "BAD_REQUEST",
"message": "Cannot remove vote",
"action_time": "2025-12-11T10:30:45",
"data": "This poll does not allow vote changes or removal"
}
Use Case Examples:
Example 1: Remove Single Vote
DELETE /e-social/posts/550e8400-e29b-41d4-a716-446655440000/vote
Poll settings: allowVoteChange = true
User voted for option 2
Result: Vote removed, option 2 count--, totalVotes--
Example 2: Remove Multiple Votes
DELETE /e-social/posts/660e8400-e29b-41d4-a716-446655440001/vote
Poll settings: allowMultipleVotes = true, allowVoteChange = true
User voted for options 1, 3, 5
Result: All 3 votes removed, all option counts--, totalVotes--
Example 3: Remove Vote - Not Allowed
DELETE /e-social/posts/770e8400-e29b-41d4-a716-446655440002/vote
Poll settings: allowVoteChange = false
Result: Error 400 - Vote removal not allowed, original vote preserved
41. Get Poll Results
Purpose: Get detailed poll results including vote counts and percentages
Endpoint: GET {base_url}/e-social/posts/{postId}/poll-results
Access Level: 🔒 Protected (Requires Bearer Token Authentication)
Authentication: Bearer Token
Behavior:
- Returns complete poll details and voting statistics
- Calculates percentages for each option
- Shows user's voting status (hasVoted, which options voted)
- Displays poll configuration (anonymous, multiple votes, change allowed)
- Shows expiration status
- Respects post visibility (must be able to view post)
- Real-time results update as votes come in
Business Rules:
- Visibility: Must have access to view parent post
- Real-Time: Results update immediately after each vote
- Percentages: Calculated as (optionVotes / totalVotes) × 100
- User State: Shows which options current user voted for
- Expiration Check: Indicates if poll has expired
- Zero Votes: Shows 0.0% for options with no votes
- Anonymous Respect: Voter identities hidden if isAnonymous true
- Public Results: Anyone who can view post can see results
Request Headers:
| Header | Type | Required | Description |
|---|---|---|---|
| Authorization | string | Yes | Bearer token for authentication |
| Content-Type | string | Yes | Must be application/json |
Path Parameters:
| Parameter | Type | Required | Description | Validation |
|---|---|---|---|---|
| postId | string | Yes | UUID of the poll post | Must be valid UUID format |
Success Response JSON Sample:
{
"success": true,
"httpStatus": "OK",
"message": "Poll results retrieved successfully",
"action_time": "2025-12-11T10:30:45",
"data": {
"pollId": "poll-uuid",
"title": "What's your favorite programming language?",
"description": "Choose your top pick for backend development",
"totalVotes": 150,
"allowMultipleVotes": false,
"isAnonymous": true,
"allowVoteChange": true,
"expiresAt": "2025-12-15T10:30:45",
"hasExpired": false,
"userHasVoted": true,
"options": [
{
"optionId": "option-uuid-1",
"optionText": "Python",
"optionImageUrl": null,
"optionOrder": 1,
"votesCount": 75,
"percentage": 50.0,
"userVoted": true
},
{
"optionId": "option-uuid-2",
"optionText": "JavaScript",
"optionImageUrl": null,
"optionOrder": 2,
"votesCount": 50,
"percentage": 33.3,
"userVoted": false
},
{
"optionId": "option-uuid-3",
"optionText": "Java",
"optionImageUrl": null,
"optionOrder": 3,
"votesCount": 25,
"percentage": 16.7,
"userVoted": false
}
]
}
}
Response Fields Explained:
| Field | Type | Description |
|---|---|---|
| pollId | string | UUID of the poll |
| title | string | Poll question/title |
| description | string | Additional poll description (optional) |
| totalVotes | integer | Total number of votes cast |
| allowMultipleVotes | boolean | Can users select multiple options |
| isAnonymous | boolean | Are voter identities hidden |
| allowVoteChange | boolean | Can users change their vote |
| expiresAt | string | Poll expiration datetime (ISO 8601, null if no expiration) |
| hasExpired | boolean | Whether poll has passed expiration time |
| userHasVoted | boolean | Has current user voted on this poll |
| options | array | Array of poll options with results |
| options[].optionId | string | UUID of this option |
| options[].optionText | string | Text for this option |
| options[].optionImageUrl | string | Optional image for this option (null if none) |
| options[].optionOrder | integer | Display order (1, 2, 3...) |
| options[].votesCount | integer | Number of votes for this option |
| options[].percentage | number | Percentage of total votes (0.0-100.0) |
| options[].userVoted | boolean | Did current user vote for this option |
Success Response Message: "Poll results retrieved successfully"
Standard Error Types:
Use Case Examples:
Example 1: View Active Poll Results
GET /e-social/posts/550e8400-e29b-41d4-a716-446655440000/poll-results
Poll has 150 total votes, user voted for Python
Result: Returns all options with vote counts, percentages, user's vote highlighted
Example 2: View Expired Poll
GET /e-social/posts/660e8400-e29b-41d4-a716-446655440001/poll-results
Poll expired yesterday, hasExpired = true
Result: Results displayed, voting disabled, final counts shown
Example 3: View Poll Without Voting
GET /e-social/posts/770e8400-e29b-41d4-a716-446655440002/poll-results
User hasn't voted yet, userHasVoted = false
Result: All options shown with current results, all userVoted = false
42. Get Poll Voters
Purpose: Get list of users who voted for a specific poll option (post author/collaborators only, non-anonymous polls only)
Endpoint: GET {base_url}/e-social/posts/{postId}/poll-voters/{optionId}
Access Level: 🔒 Protected (Requires Bearer Token Authentication + Post Author/Collaborator)
Authentication: Bearer Token
Behavior:
- Returns list of users who voted for specific poll option
- Only available for non-anonymous polls (isAnonymous = false)
- Only accessible by post author and accepted collaborators
- Sorted by vote time (newest first)
- Includes user profile information
- Paginated for large polls
Business Rules:
- Non-Anonymous Only: Only works if isAnonymous is false
- Author/Collaborator Access: Only post author and collaborators can view
- Privacy Protection: Regular users cannot see who voted
- Vote Time: Includes when each user voted
- Profile Info: Returns basic user profile (name, photo, verified status)
- Pagination: Default 50 voters per page
- Current Votes: Shows current votes (if user changed vote, shows new choice)
Request Headers:
| Header | Type | Required | Description |
|---|---|---|---|
| Authorization | string | Yes | Bearer token for authentication |
| Content-Type | string | Yes | Must be application/json |
Path Parameters:
| Parameter | Type | Required | Description | Validation |
|---|---|---|---|---|
| postId | string | Yes | UUID of the poll post | Must be valid UUID format |
| optionId | string | Yes | UUID of the poll option | Must belong to this poll |
Query Parameters:
| Parameter | Type | Required | Description | Validation | Default |
|---|---|---|---|---|---|
| page | integer | No | Page number (1-indexed) | Min: 1 | 1 |
| size | integer | No | Items per page | Min: 1, Max: 100 | 50 |
Success Response JSON Sample:
{
"success": true,
"httpStatus": "OK",
"message": "Voters retrieved successfully",
"action_time": "2025-12-11T10:30:45",
"data": {
"pollId": "poll-uuid",
"pollTitle": "What's your favorite programming language?",
"optionId": "option-uuid-1",
"optionText": "Python",
"totalVoters": 75,
"voters": [
{
"userId": "123e4567-e89b-12d3-a456-426614174000",
"userName": "john_doe",
"firstName": "John",
"lastName": "Doe",
"profilePictureUrl": "https://cdn.nexgate.com/profiles/john_doe.jpg",
"isVerified": true,
"votedAt": "2025-12-11T10:25:30"
},
{
"userId": "987e6543-e21b-12d3-a456-426614174999",
"userName": "jane_smith",
"firstName": "Jane",
"lastName": "Smith",
"profilePictureUrl": "https://cdn.nexgate.com/profiles/jane_smith.jpg",
"isVerified": false,
"votedAt": "2025-12-11T10:20:15"
}
],
"pagination": {
"currentPage": 1,
"pageSize": 50,
"totalPages": 2,
"totalElements": 75,
"hasNext": true,
"hasPrevious": false
}
}
}
Success Response Message: "Voters retrieved successfully"
Standard Error Types:
400 BAD_REQUEST: Anonymous poll (voter list not available)401 UNAUTHORIZED: Authentication required403 FORBIDDEN: Not post author/collaborator404 NOT_FOUND: Post or option not found500 INTERNAL_SERVER_ERROR: Unexpected errors
Error Response Examples:
Anonymous Poll (400):
{
"success": false,
"httpStatus": "BAD_REQUEST",
"message": "Voters not available",
"action_time": "2025-12-11T10:30:45",
"data": "This is an anonymous poll. Voter identities are hidden."
}
{
"success": false,
"httpStatus": "FORBIDDEN",
"message": "Access denied",
"action_time": "2025-12-11T10:30:45",
"data": "Only the post author and collaborators can view voter lists"
}
Use Case Examples:
Example 1: View Voters as Post Author
GET /e-social/posts/550e8400-e29b-41d4-a716-446655440000/poll-voters/option-uuid-1
User is post author
Poll is non-anonymous
Option has 75 voters
Result: Returns paginated list of 75 users who voted for this option
Example 2: View Voters as Collaborator
GET /e-social/posts/660e8400-e29b-41d4-a716-446655440001/poll-voters/option-uuid-2
User is accepted collaborator
Poll is non-anonymous
Result: Returns voter list (collaborators have same access as author)
Example 3: Anonymous Poll - Access Denied
GET /e-social/posts/770e8400-e29b-41d4-a716-446655440002/poll-voters/option-uuid-3
User is post author
Poll is anonymous (isAnonymous = true)
Result: Error 400 - Voter identities hidden for anonymous polls
Example 4: Regular User - Access Denied
GET /e-social/posts/880e8400-e29b-41d4-a716-446655440003/poll-voters/option-uuid-1
User is neither author nor collaborator
Poll is non-anonymous
Result: Error 403 - Only author/collaborators can view voters
Comment Endpoints (43-52)
43. Create Comment
Purpose: Create a comment or reply on a post
Endpoint: POST {base_url}/e-social/posts/{postId}/comments
Access Level: 🔒 Protected (Requires Bearer Token Authentication)
Authentication: Bearer Token
Behavior:
- Creates top-level comment if parentCommentId is null
- Creates nested reply if parentCommentId provided
- Increments post's commentsCount by 1
- Sends notification to post author (unless commenting on own post)
- For replies, notifies parent comment author
- Automatically parses @mentions in comment content
- All mentioned users receive notifications
- Respects post's whoCanComment privacy setting
- Supports nested replies (unlimited depth)
- Updates post's engagement metrics
Business Rules:
- Permission Check: Post must allow comments (whoCanComment setting)
- Visibility Check: Must have permission to view post to comment
- Blocking: Cannot comment on posts from blocked users
- Nesting: Supports unlimited reply depth (replies to replies to replies...)
- Mentions: All @mentioned users notified
- Notification: Post author and parent comment author notified
- Content Length: Min 1, Max 2000 characters
- Spam Prevention: Rate limited (max 10 comments per minute per user)
- Edit Window: Can edit within 15 minutes of posting
- Deleted Posts: Cannot comment on deleted posts
Request Headers:
| Header | Type | Required | Description |
|---|---|---|---|
| Authorization | string | Yes | Bearer token for authentication |
| Content-Type | string | Yes | Must be application/json |
Path Parameters:
| Parameter | Type | Required | Description | Validation |
|---|---|---|---|---|
| postId | string | Yes | UUID of the post to comment on | Must be valid UUID format |
Request JSON Sample (Top-level Comment):
{
"content": "Great post! @john_doe you should check this out",
"parentCommentId": null
}
Request JSON Sample (Nested Reply):
{
"content": "I completely agree with you @jane_doe! 💯",
"parentCommentId": "660e8400-e29b-41d4-a716-446655440001"
}
Request Body Parameters:
| Parameter | Type | Required | Description | Validation |
|---|---|---|---|---|
| content | string | Yes | Comment text | Min: 1, Max: 2000 characters |
| parentCommentId | string | No | UUID of parent comment for replies | Must be valid UUID if provided, must belong to same post |
Success Response: Returns CommentResponse object
CommentResponse Structure:
{
"id": "770e8400-e29b-41d4-a716-446655440001",
"postId": "550e8400-e29b-41d4-a716-446655440000",
"author": {
"id": "123e4567-e89b-12d3-a456-426614174000",
"userName": "john_doe",
"firstName": "John",
"lastName": "Doe",
"profilePictureUrl": "https://cdn.nexgate.com/profiles/john_doe.jpg",
"isVerified": true
},
"content": "Great post! @john_doe you should check this out",
"contentParsed": {
"text": "Great post! @john_doe you should check this out",
"entities": [
{
"type": "MENTION",
"text": "@john_doe",
"startIndex": 12,
"endIndex": 21,
"user": {
"id": "987e6543-e21b-12d3-a456-426614174999",
"userName": "john_doe"
}
}
]
},
"parentCommentId": null,
"replyCount": 5,
"likesCount": 12,
"isPinned": false,
"isEdited": false,
"userInteraction": {
"hasLiked": false
},
"createdAt": "2025-12-11T10:30:45",
"updatedAt": null
}
Success Response Message: "Comment created successfully"
Standard Error Types:
400 BAD_REQUEST: Invalid content, parent comment not found, or spam detected401 UNAUTHORIZED: Authentication required403 FORBIDDEN: Cannot comment (permissions, blocked, disabled comments)404 NOT_FOUND: Post not found422 UNPROCESSABLE_ENTITY: Validation errors (content too long/short)429 TOO_MANY_REQUESTS: Rate limit exceeded500 INTERNAL_SERVER_ERROR: Unexpected errors
Error Response Examples:
Comments Disabled (403):
{
"success": false,
"httpStatus": "FORBIDDEN",
"message": "Cannot comment on this post",
"action_time": "2025-12-11T10:30:45",
"data": "The author has disabled comments for this post"
}
Comments Followers Only (403):
{
"success": false,
"httpStatus": "FORBIDDEN",
"message": "Cannot comment on this post",
"action_time": "2025-12-11T10:30:45",
"data": "Only followers can comment on this post. Follow the author to comment."
}
Invalid Parent Comment (400):
{
"success": false,
"httpStatus": "BAD_REQUEST",
"message": "Invalid parent comment",
"action_time": "2025-12-11T10:30:45",
"data": "Parent comment does not belong to this post"
}
Rate Limit Exceeded (429):
{
"success": false,
"httpStatus": "TOO_MANY_REQUESTS",
"message": "Too many comments",
"action_time": "2025-12-11T10:30:45",
"data": "Maximum 10 comments per minute. Please wait 30 seconds."
}
Use Case Examples:
Example 1: Top-Level Comment
POST /e-social/posts/550e8400-e29b-41d4-a716-446655440000/comments
Body: {
"content": "This is exactly what I needed! Thank you 🙏",
"parentCommentId": null
}
Result: Top-level comment created, post author notified, commentsCount++
Example 2: Reply to Comment
POST /e-social/posts/550e8400-e29b-41d4-a716-446655440000/comments
Body: {
"content": "Glad you found it helpful! @jane_doe",
"parentCommentId": "660e8400-e29b-41d4-a716-446655440001"
}
Result: Nested reply created, parent comment author + @jane_doe notified
Example 3: Nested Reply (Reply to Reply)
POST /e-social/posts/550e8400-e29b-41d4-a716-446655440000/comments
Body: {
"content": "Same here! Following this thread 👀",
"parentCommentId": "770e8400-e29b-41d4-a716-446655440002"
}
Result: 2nd-level nested reply created, forms conversation thread
44. Get Comments
Purpose: Retrieve all top-level comments for a post (paginated)
Endpoint: GET {base_url}/e-social/posts/{postId}/comments
Access Level: 🔒 Protected (Requires Bearer Token Authentication)
Authentication: Bearer Token
Behavior:
- Returns top-level comments only (parentCommentId = null)
- Sorted by: Pinned first, then by createdAt (newest first)
- Includes replyCount for each comment
- Respects post visibility (must be able to view post)
- Paginated for performance
- Each comment includes author info and engagement metrics
- Does NOT include replies (use Get Replies endpoint)
Business Rules:
- Top-Level Only: Returns only direct comments on post, not replies
- Pinned Priority: Pinned comments always appear first
- Sorting: After pinned, sorted by newest first
- Reply Count: Each comment shows number of replies
- Pagination: Default 20 per page, max 100
- Visibility: Same visibility rules as viewing the post
Request Headers:
| Header | Type | Required | Description |
|---|---|---|---|
| Authorization | string | Yes | Bearer token for authentication |
| Content-Type | string | Yes | Must be application/json |
Path Parameters:
| Parameter | Type | Required | Description | Validation |
|---|---|---|---|---|
| postId | string | Yes | UUID of the post | Must be valid UUID format |
Query Parameters:
| Parameter | Type | Required | Description | Validation | Default |
|---|---|---|---|---|---|
| page | integer | No | Page number (1-indexed) | Min: 1 | 1 |
| size | integer | No | Items per page | Min: 1, Max: 100 | 20 |
Success Response: Returns array of CommentResponse objects
Success Response Message: "Comments retrieved successfully"
Standard Error Types:
45. Get Comment
Purpose: Retrieve a single comment by ID with full details
Endpoint: GET {base_url}/e-social/posts/comments/{commentId}
Access Level: 🔒 Protected (Requires Bearer Token Authentication)
Authentication: Bearer Token
Behavior:
- Returns full comment details including author, content, engagement
- Includes parsed content with @mentions
- Shows user's interaction state (hasLiked)
- Respects post visibility rules
- Returns parent comment info if it's a reply
Business Rules:
- Visibility: Must be able to view parent post
- Deleted: Returns 404 if comment deleted
- Full Details: Includes all engagement metrics
- Context: Can get comment without knowing postId
Request Headers:
| Header | Type | Required | Description |
|---|---|---|---|
| Authorization | string | Yes | Bearer token for authentication |
| Content-Type | string | Yes | Must be application/json |
Path Parameters:
| Parameter | Type | Required | Description | Validation |
|---|---|---|---|---|
| commentId | string | Yes | UUID of the comment | Must be valid UUID format |
Success Response: Returns CommentResponse object
Success Response Message: "Comment retrieved successfully"
Standard Error Types:
46. Get Replies
Purpose: Retrieve all replies to a specific comment (nested comments)
Endpoint: GET {base_url}/e-social/posts/comments/{commentId}/replies
Access Level: 🔒 Protected (Requires Bearer Token Authentication)
Authentication: Bearer Token
Behavior:
- Returns all direct replies to specified comment
- Sorted by createdAt (oldest first for conversation flow)
- Each reply can have its own replies (nested)
- Paginated for performance
- Includes reply count for each reply (supports infinite nesting)
Business Rules:
- Direct Replies Only: Returns immediate children, not grandchildren
- Conversation Order: Sorted oldest first (chronological conversation)
- Nested Support: Each reply shows its own replyCount
- Recursive Loading: Frontend loads nested replies on-demand
- Pagination: Default 50 per page (comments usually have fewer replies)
Request Headers:
| Header | Type | Required | Description |
|---|---|---|---|
| Authorization | string | Yes | Bearer token for authentication |
| Content-Type | string | Yes | Must be application/json |
Path Parameters:
| Parameter | Type | Required | Description | Validation |
|---|---|---|---|---|
| commentId | string | Yes | UUID of parent comment | Must be valid UUID format |
Query Parameters:
| Parameter | Type | Required | Description | Validation | Default |
|---|---|---|---|---|---|
| page | integer | No | Page number (1-indexed) | Min: 1 | 1 |
| size | integer | No | Items per page | Min: 1, Max: 100 | 50 |
Success Response: Returns array of CommentResponse objects
Success Response Message: "Replies retrieved successfully"
Standard Error Types:
47. Update Comment
Purpose: Edit an existing comment's content
Endpoint: PUT {base_url}/e-social/posts/comments/{commentId}
Access Level: 🔒 Protected (Requires Bearer Token Authentication)
Authentication: Bearer Token
Behavior:
- Updates comment content
- Sets isEdited flag to true
- Updates updatedAt timestamp
- Preserves original createdAt timestamp
- Re-parses @mentions in updated content
- Sends notifications to newly mentioned users
- Only comment author can edit
- Edit window: 15 minutes from creation (configurable)
Business Rules:
Request Headers:
| Header | Type | Required | Description |
|---|---|---|---|
| Authorization | string | Yes | Bearer token for authentication |
| Content-Type | string | Yes | Must be application/json |
Path Parameters:
| Parameter | Type | Required | Description | Validation |
|---|---|---|---|---|
| commentId | string | Yes | UUID of comment to edit | Must be valid UUID format |
Request JSON Sample:
{
"content": "Updated comment with correction! @new_user check this"
}
Request Body Parameters:
| Parameter | Type | Required | Description | Validation |
|---|---|---|---|---|
| content | string | Yes | Updated comment text | Min: 1, Max: 2000 characters |
Success Response: Returns updated CommentResponse object with isEdited = true
Success Response Message: "Comment updated successfully"
Standard Error Types:
400 BAD_REQUEST: Edit window expired (>15 minutes)401 UNAUTHORIZED: Authentication required403 FORBIDDEN: Not comment author404 NOT_FOUND: Comment not found422 UNPROCESSABLE_ENTITY: Validation errors500 INTERNAL_SERVER_ERROR: Unexpected errors
Error Response Examples:
Edit Window Expired (400):
{
"success": false,
"httpStatus": "BAD_REQUEST",
"message": "Cannot edit comment",
"action_time": "2025-12-11T10:30:45",
"data": "Comments can only be edited within 15 minutes of posting"
}
{
"success": false,
"httpStatus": "FORBIDDEN",
"message": "Cannot edit comment",
"action_time": "2025-12-11T10:30:45",
"data": "Only the comment author can edit this comment"
}
48. Delete Comment
Purpose: Soft delete a comment (marks as deleted, preserves data)
Endpoint: DELETE {base_url}/e-social/posts/comments/{commentId}
Access Level: 🔒 Protected (Requires Bearer Token Authentication)
Authentication: Bearer Token
Behavior:
- Performs soft delete: Sets isDeleted flag, doesn't remove from DB
- Decrements post's commentsCount by 1
- Replies remain visible but show "[deleted]" as parent
- Comment author and post author can delete
- Preserves comment data for audit/analytics
- Updates comment content to "[deleted]" in responses
- No notification sent
Business Rules:
- Who Can Delete: Comment author OR post author
- Soft Delete: Data retained in database
- Replies Preserved: Child replies remain visible
- Parent Reference: Replies show "[deleted]" as parent content
- Counter Update: Post's comment count decremented
- Cascade Option: Post author can cascade delete all replies (optional)
- Silent Operation: No notifications sent
Request Headers:
| Header | Type | Required | Description |
|---|---|---|---|
| Authorization | string | Yes | Bearer token for authentication |
| Content-Type | string | Yes | Must be application/json |
Path Parameters:
| Parameter | Type | Required | Description | Validation |
|---|---|---|---|---|
| commentId | string | Yes | UUID of comment to delete | Must be valid UUID format |
Success Response JSON Sample:
{
"success": true,
"httpStatus": "OK",
"message": "Comment deleted successfully",
"action_time": "2025-12-11T10:30:45",
"data": null
}
Standard Error Types:
Use Case Examples:
DELETE /e-social/posts/comments/770e8400-e29b-41d4-a716-446655440001
User is comment author
Comment has 3 replies
Result: Comment deleted, replies preserved, show "[deleted]" as parent
Example 2: Post Author Deletes Inappropriate Comment
DELETE /e-social/posts/comments/880e8400-e29b-41d4-a716-446655440002
User is post author (not comment author)
Comment violates community guidelines
Result: Comment deleted by post author, content moderation applied
49. Pin Comment
Purpose: Pin a comment to the top of post's comment section (post author only)
Endpoint: POST {base_url}/e-social/posts/{postId}/comments/{commentId}/pin
Access Level: 🔒 Protected (Requires Bearer Token Authentication)
Authentication: Bearer Token
Behavior:
- Pins comment to top of comment list
- Sets isPinned flag to true
- Only one comment can be pinned per post
- If another comment already pinned, it gets unpinned automatically
- Post author or collaborators can pin
- Pinned comment always appears first in GET /comments
- Sends notification to comment author
Business Rules:
Request Headers:
| Header | Type | Required | Description |
|---|---|---|---|
| Authorization | string | Yes | Bearer token for authentication |
| Content-Type | string | Yes | Must be application/json |
Path Parameters:
| Parameter | Type | Required | Description | Validation |
|---|---|---|---|---|
| postId | string | Yes | UUID of the post | Must be valid UUID format |
| commentId | string | Yes | UUID of comment to pin | Must be valid UUID, must be top-level comment |
Success Response JSON Sample:
{
"success": true,
"httpStatus": "OK",
"message": "Comment pinned successfully",
"action_time": "2025-12-11T10:30:45",
"data": null
}
Standard Error Types:
400 BAD_REQUEST: Cannot pin replies, only top-level comments401 UNAUTHORIZED: Authentication required403 FORBIDDEN: Not post author/collaborator404 NOT_FOUND: Post or comment not found500 INTERNAL_SERVER_ERROR: Unexpected errors
Error Response Examples:
Cannot Pin Reply (400):
{
"success": false,
"httpStatus": "BAD_REQUEST",
"message": "Cannot pin reply",
"action_time": "2025-12-11T10:30:45",
"data": "Only top-level comments can be pinned. Replies cannot be pinned."
}
Use Case Examples:
Example 1: Pin Important Comment
POST /e-social/posts/550e8400-e29b-41d4-a716-446655440000/comments/770e8400-e29b-41d4-a716-446655440001/pin
Post author pins helpful comment
Result: Comment appears at top, comment author notified, isPinned = true
Example 2: Pin New Comment (Auto-Unpins Previous)
POST /e-social/posts/550e8400-e29b-41d4-a716-446655440000/comments/880e8400-e29b-41d4-a716-446655440002/pin
Already have pinned comment
Result: Previous comment unpinned automatically, new comment pinned
50. Unpin Comment
Purpose: Remove pin from a comment
Endpoint: DELETE {base_url}/e-social/posts/comments/{commentId}/pin
Access Level: 🔒 Protected (Requires Bearer Token Authentication)
Authentication: Bearer Token
Behavior:
- Removes pin from comment
- Sets isPinned flag to false
- Comment returns to normal sort order (by createdAt)
- Post author or collaborators can unpin
- No notification sent
- Idempotent: Unpinning non-pinned comment returns success
Business Rules:
Request Headers:
| Header | Type | Required | Description |
|---|---|---|---|
| Authorization | string | Yes | Bearer token for authentication |
| Content-Type | string | Yes | Must be application/json |
Path Parameters:
| Parameter | Type | Required | Description | Validation |
|---|---|---|---|---|
| commentId | string | Yes | UUID of comment to unpin | Must be valid UUID format |
Success Response JSON Sample:
{
"success": true,
"httpStatus": "OK",
"message": "Comment unpinned successfully",
"action_time": "2025-12-11T10:30:45",
"data": null
}
Standard Error Types:
51. Like Comment
Purpose: Add a like to a comment
Endpoint: POST {base_url}/e-social/posts/comments/{commentId}/like
Access Level: 🔒 Protected (Requires Bearer Token Authentication)
Authentication: Bearer Token
Behavior:
- Adds current user's like to comment
- Increments comment's likesCount by 1
- Sends notification to comment author (unless self-like)
- Updates user's interaction state (hasLiked = true)
- Idempotent: Multiple like attempts don't create duplicates
- Must be able to view parent post to like comment
Business Rules:
- Visibility: Must have access to parent post
- Blocking: Cannot like comments from blocked users
- Deleted: Cannot like deleted comments
- Idempotent: Safe to call multiple times
- Notification: Comment author notified (unless self-like)
- Counter Update: Atomic increment
Request Headers:
| Header | Type | Required | Description |
|---|---|---|---|
| Authorization | string | Yes | Bearer token for authentication |
| Content-Type | string | Yes | Must be application/json |
Path Parameters:
| Parameter | Type | Required | Description | Validation |
|---|---|---|---|---|
| commentId | string | Yes | UUID of comment to like | Must be valid UUID format |
Success Response JSON Sample:
{
"success": true,
"httpStatus": "OK",
"message": "Comment liked successfully",
"action_time": "2025-12-11T10:30:45",
"data": null
}
Standard Error Types:
52. Unlike Comment
Purpose: Remove a like from a comment
Endpoint: DELETE {base_url}/e-social/posts/comments/{commentId}/like
Access Level: 🔒 Protected (Requires Bearer Token Authentication)
Authentication: Bearer Token
Behavior:
- Removes current user's like from comment
- Decrements comment's likesCount by 1
- No notification sent (silent operation)
- Updates user's interaction state (hasLiked = false)
- Idempotent: Multiple unlike attempts safe
- Can unlike even if comment deleted or user blocked
Business Rules:
- Silent Operation: No notification sent
- Always Allowed: Can unlike even if blocked or comment deleted
- Idempotent: Safe to call multiple times
- Counter Decrement: Atomic decrement
Request Headers:
| Header | Type | Required | Description |
|---|---|---|---|
| Authorization | string | Yes | Bearer token for authentication |
| Content-Type | string | Yes | Must be application/json |
Path Parameters:
| Parameter | Type | Required | Description | Validation |
|---|---|---|---|---|
| commentId | string | Yes | UUID of comment to unlike | Must be valid UUID format |
Success Response JSON Sample:
{
"success": true,
"httpStatus": "OK",
"message": "Comment unliked successfully",
"action_time": "2025-12-11T10:30:45",
"data": null
}
Standard Error Types:
Quick Reference Guide
Common HTTP Status Codes
200 OK: Successful GET/POST/PUT/DELETE request400 Bad Request: Invalid request data or business rule violation401 Unauthorized: Authentication required/failed404 Not Found: Resource not found422 Unprocessable Entity: Validation errors500 Internal Server Error: Server error
Authentication
- Bearer Token: Include
Authorization: Bearer your_tokenin headers
Data Format Standards
- Dates: Use ISO 8601 format (2025-12-11T14:30:00Z)
- IDs: UUID format (e.g., 550e8400-e29b-41d4-a716-446655440000)
- Pagination: 1-indexed pages (page=1 for first page), default size=20
Post Type Values
REGULAR: Standard text/media postPOLL: Poll post with voting options
Post Status Values
DRAFT: Unpublished draftSCHEDULED: Scheduled for future publicationPUBLISHED: Live and visibleDELETED: Soft deleted
Visibility Levels
PUBLIC: Anyone can seeFOLLOWERS: Only followers can seeMENTIONED: Only mentioned users can seePRIVATE: Only author can see
Permission Levels
EVERYONE: All usersFOLLOWERS: Only followersMENTIONED: Only mentioned users (for comments)DISABLED: Feature disabled
No comments to display
No comments to display