Skip to main content

OTA Updates

SyncKit OTA provides an auto-update server for desktop applications. It implements the Tauri updater protocol, so Tauri apps work out of the box. Non-Tauri apps can use the same HTTP endpoints directly.

Setup

1. Register a Slug

Each app needs a URL slug for the update endpoint. Set it on your SyncKit app:

PUT /api/sync/ota/apps/{app_id}/slug
Authorization: Bearer <token>
Content-Type: application/json

{
  "slug": "my-app"
}

Slugs must be 3-40 characters, lowercase alphanumeric with hyphens. This slug appears in the public update check URL.

2. Create a Release

POST /api/sync/ota/apps/{app_id}/releases
Authorization: Bearer <token>
Content-Type: application/json

{
  "version": "1.2.0",
  "notes": "Bug fixes and performance improvements",
  "signature": "<base64-encoded-signature>"
}

Response:

{
  "id": "880b1700-...",
  "version": "1.2.0",
  "notes": "Bug fixes and performance improvements",
  "signature": "<base64-encoded-signature>",
  "pub_date": "2026-03-13T12:00:00Z",
  "created_at": "2026-03-13T12:00:00Z"
}

Version must be valid semver (X.Y.Z, optionally with pre-release or build metadata).

3. Upload Artifacts

For each platform/architecture combination, request a presigned upload URL and upload the binary:

POST /api/sync/ota/apps/{app_id}/releases/{release_id}/artifacts
Authorization: Bearer <token>
Content-Type: application/json

{
  "target": "darwin",
  "arch": "aarch64",
  "file_size": 52428800
}

Response:

{
  "upload_url": "https://s3.example.com/...",
  "s3_key": "ota/my-app/1.2.0/darwin-aarch64"
}

Upload the binary directly to the presigned URL with a PUT request.

Target values: linux, darwin, windows. Arch values: x86_64, aarch64.

Update Check Endpoint

Public, no authentication required. Compatible with Tauri’s built-in updater.

GET /api/sync/ota/{slug}/{target}/{arch}/{current_version}

Example:

GET /api/sync/ota/my-app/darwin/aarch64/1.1.0

Update Available (200)

{
  "version": "1.2.0",
  "url": "https://makenot.work/api/sync/ota/my-app/download/880b1700-.../darwin/aarch64",
  "signature": "<base64-encoded-signature>",
  "notes": "Bug fixes and performance improvements",
  "pub_date": "2026-03-13T12:00:00Z"
}

No Update (204)

Empty response. The current version is already the latest.

The endpoint returns an update only if the latest release version is strictly greater than current_version (semver comparison).

Download Endpoint

GET /api/sync/ota/{slug}/download/{release_id}/{target}/{arch}

Returns a 302 redirect to a presigned S3 download URL.

Managing Releases

List Releases

GET /api/sync/ota/apps/{app_id}/releases
Authorization: Bearer <token>

Delete a Release

DELETE /api/sync/ota/apps/{app_id}/releases/{release_id}
Authorization: Bearer <token>

Deleting a release also removes all its artifacts from S3.

Tauri Integration

For Tauri 2 apps, configure the updater plugin to point at your OTA endpoint:

{
  "plugins": {
    "updater": {
      "endpoints": [
        "https://makenot.work/api/sync/ota/my-app/{{target}}/{{arch}}/{{current_version}}"
      ]
    }
  }
}

Tauri handles the update check, download, signature verification, and restart automatically.

Signature Verification

The signature field is passed through to the update check response. For Tauri apps, this is the Ed25519 signature from tauri signer sign, verified against the public key embedded at build time. For non-Tauri apps, use any signature scheme; the server stores and returns the signature without interpretation.

Publish Script

The deploy/ota-publish.sh script automates the full publish flow. See the script for usage details.

See Also