Skip to main content

Endpoints

All public traffic enters through the gateway, which strips the prefix and forwards to a container. The path a controller sees is the upstream column, not the public one.

Public paths​

Public pathUpstreamContainer
// (not stripped)website
/webview//webview SPA
/admin//admin SPA
/api/customer//customer API
/api/admin//admin API
/stream//multimedia
/trailler/:idhandled by the websitewebsite

Auth legend: P public · U Firebase ID token · U? optional token · E existence check only · S provider secret · A admin JWT · SA super admin.

Customer API​

Mounted at /, reached publicly under /api/customer/.

AreaEndpointsMethodAuth
Index/, /version, /healthGETP
Auth/signup, /loginPOSTP
Users/users/verifySession/:userId, /users/verifySubscriptionToken, /users/:idGETP
Users/users/updateUserPhoneNumber, /users/verifySubcription, /users/createPlaylist, /users/addVideoToPlayList, /users/deletePlaylist, /users/deleteVideoInsidePlaylist, /users/addUserDevice, /users/updateUserPoint, /users/updateUserLocation, /users/updateFcmToken, /users/updateUserPayPhoneNumberPATCHP
Videos/videos/getActiveVideos, /videos/season/:seasonId, /videos/series/:seriesId, /videos/series/:seriesId/season/:seasonNumber, /videos/:idGETP
Videos/videos/getArrayOfVideosPOSTP
Feedback/videosFeedback/addVideoFeedBackPATCHP
Pay/pay/stripe/webhook, /pay/webhookPOSTS
Pay/pay/payByMobileMoneyPOSTE
Pay/pay/stripe/create-checkout-session, /create-embedded-checkout-session, /portal-session, /cancel, /change-planPOSTE
Subscriptions/subscriptions/getEnableSubscriptionGETP
Series/series, /series/active, /series/search, /series/category/:category, /series/status/:status, /series/:id/seasons, /series/:idGETP
Seasons/seasons/active, /seasons/:id/episodes, /seasons/:id, /seasons/series/:seriesId, /seasons/series/:seriesId/active, /seasons/series/:seriesId/season/:seasonNumberGETP
Search/searchGETP
Catalog/catalog/home, /catalog/recommendationsGETU?
Catalog/catalog/top10, /catalog/browseGETP
Me/me, /me/my-list, /me/continue-watching, /me/subscriptionGETU
Me/me/my-list/:videoIdPUT, DELETEU
Me/me/viewsPOSTU
Me/me/views/:videoId/progressPATCHU
/series is not the public list

The website deliberately calls /series/active. /series also returns unpublished documents. The same rule applies to any new catalogue surface.

/me* is the only strongly authenticated surface. Everything marked E trusts a client-supplied user ID after an existence check; see Security notes.

Admin API​

Mounted at /, reached publicly under /api/admin/.

AreaEndpointsMethodAuth
Index/, /healthGETP
Admin/admin/loginPOSTP
Admin/admin/logout, /admin/admins, /admin/admins/:id, /admin/change-password—A
Admin/admin/signupPOSTA + SA
Admin/admin/admins/:idDELETEA + SA
Admin/admin/audit-logsGETA + SA
Users/users, /users/:idGETA
Videos/videos, /videos/getVideoById/:id, /videos/getArrayOfVideos, /videos/:id/deletionPreview, /videos/standaloneGETA
Videos/videos/addVideo, /videos/saveVideoPOSTA
Videos/videos, /videos/initThumbnailUpdate, /videos/confirmThumbnailUpdatePUTA
Videos/videos/:id, /videos (body id)DELETEA
Uploads/videos/signUpload, /videos/completeUploadPOSTA + rate limit
Uploads/videos/uploadStatusGETA
Uploads/videos/retryArtworkPOSTA
Notifications/notificationsGETA
Notifications/notifications/streamGET (SSE)A via cookie
Feedback/videosFeedback/getVideoFeedBackGETA
Pay/pay/payByMobileMoneyPOSTDTO + existence
Pay/pay/webhookPOSTverif-hash
Subscriptions/subscriptions, /subscriptions/getEnableSubscriptionGETA
Subscriptions/subscriptions/createSubscriptionPOSTA
Subscriptions/subscriptions/updateSubScriptionDefaultPrice, /subscriptions/:idPUTA
Subscriptions/subscriptions/:id/togglePATCHA
Subscriptions/subscriptions/:idDELETEA
Series/series, /series/active, /series/search, /series/category/:category, /series/status/:status, /series/:idGETA
Series/series/create, /series/savePOSTA
Series/series/initThumbnailUpdate, /series/confirmThumbnailUpdate, /seriesPUTA
Series/series/:id/status, /series/:id/activatePATCHA
Series/series (body id)DELETEA
Seasons/seasons/series/:seriesId, /seasons/series/:seriesId/active, /seasons/series/:seriesId/season/:seasonNumber, /seasons/:idGETA
Seasons/seasons/create, /seasons/savePOSTA
Seasons/seasonsPUTA
Seasons/seasons/:id/activatePATCHA
Seasons/seasons (body id)DELETEA
Episodes/episodes/series/:seriesId, /episodes/season/:seasonId, /episodes/series/:seriesId/season/:seasonNumber/episode/:episodeNumber, /episodes/:episodeIdGETA
Episodes/episodes/convertPOSTA
Episodes/episodes/:episodeId/convert-to-standalone, /episodes/movePATCHA
Episodes/episodes/:episodeId, /episodesDELETEA
Dashboard/dashboard/overview, /dashboard/videos, /dashboard/processing, /dashboard/users, /dashboard/paymentsGETA
Static paths must be declared first

/videos/uploadStatus and /videos/retryArtwork are static paths. They must be registered before any /videos/:id/... route, or the :id parameter shadows them and the request reaches the wrong controller.

Upload kinds​

signUpload accepts eight kinds:

video, trailer, thumbnail, thumbnailPreview, series-thumbnail, series-trailer, season-thumbnail, season-trailer.

Images get a V4 signed PUT; video and trailer get a resumable session URI. The extension is recorded at signing time so an object name never ends in .undefined.

Multimedia​

PathPurpose
/healthLiveness
/api/cache/*Cache statistics and eviction (unauthenticated)
/videos/*, /trailers/*HLS playlists and segments
catch-allProxied to node-media-server

RTMP is on :1935, NMS HTTP on :8080, Express on :8000. Publish, play and cache stats are unauthenticated and CORS is *.

Health​

ServiceProbeBody
Both APIsGET /health{status, appEnv, production[, version]}
Static frontendsGET /healthzsmall text
MultimediaGET /healthsmall JSON

A body with only {status} is an older build, not a different contract.

Next: Branch strategy · Security notes.