EasyPlexVersion 2.4 handbook
← Main documentation

EasyPlex 2.4 · buyer integration guide

Complete API reference

This reference documents the mobile authentication contract, representative request and response bodies, standard error envelopes, the complete set of routes invoked by the supplied Android Retrofit source, and the complete registered /admin/* panel surface.

Authentication and transport contract

Android/mobile API

Base URL: https://your-domain.example/api/. Obtain a rotating bearer token from POST tokens/mobile/generate. Protected calls send the bearer token plus the session/device headers. If signing is enabled, sign the exact method, path, timestamp, nonce, and raw body.

Accept: application/json
Authorization: Bearer ACCESS_TOKEN
X-App-Id: easyplex-mobile
X-Device-Id: STABLE_INSTALL_ID
X-Session-Id: MOBILE_SESSION_ID
X-Timestamp: UNIX_SECONDS
X-Nonce: UNIQUE_RANDOM_VALUE
X-Signature: sha256=HEX_HMAC

Admin panel API

Admin endpoints are internal browser endpoints, not a public third-party API. Sign in through the panel first. Laravel sends a session cookie and XSRF-TOKEN cookie; state-changing AJAX requests must include the decoded token as X-XSRF-TOKEN.

Accept: application/json
Content-Type: application/json
Cookie: easyp_cpanel_session=...; XSRF-TOKEN=...
X-XSRF-TOKEN: DECODED_XSRF_COOKIE
X-Requested-With: XMLHttpRequest

Do not expose credentials. Never publish access tokens, HMAC/encryption secrets, admin session cookies, payment keys, purchase codes, private signing material, or production database values. Example values here are placeholders.

Mobile request and response examples

1. Generate a mobile session

POST /api/tokens/mobile/generate
Content-Type: application/json

{
  "app_id": "easyplex-mobile",
  "device_id": "8fe21e37-8a1c-45f0-9085-b992892f8d07",
  "package_name": "com.example.easyplex",
  "platform": "android",
  "timestamp": 1760000000,
  "nonce": "4f3f2448-57a1-4c07-9948-4ef8af6d63c2",
  "signature": "APK_CERTIFICATE_SHA256_64_HEX"
}

200 OK
{
  "success": true,
  "access_token": "eyJ0eXAiOiJKV1QiLCJhbGciOi...",
  "refresh_token": "ROTATING_REFRESH_TOKEN",
  "token_type": "Bearer",
  "expires_in": 3600,
  "refresh_expires_in": 2592000,
  "session_id": "b65892dc-474f-45e7-9bec-3280d91ce01f"
}

2. Sign in a user

POST /api/login
Content-Type: application/json
Authorization: Bearer MOBILE_ACCESS_TOKEN

{
  "email": "[email protected]",
  "password": "A-strong-demo-password"
}

200 OK
{
  "success": true,
  "message": "Login successful",
  "user": {
    "id": 12,
    "name": "Demo Buyer",
    "email": "[email protected]",
    "premuim": 0
  }
}

3. Load application settings

GET /api/settings/en
Accept: application/json
Authorization: Bearer ACCESS_TOKEN

200 OK
{
  "app_name": "EasyPlex",
  "app_version": "2.4",
  "tmdb_lang": "en",
  "enable_download": 1,
  "enable_ads": 0,
  "default_theme": "dark"
}

4. Load the home catalog

GET /api/media/homecontent/en
Accept: application/json
Authorization: Bearer ACCESS_TOKEN

200 OK
{
  "featured": [],
  "movies": {
    "data": [
      {
        "id": 42,
        "name": "Licensed Feature",
        "poster_path": "https://cdn.example.com/posters/42.jpg"
      }
    ]
  },
  "series": { "data": [] },
  "streaming": { "data": [] }
}

5. Search catalog content

GET /api/search?query=licensed
Accept: application/json
Authorization: Bearer ACCESS_TOKEN

200 OK
{
  "movies": [{ "id": 42, "name": "Licensed Feature" }],
  "series": [],
  "animes": [],
  "streaming": []
}

6. Save playback progress

POST /api/watch-history/progress
Content-Type: application/json
Authorization: Bearer ACCESS_TOKEN

{
  "watchable_type": "App\\Movie",
  "watchable_id": 42,
  "episode_id": null,
  "current_position": 754,
  "duration": 6420,
  "device_id": "8fe21e37-8a1c-45f0-9085-b992892f8d07",
  "profile_id": 3
}

200 OK
{
  "success": true,
  "message": "Watch progress saved",
  "progress_percentage": 11.74
}

7. Create a profile

POST /api/profiles
Content-Type: application/json
Authorization: Bearer ACCESS_TOKEN

{
  "name": "Kids",
  "avatar": "avatar-3",
  "is_kids": true
}

201 Created
{
  "success": true,
  "profile": {
    "id": 3,
    "name": "Kids",
    "avatar": "avatar-3",
    "is_kids": true
  }
}

8. Read subscription state

GET /api/subscriptions/me
Accept: application/json
Authorization: Bearer ACCESS_TOKEN

200 OK
{
  "success": true,
  "is_premium": true,
  "subscription": {
    "plan": "Monthly",
    "status": "active",
    "ends_at": "2026-08-29T00:00:00Z"
  }
}

Exact catalog fields vary with enabled modules and settings. Use the supplied Android models as the authoritative consumer contract and test against a staging installation before release.

Admin panel request and response examples

These calls are made by the Vue administration panel after login. Paths are relative to the Laravel public URL and are protected by the panel’s session, authorization, CSRF, and license middleware.

Read settings

GET /admin/settings/data
Accept: application/json
Cookie: easyp_cpanel_session=...

200 OK
{
  "id": 1,
  "app_name": "EasyPlex",
  "app_version": "2.4",
  "enable_security": 1,
  "enable_download": 1
}

Update settings

PUT /admin/settings/update/1
Content-Type: application/json
X-XSRF-TOKEN: DECODED_XSRF_COOKIE
Cookie: easyp_cpanel_session=...; XSRF-TOKEN=...

{
  "app_name": "My Licensed Service",
  "default_theme": "dark",
  "enable_download": 1
}

200 OK
{
  "status": "success",
  "message": "Settings updated successfully"
}

List movies

GET /admin/movies/dataweb?page=1
Accept: application/json
Cookie: easyp_cpanel_session=...

200 OK
{
  "current_page": 1,
  "data": [
    {
      "id": 42,
      "name": "Licensed Feature",
      "active": 1,
      "premuim": 0
    }
  ],
  "last_page": 1,
  "total": 1
}

Create a movie

POST /admin/moviesmedia/storemovie
Content-Type: application/json
X-XSRF-TOKEN: DECODED_XSRF_COOKIE

{
  "name": "Licensed Feature",
  "tmdb_id": 12345,
  "overview": "Licensed description.",
  "poster_path": "https://cdn.example.com/poster.jpg",
  "backdrop_path": "https://cdn.example.com/backdrop.jpg",
  "release_date": "2026-07-29",
  "active": 1,
  "premuim": 0
}

201 Created
{
  "status": "success",
  "message": "Movie created successfully",
  "id": 42
}

Export Android properties

GET /admin/settings/mobile-gradle-properties
Accept: text/plain
Cookie: easyp_cpanel_session=...

200 OK
Content-Disposition: attachment; filename="gradle.properties"

SERVER_BASE_URL=https://stream.example.com/api/
MOBILE_APP_ID=easyplex-mobile
MOBILE_API_HMAC_SECRET=...

Create database backup

POST /admin/settings/database-backup
X-XSRF-TOKEN: DECODED_XSRF_COOKIE
Cookie: easyp_cpanel_session=...

200 OK
Content-Type: application/zip
Content-Disposition: attachment; filename="easyplex-backup-....zip"

[binary ZIP response]

Standard success and error shapes

400 · token request validation

{
  "success": false,
  "message": "Validation failed",
  "errors": {
    "device_id": ["The device id field is required."]
  }
}

401 · invalid APK binding

{
  "success": false,
  "message": "Authentication failed. Invalid APK signature or request parameters.",
  "error_code": "INVALID_SIGNATURE",
  "hint": "Check Laravel logs for validation details."
}

401 · signed request rejected

{
  "success": false,
  "error": {
    "code": "SIGNED_REQUEST_REJECTED",
    "message": "Unauthorized request."
  }
}

401 · session expired

{
  "message": "Unauthenticated."
}

403 · not authorized

{
  "message": "This action is unauthorized."
}

422 · form validation

{
  "message": "The given data was invalid.",
  "errors": {
    "name": ["The name field is required."],
    "tmdb_id": ["The tmdb id must be an integer."]
  }
}

429 · rate limit

{
  "message": "Too Many Attempts."
}

500 · server failure

{
  "message": "Server Error"
}

Production servers must use APP_DEBUG=false. A production error response must never include stack traces, SQL, absolute paths, secrets, or environment values.

Complete Android-used route inventory

Generated from Retrofit annotations in the supplied Android source. Provider-specific interfaces may use a separately configured base URL; inspect the source column before assuming a route belongs to the EasyPlex Laravel host.

Loading…
MethodRelative routeSource

Complete registered admin-panel route inventory

Generated from php artisan route:list --json in the supplied Laravel 2.4 backend. Dynamic values use Laravel’s {parameter} syntax. Middleware and controller names help buyers identify authentication and implementation requirements.

Loading…
MethodRouteController/actionMiddleware
Copied to clipboard