Skip to content

Apps and public page settings ​

An app groups releases and channels inside an organization. Its id is used in management API paths. Its slug, together with the organization slug, forms the public download URL. Creating an app also creates the dev, beta, and stable channels; only stable is public initially.

All routes below start with /api/v1/orgs/:orgId/apps. Most require a GitHub session. The detail read is the exception: it accepts either a session with the viewer role or an API token with read scope. An app-scoped token can read only its own app.

Method and suffixMinimum role or scopeSuccessResult
GET /Viewer session200{ "items": [app, ...] }
POST /Developer session201Created app
GET /:appIdViewer session or read token200App with channels
PATCH /:appIdDeveloper session; admin for public page fields200Updated app
GET /:appId/logoViewer session200Logo image
PUT /:appId/logoAdmin session200Updated app
DELETE /:appId/logoAdmin session200Updated app
DELETE /:appIdAdmin session204Empty body

Create and inspect an app ​

Create an app with name and an organization-unique slug. description is optional:

http
POST /api/v1/orgs/org_123/apps
Content-Type: application/json

{"name":"Field Notes","slug":"field-notes","description":"Internal field reporting app"}

The name and slug must each be 1–100 characters; the description is at most 2,000 characters. The slug uses lowercase letters, digits, and internal hyphens. An existing slug within this organization returns 409 app_slug_taken. The create response includes the app's id, orgId, name, slug, description, iconKey, publicPageEnabled, publicPageConfig, and timestamps. The app starts with its public page enabled, though that page has no downloadable build until a release reaches a public channel.

Use GET /api/v1/orgs/:orgId/apps/:appId to obtain the channel IDs needed for promotion. This response adds a channels array to the app. Each channel has id, appId, name, and isPublic. The list route returns app records sorted by name; it does not add the channels array to each item.

sh
curl -H "Authorization: Bearer $RD_TOKEN" \
  "$RD_URL/api/v1/orgs/$ORG_ID/apps/$APP_ID"

The command above works for a token with read scope. Use the returned channels[].id for a promotion; the string stable is a channel name, not its ID.

Edit the description or public page ​

PATCH /:appId accepts a partial JSON object. A developer may change description, including setting it to null to clear it. Changing publicPageEnabled or publicPageConfig requires an admin session.

http
PATCH /api/v1/orgs/org_123/apps/app_456
Content-Type: application/json

{
  "publicPageEnabled": true,
  "publicPageConfig": {
    "accentColor": "#2458A6",
    "headline": "Get Field Notes",
    "tagline": "The latest production builds",
    "footerLinks": [{"label":"Support","url":"https://example.com/support"}],
    "showChangelog": true,
    "showChecksums": true,
    "hiddenPlatforms": ["linux"]
  }
}

The config fields are structured; raw HTML and CSS are not accepted. accentColor is a six-digit hex color or null. headline allows up to 100 characters, tagline up to 280, and each of up to five footer links needs a label of 1–40 characters and an HTTP(S) URL of at most 500 characters. hiddenPlatforms may contain android, ios, macos, windows, or linux. When a config object is supplied, omitted fields take the schema defaults: empty footer links and hidden platforms, null text and color fields, and true for changelog and checksum display. Include values you want to preserve when replacing a config object.

Turning off publicPageEnabled makes /d/:orgSlug/:appSlug return 404. It does not remove releases or stop feed URLs from serving eligible updates. Hiding a platform changes the page display; it does not revoke that platform's artifact.

To serve this page from your own hostname, see Custom domains.

Logo upload ​

Send the image bytes as the request body, not multipart form data:

sh
curl -X PUT --data-binary @logo.png \
  -H "Content-Type: image/png" \
  "$RD_URL/api/v1/orgs/$ORG_ID/apps/$APP_ID/logo"

This call needs a signed-in admin session, so the example also needs your session cookie when run outside the dashboard. The server detects the file from its bytes and accepts PNG, JPEG, or WebP. SVG is rejected. The file must be nonempty and no larger than 512 KiB. A valid upload replaces the previous logo and returns the updated app. DELETE /:appId/logo removes it and also returns the app. Invalid image data or size returns 400 validation_failed.

GET /:appId/logo requires a viewer session and returns the image bytes. The public slug-based logo route is described under Public pages and downloads.

Delete an app ​

http
DELETE /api/v1/orgs/org_123/apps/app_456
Content-Type: application/json

{"confirmSlug":"field-notes"}

The confirmation must match the app's current slug. Deleting an app cascades through its releases, channels, feeds, and other app-owned records. The server then attempts to remove stored artifacts and the logo. The response is 204 No Content; there is no JSON to parse. A wrong confirmation returns 400 validation_failed and an unknown app returns 404 app_not_found.

For upload and promotion, continue with Releases and artifacts. For the page visitors see, read Public downloads.