OTA Updates API

REST API for managing OTA bundles and the SDK check endpoint.

Dashboard endpoints

These endpoints require a dashboard Authorization: Bearer token.

POST
/v1/projects/{project_id}/ota/upload

Upload a new bundle (multipart/form-data)

GET
/v1/projects/{project_id}/ota/bundles

List all bundles for a project

POST
/v1/projects/{project_id}/ota/bundles/{bundle_id}/activate

Activate a bundle (makes it the active version for its channel)

PATCH
/v1/projects/{project_id}/ota/bundles/{bundle_id}

Toggle the mandatory flag on a bundle

DELETE
/v1/projects/{project_id}/ota/bundles/{bundle_id}

Delete a bundle and remove it from R2 storage

SDK endpoint

Called by the Flutter SDK on app launch. Requires the environment public key via x-api-key header.

GET
/v1/sdk/ota/check

Check for a newer active bundle. Returns download URL if available.

Upload a bundle

bash
curl -X POST "https://api.koolbase.com/v1/projects/{project_id}/ota/upload" \
  -H "Authorization: Bearer YOUR_DASHBOARD_TOKEN" \
  -F "bundle=@./my_bundle.zip" \
  -F "channel=production" \
  -F "mandatory=false" \
  -F "release_notes=Updated banner and config"
json
{
  "id": "e3347496-9fd3-406c-bd3c-494c5778b1d8",
  "project_id": "d2bc2c2c-fb42-4891-b758-45e48a1cd871",
  "channel": "production",
  "version": 1,
  "checksum": "sha256:147599f3...",
  "storage_path": "ota/.../production/v1.zip",
  "file_size": 630,
  "mandatory": false,
  "active": false,
  "release_notes": "Updated banner and config",
  "created_at": "2026-03-23T23:29:30Z",
  "updated_at": "2026-03-23T23:29:30Z"
}

SDK check response

bash
curl "https://api.koolbase.com/v1/sdk/ota/check?channel=production&version=0" \
  -H "x-api-key: pk_live_xxxx"
json
{
  "has_update": true,
  "version": 1,
  "checksum": "sha256:147599f3...",
  "mandatory": false,
  "download_url": "https://...r2.cloudflarestorage.com/...?X-Amz-Signature=...",
  "release_notes": "Updated banner and config",
  "file_size": 630
}

When no update is available:

json
{ "has_update": false }

Upload fields

FieldTypeDescription
bundlefileRequired. The .zip bundle file. Max 50MB.
channelstringTarget channel: production, staging, or development. Defaults to production.
mandatorybooleanWhether this update must be applied before the app proceeds. Defaults to false.
release_notesstringOptional description of what changed in this bundle.