Using AI

Google OAuth "Testing" Status Expires Refresh Tokens in 7 Days: Publishing to Production and Gmail Restricted Scope Verification

Google OAuth "Testing" Status Expires Refresh Tokens in 7 Days: Publishing to Production and Gmail Restricted Scope Verification

Photo: Google for Developers (紹介目的で使用) via developers.google.com

Good morning, this is まさきん.

If your Google OAuth publishing status is “Testing,” refresh tokens expire after 7 days. I ran into this deadline with a personal tool that imports my health data. Here’s how to publish to production, including verification for Gmail restricted scopes, based on the official documentation.

This information is current as of publication. Please check the official sites for the latest details.

POINT
  • For apps with an external user type in “Testing” status, refresh tokens expire after 7 days
  • Even for a personal tool, publishing to “In production” removes the 7-day limit
  • Publishing requires a homepage URL and a privacy policy URL; a contact email alone isn’t enough
  • With sensitive or restricted scopes, users still see an unverified app warning in production until you pass verification
  • Tokens can also expire for reasons other than the 7-day rule, such as 6 months of non-use or token count limits

Why Tokens Expire After 7 Days

Let’s start with the bottom line. Google’s official documentation says, in essence:

For a project with an external user type and a publishing status of “Testing,” refresh tokens issued there expire after 7 days.

There is an exception. If the only scopes you request are name, email address, and profile, specifically ones that stay within userinfo.email, userinfo.profile, and openid, the 7-day limit doesn’t apply. An app that only uses Sign in with Google isn’t affected.

Flip that around, and any app that reads Gmail or Calendar data is affected. The same goes for health data. Even a personal script gets the same treatment if its user type is external.

”Testing” vs. “In Production”

You can check the publishing status on the “Audience” screen of the Google Auth Platform, which is where the old “OAuth consent screen” used to be. Here’s how the two states differ:

ItemTestingIn production
Who can use itOnly registered test usersAnyone with a Google account
Test user limitUp to 100None
Consent validityExpires 7 days after consentNo 7-day limit
Refresh tokensExpire after 7 daysValid until another expiration condition applies
Warning before consentA test access warning appearsWarning before verification for sensitive scopes
VerificationNot applicableRequired depending on scopes

Testing is really meant as a development state. Only people added as test users can grant consent, and that consent expires after 7 days.

In production, on the other hand, anyone can grant consent. For a personal tool that runs automatically every day, production is probably the better fit.

What Was Happening with My Tool

My tool was using Google’s Health-related APIs, and the project’s publishing status was still “Testing.”

That meant my refresh token was set to expire 7 days after it was issued. Once it expired, my automatic imports would stop. So I decided to fill in the branding and publish to “In production.”

How to Publish to Production

Here’s the flow from the official help, in the order I actually went through it:

  1. Open the Google Cloud console and check the project selector at the top of the screen
  2. Open “Branding” in the Google Auth Platform
  3. Check the app name and the user support email
  4. Enter the URLs for the app homepage and privacy policy
  5. Add the domain of those URLs to the authorized domains
  6. Enter the developer contact email and save
  7. On the “Audience” screen, click “Publish app” and continue through the confirmation
  8. Confirm that the publishing status now says “In production”
  9. Grant consent again from the tool and get a fresh refresh token

The official help recommends registering the authorized domains first. Adding them before the homepage and other URLs will likely save you some back-and-forth.

Two Things That Tripped Me Up

I Was in the Wrong Project

The first stumble was a mundane one. The Google Cloud console I’d opened was showing a different project: the one I’d created for my blog’s analytics.

The Google Cloud console remembers the last project you opened, so if you open it without thinking, you might end up somewhere else. Glancing at the project name at the top of the screen before you start is all it takes to avoid this.

When you have several personal projects, their names start to look alike. Giving them names that make their purpose obvious is a quietly effective safeguard, too.

A Contact Email Alone Isn’t Enough to Publish

The second issue was that the publish button wouldn’t become active. At first, I had only entered a contact email.

Publishing required the URLs for the app homepage and privacy policy. The official help also says these links are mandatory for external production apps. Apparently, if they’re missing, you can’t even submit for verification.

What Publishing Required

Here are the fields the Branding screen asks for, organized based on the official help:

FieldWhat it isWhat the official help says
App nameThe name shown on the consent screenNames that could be confused with Google trademarks are not allowed
User support emailWhere users can send questionsYour own address or a group you manage
App homepageA page describing the appRequired for external production apps
Privacy policyA page describing how data is handledRequired for external production apps
Terms of serviceThe app’s terms pageOptional
Authorized domainsThe domain of the URLs aboveRegister before entering the URLs
Developer contactWhere Google sends notificationsKeep it up to date
LogoThe icon on the consent screenShown in production after verification

