Skip to content

API conventions and errors ​

The management API is versioned under /api/v1/ on your ReleaseDesk server. If RD_BASE_URL is https://releases.example.com, the apps endpoint for an organization is https://releases.example.com/api/v1/orgs/<orgId>/apps. Use IDs returned by the API in management paths. Public URLs use slugs where their route names say orgSlug or appSlug.

Route families ​

PrefixPurposeUsual response
/api/v1/Organization and app managementJSON, with some empty or CSV responses
/api/auth/GitHub sign-in and session handlingAuth redirects and session responses
/d/Public app pages and changelogsHTML
/dl/Artifact files and iOS OTA manifestsBinary, redirect, or XML
/feeds/v1/Application update feedsJSON, XML, YAML, or redirect
/t/Tester sign-in and shared buildsHTML and redirects
/healthzServer healthJSON
/site/logoPublic site logoImage

Public paths and tester pages do not inherit the management API's session and token rules. Consult Authentication and access before using a path outside /api/v1/.

The instance health and version routes are public. Most management routes use a dashboard session; only routes whose reference explicitly lists a token scope accept bearer tokens. Invitation links and the tester portal have their own credentials. /api/auth/* is handled by Better Auth for GitHub sign-in and session operations, rather than by the management route modules.

Requests and responses ​

Most management endpoints accept and return JSON. Send Content-Type: application/json when the endpoint has a JSON body. The release upload endpoint is different: its body is the raw artifact bytes, and version, buildNumber, platform, arch, and format (and optionally variant) are query parameters. It is not a multipart upload.

Resumable uploads use the separate tus routes, with protocol headers and raw chunks. Logo uploads also use raw image bytes.

List endpoints generally return an object with an items array. Some endpoints return a single object. A successful delete or reset may return 204 No Content, so callers should not always attempt to parse JSON. Store publication actions can return 202 Accepted because processing continues asynchronously. Analytics CSV export returns text/csv.

ReleaseDesk uses opaque prefixed IDs such as app_..., rel_..., and art_.... Treat them as strings; do not derive a slug, version, or creation date from an ID. JSON timestamps are ISO-style strings. A field can be null when the value has not been set, such as a release's publishedAt before its first promotion.

Errors ​

Application errors return a JSON body with a stable snake-case code and a readable message:

json
{
  "error": {
    "code": "app_not_found",
    "message": "App not found"
  }
}

The error object can also contain details. Unexpected server errors include a request ID in details.requestId. Use error.code for application error handling and message for display or logs. The text of a message is not the compatibility contract.

There is one important exception: endpoints using the route schema validator currently return the validator's result as JSON with status 400 when a JSON body or query string does not match its schema. That response does not use the application error envelope above. Parse it separately if your client needs field-level validation details. A ZodError raised elsewhere is handled as 422 with code validation_failed and field issues in details.issues.

StatusWhat to check
400A route schema or request-specific constraint failed, such as an invalid confirmation slug
401No valid session, token, or private-download credential was supplied
403The caller is known but lacks permission, or a browser origin was blocked
404The resource is absent or deliberately hidden from this caller
409The requested state conflicts with existing data, such as a duplicate artifact
413The upload exceeds the configured size limit
422A validation error was raised outside the route schema validator
429The caller has reached a rate limit
500An unexpected server error occurred

Some external-store operations can also report an upstream failure. The response code and error.code together give more detail than the status alone.

Rate limits and request IDs ​

The server rate-limits sign-in routes, public downloads and pages, feeds, invitation token routes, tester portal requests, and token creation. A 429 response includes a Retry-After header in seconds. Limits are kept in memory per server process; callers should back off according to that header rather than repeatedly retrying.

Every response carries X-Request-Id. You may send your own X-Request-Id header to correlate a request with server logs. If you do not send one, the server generates an ID. Include it when reporting an unexpected error.

Caching and file transfers ​

Update feeds can send cache headers and ETags. A feed can return 204 No Content when it has no update for the request. Artifact downloads may return the file directly, a partial 206 response for a byte-range request, or a 302 redirect to storage. Download clients should follow redirects and handle range responses. For private artifacts, use the signed download link returned by the management API or an authorized dashboard session; a bearer management token is not the credential checked by /dl/.