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-archiveContent-Length: <file size>Accept-Ranges: bytesX-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
| Code | Meaning |
|---|---|
| 400 | Bad request - missing required parameters |
| 401 | Unauthorized - invalid credentials |
| 403 | Forbidden - invalid token or access denied |
| 404 | Not found - application or file not found |
| 429 | Too many requests - rate limit exceeded |
| 500 | Internal server error |