How to get a Google Maps API key for WordPress (and restrict it before you use it)
Something on your site is showing a grey box, a darkened map with a watermark across it, or a settings field labeled API key that you did not expect to fill in. You are mid-task and you want it to stop.
This is the procedure. Seven steps, in order, written to be followed with the Cloud Console open in another tab.
Worth saying once: Modern Maps does not use API keys and does not contact any Google service, so we have nothing to gain from rushing you to the end. Most guides on this term are published by plugins that need you to finish the setup, which is why they stop the moment the map turns on. The two steps that decide whether a leaked key becomes a bill are restricting the key and setting a budget alert, and both of them come after the map already works. Here they are steps 5 and 7, not a footnote.
Do you actually need a key?
Three cases. Only one of them ends in the Cloud Console.
An iframe copied out of Google Maps. No key. The embed code Google hands you from the Share menu is already authenticated. Close this tab.
A plugin, theme, or page builder that draws an interactive Google map. Key required. Anything that loads the Maps JavaScript API needs one, with billing attached to it. This is the case the rest of the post is written for.
A map plugin that renders its own basemap. No key, and no Cloud project either. If the settings screen has no key or token field at all, the plugin is not calling a paid map service and you can close this tab. If it does have one, check the plugin’s documentation for whose key it wants, since some plugins take a Mapbox or MapTiler token rather than a Google one.
Not sure which one you have? Start by working out which method you are actually using, then come back.
What you need before you start
- A Google account.
- A billing account with a real payment card on it. Google requires the card even for usage inside its free allowance. This surprises people, and it is where most abandon the process. There is no way around it.
- Every domain the map will legitimately load on, staging included.
- The list of APIs your plugin needs, taken from your plugin’s documentation.
- Ten minutes.
Step 1: create a Cloud project
In the Cloud Console, create a project and name it after the site. example-com-maps beats My Project 48392 in a year, when you are looking at a bill and trying to remember what generates it.
One project per site. It costs nothing extra, it keeps each project’s API list short, and if a key ever leaks you can delete the whole project without taking down every other site you run.
Step 2: turn on billing for that project
A billing account and a project are separate things, and creating one does not attach it to anything. Open the billing section for the project you just made and link a billing account, creating it if this is your first.
Do not confuse a billing account with a budget. The billing account is the card. The budget is the warning system, and it is step 7. Neither one is a spending cap.
Prices change often enough that any figure printed in a blog post is a liability. Read Google’s current Maps Platform pricing directly, and check the date on whatever else you find.
Step 3: enable only the APIs your plugin asks for
Find the API library for your project and enable what the plugin actually calls:
- Maps JavaScript API, for an interactive map you can pan and zoom. Most plugins.
- Geocoding API, if the plugin turns a typed address into coordinates.
- Places API, if it offers address autocomplete.
- Maps Static API, if what renders is really an image.
Take that list from your plugin’s documentation rather than guessing, and resist enabling extras to save a return trip. Every enabled API is another service a stolen key can be spent against. A leaked key scoped to two APIs is a much smaller morning than one with fifteen.
Step 4: create the key
Open the credentials screen for your project and create an API key. Google generates it immediately and shows it in a dialog.
Read this part slowly. The key on your screen works from any website, against every API you just enabled, for anyone who has the string. That is its default, not a mistake you made, and it is not a condition to leave it in. Do not paste it into WordPress yet. Finish step 5 first.
Step 5: restrict the key, both ways
Two independent restrictions live on the same screen. Set both.
Application restrictions. Choose websites, then list every host the map legitimately loads on. Patterns, not bare domains:
https://example.com/* https://www.example.com/* https://*.example.com/* https://example.stagingsite.net/*
The apex and the www variant are different referrers to Google, and a redirect between them does not help, so list both. The wildcard covers subdomains. The fourth line is the staging site, which usually lives on the host’s domain rather than yours and is covered by nothing above it.
API restrictions. Switch from unrestricted to a chosen list and select only the APIs from step 3. A key scoped to one map is then useless for the rest of the project.
Restrictions take a few minutes to take effect. People change something, reload, still see the error, and conclude they broke it. Wait, hard-refresh, then judge.
Step 6: put the key into WordPress
Three places it usually goes: a field on the plugin’s own settings screen, a theme option, or a constant in wp-config.php.
// wp-config.php, above the "That's all, stop editing" line define( 'EXAMPLE_MAPS_API_KEY', 'AIzaSy...' );
The constant only works if the plugin documents that it reads one. Check first, or you will spend an hour debugging a key that nothing is looking for.
Now the honest part about secrecy. A browser key is not a secret and cannot be made into one. It ships to the visitor in your page source, where anyone can read it in two clicks. The referrer restriction from step 5 is the actual protection.
That is not permission to be careless. Do not commit the key to a public repository, leave it visible in a screenshot, or paste it into a support ticket. Exposure invites automated probing even when your restrictions hold, and it means rotating the key later.
Step 7: set a budget and an alert
In Cloud Billing, open budgets and alerts and create a budget scoped to this project. Pick a monthly amount that would worry you, then set thresholds below it so the mail arrives while the number is still small.
Check who receives it. The default recipients are the billing account administrators, which on a client site can be nobody who reads that inbox. Point it at a human.
Then keep the limitation in view: a budget alert notifies, it does not stop anything. Spending continues past the threshold, past the budget, past the second email. The only real ceiling is a per-API quota limit, set on the API’s own quota screen, which makes requests fail once the number is reached. A map that stops working is worse than one that works and better than an open-ended invoice. Choose on purpose.
Seven checks before you call it done
The last three are the ones that get skipped, and they are the ones that decide whether a leaked key becomes a bill.
| Check | What good looks like | What it prevents |
|---|---|---|
| ☐ Project | One Cloud project, created for this site and named after it | One leak taking down every site you run |
| ☐ Billing | A billing account linked to that specific project | The darkened map and the development-purposes watermark |
| ☐ APIs | Only the APIs your plugin documents, nothing enabled just in case | A stolen key being spendable across services you never used |
| ☐ Key | Created and copied out of the dialog, not yet pasted anywhere | Nothing at all. This is the unrestricted state |
| ☐ Referrers | Apex, www, wildcard subdomain and staging, all listed as patterns | The key working from anybody else’s page |
| ☐ API lock | The key restricted to the APIs from check three | A key scoped to one map being spent on the rest of the project |
| ☐ Budget | A budget with alert thresholds, mailed to an inbox someone reads | An invoice being the first notification you get |
Console labels last checked July 2026. Each row is a destination and an outcome, not a button name.
A budget alert notifies. Only a quota limit stops.
When the map still does not work
Google prints the reason, on the map or in the browser console. Match the string.
- A darkened map watermarked “for development purposes only.” Google attributes this to a key or billing problem, and in practice it is usually billing: no billing account on the project, or a key that belongs to a different project than the one you set up. Back to step 2.
RefererNotAllowedMapError. The URL loading the map is not on the allowed referrer list. Checkhttpagainsthttps,wwwagainst the apex, and whether staging is covered. This one means step 5 is working, just aimed a few characters off.ApiNotActivatedMapError. The API is not enabled on the project. Step 3.InvalidKeyMapErrorandExpiredKeyMapError. Google does not recognize the key. Almost always a truncated paste, a trailing space, or a key from a project that has since been deleted.BillingNotEnabledMapError. Says what it means. Step 2.ApiTargetBlockedMapError. The key is restricted to a list of APIs that does not include the one being called. Add the missing API to the list. Do not widen the restriction back to unrestricted.MissingKeyMapError. No key reached the script at all. Either the field you pasted into is not the one the plugin reads, or a caching layer is still serving the old page.- A grey box with no message. Open the browser console. Google logs there even when the map surface is blank, and a blank container is often not a key problem: a JavaScript error from an unrelated plugin can stop the map script before it runs.
Google keeps the full list of Maps JavaScript API error codes, including the rare ones. Searching the exact string beats describing the symptom.
One rule across all of them: do not troubleshoot by removing a restriction, not even for a minute. An unrestricted key on a live page is exactly what automated scrapers look for, and a minute is long enough.
Rotating or deleting a key
Swapping without downtime. Create the second key first. Restrict it exactly as in step 5, paste it into WordPress, confirm the map still renders, and only then delete the old one. Both keys are valid at the same time, so there is no window where the site is broken. Do it in the other order and there is.
The day one leaks. Delete it, do not merely restrict it. A leaked key that still exists is one somebody can keep testing against every future change to the project. Create a replacement, then check the project’s API metrics for traffic you cannot account for. If the key ever reached a git repository it is in the history, so rotate even after deleting the file.
If you would rather not do any of this
None of it is hard. It is long, and it does not finish, because the key you hardened today is now something you own and maintain.
Modern Maps renders its own vector basemap and never contacts a Google service, so there is no key, no Cloud project, no billing account and no budget to watch. That is the whole difference, and why Modern Maps does not ask for one covers the reasoning if you want it.
Two caveats, without hedging. If you need Street View, live traffic, Google reviews and business data, place autocomplete, or driving directions, you need Google, and no keyless plugin substitutes for those. Go and finish the seven steps. If what you need is a map that shows where something is, styled to match the site it sits on, you do not, and the preset gallery shows what that looks like before you install anything.
Setup is about a minute, which is a 60-second walkthrough rather than seven steps.