Savra

How We Passed Google OAuth Verification in a Day: The Step-by-Step Playbook

Google approved our OAuth app verification in a day. Step-by-step: scope list, privacy policy, branding, justifications, demo video, submission, what changes after.

Kash · FounderUpdated Aug 14, 202610 min read
Poster: "Approved in a day" over a soft pastel sky with the Google logo and a "Approved" stamp (How We Passed Google OAuth Verification in a Day: The Step-by-Step Playbook)
On this page

We filed Savra's Google OAuth app verification on a Wednesday. On Thursday morning the approval email arrived from Google's Third Party Data Safety Team: both sensitive scopes approved, no questions asked, no revision round. The console had quoted three to five days to first contact and a review of up to six weeks.

Our read of that speed: the reviewer opened the file and found nothing to ask about. This post is the full sequence we ran to get there, in order, with the action for each step, the reason behind it, and the trap that waits inside it. The three earlier posts in this series go deep on the Ads developer token, the two verification tracks, and the demo video; this one is the checklist that ties them together, plus what the approval itself changes.

What did Google approve, and how quickly?

The email approves the OAuth App Verification request for our Cloud project for two scopes: Google Analytics read-only and Google Ads. Those are the two the console classifies as sensitive. Our other four scopes, Search Console read-only plus openid, email, and profile, sit under non-sensitive on the Data Access page and needed no review. The Verification Center now shows two green statuses: branding verified and shown to users, data access verified.

The timeline, so you can calibrate:

Date

Event

Tuesday, Aug 4

Google Ads API Basic Access approved (a separate track, covered in post 1)

Tuesday, Aug 11

Brand verification passed and published

Wednesday, Aug 12

Demo video recorded, uploaded unlisted, verification submitted

Thursday, Aug 13

Approval email, 10:22 in the morning

What are the steps, in order?

Ten steps. Run them in this order, because each one unlocks or protects the next.

Step 1: Derive the scope list from your code

Open the code that builds your OAuth URLs and write down every scope every flow requests on the client you are verifying. If the same client also powers "Sign in with Google", include that flow's scopes too. Your Data Access declaration must equal that union.

Ours came to six: openid, email, and profile from sign-in; openid, email, Search Console read-only, Analytics read-only, and Ads from the data connection. The trap is the tidy-up. Profile appears only in sign-in, and trimming it from the declaration would have made the filing disagree with the consent screen in our own video.

Then check the classification. The Data Access page groups scopes into non-sensitive, sensitive, and restricted, and marks the last two with lock icons. Only the locked ones need a justification and a demonstration. Search Console read-only landed under non-sensitive for us, which cut the written work by a third. Restricted scopes such as full Gmail or Drive access add an annual security assessment; if you can build the feature without one, do.

Step 2: Make your privacy policy true before you make it public

The human reviewer reads your privacy policy. Host it on the authorized domain, link it from the homepage footer, and make sure it says, in plain sentences, how the app accesses, uses, stores, and shares Google user data. Include the Limited Use disclosure the Google API Services User Data Policy requires. Name the scopes. State the read-only promise if it is true.

Then make the product match the policy. Ours says disconnecting revokes access and deletes stored tokens, and before filing we shipped that: disconnect deletes the tokens and revokes the Google grant when it is that Google account's last connection to the app. A policy that promises revocation, sitting over a disconnect button that only hides a card, is the kind of gap a reviewer is trained to spot, and the kind you cannot fix during review without restarting the clock.

Put your terms page at a stable URL and name the same legal entity on both pages. We replaced our marketing site during this process and kept both URLs identical, so the consent screen links never needed a change.

Step 3: Verify the domain in Search Console with a project Owner or Editor

Brand verification checks that your authorized domain is verified in Search Console by an account that holds Owner or Editor on the same Cloud project. A domain verified years ago by an agency account, or by a teammate who has since left, does not count. Do this with the account that will run the console steps, and do it first, because everything downstream reads this flag.

Step 4: Complete Branding, verify it, and publish it

Under Google Auth Platform in the Cloud console, fill in the Branding page: app name, logo, user-support email on a monitored inbox, homepage, privacy URL, terms URL, and the authorized domain. Click Verify Branding. The check is automated and finished in minutes for us. Then click Publish. Verified-but-unpublished branding blocks the scope submission the same way unverified branding does, and the Verification Center's submit page stays locked until the publish lands.

One more reason to do this early: the Google Ads API Basic Access form states that a brand-verified project gets expedited review. One automated check speeds up two separate queues.

Step 5: Set Audience to External and In production

Verification cannot complete from Testing. Switch the Audience page to External and In production before you record anything, because the consent screens in your video should be the production ones. Note the user counter on that page while you are there; sensitive scopes cap around 100 users until verification passes.

Step 6: If you use the Ads scope, get the developer token approved first

The Ads scope brings a second bureaucracy: the developer token in your Manager Account's API Center. Apply for Basic Access before you plan the video, because the Ads scene has to show real campaign data coming back, and a token stuck at test level returns errors instead of rows. Google approved ours on August 4 as an external reporting tool.

Then run the feature end to end before you press record. Our first attempt after approval failed on an API version the client library had pinned months earlier, which Google had since retired. It was a one-line fix. Found on camera, it would have cost the take.

Step 7: Write the justifications to a template, inside the character budget

