Skip to Content

Stories

Endpoint untuk fitur stories 24-jam. Visibility rules: own + followed users + FitMatch matches.

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


GET /stories

Mendapatkan story rings (story bar feed). Sorted: own first → unviewed → newest.

Contoh Request

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

Response 200

{ "success": true, "data": { "storyRings": [ { "userId": "clx...", "userName": "John", "userImage": "https://cdn.fumai.app/...", "storyCount": 3, "hasUnviewed": true, "latestStoryAt": "2026-05-11T...", "isOwn": false } ] } }

GET /stories?userId=:userId

Mendapatkan stories aktif (non-expired) dari user tertentu, dengan view + reaction state.

Query Parameters

ParameterTipeWajibKeterangan
userIdstringYaID user yang stories-nya ingin dilihat

Contoh Request

curl -X GET "https://fumai.app/api/mobile/v1/stories?userId=USER_ID" \ -H "Authorization: Bearer YOUR_ACCESS_TOKEN"

Response 200

{ "success": true, "data": { "stories": [ { "id": "clx...", "userId": "clx...", "user": { "id": "clx...", "name": "John", "image": "..." }, "mediaUrl": "https://cdn.fumai.app/stories/...", "mediaType": "IMAGE", "caption": "Morning run 🏃", "duration": null, "expiresAt": "2026-05-12T...", "createdAt": "2026-05-11T...", "viewCount": 12, "reactionCount": 4, "isViewed": true, "myReaction": "🔥" } ] } }

POST /stories

Buat story baru.

Request Body

FieldTipeWajibKeterangan
mediaUrlstringYaURL media
mediaTypestringYaIMAGE atau VIDEO
captionstringTidakCaption story
textColorstringTidakWarna text (hex)
bgColorstringTidakWarna background (hex)
fontStylestringTidakStyle font (e.g. "bold")
durationnumberTidakDurasi 1-60 detik (untuk VIDEO)

Contoh Request

curl -X POST https://fumai.app/api/mobile/v1/stories \ -H "Authorization: Bearer YOUR_ACCESS_TOKEN" \ -H "Content-Type: application/json" \ -d '{ "mediaUrl": "https://cdn.fumai.app/stories/...", "mediaType": "IMAGE", "caption": "Morning run 🏃", "textColor": "#ffffff", "bgColor": "#1d4ed8" }'
const res = await fetch('https://fumai.app/api/mobile/v1/stories', { method: 'POST', headers: { Authorization: `Bearer ${accessToken}`, 'Content-Type': 'application/json', }, body: JSON.stringify({ mediaUrl: 'https://cdn.fumai.app/stories/...', mediaType: 'IMAGE', caption: 'Morning run 🏃', }), })

Response 201

{ "success": true, "data": { "story": { "id": "clx...", "mediaUrl": "...", "expiresAt": "..." } } }

Info: Stories auto-expire setelah 24 jam. Daily limit: 10 stories per hari.

Error Codes

CodeStatusKeterangan
LIMIT_EXCEEDED429Sudah mencapai daily limit

GET /stories/:id

Get single story. Otomatis menandai story sebagai viewed untuk caller (kecuali owner) dan increment viewCount.

curl -X GET https://fumai.app/api/mobile/v1/stories/STORY_ID \ -H "Authorization: Bearer YOUR_ACCESS_TOKEN"

Error Codes

CodeStatusKeterangan
EXPIRED410Story sudah lewat 24 jam

DELETE /stories/:id

Hapus story. Hanya author yang bisa delete.

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

POST /stories/:id/react

Beri reaction emoji ke story. Upserts reaction (1 reaction per user per story).

Request Body

FieldTipeWajibKeterangan
emojistringYaEmoji 1-4 karakter

Contoh Request

curl -X POST https://fumai.app/api/mobile/v1/stories/STORY_ID/react \ -H "Authorization: Bearer YOUR_ACCESS_TOKEN" \ -H "Content-Type: application/json" \ -d '{ "emoji": "🔥" }'
const res = await fetch( `https://fumai.app/api/mobile/v1/stories/${storyId}/react`, { method: 'POST', headers: { Authorization: `Bearer ${accessToken}`, 'Content-Type': 'application/json', }, body: JSON.stringify({ emoji: '🔥' }), } )

Response 200

{ "success": true, "data": { "reaction": { "emoji": "🔥", "createdAt": "..." } } }

Info: Story owner mendapat STORY_REACTION notification.

Last updated on