# update-server (update.ngnear.dev) > General-purpose software update server. Programs ask it "is there a newer version of product X for my OS/arch?" and download the file, verifying sha256. Read-only HTTP API, authenticated by a per-client API key header. Releases are published locally with a CLI (there is no upload endpoint). Base URL: https://update.ngnear.dev Auth: send `X-Update-Key: ` (or `Authorization: Bearer `) on every /v1 request. Keys look like `upk_k1a2b3c4d_`. Never put the key in the URL. Ask the owner (Leonard) for a key; one key per client program, scoped to the products it may update. ## The only call most clients need GET https://update.ngnear.dev/v1/products/{product}/check?current={semver}&os={os}&arch={arch}[&channel=stable][&kind=msi] - 204 No Content -> already up to date - 200 JSON -> {"update_available":true,"mandatory":bool,"latest":{"version","notes","pub_date",...},"download":{"url","filename","size","sha256","signature?","kind","artifacts":[...]}} - 401 bad/missing key, 404 unknown product / no build for this platform, 400 bad parameters (JSON {"error":{"code","message"}}) Then GET download.url with the same key header, write to a temp file, verify size + sha256, and only then replace/install. os: windows | linux | darwin | any (aliases accepted: win32, ubuntu, macos). arch: x86_64 | aarch64 | i686 | armv7 | any (aliases: amd64, x64, arm64). You may pass your runtime's native values unchanged. ## Other endpoints (all GET/HEAD, JSON, key required unless noted) - /v1/me key sanity check - /v1/products products this key may see + latest per channel - /v1/products/{p}/latest[?channel&target=os-arch&kind] manifest, same shape as Tauri's latest.json - /v1/products/{p}/releases[?channel&limit] release list, newest first - /v1/products/{p}/releases/{version} one release with every platform file - /v1/products/{p}/releases/{version}/files/{name} file download (HEAD, Range, ETag=sha256, X-Checksum-SHA256) - (no key) / human page · /healthz · /openapi.json · /llms.txt · /docs/{architecture,api,integration,operations,decisions}.md · /clients/{update_client.py,update-client.mjs,update-check.sh,update-check.ps1} ## Read next - https://update.ngnear.dev/docs/integration.md how to add update support to a new program (bash, PowerShell, Python, Node recipes, safe install, rollback) - https://update.ngnear.dev/docs/api.md every endpoint, field and error code with real responses - https://update.ngnear.dev/docs/architecture.md data model, modules, how to extend the server - https://update.ngnear.dev/docs/operations.md publishing releases, keys, backups, tunnel/service (owner-side) - https://update.ngnear.dev/docs/decisions.md why it is designed this way (Tauri/Sparkle/Omaha/TUF comparison) - https://update.ngnear.dev/openapi.json machine-readable spec ## Rules of thumb for agents - Versions are SemVer 2.0 without build metadata (1.2.3, 1.2.3-beta.1). Compare with SemVer rules, not string order. - Treat `mandatory:true` as "do not let the user skip". - Never trust a download that fails size/sha256. Never cache these URLs in shared caches (responses are `Cache-Control: private`). - Do not invent products or platforms; list them via /v1/products and /v1/products/{p}/latest. - Reference clients to copy (public, no key): https://update.ngnear.dev/clients/update_client.py (Python, stdlib), https://update.ngnear.dev/clients/update-client.mjs (Node 18+), https://update.ngnear.dev/clients/update-check.sh (bash+curl+jq), https://update.ngnear.dev/clients/update-check.ps1 (PowerShell). Exit codes: 0 update available, 10 up to date, 1 error. - Architecture matters: every file is bound to an `os-arch` (windows-x86_64, linux-aarch64, darwin-aarch64, any-any). An x64 client never gets an arm64 file. Latest is resolved per platform. Pass emulated=1 only if emulated builds are acceptable (e.g. Windows on ARM running x64).