The logo is optional. However, uploading a logo to an external production app triggers verification. For a personal tool, leaving it blank is probably less hassle.

What to Use for the Homepage and Policy

I used pages on my own blog for the homepage and privacy policy, and added otokuken.com to the authorized domains.

The official help also lists requirements for verification: the homepage must be on a verified domain you own, the privacy policy must be on the same domain as the homepage and linked from it, and the policy must describe how Google user data is handled, among other things.

If you’re not going through verification, you might be able to publish without being that strict. But you may need verification later, so meeting the requirements from the start gives you peace of mind.

Some Scopes Require Verification

Publishing to production doesn’t make everything unrestricted. The key is how your scopes are classified.

Scope categoryVerificationBehavior before verification
Non-sensitiveNot required (brand verification if you display a name and logo)Users can consent without a warning
SensitiveRequiredAn unverified app warning appears
RestrictedRequired, plus an annual security assessmentAn unverified app warning appears

The category is shown automatically when you add a scope in the Cloud console, so you can check which one your app falls into there.

There is an exception for personal-use apps, though. According to the official help, personal apps with fewer than 100 users can keep being used without verification. In that case, users click through the unverified app warning when they sign in.

The Unverified App Warning and User Limits

If you request sensitive scopes before verification, a warning appears before the consent screen, saying something to the effect of “Google hasn’t verified this app.”

There’s also a user cap. Apps that show the unverified app screen are limited to 100 new users in total. According to the documentation, this limit applies over the entire lifetime of the project and can’t be reset.

For a tool only you use, this limit will almost never be an issue. But if you let family or friends use it too, it’s worth keeping the headcount in mind.

If you’re taking stock of things that expire or need renewing, why not review your monthly phone bill at the same time? It might lighten your fixed costs a bit.

Try the fee simulator and get 100 points, no sign-up required Review your phone bill with Rakuten Mobile

Clicking this opens the Rakuten login page. Once you log in, you’ll see the campaign details.

Other Ways Tokens Can Expire

Even in production, refresh tokens don’t last forever. Here are the expiration conditions listed in the official documentation:

ConditionDetails
The user revoked accessThey removed the app’s connection from their Google account
Unused for 6 monthsThe refresh token wasn’t used for 6 months
Password changedFor tokens that include Gmail scopes
Token count limitUp to 100 per account per client ID
Time-based accessAccess was granted for a limited period and that period ended
Admin restrictionsA Workspace admin restricted the service
Session controlYour Google Cloud organization sets a session length

The one to watch out for most is the token count limit. When you hit it, the oldest token is invalidated without warning. If you keep re-consenting while testing, you could end up wiping out the token you were using in production.

There’s also an overall limit, and the official docs suggest a workaround of keeping authorized clients to around 15 to 20 per account.

Getting a New Token

Once you’ve published to production, the next step is getting a new token. The official docs say consent granted during Testing expires 7 days after it was given, so after publishing, the user needs to grant consent again.

In my case, I still need to do this. I plan to run my tool’s auth flow and re-consent in the browser.

After you get the new token, it’s a good idea to stop using the old one. Write the new one to wherever you store it and delete the old one. If you keep tokens in multiple places, you may lose track of which one is actually live.

Common Mistakes and Pitfalls

Here’s everything so far, summarized as common mistakes:

MistakeWhat happensHow to prevent it
Working in the wrong projectYour settings don’t take effectCheck the project name before starting
Trying to publish without URLsThe publish button can’t be clickedPrepare the homepage and policy first
Leaving authorized domains for laterYou get stuck when registering URLsAdd the domain first
Assuming publishing alone fixes itOld tokens still expire after 7 daysRe-consent after publishing
Re-consenting over and overOld tokens get invalidated without warningOnly get new tokens when you need to
Leaving it idle for half a yearThe token expiresSet it up to run regularly

When a personal tool stops working, nobody tells you. That’s why I think it’s important to build it so an expired token surfaces as an error you’ll actually notice.

I’ve also written about hitting a free tier limit in How to work around the Cron Triggers limit on the Cloudflare Workers free plan. For personal automation, this kind of “silently stopping” might be the biggest weakness.

Things to Confirm Before You Start

Warning

According to the official docs, consent granted during Testing expires 7 days after it was given. It’s safest to assume that publishing to production won’t extend it. After publishing, re-consent and get a new token.

I’ve written about my overall automation setup in Having AI make a one-page “today’s briefing” while I get ready in the morning. Systems like that are all quietly held up by tokens behind the scenes.

FAQ

Q. How long until my token expires if I stay in Testing?

