AppZone Store API

Read-only discovery plus download, review and report endpoints. Everything a Flutter or native Android client needs to browse the store and keep installed apps up to date.

Base URL
https://apkzone.in/api/v1

Response envelope

Every response uses the same shape, success or failure.

Success
{
    "status": true,
    "message": "Apps fetched successfully",
    "data": []
}
Error
{
    "status": false,
    "message": "App not found"
}
Validation error (422)
{
    "status": false,
    "message": "Validation failed",
    "errors": { "rating": "Rating must be at least 1." }
}

Authentication

Discovery endpoints are public. Posting a review requires a user bearer token; downloads and reports accept one optionally so the action can be attributed.

Authorization: Bearer <token>

Tokens are stored only as SHA-256 digests, can carry an expiry, and are revocable. A token belonging to a suspended user stops working immediately.

Pagination

https://apkzone.in/api/v1/apps?page=2&limit=20

Default page size 20, maximum 100. List responses carry a pagination block with total, per_page, current_page, last_page, from, to and has_more.

Rate limits

BucketLimitWindow
General API120 requests60 s
Downloads30 requests1 hour
Review posting10 requests1 hour
Reporting10 requests1 hour

Responses carry X-RateLimit-Limit and X-RateLimit-Remaining. On 429 a Retry-After header states how many seconds to wait.

Error codes

CodeMeaning
200Success.
201Resource created (review, report).
400Malformed request.
401Authentication required — send a valid bearer token.
403Not permitted — the app is suspended, removed or unpublished.
404Endpoint or resource not found.
409Conflict — for example, you already reviewed this app.
422Validation failed. An errors object lists each field.
429Rate limit exceeded. Check the Retry-After header.
500Server error. Details are logged, never returned in production.

Discovery

GET /api/v1/ None

Lists every available endpoint and the API version.

Response
{
  "status": true,
  "message": "AppStore API",
  "data": { "version": "v1", "endpoints": [ ... ], "docs": "..." }
}
Try it
curl 'https://apkzone.in/api/v1/'

Authentication

POST /api/v1/auth/register None

Creates a store-user account and returns a bearer token. Send the token as "Authorization: Bearer <token>" on endpoints that act on behalf of a person. Rate limited to 5 registrations per IP per hour.

Parameters
NameTypeNotes
name string Required. 2-120 characters.
email string Required. Must be unique.
password string Required. Minimum 10 characters, letters and digits.
mobile string Optional mobile number.
device_name string Optional label shown in the user's device list.
platform string android (default) | ios | web | other
Response
{
  "status": true,
  "message": "Account created successfully.",
  "data": {
    "token": "IVpqj1hfelkCzusGQ7ZQ…",
    "token_type": "Bearer",
    "expires_at": "2026-10-31 16:49:25",
    "user": { "id": 4, "name": "Flutter User", "email": "user@example.com" }
  }
}
Try it
curl -X POST \
     -H 'Content-Type: application/json' \
     'https://apkzone.in/api/v1/auth/register'
POST /api/v1/auth/login None

Exchanges e-mail and password for a bearer token. Subject to the same lockout as the web panels: after 5 failed attempts the account is locked and the endpoint answers 429. Unknown accounts and wrong passwords return an identical message so accounts cannot be enumerated.

Parameters
NameTypeNotes
email string Required.
password string Required.
device_name string Optional label for this token.
platform string android (default) | ios | web | other
Response
{
  "status": true,
  "message": "Signed in successfully.",
  "data": {
    "token": "CWCuoWd2yL3JV7wqJd2pF05uAv…",
    "token_type": "Bearer",
    "expires_at": "2026-10-31 16:49:40",
    "user": { "id": 4, "name": "Flutter User", "email": "user@example.com" }
  }
}
Try it
curl -X POST \
     -H 'Content-Type: application/json' \
     'https://apkzone.in/api/v1/auth/login'
GET /api/v1/auth/me Bearer required

Returns the profile behind the presented token. Useful on app start to confirm a stored token is still valid.

Response
{
  "status": true,
  "message": "Profile fetched successfully",
  "data": {
    "id": 4, "name": "Flutter User", "email": "user@example.com",
    "mobile": null, "avatar": null, "created_at": "2026-08-02 16:49:25"
  }
}
Try it
curl 'https://apkzone.in/api/v1/auth/me'
POST /api/v1/auth/logout Bearer required

Revokes only the token used for this call, so other devices stay signed in. Revoked and expired tokens are removed by cron/cleanup.php.

