# Registry API

The registry is the read side of Ember's distribution: a catalog of published applets and extensions, immutable package bytes, and the desktop client's update feed. Every response is public and unauthenticated. Writing to the registry is covered in [publishing](/docs/publishing.md).

## Catalog

```http
GET /v1/catalog
```

Returns every published applet and extension.

```json
{
  "schemaVersion": 1,
  "generatedAt": "2026-01-01T00:00:00.000Z",
  "applets": [
    {
      "id": "com.example.hello",
      "name": "Hello Ember",
      "description": "My first Ember applet.",
      "version": "1.0.0",
      "publisher": "Example",
      "sha256": "…",
      "packageUrl": "https://ember.hcws.dev/packages/….ember-applet",
      "size": "12 KB",
      "permissions": ["storage"]
    }
  ],
  "extensions": []
}
```

`packageUrl` and `sha256` describe one immutable release. A new version publishes a new object at a new URL; existing bytes are never rewritten. Clients may cache package downloads forever and should re-fetch the catalog to discover updates.

## Packages

```http
GET /packages/<sha256>.ember-applet
GET /packages/<sha256>.ember-extension
```

Package files are named by the SHA-256 of their contents. Ember downloads the URL from the catalog, hashes what it received, and refuses to continue if the digest does not match. It then verifies the applet's signature and shows the capability review. A registry that serves the wrong bytes fails at the client, not silently.

## Desktop updates

```http
GET /v1/updates/windows/<arch>/<current-version>
```

`arch` is `x86_64`, `i686`, or `aarch64`. The endpoint returns `204 No Content` when the client is already current, and otherwise a Tauri updater release object with `version`, `notes`, `pub_date`, `signature`, and `url`. Update archives are served from `/updates/<sha256>.zip` and are immutable.

## Health

```http
GET /health
```

Returns `{ "ok": true }`. Use it for container and load balancer probes.

## Running your own

```sh
$env:EMBER_PUBLISH_TOKEN = "choose-a-long-secret"
npm run registry:dev
```

The server listens on port 4010. Set `EMBER_PUBLIC_URL` so published package URLs point at your public origin rather than the container's own host header. Point a client at it with `VITE_EMBER_REGISTRY_URL`.

The reference server stores packages on disk and keeps the catalog in a JSON file. Put it behind TLS, and move packages to object storage and the catalog to a database before running it for anyone but yourself.
