Check whether an update is available for the client
const url = 'https://api.aetherpush.com/v0.1/public/codepush/update_check?deployment_key=example&is_companion=true&platform=ios';const options = {method: 'GET'};
try { const response = await fetch(url, options); const data = await response.json(); console.log(data);} catch (error) { console.error(error);}curl --request GET \ --url 'https://api.aetherpush.com/v0.1/public/codepush/update_check?deployment_key=example&is_companion=true&platform=ios'Called by the React Native SDK at app launch (and periodically thereafter) to determine if a newer JS bundle is available.
Field names in the response use snake_case for backward
compatibility with the react-native-code-push SDK.
Caches responses for short windows in Redis to amortize per-deployment fanout.
Parameters
Section titled “Parameters”Query Parameters
Section titled “Query Parameters”Deployment key (provided in app bundle config).
Binary version of the installed app (semver). The server
tolerates plain integer versions (1) and missing-patch
versions (1.0) by normalizing internally. Missing or empty
answers 200 with is_available false, same as an unresolved
deployment key.
SHA-256 hash of the currently installed JS bundle.
Stable per-install identifier for rollout selection.
Optional coarse client platform. Invalid values are dropped; never used for update selection.
Optional OS version; server keeps the leading major digits only.
Optional React Native version as major.minor.
Optional SDK version string for telemetry.
Responses
Section titled “Responses”Update info. is_available: false means no update was
selected for this device: it already runs the latest eligible
release, nothing targets its binary version, every enabled
release covering it is an older range outranked by a newer
release that targets exactly its binary version (enabled or
not), its deployment key did not resolve, the deployment was
deleted after the key was resolved, or the release’s download
URL could not be re-signed
for a reason retrying will not fix, such as a blob the storage
provider no longer holds. A device outside a staged rollout
receives the eligible non-rollout fallback; unavailable follows
only when that fallback is not eligible. A database failure
while refreshing that URL answers 503 instead.
Wrapper response for update_check. The actual update info lives
under update_info.
object
Response shape consumed by the React Native SDK acquisition endpoint.
Field names use snake_case for backward compatibility with
react-native-code-push. Returned wrapped in { "update_info": ... }.
object
Semver range of binary versions this update targets.
Present only when a free tenant’s monthly active device count is at or above its quota. Hours the client should wait before its next update check. The server sends 48. Omitted when the tenant is not throttled.
Example
{ "update_info": { "is_available": true, "is_mandatory": false, "app_version": "1.0.0", "target_binary_range": "1.0.0", "package_hash": "9b8c7d6e5f4a3b2c1d0e9f8a7b6c5d4e3f2a1b0c9d8e7f6a5b4c3d2e1f0a9b8c", "download_url": "https://example-cdn.com/bundles/abc123", "package_size": 1234567, "description": "Bug fixes", "label": "v3", "should_run_binary_version": false, "update_app_version": false }}Headers
Section titled “Headers”Present on legacy acquisition endpoints. Signals the endpoint is
deprecated in favor of its canonical /v1/public/aether/* successor.
The value is the string true.
Example
trueRFC 8288 link header with two link values: the canonical successor endpoint via rel=“successor-version”, and the CodePush migration guide via rel=“deprecation”.
Example
</v1/public/aether/update_check>; rel="successor-version", <https://docs.aetherpush.com/migration/codepush/>; rel="deprecation"Present on an update check only when a free tenant’s monthly active
device count is at or above its quota. The one current value is
over_quota_throttled. The body then also carries throttle_hours
on the snake_case routes, or throttleHours on legacy /updateCheck.
The deployment key resolved, but app_version is present,
non-empty, and does not conform to semver after the integer
and missing-patch expansions this endpoint accepts. A missing
or empty app version, and a key that does not resolve
(malformed or unknown), answer 200 with is_available false
instead.
Standard error envelope. code is the stable machine identifier for
client branching and i18n. The wording of error is a human-readable
fallback and is not part of the contract. Specialized responses keep
narrower code enums where clients already branch on them.
object
Human-readable error message.
Stable machine code. Prefer this over matching on error. The
values this API can answer with are listed in the ApiErrorCode
schema of the raw document at
https://api.aetherpush.com/openapi.yaml. The field stays an
open string here so that a release adding a value does not
invalidate this response.
Unique identifier for the request, also exposed as the X-Request-Id response header.
Example
{ "error": "The requested resource was not found.", "code": "not_found", "requestId": "req_abc123"}The request did not arrive through the trusted edge. This endpoint is unauthenticated; 403 is that refusal, not a missing bearer token.
Standard error envelope. code is the stable machine identifier for
client branching and i18n. The wording of error is a human-readable
fallback and is not part of the contract. Specialized responses keep
narrower code enums where clients already branch on them.
object
Human-readable error message.
Stable machine code. Prefer this over matching on error. The
values this API can answer with are listed in the ApiErrorCode
schema of the raw document at
https://api.aetherpush.com/openapi.yaml. The field stays an
open string here so that a release adding a value does not
invalidate this response.
Unique identifier for the request, also exposed as the X-Request-Id response header.
Example
{ "error": "Forbidden", "code": "forbidden", "requestId": "req_abc123"}The request failed for a reason the server does not classify
as retryable, so it carries no Retry-After. A database
failure the server recognises answers 503 above instead, and a
download URL that cannot be re-signed answers 200 with
is_available false, described above.
Everything else answers here, a Redis failure and a defect
alike, so this status is not by itself evidence of either.
Standard error envelope. code is the stable machine identifier for
client branching and i18n. The wording of error is a human-readable
fallback and is not part of the contract. Specialized responses keep
narrower code enums where clients already branch on them.
object
Human-readable error message.
Stable machine code. Prefer this over matching on error. The
values this API can answer with are listed in the ApiErrorCode
schema of the raw document at
https://api.aetherpush.com/openapi.yaml. The field stays an
open string here so that a release adding a value does not
invalidate this response.
Unique identifier for the request, also exposed as the X-Request-Id response header.
Example
{ "error": "The requested resource was not found.", "code": "not_found", "requestId": "req_abc123"}A database read this request depends on could not be
completed, so no update decision was made. Retryable:
Retry-After carries the seconds to wait. All three of the
request’s reads answer this way: resolving the deployment
key when nothing is cached for it, reading that deployment’s
releases, and refreshing the download URL of a release the
deployment would serve, which covers the staged-rollout
candidate as well as the current one, so a failure on either
answers this way for every device whose response is not already
cached. Whichever of the three an outage
reaches, the status is the same, so it no longer depends on
which of them the server had cached, and a device is never
told it is up to date because the server could not reach its
database.
Returned with HTTP 503 when the server could not complete an
operation for a reason it expects to pass, and says so rather than
answering as though it had. On the management API, a release or
deployment write could not finish because of database contention
(lock wait expired, deadlock, or a serialization failure) and
nothing was written, or a release
upload could not read back the package it had just stored in order
to sign its URL. On the
acquisition endpoints, a database read the request depends on
could not be completed: resolving a deployment key with nothing
cached for it, reading that deployment’s releases, or refreshing
the download URL of the release it would serve. The release and
download-URL reads answer this way for the failures the server
recognises as transient, and the deployment lookup answers this
way for any failure it cannot serve from a cached entry, so an
outage no longer produces a different status depending on which
of them it reached.
retryAfterSeconds is the minimum interval before a
retry is useful for the path that failed, and is also sent as the
Retry-After response header. Management lock-contention 503s use
the commit lock wait; acquisition and other transient-read 503s use
the deployment-cache failure grace. Those intervals are independent
and can differ. code is connection_failed on every response this
schema describes, management lock contention included. The operation
and the message are what distinguish the paths.
object
Example
{ "error": "This release could not finish because another release was committing to the same deployment. No release was created. Please try again.", "code": "connection_failed", "retryAfterSeconds": 5, "requestId": "req_abc123"}Headers
Section titled “Headers”Seconds to wait before retrying.