Response
{
  "status": true,
  "message": "Signed out."
}
Try it
curl -X POST \
     -H 'Content-Type: application/json' \
     'https://apkzone.in/api/v1/auth/logout'

Apps

GET /api/v1/apps None

Paginated list of published apps.

Parameters
NameTypeNotes
page int Page number. Default 1.
limit int Items per page. Default 20, max 100.
category int Filter by category id.
platform string android | ios. Omit for both. Every listing endpoint accepts this.
sort string popular (default) | new | rating | updated | name
Response
{
  "status": true,
  "message": "Apps fetched successfully",
  "data": [
    {
      "id": 11,
      "name": "PAN MITRA",
      "slug": "pan-mitra",
      "package_name": "com.example.app",
      "short_description": "…",
      "icon": "https://…/uploads/icons/…png",
      "category": "Business",
      "developer": { "name": "Acme", "slug": "acme", "verified": true },
      "version": "1.4.0",
      "version_code": 15,
      "size": 13831254,
      "size_human": "13.2 MB",
      "min_sdk": 21,
      "min_android": "5.0",
      "rating": 4.5,
      "rating_count": 128,
      "downloads": 5210,
      "published_at": "2026-08-01 23:04:04",
      "url": "https://…/app/pan-mitra",
      "download_url": "https://…/api/v1/apps/11/download"
    }
  ],
  "pagination": {
    "total": 42, "per_page": 20, "current_page": 1,
    "last_page": 3, "from": 1, "to": 20, "has_more": true
  }
}
Try it
curl 'https://apkzone.in/api/v1/apps'
GET /api/v1/apps/{id} None

Full detail for one app, including screenshots, permissions and the current release.

Parameters
NameTypeNotes
id int App id (path parameter).
Response
{
  "status": true,
  "message": "App fetched successfully",
  "data": {
    "id": 11, "name": "…", "full_description": "…",
    "screenshots": [ "https://…/1.png", "https://…/2.png" ],
    "current_release": {
      "version_name": "1.4.0", "version_code": 15,
      "size": 13831254,
      "sha256": "ea9d559de7c0…",
      "min_sdk": 21, "target_sdk": 34,
      "abis": ["arm64-v8a"],
      "release_notes": "…",
      "published_at": "2026-08-01 23:04:04"
    },
    "permissions": [
      { "name": "android.permission.CAMERA", "dangerous": true }
    ]
  }
}
Try it
curl 'https://apkzone.in/api/v1/apps/{id}'
GET /api/v1/apps/{id}/versions None

Every published release of an app, newest first. Pending and rejected releases are never returned.

Parameters
NameTypeNotes
id int App id.
Response
{
  "status": true,
  "message": "Versions fetched successfully",
  "data": [
    {
      "version_name": "1.4.0", "version_code": 15,
      "size": 13831254, "size_human": "13.2 MB",
      "sha256": "ea9d559de7c0…",
      "min_sdk": 21, "target_sdk": 34,
      "release_notes": "…", "published_at": "…", "downloads": 5210
    }
  ]
}
Try it
curl 'https://apkzone.in/api/v1/apps/{id}/versions'

Discovery lists

GET /api/v1/new None

Ordered by first publication date.

Parameters
NameTypeNotes
page int
limit int
Response
Same envelope and item shape as GET /apps.
Try it
curl 'https://apkzone.in/api/v1/new'
GET /api/v1/updates None

Apps with the most recent releases.

Parameters
NameTypeNotes
page int
limit int
Response
Same envelope and item shape as GET /apps.
Try it
curl 'https://apkzone.in/api/v1/updates'

Categories

GET /api/v1/categories None

All active categories with a live published-app count.

Response
{
  "status": true,
  "message": "Categories fetched successfully",
  "data": [
    { "id": 1, "name": "Games", "slug": "games", "icon": "bi-controller",
      "description": null, "app_count": 12, "url": "https://…/category/games" }
  ]
}
Try it
curl 'https://apkzone.in/api/v1/categories'
GET /api/v1/categories/{id}/apps None

Published apps inside one category.

Parameters
NameTypeNotes
id int Category id.
page int
limit int
Response
Same envelope and item shape as GET /apps.
Try it
curl 'https://apkzone.in/api/v1/categories/{id}/apps'

Search

Downloads

POST /api/v1/apps/{id}/download Optional bearer

Authorises a download. With Accept: application/json it returns metadata plus a URL; without it (or via GET) the APK bytes are streamed directly. The download is recorded once per client per 24 hours; obvious bots are logged but never counted. Android only. For an iOS listing this answers 409 with {"platform":"ios","store_url":"…"} — open that App Store URL instead, because Apple does not permit a third party to host or install iOS builds.

