A NetSparkleUpdater-compatible JSON appcast for one RedGuides resource, gated per authenticated user. Each item carries an authenticated installer URL and an Ed25519 signature of the installer bytes. The feed is dynamic, so there is no signed appcast file — verify downloads only (see NetSparkle Setup).
| Thing | Value |
|---|---|
| Appcast | GET /community/api/resources/{id}/appcast |
| Download | items[].url |
| Auth | OAuth2 Authorization Code + PKCE (S256), public client, no secret |
| Scopes | resource:read (required), user:read (only for GET /api/me) |
| Client ID | 1363608282203325 |
| Redirect URI | http://127.0.0.1/ (any loopback port accepted) |
| Entitlement header | X-RG-Entitlement: active | expired | none |
| Public key | ZGqWpU6GzJw+ERgQwxZXWo3Hf4828oCoh498Zf1ir6c= |
| Cache | Cache-Control: private, no-store |
Send Authorization: Bearer <access_token> on both appcast and download requests, using XenForo 2.3
OAuth2 (Authorization Code + PKCE).
| Endpoint | URL |
|---|---|
| Authorize | https://www.redguides.com/community/oauth2/authorize |
| Token | https://www.redguides.com/community/api/oauth2/token |
| Revoke | https://www.redguides.com/community/api/oauth2/revoke |
Tokens expire and refresh-token rotation is supported. (XF-Api-Key also works, but OAuth2 is the
supported app path.)
GET https://www.redguides.com/community/api/resources/{id}/appcast
Authorization: Bearer <access_token>
Accept: application/json{
"title": "MQ2Grind",
"link": "https://www.redguides.com/community/resources/mq2grind.1967/",
"description": "MQ2Grind updates",
"language": "en",
"items": [
{
"title": "MQ2Grind 3.1.52471.15",
"version": "3.1.52471.15",
"short_version": "3.1.52471.15",
"url": "https://www.redguides.com/community/api/resource-versions/27668/download?file=77622",
"os": "windows",
"type": "application/octet-stream",
"signature": "Xy9k2...<88-char base64 Ed25519 signature>...g3Dw==",
"description": "<release notes HTML>",
"publication_date": "2026-06-18T03:10:47Z",
"size": 1244452
}
]
}Keys are snake_case; null/empty fields are omitted; only the latest build is advertised.
| Item key | Notes |
|---|---|
version / short_version |
The resource's version_string verbatim. Author-supplied, not normalized — values like 4.4.3, 2782, v0.42, or 06/17/2026 all occur, so don't assume it parses as SemVer. |
url |
Authenticated installer download URL. |
signature |
Base64 Ed25519 signature of the installer bytes. |
description |
Release notes as HTML (can change without a version bump). |
publication_date |
ISO-8601 UTC. |
size |
Installer size in bytes. |
os / type |
windows / application/octet-stream. |
An empty items[] means "nothing to offer" — leave the installed app as-is.
| Situation | Response |
|---|---|
| Entitled, published build available | 200, one item |
| Authenticated but not entitled, or nothing published | 200, empty items[] |
| Missing/invalid token | 401 |
| Unknown resource id | 404 |
| Header | Meaning |
|---|---|
X-RG-Entitlement |
active (can download now), expired (lapsed, may be renewable), none. |
X-RG-License-End-Date |
ISO-8601 license end date when a license row exists. Display hint only — don't gate updates on it. |
X-RG-Renewal-Url |
Present only when expired and renewable. |
Use items[] plus X-RG-Entitlement as the source of truth for whether the app can update now.
https://www.redguides.com/community/api/resource-versions/{version_id}/download?file={attachment_id}
Uses the same bearer token, re-checks entitlement, and returns the exact installer bytes
(application/octet-stream) that items[].signature was computed over. Auth/entitlement failures
return an API error instead of bytes.
Use SecurityMode.OnlyVerifySoftwareDownloads with the public key — Strict expects a signed appcast
file this dynamic feed does not provide.
_sparkle = new SparkleUpdater(
"https://www.redguides.com/community/api/resources/{id}/appcast",
new Ed25519Checker(
SecurityMode.OnlyVerifySoftwareDownloads,
"ZGqWpU6GzJw+ERgQwxZXWo3Hf4828oCoh498Zf1ir6c="
)
);