What it takes to get approved on the Zoom App Marketplace

roee_tsur1 pts0 comments

What it takes to get approved on the Zoom App Marketplace · Sponja<br>Skip to contentTL;DR<br>We just got Sponja approved on the Zoom App Marketplace after 20 days and 4 rejection rounds. This is what each round actually surfaced: reviewer login access, OAuth scope auditing, a configuration issue Zoom's testing helped us catch, and listing-level fixes. Posting our notes while they're fresh in case any of it saves someone else a round.<br>I want to write this down while it's fresh. Almost nothing I found online prepared me for what the Zoom review team actually checks, and we just came through it the hard way.

Sponja is a post-event intelligence app for Zoom meetings and webinars. The integration was live for our early customers before we submitted to the marketplace, so I walked in thinking "we've been running this in prod for weeks, how bad can the review be." I was wrong about that.

If you're about to submit, or you're in the middle of a review cycle right now, this is what they actually care about.

Round 1: They need to be able to log in (so they can actually use your app)

The first rejection came back with the subject line "Account Credentials - CREATE."

What this means: the review team is going to log into your app and exercise the integration end to end. They need credentials. If your only auth method is "Sign in with Google" or any other federated SSO, they can't create an account on their own, and they will reject you.

Sponja was Google-SSO only at the time. I had to ship a second auth path. We added a separate email and password login flow specifically for the Zoom review team, with their account provisioned manually. It's normal Firebase auth on a dedicated route. The review team uses it.

If I had read this post before submitting, I would have built that flow upfront. It's the lowest-effort thing on this entire list and it removes a full round trip.

Round 2: They test every scope and remove the ones you don't use

This is the round that taught me the most. The reviewer sent this email back:

By following the test plan provided, we have validated the use of scopes and found:

webinar:read:webinar - No calls to fetch webinar details were found.

webinar:read:list_past_participants - No calls to list webinar participants were found.

cloud_recording:read:list_user_recordings - The developer lists recordings by Meeting ID, not by User ID.

cloud_recording:read:meeting_transcript - Although you receive a 'transcript ready' webhook, you never call the API to actually read or download that transcript.

Please remove these scopes at this time to pass the functional portion of this review. If you need these scopes, please expand on your test plan that includes steps to test for them.

Two things to know about this round.

The reviewer instruments every test call against your app and checks it against the scopes you requested. If a scope isn't exercised during their test, you either remove it or write a test plan step that forces them to hit it. There's no arguing. If you want to see how this maps to a real integration, we publish exactly what data Sponja reads from Zoom and what each scope is used for.

The test plan you submit is the whole game. They follow it literally. If your test plan only covers meeting ingestion and not webinar ingestion, you cannot keep the webinar scopes. The fix isn't to push back, it's to write a plan that walks them through every integration path you actually need.

The interesting one for us was cloud_recording:read:meeting_transcript. We had requested it because we ingest transcripts and the scope name says "meeting_transcript." But that scope actually gates a separate endpoint called GetMeetingTranscript, which we don't call. Transcripts come down through the recordings file listing under a different scope. We removed the scope and kept the transcripts. The takeaway: map scopes by endpoint, not by what the scope name sounds like. The granular scopes table at developers.zoom.us is the source of truth.

We expanded the test plan to cover webinars, dropped the unused scope, and resubmitted.

Round 3: When their tests fail, sometimes you really are the bug

The reviewer came back with two screenshots. One showed their Zoom developer dashboard with our API calls erroring out. The other showed our dashboard with their test events stuck in "ingesting" forever.

My first instinct was that their test events just didn't have cloud recording enabled. That would explain the 404s. It was the wrong instinct.

After spending an hour in Cloud Logs and Firestore for that specific team, we found the actual cause. We had recently rotated our Zoom credentials and the dev and prod Zoom Client IDs ended up in the wrong secret slots. Production was verifying webhook signatures against the dev secret. Every signature failed silently. Every event got stuck.

The blast radius was narrow (events that came in during a short window after the rotation), the fix was one secret update, and we added a...

zoom test scope round actually review

Related Articles