Parameters
NameTypeNotes
id int App id (path parameter).
version int Optional. A specific published version id; defaults to the latest.
Response
{
  "status": true,
  "message": "Download authorised",
  "data": {
    "app_id": 11,
    "package_name": "com.example.app",
    "version": "1.4.0",
    "version_code": 15,
    "size": 13831254,
    "sha256": "ea9d559de7c0…",
    "file_name": "com.example.app_1.4.0.apk",
    "download_url": "https://…",
    "expires_in": null
  }
}
Try it
curl -X POST \
     -H 'Content-Type: application/json' \
     'https://apkzone.in/api/v1/apps/{id}/download'

Update check

POST /api/v1/check-update None

The endpoint an installed Android app calls to discover updates. Only published, non-blocked releases are ever returned.

Parameters
NameTypeNotes
package_name string Required. The applicationId of the installed app.
version_code int Required. The versionCode currently installed.
Request body
{
  "package_name": "com.example.app",
  "version_code": 10
}
Response
{
  "status": true,
  "update_available": true,
  "message": "An update is available.",
  "app_id": 11,
  "app_name": "Example",
  "package_name": "com.example.app",
  "latest_version": "2.0",
  "latest_version_code": 15,
  "apk_size": 25000000,
  "sha256": "ea9d559de7c0…",
  "min_sdk": 21,
  "release_notes": "Performance improvements",
  "published_at": "2026-08-01 23:04:04",
  "download_url": "https://…/api/v1/apps/11/download"
}
Try it
curl -X POST \
     -H 'Content-Type: application/json' \
     'https://apkzone.in/api/v1/check-update'

Reviews

GET /api/v1/apps/{id}/reviews None

Approved reviews for an app, newest first.

Parameters
NameTypeNotes
id int App id.
page int
limit int
Response
{
  "status": true,
  "message": "Reviews fetched successfully",
  "data": [
    { "rating": 5, "title": "Great", "review": "…", "created_at": "…",
      "developer_reply": null, "user_name": "Asha" }
  ],
  "pagination": { … }
}
Try it
curl 'https://apkzone.in/api/v1/apps/{id}/reviews'
POST /api/v1/apps/{id}/reviews Bearer required

Post a review. One review per user per app. Rate limited to 10 per hour.

Parameters
NameTypeNotes
rating int Required. 1-5.
title string Optional. Max 150 characters.
review string Optional. Max 5000 characters.
Request body
{ "rating": 5, "title": "Works well", "review": "Fast and stable." }
Response
{ "status": true, "message": "Review submitted and awaiting moderation." }
Try it
curl -X POST \
     -H 'Content-Type: application/json' \
     'https://apkzone.in/api/v1/apps/{id}/reviews'

Reports

POST /api/v1/apps/{id}/report Optional bearer

Report an app. Malware reports are automatically raised to critical priority. Rate limited to 10 per hour per client.

Parameters
NameTypeNotes
reason string Required. malware | fake_app | copyright | privacy | inappropriate | other
details string Optional. Max 5000 characters.
reporter_email string Optional contact address for anonymous reports.
Request body
{ "reason": "malware", "details": "Requests SMS access with no reason." }
Response
{ "status": true, "message": "Report submitted. Our team will review it." }
Try it
curl -X POST \
     -H 'Content-Type: application/json' \
     'https://apkzone.in/api/v1/apps/{id}/report'

Flutter client example

Minimal update check from an installed Android app.

import 'dart:convert';
import 'package:http/http.dart' as http;
import 'package:package_info_plus/package_info_plus.dart';

Future<Map<String, dynamic>?> checkForUpdate() async {
  final info = await PackageInfo.fromPlatform();

  final response = await http.post(
    Uri.parse('https://apkzone.in/api/v1/check-update'),
    headers: {'Content-Type': 'application/json'},
    body: jsonEncode({
      'package_name': info.packageName,
      'version_code': int.parse(info.buildNumber),
    }),
  );

  if (response.statusCode != 200) return null;

  final data = jsonDecode(response.body) as Map<String, dynamic>;
  if (data['update_available'] != true) return null;

  // data['download_url'], data['latest_version'], data['sha256'],
  // data['apk_size'] and data['release_notes'] are all present here.
  return data;
}
Verify what you download. Every release exposes its sha256. Hash the downloaded file and compare before handing it to the package installer — this is what makes a self-hosted store safe to update from.

← Back to AppZone Store