Ultralight ships for various targets as a prebuilt 7-Zip package. You can download the latest SDK release from our [website](https://ultralig.ht/download) or [API](#content-downloading-from-the-api).

> 📘 Build Prerequisites
>
> Make sure to [setup your build environment](/docs/2.0/installing-prerequisites) before using the SDK in your applications.

## Downloading from the Website

Visit [our download page](https://ultralig.ht/download) to get the latest SDK for your platform.

Our Free SDK is available for all developers, make sure to login to access paid SDKs if you have purchased a license.

## Downloading from the API

You can also download SDK packages over HTTP using our API (great for automating downloads or bootstrapping CI scripts).

### API Endpoints

| | |
|---|---|
| List packages | `GET /api/v1/sdk/releases` |
| Download a package | `GET /api/v1/sdk/download` |

All endpoints live under `https://ultralig.ht`. They need no credentials and serve the Free edition on their own; add an API key to the same requests and they serve everything your account can download.

> 📘 One script for every account
>
> The endpoints are the same with or without a key, so a script written for the Free edition needs nothing but the key added to download a paid edition.

### API Keys

#### Creating a Key

Create a key on the [API Keys](https://ultralig.ht/dashboard/api-keys) page of your dashboard. Any account can, including free ones. Give it a name and a lifetime, then copy it: it is shown once.

> 🚧 Keep keys confidential
>
> A key can download everything your account can. Store it in your build system's secret store, never in a repository, and revoke it from the same page if it leaks.

#### Using a Key

Pass it in the `Authorization` header:

```shell
curl -H "Authorization: Bearer $ULTRALIGHT_API_KEY" \
  "https://ultralig.ht/api/v1/sdk/releases"
```

> 🚧 A key that fails is refused
>
> A request that sends an expired or revoked key gets a `401`, never the Free edition in its place. Only a request with no `Authorization` header at all is treated as anonymous.

### Listing Packages

Ask for the list to see which versions and platforms you can download:

```shell
curl "https://ultralig.ht/api/v1/sdk/releases"
```

```json
{
  "data": [
    {
      "version": "2.0.0",
      "channel": "stable",
      "platform": "linux-x64",
      "edition": "free",
      "build": "release",
      "filename": "ultralight-sdk-2.0.0-linux-x64.7z",
      "sha256": "…"
    }
  ]
}
```

The list has one entry per package file, newest release first. With a key it includes every edition your account can download.

#### Stable and Dev Channels

Each release is on the `stable` channel or the `dev` channel. Dev releases carry fixes and features ahead of the next stable release.

> 📘 `latest` means the newest stable release
>
> A dev release is never picked by default. Add `channel=dev` to get the newest dev release, or name a dev release's `version`.

### Downloading Packages

#### The Newest Stable Release

Pass a `platform` from the list:

```shell
curl -L -o ultralight-sdk.7z \
  "https://ultralig.ht/api/v1/sdk/download?platform=linux-x64"
```

#### The Newest Dev Release

Add `channel=dev`:

```shell
curl -L -o ultralight-sdk.7z \
  "https://ultralig.ht/api/v1/sdk/download?platform=linux-x64&channel=dev"
```

#### A Specific Release

Add its `version`, stable or dev:

```shell
curl -L -o ultralight-sdk.7z \
  "https://ultralig.ht/api/v1/sdk/download?platform=linux-x64&version=2.0.0"
```

#### A Paid Edition

With a key, the same request gives you the highest edition your account holds. Add `edition` to pick another:

```shell
curl -L -H "Authorization: Bearer $ULTRALIGHT_API_KEY" -o ultralight-sdk.7z \
  "https://ultralig.ht/api/v1/sdk/download?platform=windows-x64&edition=pro"
```

> 📘 Name the edition in scripts
>
> A request that names a paid edition without a key is refused with a `401`, so a CI job whose key is missing fails at once instead of quietly building against the Free edition.

> 🚧 Some clients forward your key
>
> A download redirects to a signed link on another host. `wget` and `curl --location-trusted` send the `Authorization` header along to it. With those clients, request the link with `format=json` (below) and fetch it in a second request that carries no key.

### Verifying Packages

Add `format=json` to get the download link together with the package's SHA-256 checksum instead of the file:

```shell
curl "https://ultralig.ht/api/v1/sdk/download?platform=linux-x64&format=json"
```

```json
{
  "url": "https://…",
  "version": "2.0.0",
  "platform": "linux-x64",
  "filename": "ultralight-sdk-2.0.0-linux-x64.7z",
  "sha256": "…",
  "expires_in": 300
}
```

Fetch the `url`, then compare the checksum before you unpack:

```shell
shasum -a 256 ultralight-sdk.7z
```

```shell
certutil -hashfile ultralight-sdk.7z SHA256
```

> 📘 The link expires
>
> `expires_in` is in seconds. Fetch the `url` within five minutes of asking for it, or ask again.

### Full API Reference

#### Conventions

| | |
|---|---|
| Base URL | `https://ultralig.ht` |
| Method | `GET` only. A `HEAD` request is refused. |
| Authentication | `Authorization: Bearer <key>`, optional. Without it, the endpoints serve the Free edition. |
| Responses | JSON, except a download without `format=json`, which redirects to a signed link. |
| Platforms | `windows-x64`, `macos-x64`, `macos-arm64`, `linux-x64`, `linux-arm64` |
| Editions | `free`, `indie`, `pro`, `enterprise` |
| Channels | `stable`, `dev` |

#### List Packages

`GET /api/v1/sdk/releases`

Every package you can download, newest release first, one entry per file. Without a key: every Free package of every published release.

| Field | Type | Meaning |
|---|---|---|
| `data[].version` | string | The release version. |
| `data[].channel` | string | `stable` or `dev`. |
| `data[].platform` | string | The platform token. |
| `data[].edition` | string | `free`, `indie`, `pro`, or `enterprise`. |
| `data[].build` | string | `release` or `debug`. |
| `data[].filename` | string | The package's file name. |
| `data[].sha256` | string | The package's SHA-256 checksum. |

Rate limit: 60 requests an hour per address without a key; 120 requests an hour per key with one.

#### Download a Package

`GET /api/v1/sdk/download`

##### Query Parameters

| Parameter | Required | Value |
|---|---|---|
| `platform` | yes | One of the platform tokens. |
| `version` | no | A version from the listing. Default `latest`, the newest release on the channel. |
| `channel` | no | `stable` (default) or `dev`. Which channel `latest` means; a named `version` is unaffected. |
| `edition` | no | One of the editions. With a key, default: the highest edition your account holds. Without one, only `free`. |
| `build` | no | `release` (default), or `debug` where your account has debug packages. Needs a key. |
| `format` | no | `json` returns the link and the checksum instead of redirecting. |

##### Response

Without `format=json`: a `302` redirect to a signed link that expires five minutes after it is issued.

With `format=json`:

| Field | Type | Meaning |
|---|---|---|
| `url` | string | The signed download link. |
| `version` | string | The release version served. |
| `platform` | string | The platform token. |
| `filename` | string | The package's file name. |
| `sha256` | string | The package's SHA-256 checksum. |
| `expires_in` | integer | Seconds until `url` stops working. |

##### Rate Limits

| | Limit |
|---|---|
| Without a key | 30 downloads per ten minutes per address. |
| With a key | 60 downloads an hour per key, and 30 per ten minutes per account and per address. |

#### Errors

| Status | Meaning |
|---|---|
| `401` | The key is revoked, expired, or missing for a paid edition or a non-release build. |
| `404` | No package matches, or your account can't download it. |
| `405` | The request was a `HEAD`; use `GET`. |
| `422` | A parameter is missing, or isn't one of the listed values. |
| `429` | Too many requests. The `Retry-After` header says how many seconds to wait. |

## Package Contents

Along with the folders below, the package root contains a README, a `VERSION.txt` file tracking the release version, and a root `CMakeLists.txt` for building the bundled samples and tools.

| Folder | Contents |
|---|---|
| `bin/` | The four shared libraries that your application runs against. |
| `lib/` | Import libraries for linking on Windows, and a `cmake/` subfolder holding the CMake package. |
| `include/` | The public API headers, divided into `Ultralight/`, `AppCore/`, and `JavaScriptCore/`. |
| `resources/` | Runtime data files that the library loads, including ICU internationalization data and the SSL certificate bundle. |
| `inspector/` | The Web Inspector front end, needed only when your application opens developer tools. |
| `samples/` | Sample projects illustrating features from a basic window up to a full web browser. |
| `tools/` | MiniBrowser, a minimal browser application for testing your pages. |
| `platform/` | Open-source reference implementations of platform handlers (under the Zlib license)— a starting point for your own integrations. |
| `license/` | The Ultralight license, End User License Agreement (EULA), and third-party legal notices. |

For details on which runtime binaries and resource assets your application must bundle and deploy, see [Linking to the Library](/docs/2.0/linking-to-the-library).
