OTA Check API
Mobile devices use the OTA check endpoint to check for available updates.
Endpoint
GET /api/update/check/{bundleId}Authentication: None required (public endpoint)
Parameters
Path Parameters
| Parameter | Type | Description |
|---|---|---|
bundleId | string | App bundle identifier (e.g., com.example.myapp) |
Query Parameters
| Parameter | Required | Type | Description |
|---|---|---|---|
currentVersion | Yes | string | Current app version (e.g., 1.0.0) |
currentBuild | No | string | Current build number |
platform | No | string | Platform: ios, android, visionos |
fingerprint | No | string | Current runtime fingerprint hash |
configuration | No | string | Deployment target config (e.g., prod, stg) |
Request Example
curl "https://norrix.net/api/update/check/com.example.myapp?currentVersion=1.0.0¤tBuild=42&platform=ios&fingerprint=abc123...&configuration=prod"Response
Update Available
{
"updateAvailable": true,
"requiresStoreUpdate": false,
"platform": "ios",
"version": "1.0.1",
"buildNumber": "43",
"releaseNotes": "Bug fixes and performance improvements",
"url": "https://s3.amazonaws.com/...",
"expiresAt": "2024-01-15T11:00:00.000Z",
"compatibilityReason": null
}No Update Available
{
"updateAvailable": false,
"message": "No update available"
}Store Update Required
When the update has incompatible native changes:
{
"updateAvailable": true,
"requiresStoreUpdate": true,
"platform": "ios",
"version": "2.0.0",
"buildNumber": "50",
"releaseNotes": "Major update with new features",
"url": "https://s3.amazonaws.com/...",
"expiresAt": "2024-01-15T11:00:00.000Z",
"compatibilityReason": "Native plugin version changed: @nativescript/camera 4.5.0 -> 5.0.0"
}Response Fields
| Field | Type | Description |
|---|---|---|
updateAvailable | boolean | Whether an update is available |
requiresStoreUpdate | boolean | Whether a store update is needed |
platform | string | Platform (ios/android/visionos) |
version | string | Update version |
buildNumber | string | Update build number |
releaseNotes | string | Release notes |
url | string | Signed download URL |
expiresAt | string | URL expiration timestamp |
compatibilityReason | string | Why store update is required |
message | string | Status message |
Version Comparison
The API uses semantic version comparison:
- Version: Compared as semver (1.0.1 > 1.0.0)
- Build Number: Compared numerically if versions match (42 > 41)
An update is available when:
- Update version > current version, OR
- Versions are equal AND update build > current build
Fingerprint Matching
When fingerprint is provided:
- Server looks up the update’s stored fingerprint
- Compares with the device’s fingerprint
- If mismatch:
requiresStoreUpdate: truewithcompatibilityReason
Fingerprint Components
The fingerprint hash includes:
- Native plugin versions
- App_Resources hash
- NativeSource hash
See Fingerprinting for details.
Download URL
The url field contains a pre-signed S3 URL:
- Valid for 1 hour (check
expiresAt) - Download immediately after receiving
- Re-check if URL expires
Error Responses
Missing Bundle ID
{
"error": "Bad Request",
"message": "Bundle ID is required"
}HTTP Status: 400
Missing Version
{
"error": "Bad Request",
"message": "currentVersion is required"
}HTTP Status: 400
Not Found
{
"updateAvailable": false,
"message": "No updates found for this bundle"
}HTTP Status: 200 (not an error)
SDK Integration
The Client SDK calls this endpoint automatically:
// SDK handles this internally
const checkUrl = `${updateUrl}/api/update/check/${bundleId}?currentVersion=${version}&platform=${platform}&fingerprint=${hash}&configuration=${config}`;Manual Usage
async function checkForUpdate() {
const bundleId = getBundleId();
const version = getAppVersion();
const fingerprint = getFingerprint();
const configuration = getConfiguration(); // e.g., 'prod', 'stg'
const response = await fetch(
`https://norrix.net/api/update/check/${bundleId}?` +
`currentVersion=${version}&` +
`platform=ios&` +
`fingerprint=${fingerprint}&` +
`configuration=${configuration}`
);
return await response.json();
}Caching
The endpoint includes cache headers:
Cache-Control: no-cache, no-store, must-revalidateAlways fetch fresh results. Don’t cache OTA check responses.