For projects with external users in Testing, tokens expire after 7 days, counted from the moment of consent. If your scopes are limited to name, email, and profile, this limit doesn’t apply.

Q. Can I publish to production even if I’m the only user?

Yes. The official help says personal apps with fewer than 100 users can keep being used without verification. However, sensitive scopes will show an unverified app warning.

Q. Why can’t I click the publish button?

You may be missing required branding fields. External production apps need homepage and privacy policy URLs. Also check that your authorized domains are registered.

Q. Once I publish, can I keep using my current token?

The official docs say consent granted during Testing expires 7 days after it was given. To be sure, re-consent and get a new token after publishing. This requires action from the user.

Q. Do I absolutely have to go through verification?

If you use sensitive or restricted scopes for the general public, verification is required. There’s an exception for personal apps with fewer than 100 users, which can keep being used without it. Restricted scopes also require an annual security assessment.

Q. How many test users can I register?

Projects in Testing can have up to 100 test users. Once someone is added, they count against that limit.

Q. In production, can I use a token forever?

Not forever. Tokens expire if they go unused for 6 months or if the user revokes access. There’s also a limit of 100 per account per client ID.

The official help says displaying the app name and logo requires verification. Before verification, the app’s domain is shown instead. For a personal tool, not uploading a logo is probably less hassle.

Official Sources I Referenced

Summary

The reason my refresh token was expiring after 7 days was the “Testing” publishing status. Even for a personal tool, publishing to production removes that limit.

What I needed were URLs for a homepage and a privacy policy, plus registering the authorized domain, and being careful not to work in the wrong project. From here, I’m moving on to getting a new token.

If you have anything running automatically, it’s worth taking a quick look at its status.

Try the fee simulator and get 100 points, no sign-up required Check Rakuten Mobile plans and prices

Clicking this opens the Rakuten login page. Once you log in, you’ll see the campaign details.

This article contains affiliate advertising. If you sign up for a product or service through a link on this site, we may receive compensation from the partner company. The site operator is also an employee of Rakuten Group and may receive compensation through an employee referral program. The content and opinions here are based on the operator’s own experience and research regardless of any advertising relationship, but please read with the above in mind. See the Disclaimer & Affiliate Disclosure for details. Disclaimer & Affiliate Disclosure

This article includes machine-translated content. Please check the official Rakuten Mobile multilingual page for exact terms.

If you have concerns about Rakuten Mobile coverage or signal quality, you can consult through the official signal improvement request form .

ABOUT THE AUTHOR
まさきん

Rakuten Group employee · Digital Marketer (holds a Financial Planner qualification)

In his early 40s, part of a dual-income household with four kids. Works as a digital marketer at Rakuten Group, while also using his Financial Planner (FP) qualification to focus on household finances and building assets.

View Profile

Related Articles

RELATED
Gemini (Google AI Pro) Family Sharing Covers Up to 5 Family Members: Setup Steps and Scope Using AI

Gemini (Google AI Pro) Family Sharing Covers Up to 5 Family Members: Setup Steps and Scope

Google AI Pro can be shared with up to 5 family members besides the manager. The Gemini app and storage are shared, while YouTube Premium Lite is for the manager only. Flow limits are shared across the family. I went through the official help to sort out the setup steps and how child accounts are handled.

2026.10.13 · 11 min read
3 Reasons Your AI Subscription Billing Date Does Not Match Your Budget: Claude Upgrades Change It Using AI

3 Reasons Your AI Subscription Billing Date Does Not Match Your Budget: Claude Upgrades Change It

If you upgrade Claude to Max mid-month, your billing cycle resets and that day becomes your new billing date. The yen conversion of dollar charges is set when the data reaches your card company, and statements and budgeting apps lag by a few days. Here are 5 steps to decide the month using the receipt email as your source of truth.

2026.10.13 · 12 min read
Turning Unprocessed freee Accounting Transactions into a Monthly Reconciliation Run: 7:30 on the 5th, 3 Categories, and a Cap of 15 Items Handed to a Human Using AI

Turning Unprocessed freee Accounting Transactions into a Monthly Reconciliation Run: 7:30 on the 5th, 3 Categories, and a Cap of 15 Items Handed to a Human

About 18 unprocessed transactions sat untouched in freee Accounting across 6 weekly checks. Here is my design for a reconciliation run on my home Mac at 7:30 a.m. on the 5th of each month, and where I drew the line: one monthly task for the items that can be confirmed, and one task each, capped at 15, for the ones that need a human decision.

2026.10.12 · 13 min read
Switch to Rakuten Mobile, get up to 14,000 points Try the fee simulator and get 100 points, no sign-up required →
Apply Now →