Code Push API

REST API for publishing runtime bundles and for the SDK update-check endpoint. For the Flutter integration, see the Code Push SDK guide.

Authentication

Code Push has two groups of endpoints with different auth:

  • SDK endpoints (check, events) authenticate with your environment public key via the x-api-key header. These are called from the app at runtime.
  • Dashboard endpoints (bundle management) require a logged-in dashboard session via Authorization: Bearer.
Throughout this page, {app_id} is your project ID. Bundle versions are sequential per app + platform + channel — stable and beta are independent sequences.

SDK endpoints

Authenticated with x-api-key. Normally called by the SDK, not by hand.

GET
/v1/code-push/check

Check whether a newer bundle is available for this device. Rate-limited per device_id (fair-use; a device checking on every launch is never affected). On limit it returns a no_update response, so apps keep running their current code.

POST
/v1/code-push/events

Record a client-side telemetry event (check / download / activation / failure). Emitted automatically by the SDK.

Dashboard endpoints

Authenticated with a dashboard Authorization: Bearer token.

POST
/v1/apps/{app_id}/bundles

Create a draft bundle.

POST
/v1/apps/{app_id}/bundles/{bundle_id}/upload

Upload the bundle artifact (multipart/form-data, field: artifact). Draft only.

PATCH
/v1/apps/{app_id}/bundles/{bundle_id}/checksum

Set the artifact checksum and size. Draft only.

POST
/v1/apps/{app_id}/bundles/{bundle_id}/publish

Publish a draft. Automatically recalls the currently-published bundle for this channel.

POST
/v1/apps/{app_id}/bundles/{bundle_id}/recall

Recall a published bundle. Devices revert on their next check. Published only.

GET
/v1/apps/{app_id}/bundles

List all bundles for an app.

GET
/v1/apps/{app_id}/bundles/{bundle_id}

Fetch a single bundle.

GET
/v1/apps/{app_id}/bundles/{bundle_id}/stats

Fetch check / download / activation / failure counts for a bundle.

PATCH
/v1/apps/{app_id}/bundles/{bundle_id}/mandatory

Toggle the mandatory (force-update) flag on a bundle.

Publishing a bundle

A bundle moves through draft → published. The CLI's koolbase bundle deploy runs all four steps for you; the raw flow is:

1. Create a draft

curl -X POST "https://api.koolbase.com/v1/apps/{app_id}/bundles" \
  -H "Authorization: Bearer YOUR_SESSION_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "base_app_version": "1.2.0",
    "max_app_version": "1.2.99",
    "platform": "ios",
    "channel": "stable",
    "rollout_percentage": 10,
    "mandatory": false,
    "release_notes": "Updated checkout config",
    "payload": {
      "config": { "api_timeout_ms": 8000 },
      "flags": { "new_checkout_flow": true },
      "directives": {},
      "assets": { "images": [], "json": [], "fonts": [] }
    }
  }'

Returns the created bundle with status: "draft":

{
  "bundle_id": "e3347496-9fd3-406c-bd3c-494c5778b1d8",
  "app_id": "d2bc2c2c-fb42-4891-b758-45e48a1cd871",
  "version": 3,
  "base_app_version": "1.2.0",
  "max_app_version": "1.2.99",
  "platform": "ios",
  "channel": "stable",
  "status": "draft",
  "rollout_percentage": 10,
  "mandatory": false,
  "release_notes": "Updated checkout config",
  "checksum": "",
  "signature": "",
  "size_bytes": 0,
  "storage_key": "code-push/.../stable/v3.zip",
  "payload": { "config": {}, "flags": {}, "directives": {}, "assets": {} },
  "created_by": "usr_...",
  "created_at": "2026-05-20T10:14:00Z"
}

2. Upload the artifact

curl -X POST "https://api.koolbase.com/v1/apps/{app_id}/bundles/{bundle_id}/upload" \
  -H "Authorization: Bearer YOUR_SESSION_TOKEN" \
  -F "artifact=@./bundle.zip"

Max 50 MB. Draft bundles only — a published or recalled bundle returns 409. Response:

{ "status": "uploaded" }

3. Set the checksum

curl -X PATCH "https://api.koolbase.com/v1/apps/{app_id}/bundles/{bundle_id}/checksum" \
  -H "Authorization: Bearer YOUR_SESSION_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{ "checksum": "sha256:147599f3...", "size_bytes": 8421 }'
{ "status": "updated" }

4. Publish

curl -X POST "https://api.koolbase.com/v1/apps/{app_id}/bundles/{bundle_id}/publish" \
  -H "Authorization: Bearer YOUR_SESSION_TOKEN"

Publishing recalls the previously-published bundle for this app + platform + channel, then makes this one live. Fails with 409 if the artifact was never uploaded. Response:

{ "status": "published" }

Checking for updates

The SDK calls this on cold launch. All four query params except current_bundle are required.

curl "https://api.koolbase.com/v1/code-push/check?app_version=1.2.0&platform=ios&channel=stable&device_id=abc-123&current_bundle=2" \
  -H "x-api-key: pk_live_xxxx"

Update available — the device should download and stage the bundle:

{
  "status": "update_available",
  "bundle": {
    "bundle_id": "e3347496-9fd3-406c-bd3c-494c5778b1d8",
    "version": 3,
    "download_url": "https://...r2.cloudflarestorage.com/...?X-Amz-Signature=...",
    "checksum": "sha256:147599f3...",
    "signature": "MEUCIQ...",
    "size_bytes": 8421,
    "mandatory": false,
    "release_notes": "Updated checkout config"
  }
}

The download_url is a signed URL valid for 15 minutes.

Rollback — the device is on a bundle that has since been recalled and should revert. revert_to is the target version, as a string:

{ "status": "rollback", "revert_to": "2" }

No update — the device is current (also returned when the per-device rate limit is exceeded):

{ "status": "no_update" }

Recall & mandatory

Recall a live bundle — devices on it revert to the previous version on their next check:

curl -X POST "https://api.koolbase.com/v1/apps/{app_id}/bundles/{bundle_id}/recall" \
  -H "Authorization: Bearer YOUR_SESSION_TOKEN"

Toggle the mandatory (force-update) flag. When mandatory is true, the SDK applies the bundle before the app proceeds:

curl -X PATCH "https://api.koolbase.com/v1/apps/{app_id}/bundles/{bundle_id}/mandatory" \
  -H "Authorization: Bearer YOUR_SESSION_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{ "mandatory": true }'

The bundle object

FieldTypeDescription
bundle_idstringUnique bundle identifier.
app_idstringThe owning project ID.
versionintSequential version per app + platform + channel.
base_app_versionstringLowest app version eligible for this bundle.
max_app_versionstringHighest app version eligible for this bundle.
platformstringios or android.
channelstringstable, beta, etc.
statusstringdraft, published, or recalled.
rollout_percentageint0–100. Deterministic per device_id.
mandatoryboolWhether the update is forced.
release_notesstringOptional notes shown for this bundle.
checksumstringSHA-256 of the artifact.
signaturestringEd25519 signature of the artifact.
size_bytesintArtifact size.
storage_keystringInternal storage path for the artifact.
payloadobjectconfig, flags, directives, assets.
created_bystringUser who created the bundle.
created_attimestampCreation time.
published_attimestamp?Set when published.
recalled_attimestamp?Set when recalled.