Android OTA Platform - REST API Documentation

Secure REST API for integrating your Android apps with the OTA update platform.

Base URL: https://j.hafidy.com/api/


Authentication

All API endpoints require either a secret_key or app_token for authentication. These are auto-generated when you create an application in the admin panel.

POST GET 1. Check Update

Check if a new update is available for the application.

Endpoint:
POST https://j.hafidy.com/api/check-update.php
GET  https://j.hafidy.com/api/check-update.php?app_id=APP_XXX&token=AT_XXX&version_code=1
Request Body (POST JSON):
{
    "application_id": "APP_XXXXXXXX",
    "secret_key": "SK_XXXX...XXXX",
    "version_code": 1,
    "device_uuid": "abc123-device-id",
    "device_model": "Pixel 7",
    "device_brand": "Google",
    "android_version": "14",
    "android_api_level": 34
}
Response:
{
    "success": true,
    "application_id": "APP_XXXXXXXX",
    "has_update": true,
    "force_update": false,
    "critical_update": false,
    "latest_version": {
        "version_code": 2,
        "version_name": "1.1.0",
        "update_type": "stable",
        "priority": 5
    },
    "min_version": 1,
    "release_date": "2024-01-15 10:30:00",
    "apk_url": "https://example.com/api/download.php?app_id=APP_XXX&token=AT_XXX",
    "download_url": "https://example.com/api/download.php?...",
    "file_size": 25165824,
    "sha256": "abc123...",
    "md5": "def456...",
    "update_message": "Bug fixes and improvements",
    "popup_title": "New Update Available",
    "popup_description": "Version 1.1.0 is now available",
    "update_button_text": "Update Now",
    "skip_button_text": "Later",
    "allow_skip": true,
    "server_time": "2024-01-15T10:35:00+00:00",
    "api_version": "1.0"
}
GET 2. Download APK

Download the latest APK file. Supports resume via HTTP Range header.

Endpoint:
GET https://j.hafidy.com/api/download.php?app_id=APP_XXX&token=AT_XXX
Headers in response:
  • Content-Type: application/vnd.android.package-archive
  • Content-Length: <file size>
  • Accept-Ranges: bytes
  • X-SHA256: <sha256 hash>
  • X-MD5: <md5 hash>
POST 3. Register Device

Register or update a device in the platform.

POST https://j.hafidy.com/api/register-device.php

{
    "application_id": "APP_XXX",
    "secret_key": "SK_XXX",
    "device_uuid": "abc123",
    "device_model": "Pixel 7",
    "device_brand": "Google",
    "android_version": "14",
    "android_api_level": 34,
    "version_code": 1
}
Response:
{
    "success": true,
    "message": "Device registered successfully"
}
GET 4. App Info

Get application information (no authentication via secret_key required, only app_token).

GET https://j.hafidy.com/api/app-info.php?app_id=APP_XXX&token=AT_XXX
Android Integration Example (Kotlin)
// Check for update from your Android app
fun checkForUpdate(context: Context, currentVersionCode: Int) {
    val json = JSONObject().apply {
        put("application_id", "APP_XXXXXXXX")
        put("secret_key", "SK_XXXX")
        put("version_code", currentVersionCode)
        put("device_uuid", getDeviceUuid(context))
        put("device_model", Build.MODEL)
        put("device_brand", Build.BRAND)
        put("android_version", Build.VERSION.RELEASE)
        put("android_api_level", Build.VERSION.SDK_INT)
    }

    val request = JsonObjectRequest(
        Request.Method.POST,
        "https://your-domain.com/api/check-update.php",
        json,
        { response ->
            if (response.optBoolean("has_update")) {
                val forceUpdate = response.optBoolean("force_update")
                showUpdateDialog(response, forceUpdate)
            }
        },
        { error -> Log.e("OTA", "Update check failed: $error") }
    )
    Volley.newRequestQueue(context).add(request)
}

// Download APK
fun downloadApk(downloadUrl: String, sha256: String) {
    val request = DownloadManager.Request(Uri.parse(downloadUrl)).apply {
        setMimeType("application/vnd.android.package-archive")
        setTitle("Downloading Update")
        setNotificationVisibility(DownloadManager.Request.VISIBILITY_VISIBLE)
        setDestinationInExternalFilesDir(context, Environment.DIRECTORY_DOWNLOADS, "update.apk")
    }
    val dm = context.getSystemService(Context.DOWNLOAD_SERVICE) as DownloadManager
    dm.enqueue(request)
}
Error Codes
CodeMeaning
400Bad request - missing required parameters
401Unauthorized - invalid credentials
403Forbidden - invalid token or access denied
404Not found - application or file not found
429Too many requests - rate limit exceeded
500Internal server error