App distribution feeds
The Sparkle appcast feeds and download URLs desktop apps update from, and who gets what.
View as MarkdownDesktop apps bought on Gujo update from the distribution feeds on the app host. Feeds use the Sparkle 2 format, and on every request the server builds the feed from only the releases that caller may get.
Feed URL
https://app.gujo.ai/distribution/v1/products/{id}/appcast.xml
curl https://app.gujo.ai/distribution/v1/products/42/appcast.xml \
-H "Authorization: Bearer $GUJO_DEVICE_KEY"
{id}is the numeric id of the app product.- An app product's feed always needs
Authorization: Bearer <device key>, and that key needs thedevice.installability. A key bound to one product must be bound to this one. - The response is
application/rss+xml; charset=UTF-8, and consumers need Sparkle 2.9 or later. - Responses that saw a device key carry
Cache-Control: no-store, privateandVary: Authorization. Sessions and cookies are not used. - The feed URL is the installed app's
SUFeedURL, which cannot change without shipping the app again. That is why this path stays fixed.
Who gets what
Each state of an app product decides who may fetch it and which releases it carries.
| Product state | Who may fetch | Releases carried |
|---|---|---|
Draft (draft) |
Device key + an entitlement to that product (for test installs) | dev and approved releases |
Published (published) |
Device key + an entitlement to the app, or a Gujo Pass subscription that opens it | Approved stable, beta and alpha (not dev) |
Retired (retired) |
Same as published + an install record the server received before the retirement time | The last stable approved before retirement, only |
- Gujo Pass opens app products only. Assets and lectures are not opened by Pass.
- stable, beta and alpha releases appear in feeds only after a person approves them. A release waiting for approval appears in no one's feed.
- For a retired app, the install record counts by the time the server first received it. The install time the device reports is ignored.
Everything else is 404
An unknown product, a product that is not an app, an unknown channel and a request the rules above reject all get 404. Answering 401 or 403 would reveal that the product or release exists. If a feed returns 404, check the key, its device.install ability, then the entitlement or Pass.
Channels
Channels are stable, beta, alpha and dev.
- The URL without a query is the combined feed. It carries releases of every published channel, newest first, and adds a
<sparkle:channel>tag only to items that are not stable. The app picks the channels to follow from its installed settings (allowedChannels). - The
?channel=<c>URL is kept for older builds that put the channel in the feed URL. It carries only that channel's items, without tags. - The item limit applies per channel.
Downloads
https://app.gujo.ai/distribution/v1/releases/{id}/download
- Call it with the same device key as the feed. The rules are the same as the feed's.
- When allowed, it answers 302 to a short-lived signed URL, with
Cache-Control: no-store, privateand noSet-Cookie. - A missing, withdrawn or still-pending release, or one the product's current state does not carry, gets 404.
- If the server has no distribution storage configured, it answers 503
distribution_not_configured.
Don't send the device key again to the signed URL.
Registering releases
Only Gujo's publishing tools register releases. Keys from this site cannot.