The Verification Center gives you one justification field for all sensitive scopes together, with a 1,000-character limit. Two sensitive scopes means about 450 characters each. Whatever a teammate typed there months ago is what Google will read, so open the field and rewrite it rather than trusting it.

Each scope's paragraph should answer four things, in this order:

  1. Which feature the customer sees, and that the data is the customer's own.
  2. What the app reads, in concrete nouns: reports, metrics, dimensions.
  3. Why no narrower scope works.
  4. What the app never does with the data: no selling, no sharing with ad platforms or brokers, no model training, and, for read-only scopes, no writes.

Google Ads deserves one extra sentence. The Ads API exposes a single scope whose consent text reads "see, edit, create, and delete", and you cannot soften it. State that no read-only variant exists, that the app uses the scope for reporting only, and that any future write feature would require the customer's explicit per-action confirmation and a policy update. Write it before a reviewer has to ask.

The video is where the reviewer watches your claims run. Requirements: English narration or captions, browser URL bar visible throughout, each consent flow recorded in one continuous take from button click to redirect, and every sensitive scope shown returning real data inside the product. If your client powers sign-in with Google, show that flow too, with a Google account that has never granted to your app, so its first-grant consent screen appears.

Our scene list ran: homepage and footer privacy link; sign-in with a fresh account; the connect flow from a disconnected state, every consent checkbox ticked on camera, the client ID held readable in the URL bar; the customer choosing which site, property, and ad account the app may read; three scenes of Search Console, Analytics, and Ads data returned for that account; the in-app disconnect. Hard cuts between scenes, none inside a consent flow.

Two rules from that day. Keep the "Google hasn't verified this app" interstitial on camera; the submission form says it must be shown, and it vanishes after approval. And end at the in-app disconnect rather than the Google-side connections page, because a disconnect that revokes only on the last connection looks like a failed revoke when another workspace is still linked.

Upload unlisted, put scene timestamps in the description, and check that the link opens in a logged-out browser.

Step 9: File in the Verification Center, and read the form as a pre-review

The data-access submission asks for the justification (one field, sensitive scopes only), the video link (its own required field), an additional-information box, and a short questionnaire. We spent the free-text box on a map of the two OAuth flows and which scopes each one exercises, plus a pointer at the video timestamps. The questionnaire asks four yes-or-no questions establishing that the app is a real production product rather than personal, internal, or still in development, followed by acknowledgements. Answer them and submit.

The status flipped to under review the moment we submitted, and the console told us to expect first contact within three to five days and a review of up to six weeks.

Step 10: Freeze, watch every listed inbox, then read the approval as a contract

While the review runs, change nothing the reviewer is reading: branding, scopes, publishing status, legal pages. The approval email lands in the inboxes of every Owner and Editor on the Cloud project, so those accounts need to belong to people who read mail. Ours arrived the next morning.

What did the reviewers have in front of them?

We cannot see Google's checklist. We can see what the reviewer had, and that none of it triggered a question: a scope list equal to the union of two real flows, a video that demonstrated all six scopes on production with real data, a justification that named each locked scope and pre-empted the Ads wording, and a privacy policy on the authorized domain that made the same promises in the same words. Every artifact described the same product. Building that agreement before filing took us a week of small fixes. Building it under review would have restarted the clock each time.

What changes after approval?

Two things you will notice and three you must remember.

The interstitial is gone: users connecting Analytics or Ads no longer click through the unverified-app warning. And the sensitive-scope user cap lifts, so the counter on the Audience page stops mattering.

The approval email closes with three rules worth pinning to your team's runbook:

  1. Keep the Cloud project's Owner and Editor accounts current. Future communications, including any re-review, go to those addresses.
  2. Any new scope, and any change to your OAuth consent-screen configuration, requires a new verification request. That covers branding fields, so treat a rename, a logo swap, or a new authorized domain as a filing event with its own justification and video, and batch such changes.
  3. Verification is not inherited. Unapproved sensitive or restricted scopes stay unusable until they pass their own review, so add them one filing at a time.

Why do we think it went this fast?

Honest answer: we do not know, and one data point is not a pattern. What we can say is which choices removed reasons for a reviewer to write back. We asked for sensitive scopes only, so no security assessment sat in the path. We finished the Ads token and brand verification before filing, so the submission form had no red flags to clear. The video covered both flows and every declared scope, with timestamps. The justification and the privacy policy agreed with each other and with the product. Do the same and you may still wait; the queue is Google's. What you control is whether the reviewer has to write back.

FAQ

How long does Google OAuth verification take?
Google quotes 3 to 5 days to first contact and up to 4 to 6 weeks overall. Ours cleared the morning after filing with no questions. Plan for weeks; prepare so the reviewer has none.

Do I have to submit the demo video with the form?
Yes. The video link has its own required field, so record and upload before you file. Unlisted YouTube with timestamps in the description works.

What changes after approval?
The unverified-app interstitial disappears and the roughly 100-user cap on sensitive scopes lifts. A new scope or any consent-screen change means a new verification request, and unapproved scopes stay unusable.

Which scopes need a written justification?
Only the ones the Data Access page marks sensitive or restricted. For us that was Analytics read-only and Ads; Search Console read-only was classified non-sensitive.

Keep reading

See if your brand sounds like itself.

Run the free 90-second Brand Genome audit. No card, just your score.