Topolo Docs Topolo Platform
Open workspace

Read an app’s marketing metadata

Read saved marketing fields and marketplace subcategory while distinguishing authored configuration from public listing, copy approval and live content.

Outcome

Read saved app marketing metadata and marketplace subcategory in the authorized developer console.

GET /api/developer-console/apps/{appId}/marketing

Before you start

Use the original authenticated organization with the published Developers apps:read permission. Discover an accessible canonical Developers workspace and bind it separately as resource context. Input appId is an accessible developer app record identifier; it is not a workspace id or an access grant.

The concrete route allows suspended developer profiles to read but denies revoked access. It resolves a developer profile and verified workspace, then requires app read access in that workspace. Platform authority, organization administrator status, app membership and developer ownership are distinct source branches; an app outside the selected workspace or invisible to the actor returns404. Do not broaden the organization or grant after a refusal.

This is an authorized read of saved marketing metadata, not a public listing or approval of its copy/media. Actual authored app/organization data remains behind the original caller’s access checks.

The shared request path can insert a local identity-only workspace mirror and, for an enabled organization without a developer profile, create the initial developer profile after resolving a platform-issued workspace. This can precede app access refusal. No canonical Auth workspace is minted, and readOnly metadata is not a promise of zero initialization writes.

All worked responses are source-derived synthetic UNRUN examples. No real developer app, declaration, provider, key, person, private record, publication or other business action was read or changed. The immutable source matches the retained declaration revision; serving-runtime adoption is not independently proven.

Request and response

Action: app_topolo_developers.apps.marketing.get.

{"appId":"app_docs_fixture"}

The id is fictional. Discover the actual app and bind its canonical Developers workspace separately; validate/plan against the current contract before a real call.

The complete HTTP200 envelope is {success:true,message,data:{appId,marketing,subcategory}}. appId is the requested app id after the app/workspace/actor checks. subcategory is the app’s marketplaceSubcategory or null, separate from marketing.marketplaceCategory. Input requires appId; the handler implements no field projection, filter, cursor or publication flag.

The route allows suspended profile reads, not revoked access, and does not require completed onboarding for GET. It resolves the profile/workspace then requires the selected app to belong to that workspace and actor.canRead. Ordinary same-organization workspace selection is Auth-verified; the existing privileged cross-organization platform branch uses the seeded profile workspace without honoring a requested header.

Shared context can insert a local identity-only workspace mirror and initialize a missing developer profile for an enabled organization after resolving a platform-issued workspace. No Auth workspace is created. These effects can occur before a later app-access refusal, so the read declaration is not a whole-request no-write guarantee.

The app row and joined submission are mapped first, but this handler returns only the app id, normalized metadata.marketing value and marketplace subcategory. It does not return the whole app, actor flags, member/transfer records, action definitions, P2P capabilities or mobile artifacts.

marketing uses the saved value when it is truthy and typeof object, otherwise {}. Arrays also satisfy that JavaScript condition; this read does not enforce a precise object schema or the write path’s marketing-field defaults/description rules. It does not remove a legacy marketing.visible property, validate HTML/URLs/media, sanitize arbitrary authored values or certify marketplace copy approval.

Known write-path fields such as tagline,description,heroMedia,gallery,benefits,features and launcherQuickLinks may be present, but the read forwards the stored marketing value rather than synthesizing all those fields. A missing key does not prove the copy was intentionally cleared. Do not send a raw read body back as a write without discovering the current write schema and reviewing its actual partial-update/publication effects.

A saved marketing.status, stageLabel, URL/media reference, docs link or marketplace subcategory is configuration, not proof of public registry visibility, deployed release, live URL/media availability, approved positioning or entitlement. This GET does not fetch a URL, publish a manifest, verify a provider or execute an app action.

If an app does not exist or is not visible in the selected workspace/actor context, the handler returns404 Developer app not found rather than an empty marketing success. Dependency/auth/profile/workspace errors are distinct; this handler does not replace a failed query with {}. Preserve the actual status, context and request id.

Worked responses

No saved marketing object

Complete source-derived synthetic UNRUN HTTP200 after all app/context checks succeed. Assume the fictional stored app has no marketing value and no marketplace subcategory. The default{} is a successful mapping, not a public-listing or copy-approval result.

{
  "success": true,
  "message": "App marketing metadata fetched",
  "data": {
    "appId": "app_docs_fixture",
    "marketing": {},
    "subcategory": null
  }
}

Retain absent saved metadata in the original context; do not create, publish or fetch content to make the result nonempty.

Return exactly the saved fields

Complete synthetic UNRUN HTTP200 assuming the stored marketing object contains exactly the shown tagline/features fields. The read does not synthesize the remaining optional write-path fields or revalidate this legacy object. No actual app or authored content was read.

{
  "success": true,
  "message": "App marketing metadata fetched",
  "data": {
    "appId": "app_docs_fixture",
    "marketing": {
      "tagline": "Fixture workspace tools",
      "features": []
    },
    "subcategory": null
  }
}

Treat these values as saved authored configuration, not approved/public/live content or a valid complete update payload.

App missing or not visible

Complete synthetic UNRUN HTTP404 after shared context resolution for a missing app or app-workspace/actor mismatch. It does not distinguish inaccessible from absent and does not prove no initialization happened.

{
  "success": false,
  "error": {
    "message": "Developer app not found"
  }
}

Preserve original context and actual refusal/request id; do not broaden organization/workspace or guess ids as recovery.

Verify and recover

  1. Compare actual data.appId with the discovered app and separately bound original workspace context. A successful{} marketing value is not the missing/inaccessible-app response.

  2. Read the exact stored marketing shape and separate subcategory; preserve authored/legacy values without claiming field completeness, sanitization, approval or current public availability.

  3. For any intended edit/publication, separately discover current actions and schemas, review the exact before/after and obtain concrete authority. No media fetch, URL navigation, registry publication or business execution is needed to verify this read.

  4. Preserve actual errors and possible shared initialization for the owner. Do not delete/create a profile/mirror, change grants, edit copy or publish as an automatic inverse.

Change log

  • 2026-10-21: Added the exact saved-marketing carrier, fallback/legacy-shape handling, actual read access and configuration-versus-publication limits, with complete source-derived synthetic unrun examples. No app copy, provider or release was changed.