← All frames
Flow 4 · Marketplace publish · Frame (g) · route /admin/marketplace-requests (platform admin)

Marketplace review queue

Platform admins only. Every pending request, oldest first, with what a reviewer needs to decide: the app, its publisher (the owning org), the creator as contact while they're a member, the requester's notes. Approve lists it; Reject requires a reason the requester will read.

(g1) Pending requests

Pending review

3 requests · oldest first

AppPublisherNotesSubmittedActions
Expense trackerexpense-tracker
Acme CorpContact: Dana Levi
Used daily by our finance team for six months… 2 Oct 2026
View
Shift plannershift-planner
Northwind LogisticsContact: former member
— 3 Oct 2026
View
Recipe boxrecipe-box
Sam OrtizPersonal workspace
Family recipes with a shopping list. 4 Oct 2026
View
(g2) Approve — POST /apps/{slug}/publication-requests/approve { notes? }
(g3) Reject — reason required (1–2000), shown to the requester verbatim
(g4) 409 NOT_PENDING — another admin decided first: row leaves the queue with a notice
(g5) Empty queue

Nothing to review

New marketplace requests will appear here.

(g6) Loading, and load error with retry
(g7) Not a platform admin — 403 in place; no nav entry for non-admins

Platform admins only

You don't have access to marketplace review.

Contract gap — commissioned by approval. app-registry 1.2.0 has approve/reject per app but no way to list pending requests. This queue needs an additive, platform-admin-only, cursor-paginated GET /publication-requests?status=pending returning AppPublication plus the app's display name, icon and organizationId (flag-gated like its siblings). contract-designer owns that amendment (1.3.0, minor); until it lands this flow cannot be implemented — the frames do not invent a client-side scan of GET /apps.
Decisions. Approve → visibility=marketplace; Reject → { reason }, the app may be resubmitted. Both remove the row optimistically and restore it on any non-2xx except 409 NOT_PENDING (g4). Publisher is the owning org; the contact column follows the frame (e) rule — a former member is never named. Nav entry lives beside the other admin consoles and renders only for platform admins.
Test hooks: [data-frame='07-review-queue'] · [data-panel='publication-queue'] · [data-queue-item='expense-tracker'] · [data-action='approve-publication'] · [data-action='reject-publication'] · [data-panel='approve-publication-dialog'] · [data-action='confirm-approve-publication'] · [data-panel='reject-publication-dialog'] · [data-input='rejection-reason'] · [data-action='confirm-reject-publication'] · [data-error-code='NOT_PENDING'] · [data-state='empty'] · [data-state='loading'] · [data-state='error'] · [data-state='forbidden'].

← Publish to marketplaceIndex →
Review · app-builder approve or reject each flow ↓
build-entrypendingApproveReject
build-sessionpendingApproveReject
creator-ownershippendingApproveReject
marketplace-publishpendingApproveReject