Chorki Mobile App — API Reference
Chorki Mobile App — API Reference
Section titled “Chorki Mobile App — API Reference”Reverse-mapped from the Flutter app’s data layer (lib/data/datasources/** and lib/core/network/dio_api_provider.dart). This documents every network call the app makes.
Companion files in this folder:
chorki-api.postman_collection.json— import into Postman or Hoppscotch. Contains all requests, descriptions, and saved real responses.chorki-api.postman_environment.json— variables (base URLs,token,country,language).
| Variable | Value | Purpose |
|---|---|---|
{{static_base}} |
https://api-static.chorki.com | Catalog/content — GET, CDN-cached (7-day max-stale). Paths under /v1, /v2. |
{{dynamic_base}} |
https://api-dynamic.chorki.com | Auth + user data & writes. Paths under /v1, /v2, /v3. |
{{ipinfo_base}} |
https://ipinfo.chorki.com/api/v2 | Geo / VPN detection (sets country). |
{{matomo_base}} |
https://analytics.chorki.com | Matomo analytics (base from settings API). |
{{frontend_base}} |
https://www.chorki.com | Web frontend: captcha page + in-app WebViews. |
{{video_cdn_base}} |
https://video.chorkicdn.com | HLS playlists / segments. |
Staging: the app uses
api-static-porikkhamulok.chorki.netandapi-dynamic-porikkhamulok.chorki.net(and the Turnstile test site key) when built with--dart-define=USE_STAGING=true; seelib/core/constant/api_url_const.dart.
Global conventions
Section titled “Global conventions”Applied automatically by DioApiProvider to every backend call:
- Query params:
country=<code>andplatform=mobileon all calls; GETs additionally sendlanguage=<en|bn>. - Headers:
Accept: application/json,Content-Type: application/json, aua_client_hintsUser-Agent, andAuthorization: Bearer <token>when a user is logged in. - Timeouts: GET 20s · POST 30s · PUT/DELETE 60s.
- Caching: static GETs use
dio_cache_interceptorwith 7-day max-stale (cache is bypassed on 401/403).
Authentication
Section titled “Authentication”- Obtain a bearer token via one of the Auth flows (phone-OTP, email/password, or social). The token is returned as
result.token. - Set the
tokenvariable (collection or environment) to that value. All authenticated requests send it asBearer {{token}}. - Captcha:
register,send-otp, and everyloginrequire a Cloudflare Turnstilecaptchatoken from the{{frontend_base}}/captchawebview (siteKey0x4AAAAAADILz4KWcCAtxCtt). It is short-lived and single-use.
Endpoints
Section titled “Endpoints”64 requests across 19 groups. ✅ = a real production response is saved in the collection as an example.
Settings & Config
Section titled “Settings & Config”App bootstrap: server-driven settings, geo/VPN detection, ads config. All public.
| Method | Path | Auth | Live | Purpose |
|---|---|---|---|---|
GET |
/v2/settings |
— | ✅ | Bootstrap configuration: navigation tabs, language config, min app versions, Matomo analyt… |
GET |
(ipinfo) / |
— | ✅ | Returns caller’s country and proxy/VPN flags |
GET |
/v1/ads |
— | ✅ | Ad units / AdMob configuration for free-tier playback |
Phone-OTP, email/password, and social login flows on api-dynamic /v3 & /v2, plus session management. Login/register/OTP endpoints require a Cloudflare Turnstile captcha token.
| Method | Path | Auth | Live | Purpose |
|---|---|---|---|---|
POST |
/v3/auth/login |
— | ⏳ | Step 1 of phone login: sends an OTP SMS to the number |
POST |
/v3/auth/login |
— | ⏳ | Step 2 of phone login: exchanges number+OTP for a bearer token (`result |
POST |
/v3/auth/send-otp |
— | ⏳ | Sends an OTP to the given email (signup / verification flow) |
POST |
/v3/auth/register |
— | ⏳ | Starts email signup; server emails an OTP which is then verified via /v2/auth/verify-otp a… |
POST |
/v3/auth/login |
— | ⏳ | Email/password login, returns bearer token in `result |
POST |
/v2/auth/verify-otp |
— | ⏳ | Verifies the OTP emailed during signup |
POST |
/v2/auth/set-password |
— | ⏳ | Final step of email signup: sets the account password using the verified OTP |
POST |
/v2/auth/check-email |
— | ⏳ | Tells the auth bottomsheet whether to show login (existing) or signup (new) for this email |
POST |
/v1/auth/oauth/register |
— | ⏳ | Login/registration with a Google or Apple identity token |
GET |
/v1/auth/user |
🔒 | ⏳ | Current user profile incl |
POST |
/v1/auth/user/vppa-consent |
🔒 | ⏳ | Records the user’s acceptance of the VPPA (Video Privacy Protection Act) consent prompt |
DELETE |
/v1/auth/device/authorizations |
🔒 | ⏳ | Rejecting VPPA consent deletes the device authorization (device is signed out server-side) |
POST |
/v1/auth/logout |
🔒 | ⏳ | Invalidates the bearer token server-side; app then clears the cached user |
Devices
Section titled “Devices”Push-token registration and device/stream limit checks. Bearer auth.
| Method | Path | Auth | Live | Purpose |
|---|---|---|---|---|
POST |
/v1/auth/device/tokens |
🔒 | ⏳ | Registers the FCM/APNs token so the backend can push notifications |
GET |
/v1/auth/device/authorizations/usages |
🔒 | ⏳ | How many devices are authorized vs |
GET |
/v1/user/watch-history/active-stream |
🔒 | ⏳ | Number of concurrent playback streams on the account (enforces stream limits before starti… |
Home & Pages
Section titled “Home & Pages”Server-driven tab pages (tab URIs come from the settings API) with cursor pagination.
| Method | Path | Auth | Live | Purpose |
|---|---|---|---|---|
GET |
/v2/:page_uri |
— | ✅ | Section-based page payload for a bottom-nav/header tab |
GET |
/v2/movie |
— | ✅ | Concrete example of a tab page request (Movies tab) |
GET |
/v2/ |
— | ✅ | Continuation request for infinite scroll |
Content
Section titled “Content”Content detail pages, adjacent-episode lookup, and the view counter.
| Method | Path | Auth | Live | Purpose |
|---|---|---|---|---|
GET |
/v1/:type/:slug |
— | ✅ | Full detail page for a content item: metadata, playback URL (HLS master playlist on the CD… |
GET |
/v1/:type/:slug/adjacent |
— | ✅ | Previous/next episodes relative to the given content (used by the player’s next-episode lo… |
POST |
/v1/analytics/views |
— | ⏳ | Increments the view counter when a content page is opened |
Series
Section titled “Series”Season and episode listings for series.
| Method | Path | Auth | Live | Purpose |
|---|---|---|---|---|
GET |
/v1/series/:slug/seasons |
— | ✅ | All seasons for a series |
GET |
/v1/series/:slug/episodes |
— | ✅ | Episodes of one season, paginated |
Search
Section titled “Search”Full-text search (dynamic host), advanced-search meta types and meta lists.
| Method | Path | Auth | Live | Purpose |
|---|---|---|---|---|
GET |
/v1/search |
— | ✅ | Full-text content search with optional meta filters |
GET |
/v2/settings/content-types |
— | ✅ | Meta types (genres, casts, …) used to build the advanced-search filter UI |
GET |
/v1/metas/:slug |
— | ✅ | Lists metas of one type (e |
Collections
Section titled “Collections”Curated list pages (see-more targets).
| Method | Path | Auth | Live | Purpose |
|---|---|---|---|---|
GET |
/v1/lists/:slug |
— | ✅ | Curated collection page (‘see more’ targets from home sections) |
Meta & Artists
Section titled “Meta & Artists”Artist/meta profile pages and the artists archive with filters.
| Method | Path | Auth | Live | Purpose |
|---|---|---|---|---|
GET |
/v1/metas/:type/:slug |
— | ✅ | Artist/meta profile page with their content sections (route comes from content metas or th… |
GET |
/v1/icons |
— | ✅ | Paginated artists archive |
GET |
/v1/icons |
— | ✅ | Concrete example of the icons archive with type + search filters combined |
Shorts
Section titled “Shorts”Vertical short-video (bytes) feed.
| Method | Path | Auth | Live | Purpose |
|---|---|---|---|---|
GET |
/v1/suggestions/bytes |
— | ✅ | Vertical short-video feed |
Watchlist
Section titled “Watchlist”User playlists CRUD. Note: create and add-item share POST /v1/user/watchlists. Bearer auth.
| Method | Path | Auth | Live | Purpose |
|---|---|---|---|---|
GET |
/v1/user/watchlists |
🔒 | ⏳ | All watchlist collections of the user, optionally with their items |
POST |
/v1/user/watchlists |
🔒 | ⏳ | Creates a new (empty) named watchlist |
POST |
/v1/user/watchlists |
🔒 | ⏳ | Same endpoint as create — sending playlist_id + playable_id/playable_type toggles th… |
GET |
/v1/user/watchlists/:slug |
🔒 | ⏳ | Items inside one watchlist |
PUT |
/v1/user/watchlists/:id |
🔒 | ⏳ | Renames a watchlist |
DELETE |
/v1/user/watchlists/:id/remove-item |
🔒 | ⏳ | Removes one item from a watchlist (DELETE with JSON body) |
DELETE |
/v1/user/watchlists/:id |
🔒 | ⏳ | Deletes the whole watchlist |
Watch History
Section titled “Watch History”Playback progress reporting, continue-watching, history search and removal. Bearer auth.
| Method | Path | Auth | Live | Purpose |
|---|---|---|---|---|
GET |
/v1/user/watch-history |
🔒 | ⏳ | Full watch history of the active profile |
POST |
/v1/user/watch-history |
🔒 | ⏳ | Reports playback progress |
POST |
/v1/user/watch-history/search |
🔒 | ⏳ | Looks up history entries for a specific content |
GET |
/v1/user/watch-history/continue-watching |
🔒 | ⏳ | Continue-watching rail for the home screen |
DELETE |
/v1/user/watch-history/:content_id |
🔒 | ⏳ | Removes a single content from the history |
DELETE |
/v1/user/watch-history |
🔒 | ⏳ | ⚠️ Destructive: wipes the entire watch history of the active profile |
Profiles
Section titled “Profiles”Multi-profile support: list and switch (PIN for locked profiles). Bearer auth.
| Method | Path | Auth | Live | Purpose |
|---|---|---|---|---|
GET |
/v1/user/profiles |
🔒 | ⏳ | All profiles on the account (multi-profile support incl |
POST |
/v1/user/profiles/:id/switch |
🔒 | ⏳ | Switches the active profile |
Reactions
Section titled “Reactions”Like/love/dislike reactions: batch check + toggle. Bearer auth.
| Method | Path | Auth | Live | Purpose |
|---|---|---|---|---|
POST |
/v1/user/content-reaction/check |
🔒 | ⏳ | Returns the user’s existing reactions for a batch of contents (used on content pages and t… |
POST |
/v1/user/content-reaction/react |
🔒 | ⏳ | Creates/updates a reaction |
Subscription & Payments
Section titled “Subscription & Payments”SVOD packages and store receipt validation (Google Play / App Store).
| Method | Path | Auth | Live | Purpose |
|---|---|---|---|---|
GET |
/v1/packages |
— | ✅ | Available subscription plans (price, duration, features, store product ids) |
POST |
/v1/payment/liap/validate/google_play |
🔒 | ⏳ | Server-side receipt validation after a Google Play Billing purchase; activates the subscri… |
POST |
/v1/payment/liap/validate/app_store |
🔒 | ⏳ | Server-side receipt validation for Apple App Store purchases |
Purchases
Section titled “Purchases”TVOD purchases/rentals of the user. Bearer auth.
| Method | Path | Auth | Live | Purpose |
|---|---|---|---|---|
GET |
/v1/user/purchases/contents |
🔒 | ⏳ | TVOD purchases/rentals of the user; paginated via `links |
Notifications
Section titled “Notifications”Server-driven popup notifications.
| Method | Path | Auth | Live | Purpose |
|---|---|---|---|---|
GET |
/v2/popup-notifications |
— | ✅ | Marketing/announcement popups shown on the home screen |
Analytics
Section titled “Analytics”Matomo media-analytics hits (tracker URL comes from settings).
| Method | Path | Auth | Live | Purpose |
|---|---|---|---|---|
GET |
(matomo) /matomo.php |
— | ✅ | Raw Matomo tracking endpoint |
Auxiliary Services
Section titled “Auxiliary Services”Everything else the app touches that is not the core REST API: captcha & payment WebViews, HLS CDN, local playback proxy, SDK-managed trackers.
| Method | Path | Auth | Live | Purpose |
|---|---|---|---|---|
GET |
(web) /captcha |
— | ✅ | HTML page hosting the Cloudflare Turnstile widget (siteKey 0x4AAAAAADILz4KWcCAtxCtt) |
GET |
(award) /carnival |
— | ✅ | Promotional awards page opened in a WebView from the /awards deeplink |
GET |
(web) /subscribe |
— | · | URL pattern for every in-app WebView that needs the user’s session: subscription checkout … |
GET |
(cdn) /transcoded/:asset_id/playlist.m3u8 |
— | ✅ | Playback: content responses carry an HLS master-playlist URL on the video CDN |
GET |
(local) /<downloaded-asset-path> |
— | · | Not a remote API: for offline playback the app runs an HTTP server on 127 |
GET |
(marktag) / |
— | · | Marktag SDK is initialized with tag host `mtag-cayk |
Legend: 🔒 needs bearer token · ⏳ live capture pending a test token · · not executed (WebView/SDK/local).
Request bodies (writes)
Section titled “Request bodies (writes)”Exact JSON shapes for POST/PUT/DELETE (from the app’s payload builders):
POST /v3/auth/login — Request OTP (phone)
{ "number": "+8801XXXXXXXXX", "captcha": "<turnstile-token>"}POST /v3/auth/login — Login with phone + OTP
{ "number": "+8801XXXXXXXXX", "otp": 1234, "type": "android", "deviceinfo": { "brand": "samsung", "device": "a52q", "model": "SM-A525F", "manufacturer": "samsung", "product": "a52qnsxx", "id": "TP1A.220624.014", "isPhysicalDevice": true, "version": { "sdkInt": 34, "release": "14", "securityPatch": "2025-11-01" } }, "captcha": "<turnstile-token>"}POST /v3/auth/send-otp — Send OTP (email)
{ "email": "user@example.com", "captcha": "<turnstile-token>"}POST /v3/auth/register — Register (email)
{ "email": "user@example.com", "captcha": "<turnstile-token>"}POST /v3/auth/login — Login with email + password
{ "email": "user@example.com", "password": "<password>", "type": "android", "captcha": "<turnstile-token>", "deviceinfo": { "brand": "samsung", "device": "a52q", "model": "SM-A525F", "manufacturer": "samsung", "product": "a52qnsxx", "id": "TP1A.220624.014", "isPhysicalDevice": true, "version": { "sdkInt": 34, "release": "14", "securityPatch": "2025-11-01" } }}POST /v2/auth/verify-otp — Verify email OTP
{ "email": "user@example.com", "otp": "1234"}POST /v2/auth/set-password — Set password (email signup)
{ "password": "<new-password>", "otp": "1234", "email": "user@example.com"}POST /v2/auth/check-email — Check email exists
{ "email": "user@example.com"}POST /v1/auth/oauth/register — Social login (OAuth register)
{ "token": "<google-or-apple-id-token>", "oauth_type": "google", "type": "android", "deviceinfo": { "brand": "samsung", "device": "a52q", "model": "SM-A525F", "manufacturer": "samsung", "product": "a52qnsxx", "id": "TP1A.220624.014", "isPhysicalDevice": true, "version": { "sdkInt": 34, "release": "14", "securityPatch": "2025-11-01" } }}POST /v1/auth/device/tokens — Register push-notification device token
{ "device_token": "<fcm-token>", "platform": "android", "app_version": "2.1.1"}POST /v1/analytics/views — Record view count
{ "content_id": 227012874518691840, "content_type": "App\\Models\\Video"}POST /v1/user/watchlists — Create watchlist
{ "title": "My favourites"}POST /v1/user/watchlists — Add content to watchlist
{ "playlist_id": "<watchlist-id>", "playable_id": 227012874518691840, "playable_type": "App\\Models\\Video"}PUT /v1/user/watchlists/:id — Rename watchlist
{ "title": "Renamed list"}DELETE /v1/user/watchlists/:id/remove-item — Remove item from watchlist
{ "playable_id": 227012874518691840, "playable_type": "App\\Models\\Video"}POST /v1/user/watch-history — Add to watch history
{ "history": [ { "content_id": 227012874518691840, "content_type": "App\\Models\\Video", "watched_duration": 120, "watched_at": "2026-07-02T12:00:00.000+0600" } ]}POST /v1/user/watch-history/search — Search watch history
{ "series_id": 203837912592957440}POST /v1/user/profiles/:id/switch — Switch active profile
{ "password": "<pin-if-locked>"}POST /v1/user/content-reaction/check — Check reactions on contents
{ "contents": [ { "content_id": 227012874518691840, "content_type": "App\\Models\\Video" } ]}POST /v1/user/content-reaction/react — React to content
{ "content_id": 227012874518691840, "content_type": "App\\Models\\Video", "type": "like"}POST /v1/payment/liap/validate/google_play — Validate in-app purchase (Google Play)
{ "purchase_token": "<play-billing-purchase-token>", "item_id": "<product-id>"}POST /v1/payment/liap/validate/app_store — Validate in-app purchase (App Store)
{ "receipt": "<base64-app-store-receipt>"}Notes on auxiliary surfaces
Section titled “Notes on auxiliary surfaces”- WebView checkout/account pages: the app takes a URL from the API (
subscription.purchase_url,content.rental_url, tools/account URLs) and appendsaccess_token=<token>&view=app_view. Payment gateways (bKash / SSLCommerz / etc.) run inside those pages;upi://intents are handed to the OS. - HLS playback: content responses carry an HLS master-playlist URL on
{{video_cdn_base}}; the player fetches master → variant → audio playlists and segments. DRM keys come from#EXT-X-KEYURIs. CDN auth tokens arrive in the settings response (obfuscatedytirucesblock). - Offline playback: downloaded HLS is served by a loopback HTTP server on
127.0.0.1:8080(lib/domain/services/local_server.dart) — not a remote endpoint. - SDK-managed: Marktag (
mtag-cayk.chorki.com), Firebase (Analytics/Messaging/Remote Config), Sentry (crash ingest), and Chromecast (binary protobuf on device port 8009) have no directly-callable REST surface.
How this was generated
Section titled “How this was generated”Endpoints were extracted by static analysis of the datasources and DioApiProvider. Public GETs were executed against production to capture real example responses; authenticated and write endpoints are fully documented and their live examples can be captured once a bearer token is set.