Skip to Content

Feed

Endpoint untuk social feed: post, like, comment, dan filter feed. Visibility filtering, hashtag parsing, dan mention notifications mengikuti behavior web — yang berbeda hanya envelope response ({ success, data }).

Semua endpoint memerlukan JWT authentication. Base path: /api/mobile/v1/feed.


GET /feed

List feed dengan cursor-based pagination.

Query Parameters

ParameterTipeKeterangan
feedTypestringall (default), following, discover, trending
limitnumber1-50 (default: 20)
cursorstringLast post ID dari halaman sebelumnya
userIdstringView post user tertentu (own = semua, other = PUBLIC only)
typestringFilter tipe: TEXT, IMAGE, VIDEO, POLL, WORKOUT, ACHIEVEMENT, ACTIVITY

Feed Types

TypeKeterangan
allPublic posts + posts dari following + posts dari FitMatch matches
followingHanya posts dari following (tanpa public fallback)
discoverPublic posts dari non-connections
trendingPosts trending

Contoh Request

curl -X GET "https://fumai.app/api/mobile/v1/feed?feedType=all&limit=20" \ -H "Authorization: Bearer YOUR_ACCESS_TOKEN"
const res = await fetch( 'https://fumai.app/api/mobile/v1/feed?feedType=all&limit=20', { headers: { Authorization: `Bearer ${accessToken}` } } ) const data = await res.json()

Response 200

{ "success": true, "data": { "posts": [ { "id": "clx...", "userId": "clx...", "user": { "id": "clx...", "name": "John", "image": "..." }, "type": "TEXT", "visibility": "PUBLIC", "content": "Hari ini latihan dada 💪", "mediaUrls": [], "likesCount": 12, "commentsCount": 3, "isLiked": true, "createdAt": "2026-05-11T..." } ], "nextCursor": "clx..." } }

Info: nextCursor adalah null jika tidak ada halaman selanjutnya.


POST /feed

Buat post baru.

Request Body

FieldTipeWajibKeterangan
typestringYaTEXT, IMAGE, VIDEO, POLL, WORKOUT, ACHIEVEMENT, ACTIVITY
contentstringTidakIsi post (mendukung hashtag #tag dan mention @username)
visibilitystringTidakPUBLIC (default), FOLLOWERS, PRIVATE
mediaUrlsstring[]TidakURL media (untuk IMAGE/VIDEO)
mediaTypestringTidakMIME type media
activityIdstringTidakLink ke activity
workoutIdstringTidakLink ke workout
achievementIdstringTidakLink ke achievement
pollQuestionstringTidakPertanyaan poll
pollOptionsobject[]TidakOpsi poll: [{ text }]
pollEndsAtstringTidakISO date akhir poll
locationNamestringTidakNama lokasi
latitudenumberTidakGPS latitude
longitudenumberTidakGPS longitude

Contoh Request — Text Post

curl -X POST https://fumai.app/api/mobile/v1/feed \ -H "Authorization: Bearer YOUR_ACCESS_TOKEN" \ -H "Content-Type: application/json" \ -d '{ "type": "TEXT", "content": "Hello!" }'

Contoh Request — Image Post

curl -X POST https://fumai.app/api/mobile/v1/feed \ -H "Authorization: Bearer YOUR_ACCESS_TOKEN" \ -H "Content-Type: application/json" \ -d '{ "type": "IMAGE", "visibility": "PUBLIC", "content": "Beach run! #morning", "mediaUrls": ["https://cdn.fumai.app/posts/..."], "mediaType": "image/jpeg", "locationName": "GBK Stadium" }'
const res = await fetch('https://fumai.app/api/mobile/v1/feed', { method: 'POST', headers: { Authorization: `Bearer ${accessToken}`, 'Content-Type': 'application/json', }, body: JSON.stringify({ type: 'IMAGE', content: 'Beach run! #morning', mediaUrls: ['https://cdn.fumai.app/posts/...'], }), })

Response 201

{ "success": true, "data": { "post": { "id": "clx...", "type": "IMAGE", "content": "..." } } }

Info: Hashtag (#tag) dan mention (@username) di-parse dari content dan disimpan. User yang di-mention mendapat SOCIAL_FEED notification.


GET /feed/:id

Get single post. Increment view count dan respect visibility:

VisibilityAkses
PUBLICSemua user authenticated
FOLLOWERSFollowers + author
PRIVATEAuthor saja
curl -X GET https://fumai.app/api/mobile/v1/feed/POST_ID \ -H "Authorization: Bearer YOUR_ACCESS_TOKEN"

Peringatan: Returns 410 Gone jika post di-delete, 403 Forbidden jika tidak punya akses.


DELETE /feed/:id

Soft-delete post (isDeleted: true). Hanya author yang bisa delete.

curl -X DELETE https://fumai.app/api/mobile/v1/feed/POST_ID \ -H "Authorization: Bearer YOUR_ACCESS_TOKEN"

POST /feed/:id/like

Like post. Otomatis kirim SOCIAL_FEED notification ke author.

curl -X POST https://fumai.app/api/mobile/v1/feed/POST_ID/like \ -H "Authorization: Bearer YOUR_ACCESS_TOKEN"

Response 200

{ "success": true, "data": { "liked": true } }

Error Codes

CodeStatusKeterangan
ALREADY_LIKED400Post sudah di-like

DELETE /feed/:id/like

Unlike post.

curl -X DELETE https://fumai.app/api/mobile/v1/feed/POST_ID/like \ -H "Authorization: Bearer YOUR_ACCESS_TOKEN"

Error Codes

CodeStatusKeterangan
NOT_LIKED400Belum di-like

GET /feed/:id/comment

List comments dengan cursor pagination, sorted oldest-first.

Query Parameters

ParameterTipeKeterangan
cursorstringLast comment ID untuk pagination
limitnumberDefault: 20
parentIdstringList replies dari comment tertentu

Contoh Request

curl -X GET "https://fumai.app/api/mobile/v1/feed/POST_ID/comment?limit=20" \ -H "Authorization: Bearer YOUR_ACCESS_TOKEN"

Response 200

{ "success": true, "data": { "comments": [ { "id": "clx...", "content": "Mantap!", "user": { "name": "Jane" } } ], "nextCursor": "clx..." } }

POST /feed/:id/comment

Buat comment atau reply.

Request Body

FieldTipeWajibKeterangan
contentstringYaIsi comment (mendukung mention @username)
parentIdstringTidakComment ID parent (untuk reply)

Contoh Request

curl -X POST https://fumai.app/api/mobile/v1/feed/POST_ID/comment \ -H "Authorization: Bearer YOUR_ACCESS_TOKEN" \ -H "Content-Type: application/json" \ -d '{ "content": "Mantap @john!" }'
const res = await fetch( `https://fumai.app/api/mobile/v1/feed/${postId}/comment`, { method: 'POST', headers: { Authorization: `Bearer ${accessToken}`, 'Content-Type': 'application/json', }, body: JSON.stringify({ content: 'Mantap @john!' }), } )

Response 201

{ "success": true, "data": { "comment": { "id": "clx...", "content": "Mantap @john!" } } }

Info: Mention (@username) di-link dan user yang di-mention mendapat notifikasi.

Last updated on