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
| Parameter | Tipe | Keterangan |
|---|---|---|
feedType | string | all (default), following, discover, trending |
limit | number | 1-50 (default: 20) |
cursor | string | Last post ID dari halaman sebelumnya |
userId | string | View post user tertentu (own = semua, other = PUBLIC only) |
type | string | Filter tipe: TEXT, IMAGE, VIDEO, POLL, WORKOUT, ACHIEVEMENT, ACTIVITY |
Feed Types
| Type | Keterangan |
|---|---|
all | Public posts + posts dari following + posts dari FitMatch matches |
following | Hanya posts dari following (tanpa public fallback) |
discover | Public posts dari non-connections |
trending | Posts 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:
nextCursoradalahnulljika tidak ada halaman selanjutnya.
POST /feed
Buat post baru.
Request Body
| Field | Tipe | Wajib | Keterangan |
|---|---|---|---|
type | string | Ya | TEXT, IMAGE, VIDEO, POLL, WORKOUT, ACHIEVEMENT, ACTIVITY |
content | string | Tidak | Isi post (mendukung hashtag #tag dan mention @username) |
visibility | string | Tidak | PUBLIC (default), FOLLOWERS, PRIVATE |
mediaUrls | string[] | Tidak | URL media (untuk IMAGE/VIDEO) |
mediaType | string | Tidak | MIME type media |
activityId | string | Tidak | Link ke activity |
workoutId | string | Tidak | Link ke workout |
achievementId | string | Tidak | Link ke achievement |
pollQuestion | string | Tidak | Pertanyaan poll |
pollOptions | object[] | Tidak | Opsi poll: [{ text }] |
pollEndsAt | string | Tidak | ISO date akhir poll |
locationName | string | Tidak | Nama lokasi |
latitude | number | Tidak | GPS latitude |
longitude | number | Tidak | GPS 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 daricontentdan disimpan. User yang di-mention mendapatSOCIAL_FEEDnotification.
GET /feed/:id
Get single post. Increment view count dan respect visibility:
| Visibility | Akses |
|---|---|
PUBLIC | Semua user authenticated |
FOLLOWERS | Followers + author |
PRIVATE | Author saja |
curl -X GET https://fumai.app/api/mobile/v1/feed/POST_ID \
-H "Authorization: Bearer YOUR_ACCESS_TOKEN"Peringatan: Returns
410 Gonejika post di-delete,403 Forbiddenjika 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
| Code | Status | Keterangan |
|---|---|---|
ALREADY_LIKED | 400 | Post 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
| Code | Status | Keterangan |
|---|---|---|
NOT_LIKED | 400 | Belum di-like |
GET /feed/:id/comment
List comments dengan cursor pagination, sorted oldest-first.
Query Parameters
| Parameter | Tipe | Keterangan |
|---|---|---|
cursor | string | Last comment ID untuk pagination |
limit | number | Default: 20 |
parentId | string | List 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
| Field | Tipe | Wajib | Keterangan |
|---|---|---|---|
content | string | Ya | Isi comment (mendukung mention @username) |
parentId | string | Tidak | Comment 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.