Outcome
Inspect saved Android and iOS artifact metadata without downloading, installing or promoting a mobile build.
GET /api/developer-console/apps/{appId}/mobile-artifacts
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.
These are saved app configuration reads, not a live P2P provider discovery result or a downloadable/installable mobile catalog. Publication and saved sync flags do not grant caller access, install an app or authorize a provider execution.
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
Action: app_topolo_developers.apps.mobile_artifacts.list.
{
"appId": "app_docs_fixture"
}
These identifiers are fictional; discover the actual app and separately bind its canonical Developers workspace. Validate and plan with the current published schema before any real call.
Response and behavior
HTTP200 uses the full envelope {success:true,message,data:{...}}. Read records inside data rather than assuming the top-level response is the collection. Exact JSON schemas below are copied from the current declaration, whose structural permissiveness does not substitute for the source-qualified field meanings.
The shared context first authenticates and finds or initializes a developer profile; a revoked profile is refused and a suspended profile is allowed for these GET handlers. For an ordinary same-organization request, Auth verifies the requested workspace at minimum read level. The existing privileged cross-organization platform context instead uses the seeded developer profile’s workspace and does not honor a requested workspace header on that branch. Both branches still reach the app-workspace match and actor.canRead checks. The app-specific handlers do not require completed onboarding for reads. Missing and inaccessible app records are deliberately indistinguishable404 responses.
App access is evaluated after workspace selection. In the source actor calculation, recognized platform access can produce owner role, an organization mismatch otherwise denies, an administrator of the owning organization is an owner, explicit matching user id/email membership can supply a role, and matching developer ownership is the fallback. A permission string alone does not establish all these context conditions.
The selected list query reads saved app metadata without contacting P2P, fetching an artifact URL, installing code, publishing a declaration, minting a key or sending a notification. Shared mirror/profile initialization remains a separate possible effect; do not delete those records as automatic rollback.
Success returns data.artifacts. The query selects every developer_mobile_artifacts row for app_id, ordered platform ASC,release_track ASC,updated_at DESC. It has no LIMIT, cursor, platform/release-track filter, approval filter or final id tie-breaker. Draft records may be returned and equal sort keys do not promise stable order.
Input requires appId. Only that selector is used by this GET; broad generic empty-schema keys do not implement platform, status, release-track or pagination options. The concrete list path permits suspended reads and does not require completed onboarding. It still requires the same app/workspace and actor read checks as the other app configuration reads.
Each record has id,appId,developerId,organizationId,platform,packageName,bundleId,versionName,buildNumber,artifactType,artifactUrl,checksumSha256,releaseTrack,distributionChannel,catalogCategory,status,minimumOsVersion,supportedDeviceClasses,metadata,createdAt,updatedAt. It does not project workspaceId. The mapper parses device classes/metadata and applies defaults; it does not re-run the mobile-artifact save validator.
An artifactType metadata row can have empty artifactUrl/checksum. The list endpoint neither downloads bytes nor verifies a digest/signature, URL availability, OS/device compatibility, store approval, rollout, installability or production runtime. status, releaseTrack and distributionChannel remain saved labels. A checksum string here is not a completed checksum verification.
This authenticated developer-console collection is separate from the approved public artifact catalog. It does not assert that a draft/internal record is publicly discoverable or that a public catalog item is currently installable. Do not automatically follow authored URLs, execute/install a package, promote a track or mutate a release status to verify this read.
Worked responses
One saved draft configuration record
Complete source-derived synthetic UNRUN HTTP200 after all context/app checks succeed. Exactly one fictional saved draft record is present. It is not an execution, approval, provider result, download or install.
{
"success": true,
"message": "Mobile artifacts fetched successfully",
"data": {
"artifacts": [
{
"id": "artifact_docs_fixture",
"appId": "app_docs_fixture",
"developerId": "dev_docs_fixture",
"organizationId": "org_docs_fixture",
"platform": "android",
"packageName": "invalid.fixture.docs",
"bundleId": "",
"versionName": "0.0.0",
"buildNumber": "1",
"artifactType": "metadata",
"artifactUrl": "",
"checksumSha256": "",
"releaseTrack": "internal",
"distributionChannel": "managed_catalog",
"catalogCategory": "topolo-apps",
"status": "draft",
"minimumOsVersion": "",
"supportedDeviceClasses": [
"phone"
],
"metadata": {},
"createdAt": "2026-10-21T08:00:00.000Z",
"updatedAt": "2026-10-21T08:00:00.000Z"
}
]
}
}
Inspect the actual saved record in the original context; draft metadata authorizes no subsequent operation.
A successful empty collection
Complete synthetic UNRUN HTTP200 after successful auth/workspace/app checks and an empty successful database query. This is not a dependency failure or missing/inaccessible app.
{
"success": true,
"message": "Mobile artifacts fetched successfully",
"data": {
"artifacts": []
}
}
Retain the scoped empty collection; do not create a record or change access to make it nonempty.
App not visible in this workspace
Complete synthetic UNRUN HTTP404 after shared context resolution for a missing app or workspace/actor mismatch. This deliberately does not distinguish inaccessible from absent data. Initialization can already have occurred.
{
"success": false,
"error": {
"message": "Developer app not found"
}
}
Preserve actual refusal/request id and original scope; do not try another organization, guess identifiers or broaden grants.
Verify and recover
-
Read data.artifacts[].id and compare appId/organizationId with the actual original app/context. Identify the intended platform and release track from the returned fields rather than assuming the first row is the latest or approved build.
-
Interpret version/build/type/url/checksum/status as saved metadata. Empty artifact URL on a metadata record is not a download failure; a nonempty URL and hash are not artifact verification or installation evidence.
-
Preserve missing/inconsistent metadata or actual read refusal for the owner. A separately authorized artifact download/release has its own discovery, byte verification and release custody; do not install or promote anything as list recovery.
The selected query has no saved-record mutation to undo; shared initialization can still have separate effects. Do not delete a profile/mirror or perform a business operation as an automatic inverse.
Change log
- 2026-10-21: Added complete source-qualified response envelopes, saved configuration field meanings, exact collection/access behavior and synthetic examples. Provider execution, sync, download, installation and production runtime remain separate evidence. Examples are unrun.