Developer Documentation
Two public read-only endpoints for in-app update checks and maintenance notices, plus the contract for your own release page HTML.
Access-Control-Allow-Origin: *).
Replace <appname> with the app path you set in the console. No API key is required, and no
download URL is ever returned — downloads only happen on the release page.
Version Check API
Returns the metadata of the app's current version.
GET https://api.apprelease.click/<appname>/version/latest
Response fields
| Field | Type | Description |
|---|---|---|
version | string | Version label you entered when uploading, free-form text (e.g. 1.2.3). The platform never parses or compares it. |
notes | string | Release notes, may be empty. |
filename | string | Original file name of the package. |
size | number | File size in bytes. |
uploaded_at | string | Upload time, ISO 8601 UTC. |
page_url | string | Permanent release page URL to open for the download. |
min_supported_version | string | Oldest client version you still support. Empty string when unset — compare it yourself if you use it. |
force_update | boolean | Whether the current release is a mandatory update. |
Example
{
"version": "1.2.3",
"notes": "Fixed login crash on Android 14.",
"filename": "pixelcraft-1.2.3.apk",
"size": 18432000,
"uploaded_at": "2025-05-04T09:12:30Z",
"page_url": "https://apprelease.click/pixelcraft",
"min_supported_version": "1.2.0",
"force_update": false
}
Status codes
| Code | Meaning |
|---|---|
200 | Success. |
404 | App not found or banned, or no package uploaded yet. Body: {"error":"..."}. |
Maintenance API
Reports whether the app is under maintenance. It always answers 200 even when the app is fine, so your client only needs one code path. Maintenance never affects the release page or downloads.
GET https://api.apprelease.click/<appname>/maintenance
{
"maintenance": true,
"notice": "Upgrading the backend, back around 06:00 UTC.",
"resume_at": "2025-05-04T06:00:00Z"
}
notice and resume_at are null when unset. resume_at is informational only — the app stays in maintenance until you turn it off in the console.
Release Page Contract
Upload your own HTML in the console under Release Page, or use the built-in default download page.
Download action
Add the class apprelease-download-action to any element that should trigger the download:
<a class="apprelease-download-action" href="#">Download for Android</a>
Your HTML is served in a cross-origin frame on the main domain. Clicks on elements with that class are intercepted and forwarded to the shell page, which opens the download confirmation and serves the file from the dedicated download domain. Write nothing else on the element — no URL, no JavaScript. With no package uploaded yet the action is inert.
Placeholders
| Token | Replaced with |
|---|---|
{{version}} | Version label of the current package (HTML-escaped; empty when no package). |
{{sha256}} | SHA256 checksum of the current package (HTML-escaped; empty when unknown). |
Whitespace inside the braces is tolerated: {{ version }} works too. Everything else in your HTML is served as uploaded.
Code Samples
curl
curl -s https://api.apprelease.click/pixelcraft/version/latest
JavaScript / TypeScript
const res = await fetch('https://api.apprelease.click/pixelcraft/version/latest');
if (!res.ok) throw new Error('version check failed: ' + res.status);
const latest = await res.json();
if (latest.version !== currentVersion) {
// latest.force_update decides whether the user may skip this update.
openInBrowser(latest.page_url);
}
Kotlin (Android)
val json = URL("https://api.apprelease.click/pixelcraft/version/latest")
.openConnection()
.run { (this as HttpURLConnection).connectTimeout = 5000; inputStream.bufferedReader().readText() }
val latest = JSONObject(json)
val forceUpdate = latest.getBoolean("force_update")
Swift (iOS / macOS)
let url = URL(string: "https://api.apprelease.click/pixelcraft/version/latest")!
let (data, _) = try await URLSession.shared.data(from: url)
let latest = try JSONDecoder().decode(Latest.self, from: data)
struct Latest: Decodable {
let version: String
let notes: String
let pageURL: String
let forceUpdate: Bool
enum CodingKeys: String, CodingKey {
case version, notes
case pageURL = "page_url"
case forceUpdate = "force_update"
}
}
Dart (Flutter)
final res = await http.get(
Uri.parse('https://api.apprelease.click/pixelcraft/version/latest'),
);
if (res.statusCode == 200) {
final latest = jsonDecode(res.body) as Map<String, dynamic>;
final forceUpdate = latest['force_update'] as bool;
// Send the user to latest['page_url'] — downloads only happen there.
}
Client Guidance
The endpoints are read-only and cheap, but they are still served from a single origin — check for updates at most once per app launch, and cache the answer for a few minutes on your side.