Appearance
Custom domains for download pages
Give an app's public download page its own hostname, such as downloads.example.com. After verification, visitors open https://downloads.example.com/ instead of /d/:orgSlug/:appSlug on the ReleaseDesk host. Release pages use /releases/:version and the app logo uses /logo on that hostname. The original /d/:orgSlug/:appSlug URL remains available while the app's public page is enabled.
Custom domains serve public download pages and their downloads. They do not host the dashboard, management API, or update feeds. A release still needs an artifact promoted to a public channel before a visitor can download it. See Apps and public pages and Public pages and downloads.
Before you start
- You need an app in the organization and an admin or owner dashboard session.
- The app's public page must be enabled to display it. A new app has this enabled by default.
- You must control DNS for the hostname and configure your reverse proxy to serve it over HTTPS while forwarding the original
Hostheader to ReleaseDesk. The bundled production Caddyfile serves onlyRD_DOMAIN; it does not automatically add customer hostnames or issue certificates for them. - On hosted plans, custom domains must be included in the organization's plan. Self-hosted instances have no plan restriction for this feature.
Set up a domain in the dashboard
- Open Settings → Domains, select the app, enter a hostname such as
downloads.example.com, and click Add domain. Enter the hostname only, withouthttps://or a path. - Copy the TXT host and TXT value shown on the pending domain. Create that TXT record with your DNS provider. For the example hostname, the host is
_releasedesk.downloads.example.com; the value starts withreleasedesk-verify=and is unique to this domain claim. Some DNS providers ask for a name relative to the zone, such as_releasedesk.downloadswhen the zone isexample.com. - Point the hostname at the reverse proxy serving ReleaseDesk. For a subdomain, a CNAME to the proxy's public hostname is often suitable; an A or AAAA record to the proxy's address also works. This routing record is separate from the TXT ownership record.
- Configure HTTPS for that hostname on the reverse proxy and forward requests to ReleaseDesk with the requested
Hostintact. - Once the TXT record is visible in public DNS, click Verify. ReleaseDesk queries DNS for the exact TXT value and changes the status to Verified. Then open
https://downloads.example.com/and check the page and a release download.
The TXT record proves control of the hostname; it does not route traffic or issue a TLS certificate. Verification may succeed before the page is reachable if the routing record or proxy configuration is still missing.
API example
The management routes are under /api/v1/orgs/:orgId/domains and require an admin or owner session cookie. API tokens cannot call them. Assume RD_URL=https://releases.example.com, ORG_ID and APP_ID are IDs returned by the API, and RD_SESSION_COOKIE is your authenticated session cookie:
sh
curl -X POST "$RD_URL/api/v1/orgs/$ORG_ID/domains" \
-H "Cookie: $RD_SESSION_COOKIE" \
-H "Content-Type: application/json" \
-d '{"appId":"'"$APP_ID"'","hostname":"downloads.example.com"}'The 201 response includes an id, hostname, verified: false, and the DNS record to publish:
json
{
"id": "dom_example",
"appId": "app_example",
"hostname": "downloads.example.com",
"verified": false,
"verifiedAt": null,
"createdAt": "2026-01-01T00:00:00.000Z",
"dns": {
"txtHost": "_releasedesk.downloads.example.com",
"txtValue": "releasedesk-verify=<unique-token>"
}
}After adding the TXT record, verify and list domains:
sh
curl -X POST -H "Cookie: $RD_SESSION_COOKIE" \
"$RD_URL/api/v1/orgs/$ORG_ID/domains/$DOMAIN_ID/verify"
curl -H "Cookie: $RD_SESSION_COOKIE" \
"$RD_URL/api/v1/orgs/$ORG_ID/domains"GET /domains returns { "items": [...] }. Verification returns the updated domain. Remove a domain with DELETE /api/v1/orgs/:orgId/domains/:domainId (success: 204 No Content). Removing it stops ReleaseDesk from serving that hostname, but does not remove its DNS records or proxy configuration.
For reverse proxies that request certificates on demand, GET /api/v1/domains/check?domain=downloads.example.com returns 200 only for a verified hostname that still belongs to an app; otherwise it returns 404. It is an unauthenticated, rate-limited certificate authorization check, not the endpoint that verifies DNS ownership.
Troubleshooting
| Symptom | Check |
|---|---|
Verify reports domain_unverified | Query the exact dns.txtHost from the API response, confirm the complete dns.txtValue is published, and allow time for DNS propagation. ReleaseDesk checks public DNS; a local hosts-file entry does not count. |
| The domain is verified, but HTTPS fails | Confirm the hostname points to your proxy and that the proxy has a certificate for that hostname. The default RD_DOMAIN Caddy site alone does not cover other hostnames. |
| HTTPS works, but the wrong site appears | Confirm the proxy forwards the original Host header and routes the hostname to the ReleaseDesk server. Only verified hostnames are mapped to apps. |
| The page returns 404 or has no build | Check that the app's public page is enabled and a release with the relevant artifact is promoted to a public channel. |
Adding a domain returns domain_taken | Another organization has already verified that hostname. An unverified claim does not permanently reserve it. |
Adding a domain returns plan_limit_reached | The hosted organization's plan does not include custom domains. |
Hostnames are normalized to lowercase and must be DNS names, not URLs. ReleaseDesk rejects its own configured base hostname as a custom domain. For proxy configuration on your deployment, also see Country stats and Caddy.